Commit Graph

11174 Commits

Author SHA1 Message Date
gsxdsm
e559b2b538 FN-7853: preserve chat thread during active streaming turns
Fix useChat so already-rendered user/assistant messages no longer flicker away while an agent turn is actively streaming.

- useChat.ts: during an active streaming turn for the current session, treat stale/empty/cross-session loadMessages responses as append-only against the visible thread instead of replacing it, merging any genuinely new same-session messages in and skipping the session-cache write when the active thread is being preserved.
- ChatView.streaming-thread.test.tsx: add coverage asserting the rendered thread stays visible across mid-turn session-update/tool-call/stale-reload churn.
- useChat.test.ts: add hook-level regression tests for the append-only/merge/cache-skip behavior during active streaming.
- docs/architecture.md, docs/dashboard-guide.md: document the append-only mid-turn thread-stability behavior.
- Add changeset (patch) for @runfusion/fusion describing the user-facing fix.

Files changed:
 .../fn-7853-chat-mid-turn-message-stability.md     |   7 +
 docs/architecture.md                               |   1 +
 docs/dashboard-guide.md                            |   1 +
 .../__tests__/ChatView.streaming-thread.test.tsx   | 130 +++++++++++++
 .../dashboard/app/hooks/__tests__/useChat.test.ts  | 208 +++++++++++++++++++++
 packages/dashboard/app/hooks/useChat.ts            |  35 +++-
 6 files changed, 380 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7853

Fusion-Task-Lineage: d9909469-082c-4eeb-81fb-b36d1a9e4705

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 11:26:53 -07:00
gsxdsm
20c6db9534 FN-7861: make pause/unpause task state update the board immediately
Patch useTasks pauseTask/unpauseTask to update local hook state and the project SWR task cache immediately on API success, instead of waiting for SSE/poll to reconcile paused state.

- pauseTask/unpauseTask now bump fetchVersionRef, patch the in-memory tasks list, and patch/clear the project SWR cache the same way retryTask/bypassReview already do
- guards against stale in-flight fetches clobbering the just-applied paused/unpaused state and against missing-id cache entries
- adds regression tests covering immediate local+cache reflection for pause and unpause, stale in-flight fetch ordering, and missing-id stability
- adds a patch changeset documenting the user-facing fix

Files changed:
 .changeset/fn-7861-immediate-pause-state.md        |   7 +
 .../dashboard/app/hooks/__tests__/useTasks.test.ts | 151 +++++++++++++++++++++
 packages/dashboard/app/hooks/useTasks.ts           |  66 ++++++++-
 3 files changed, 222 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7861

Fusion-Task-Lineage: fefbaf4f-8eb7-44a7-a1e2-ac8471a726bd

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 11:23:23 -07:00
gsxdsm
9bb74595c2 FN-7852: add one-time SQLite→embedded Postgres storage notice banner
Adds a dismissible, one-time dashboard banner announcing the upcoming SQLite→embedded-Postgres storage backend change.

- New self-contained StorageMigrationNoticeBanner component with title/body copy and a dismiss control that persists via localStorage key fusion:storage-migration-notice-dismissed
- Wire the banner into DashboardBanners alongside the CLI binary install banner for project-scoped views
- Add en locale strings (storageMigrationNotice.title/body/dismissLabel) in app.json
- Add component test coverage for render/dismiss/persistence behavior
- Document the notice in docs/dashboard-guide.md
- Add a minor changeset for @runfusion/fusion

Files changed:
 .changeset/fn-7852-storage-migration-notice.md     |  7 ++
 docs/dashboard-guide.md                            |  2 +
 .../components/StorageMigrationNoticeBanner.css    | 73 +++++++++++++++++++
 .../components/StorageMigrationNoticeBanner.tsx    | 65 +++++++++++++++++
 .../StorageMigrationNoticeBanner.test.tsx          | 82 ++++++++++++++++++++++
 .../app/components/dashboard/DashboardBanners.tsx  | 11 ++-
 packages/i18n/locales/en/app.json                  |  5 ++
 7 files changed, 242 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7852

Fusion-Task-Lineage: e3235cce-9ca3-4830-8733-a2ec46c53246

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 11:19:52 -07:00
gsxdsm
c13d2ee9c2 FN-7858: honor per-project plugin-skill toggles in session merging
Session skill merging (collectPluginSkillNames) previously ignored per-project
Skills view enable/disable toggles and only consulted each plugin's static
default, so a user disabling a plugin skill in the Skills view would still see
it merged into live agent sessions. Extracted the effective-enablement
resolver shared by dashboard discovery and engine session assembly into
@fusion/core so both surfaces stay in sync.

- Added packages/core/src/skill-settings.ts with computeSkillId/parseSkillId/
  normalizeStoredSkillPath/getSkillSettingState/resolvePluginSkillEnabled,
  exported from @fusion/core's index.
- packages/dashboard/src/skills-adapter.ts now re-exports and delegates to the
  shared @fusion/core resolver instead of duplicating its own
  getSkillSettingState/computeSkillId/parseSkillId implementations.
- packages/engine/src/session-skill-context.ts: collectPluginSkillNames now
  accepts a projectRootDir, reads project settings via skill-resolver's newly
  exported readProjectSettings/resolveProjectRoot, and calls
  resolvePluginSkillEnabled instead of only checking the plugin's static
  skill.enabled flag; mergePluginSkills passes projectRootDir through.
- packages/engine/src/skill-resolver.ts: exported readProjectSettings and
  ProjectSkillSettings for reuse by session-skill-context.
- Updated docs/plugin-management.md to document that per-project Skills view
  toggles now apply to runtime agent sessions, not just discovery.
- Added unit tests for the new core resolver and updated dashboard/engine
  tests to cover per-project toggle overrides in session merging.
- Added a patch changeset for @runfusion/fusion.

Files changed:
 .changeset/fn-7858-plugin-skill-session-toggle.md  |   7 ++
 docs/plugin-management.md                          |   4 +-
 packages/core/src/__tests__/skill-settings.test.ts |  62 +++++++++
 packages/core/src/index.ts                         |   8 ++
 packages/core/src/skill-settings.ts                | 102 +++++++++++++++
 .../dashboard/src/__tests__/skills-adapter.test.ts |  60 ++++++++-
 packages/dashboard/src/skills-adapter.ts           | 107 +++-------------
 .../src/__tests__/session-skill-context.test.ts    | 140 ++++++++++++++++++++-
 packages/engine/src/session-skill-context.ts       |  23 +++-
 packages/engine/src/skill-resolver.ts              |   4 +-
 10 files changed, 409 insertions(+), 108 deletions(-)

Fusion-Task-Id: FN-7858

Fusion-Task-Lineage: 90e44d24-e385-4a74-b8e4-3c864ec39a95

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 11:15:52 -07:00
gsxdsm
729298fa36 FN-7855: refresh persisted plugin manifest metadata on reload/re-import
Path-registered plugin reload/restart now refreshes persisted manifest metadata instead of leaving stale version/settingsSchema in the store.

- PluginLoader.loadPlugin/reloadPlugin call a new refreshPersistedManifestMetadata helper after each fresh module import, generalizing the previously bundled-only refresh to path-registered plugins
- Refresh is metadata-only (version, settingsSchema) via a stable-JSON comparison, preserving per-project enablement and saved setting values, and is a no-op when nothing changed
- PluginStore.PluginUpdateInput/updatePlugin gain a settingsSchema field (undefined = unchanged, null = explicitly clear) so updatePlugin can persist manifest schema changes independently of setting values
- Docs: add a "Updating path-registered plugins" section to docs/PLUGIN_AUTHORING.md describing the new reload/refresh loop
- Tests: add coverage in plugin-loader.test.ts and plugin-store.test.ts for manifest metadata refresh on load/reload and settingsSchema persistence
- Add a patch changeset for @runfusion/fusion

Files changed:
 .changeset/fn-7855-plugin-manifest-refresh.md     |   7 +
 docs/PLUGIN_AUTHORING.md                          |  10 ++
 packages/core/src/__tests__/plugin-loader.test.ts | 177 ++++++++++++++++++++++
 packages/core/src/__tests__/plugin-store.test.ts  |  42 +++++
 packages/core/src/plugin-loader.ts                |  53 +++++++
 packages/core/src/plugin-store.ts                 |  10 ++
 6 files changed, 299 insertions(+)

Fusion-Task-Id: FN-7855
Fusion-Task-Lineage: f4d94023-5a27-4059-a7a5-61f524c171b8
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 11:11:50 -07:00
gsxdsm
8b601810e0 fix(FN-7851): enforce per-agent assignment policy across all task-routing binding primitives
Issue #2015: product-code executor tasks were repeatedly routed to a
liaison-only agent because every routing path gated only on the coarse
role field, and several binding primitives had no guard at all.

- Add runtimeConfig.assignmentPolicy ("auto" | "explicit-only" | "none");
  "none" can never be bound to implementation tasks by ANY path — no
  override bypasses it (the liaison guarantee)
- Route every binding surface through one shared evaluator
  (evaluateImplementationTaskBind): claimTaskForAgent, the previously
  unguarded checkoutTask/assignTask primitives, selectNextTaskForAgent
  (including the in-progress re-selection loop), scheduler auto-assign
  pool, heartbeat inbox/auto-claim, fn_delegate_task, CLI agent-id
  validation, and dashboard assign/checkout/inbox routes
- Lock project isolation with a regression test: a foreign-project
  agent id is rejected by every binding primitive
- Expose Assignment Policy in Agent Detail settings; document in
  docs/agents.md; add changeset

Fusion-Task-Id: FN-7851

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 10:04:29 -07:00
gsxdsm
f23619c2d4 fix: preserve user pause across executor pause teardown (FN-7851 pause-bounce loop)
Pausing an in-progress task never stuck: the pause teardown re-queued the
row to todo with a plain engine move, and the reopen block wiped
paused/pausedByAgentId/pausedReason. The graph-failure classifier then saw
an unpaused row, misread the hard-cancel as an engine-internal abort, and
auto-continued the session (graphResumeRetryCount 1/2, 2/2); once the
budget was exhausted the benign re-queue left the row dispatchable and the
scheduler re-dispatched it seconds later — an indefinite pause/resume
bounce, burning a fresh worktree + pnpm install per cycle.

- store: new moveTask option `preservePause` keeps the pause park across a
  reopen-to-todo/triage move (flag-ON trait hook + flag-OFF legacy inline,
  kept in sync). It never SETS a pause, only prevents clearing one.
- executor teardown: when the pause that caused the abort is still in
  force, move with preservePause so the row lands in todo still parked
  (scheduler skips paused/userPaused rows until explicit unpause).
- classifier: a live task pause is labeled operator intent, never
  "engine abort during pause/resume"; the benign log now says
  "parked … awaiting explicit unpause" instead of the contradictory
  "cleared for normal scheduling" for parked rows.

Surfaces covered by tests: flag-ON hook (preserve + never-set + default
clear), classifier no-auto-continue for task-pause/user-pause/global-pause
rows in todo, provenance labels.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 10:04:29 -07:00
gsxdsm
5f4ad172f4 fix: give Grok ACP absolute paths for chat image attachments
Grok advertises promptCapabilities.image=false and ignores ACP image
ContentBlocks (live probe: NO_IMAGE). Path-based vision works when the
agent is given an absolute file path. Include path hints in chat prompts
from .fusion/chat-attachments and carry path on ChatImageContent for
file:// uris.
2026-07-12 09:56:26 -07:00
gsxdsm
3d7eaeabee FN-7849: reconcile streaming user-message echo to render chat attachments immediately
Fix chat image/file attachments not rendering until re-entering the thread by reconciling the optimistic temp user bubble with the persisted user-message SSE echo during active streaming.

- In useChat, when a persisted user-role message arrives via chat:message:added while the active session is streaming, replace the optimistic temp-* bubble with the reconciled persisted message (real id + attachment filenames) instead of leaving the temp bubble in place with no refetch.
- Add regression coverage: persisted user attachment echo reconciles without duplicate/refetch, attachment-only echo reconciles content+attachments, and text-only echo still reconciles without duplicating messages.
- Extend test helper makeMessage to pass through attachments overrides.

Files changed:
 .../dashboard/app/hooks/__tests__/useChat.test.ts  | 160 +++++++++++++++++++++
 packages/dashboard/app/hooks/useChat.ts            |  13 ++
 2 files changed, 173 insertions(+)

Fusion-Task-Id: FN-7849

Fusion-Task-Lineage: dbabda9c-5842-4d16-bafb-776a6536e51f

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 00:26:51 -07:00
gsxdsm
0a74059113 FN-7850: change dashboard TUI splash tagline to "software factory"
Update the TUI splash tagline to match the README's current product positioning, with matching test and changeset.
- Changed FUSION_TAGLINE in packages/cli/src/commands/dashboard-tui/logo.ts from "multi node agent orchestrator" to "software factory", with an FNXC comment explaining the rationale
- Updated the dashboard TUI smoke test assertion to expect "software factory" instead of the old tagline
- Added a patch changeset documenting the tagline change

Files changed:
 .changeset/fn-7850-tui-tagline.md                              | 7 +++++++
 packages/cli/src/commands/dashboard-tui/__tests__/app.test.tsx | 2 +-
 packages/cli/src/commands/dashboard-tui/logo.ts                | 6 +++++-
 3 files changed, 13 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7850

Fusion-Task-Lineage: d8517d7c-f7dd-43af-bb57-0092c7339aad

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 00:17:41 -07:00
gsxdsm
f82a3d2840 chore(release): v0.58.0
Version bump via changesets.
2026-07-11 23:50:00 -07:00
gsxdsm
7e60b0dcab docs: note chat image ContentBlocks on Grok ACP promptWithFallback 2026-07-11 23:46:08 -07:00
gsxdsm
c2d3bf0e8a fix: forward chat image attachments into Grok/ACP session/prompt
AcpRuntimeAdapter.promptWithFallback ignored options, so dashboard chat
images never became ACP ContentBlock image entries. Extract images from
prompt options and pass them through buildPromptBlocks for both acp-runtime
and the Grok vendored client.
2026-07-11 23:46:08 -07:00
gsxdsm
70cca2f96b fix: accept Grok ACP extension notifications without Method not found
Grok emits `_x.ai/session_notification` / `_x.ai/session/update` for
hook_execution status. The ACP SDK routes those to Client.extNotification;
without it, every successful post_tool_use hook logged -32601 Method not
found. Implement no-op extMethod/extNotification on default and bridging
handlers in acp-runtime and the Grok vendored copy.
2026-07-11 23:46:08 -07:00
gsxdsm
a850cb7ead fix: document non-pi customTools fail-open when gate context omitted
Matches pi wrapToolsWithActionGate semantics: callers that omit
actionGateContext (chat/triage) intentionally leave tools ungated.
Add a content-free warn when a non-pi runtime receives customTools without
gate context so the path is visible without inventing deny-all defaults.
2026-07-11 23:34:35 -07:00
gsxdsm
0b4ce01ea8 fix: gate customTools for non-pi runtimes before createSession
Greptile P1 on PR #2011: Grok ACP (and other plugin runtimes) previously
executed engine-injected fn_* tools without the pi action-gate / permanent-
agent / RTK rewrite chain. Wrap customTools once in createResolvedAgentSession
for non-pi runtimes so loopback MCP bridges dispatch already-gated closures.
Pi still owns its own wrap chain inside createFnAgent to avoid double-wrapping.
2026-07-11 23:34:35 -07:00
gsxdsm
40a01f1d0f fix: Grok ACP skill packaging paths and dead-session follow-up prompts 2026-07-11 23:23:31 -07:00
gsxdsm
82f007b273 fix: resolve Grok ACP adapter TypeScript errors for CI typecheck/build 2026-07-11 23:23:31 -07:00
gsxdsm
de8d00a475 fix: address CI lint failures in chat routes and grok MCP schema server 2026-07-11 23:23:31 -07:00
gsxdsm
6267a762a4 feat: drive Grok CLI sessions over ACP with tools, skills, and MCP
Replace one-shot grok -p JSON with native grok agent stdio (ACP) for realtime
streaming, tool visibility, and multi-turn sessions. Vendor the ACP client
into fusion-plugin-grok-runtime, forward Fusion fn_* tools and operator MCP,
stage Fusion skills via --plugin-dir, authenticate per xAI headless docs, and
align project chat manager store resolution so Grok chat sessions can send.
2026-07-11 23:23:31 -07:00
gsxdsm
b613a87e75 FN-7848: keep GitHub star count visible in mobile Settings header
Restores the GitHub star count pill on mobile Settings, which had been hidden by a prior mobile CSS override, and updates related tests to match.

- Remove the <=768px `display:none` on `.settings-github-star-btn__count` in SettingsModal.css so the count stays visible; only the redundant "Star" label text stays collapsed on mobile to save space (relies on `.settings-modal-heading` min-width: 0 to truncate the title before the pill wraps)
- Add a changeset (`@runfusion/fusion` patch) documenting the fix
- Update settings-mobile.test.tsx with a new regression test asserting the star count stays visible and formatted (e.g. "1.2k") in both the modal and embedded SettingsView on mobile, plus a helper to scan mobile-only CSS media blocks for the absence of the display:none rule, and align existing mobile CSS assertions (section-heading padding, settings-navigation base rule) with current styles
- Update SettingsModal.models-auth.test.tsx version-label assertions ("Version 1.2.3" -> "v1.2.3") and seed `fusion:settings:show-advanced` in localStorage to match current UI

Files changed:
 .changeset/mobile-settings-star-count.md           |  7 +++
 .../dashboard/app/components/SettingsModal.css     |  9 ++-
 .../__tests__/SettingsModal.models-auth.test.tsx   | 12 ++--
 .../components/__tests__/settings-mobile.test.tsx  | 66 +++++++++++++++++++++-
 4 files changed, 82 insertions(+), 12 deletions(-)

Fusion-Task-Id: FN-7848

Fusion-Task-Lineage: 0bbd0e81-6edb-4e9a-884d-b48fcf41f202

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 23:18:49 -07:00
gsxdsm
d99c04cded FN-7847: add pricing for GLM-5.2, MiniMax-M3, and Kimi K2.6
Adds static MODEL_PRICING rows for three previously-unpriced models so their token usage renders a dollar cost instead of "—" in the dashboard.

- Add zai:glm-5.2, minimax:minimax-m3, and kimi-coding:kimi-k2.6-preview pricing rows to MODEL_PRICING, sourced from each provider's public pricing docs
- Bump pricingAsOf to 2026-07-11
- Add regression tests asserting costFor() prices these three models (not unavailable) and that lookupPricing() resolves them by provider-normalized and bare model-id keys
- Add a minor changeset documenting the pricing addition for @runfusion/fusion release notes

Files changed:
 .changeset/fn-7847-model-pricing.md               |  7 +++++
 packages/core/src/__tests__/model-pricing.test.ts | 24 +++++++++++++++
 packages/core/src/model-pricing.ts                | 36 ++++++++++++++++++++++-
 3 files changed, 66 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7847

Fusion-Task-Lineage: 6c138aa3-53e9-4165-909d-c8fc02acb48b

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 23:10:58 -07:00
gsxdsm
9b7623bc4c test: fix heartbeat getSettings mock + recoveryEligible (FN-7835), skip planner confirmation gate (FN-7840), chat engine mock, dashboard lucide+tabs 2026-07-11 23:08:36 -07:00
gsxdsm
dd95634262 FN-7845: show task-scoped artifacts alongside Task Documents
Extend the dashboard's Task Documents tab to union each task's registered documents with its task-scoped artifacts, with an inline right-pane viewer for the added artifact types.

- DocumentsView Task Documents tab now merges task documents and task-scoped artifacts per task group, sorted/grouped consistently
- Adds an inline right-pane artifact viewer (image/video/audio/pdf/inline-doc/other) reusing getArtifactCategory + artifactMediaUrl/fetchArtifact
- Selection state is a discriminated document|artifact union kept separate from Project Files selection; the standalone Artifacts gallery tab is unchanged
- Updates dashboard-guide.md to describe the merged Task Documents behavior (grouping, search, and preview now cover both documents and artifacts)
- Adds a minor changeset for @runfusion/fusion documenting the artifact-in-Task-Documents feature
- Expands DocumentsView test coverage for the new union/selection/preview behavior

Files changed:
 .changeset/fn-7845-task-documents-artifacts.md     |   7 +
 docs/dashboard-guide.md                            |   6 +-
 .../dashboard/app/components/DocumentsView.css     | 142 +++++++-
 .../dashboard/app/components/DocumentsView.tsx     | 389 ++++++++++++++++++---
 .../components/__tests__/DocumentsView.test.tsx    | 290 ++++++++++++++-
 5 files changed, 780 insertions(+), 54 deletions(-)

Fusion-Task-Id: FN-7845

Fusion-Task-Lineage: 32bbe6dc-4c02-449c-a13f-38abb8fd727d

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 22:43:34 -07:00
gsxdsm
9ac4da0794 FN-7846: move task card size badge to the right edge of header actions
Repositions the S/M/L size badge on task cards so it is the trailing element in the header-actions cluster, aligning its right margin with the card's top padding instead of leaving it stranded before the menu button.

- Move the `card-size-badge` span to render after the more-actions menu button within `.card-header-actions` in TaskCard.tsx
- Add FNXC layout comment documenting why the badge must be last (right-edge alignment while preserving FN-7837 no-orphaned-second-row grouping)
- Add a regression test asserting the size badge is the last child of `.card-header-actions` with no trailing sibling
- Add a patch changeset documenting the fix for release notes

Files changed:
 .changeset/FN-7846-card-size-badge-right-edge.md    |  7 +++++++
 packages/dashboard/app/components/TaskCard.tsx      | 14 +++++++++-----
 .../app/components/__tests__/TaskCard.test.tsx      | 21 +++++++++++++++++++++
 3 files changed, 37 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-7846
Fusion-Task-Lineage: ee2c1864-e0fe-4d82-a280-59edbb923dca
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 22:40:49 -07:00
gsxdsm
1a7f35dac6 chore: ignore .orca directory
Keep Orca local workspace state out of version control.
2026-07-11 22:35:36 -07:00
gsxdsm
c9d0211bec FN-7844: coordinate heartbeat and self-healing durable-agent error recovery
Unifies the two independent durable-agent error-recovery paths (heartbeat timer and self-healing sweep) so they share one retry budget, eligibility check, and audit surface instead of racing separate counters.

- Share the heartbeatErrorRecovery attempt budget between HeartbeatMonitor's timer-entry recovery and SelfHealingManager.recoverOrphanedAgents(), with self-healing's legacy durableErrorRecovery metadata folded into the same counter via readHeartbeatErrorRetryCount().
- Add isHeartbeatErrorRecoverable() as the single transient/non-operator-actionable eligibility check, used by both the heartbeat timer and self-healing paths (self-healing additionally allows stale-worktree module-resolution errors).
- resetHeartbeatErrorRecoveryMetadata() now strips the legacy durableErrorRecovery field so recovered agents don't retain stale sweep bookkeeping.
- Self-healing emits the shared agent:auto-recover-error-state / agent:error-retry-exhausted run-audit events with source:"self-healing", and parks the agent paused with pauseReason:"error-retry-exhausted" on budget exhaustion, matching the heartbeat-timer behavior.
- Update AGENTS.md, docs/architecture.md, and docs/agents.md to describe the consolidated recovery budget and audit surface.
- Add a patch changeset documenting the fix for @runfusion/fusion.

Files changed:
 .changeset/fn-7844-error-recovery-coordination.md  |  7 ++
 AGENTS.md                                          |  2 +-
 docs/agents.md                                     | 14 ++--
 docs/architecture.md                               |  2 +-
 packages/engine/src/__tests__/heartbeat-error-recovery.test.ts | 13 +++-
 packages/engine/src/__tests__/self-healing.test.ts | 58 ++++++++++++++-
 packages/engine/src/agent-heartbeat.ts             | 35 ++++++---
 packages/engine/src/self-healing.ts                | 85 ++++++++++++++++++----
 8 files changed, 180 insertions(+), 36 deletions(-)

Fusion-Task-Id: FN-7844
Fusion-Task-Lineage: b70dcba5-56b6-412c-8be2-ef827bee9964
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 22:31:30 -07:00
gsxdsm
4397cafb94 fix: wire push-after-merge into the unified runAiMerge path with remote/branch dropdown settings
pushAfterMerge was only implemented in the soft-deprecated legacy aiMergeTask
pipeline, so after master-plan U0 made runAiMerge the sole merge path the
setting silently did nothing and origin fell permanently behind local main.

- runAiMerge now runs a post-finalize push step: working-tree-independent
  ref-to-ref push fast path; on remote divergence a detached clean-room
  pull --rebase (with AI conflict resolution) pushes HEAD and CAS-advances
  the local integration ref (explicit non-FF opt-in, push path only), then
  runs merge-advance auto-sync and refreshes mergeDetails.commitSha.
- Push failures stay non-fatal (task finalizes done) with push:origin
  run-audit events and PushToRemoteFailed task-log entries.
- Merge settings: Push Remote free-text replaced by remote + target-branch
  dropdowns (Custom… escape, free-text fallback when no remotes), persisting
  to the same pushRemote setting string. New GET /api/git/remotes/:name/branches
  endpoint lists remote-tracking branches.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 22:16:48 -07:00
gsxdsm
391ff0d269 FN-7835: auto-clear durable agent error state and retry on next heartbeat
Heartbeat-managed durable agents that land in state:"error" now self-recover on the next heartbeat instead of staying stuck until an operator intervenes.

- HeartbeatTriggerScheduler keeps timers armed for durable heartbeat-managed agents in error state when the last error is transient and not operator-actionable (credential/quota/model-access/permanent-config failures stay parked).
- executeHeartbeat clears recoverable errors at run entry (error → active, clears lastError), bounded by MAX_HEARTBEAT_ERROR_RECOVERY_ATTEMPTS (settings-overridable); a successful run resets the counter.
- On budget exhaustion, the agent is parked paused with pauseReason:"error-retry-exhausted".
- Emits new run-audit events agent:auto-recover-error-state and agent:error-retry-exhausted (added to DatabaseMutationType).
- Adds heartbeat-error-recovery.test.ts and extends heartbeat-scheduler.test.ts to cover the recovery/exhaustion paths.
- Adds changeset and documents the new behavior in AGENTS.md and docs/architecture.md.

Files changed:
 .changeset/fn-7835-agent-error-auto-recovery.md    |   7 +
 AGENTS.md                                          |   1 +
 docs/architecture.md                               |   2 +
 .../src/__tests__/heartbeat-error-recovery.test.ts | 323 +++++++++++++++++++++
 .../src/__tests__/heartbeat-scheduler.test.ts      |  89 +++++-
 packages/engine/src/agent-heartbeat.ts             | 209 ++++++++++++-
 packages/engine/src/run-audit.ts                   |   2 +
 7 files changed, 618 insertions(+), 15 deletions(-)

Fusion-Task-Id: FN-7835

Fusion-Task-Lineage: 1bbb28a3-8eb9-40e3-8177-6658ec5dae40

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 22:16:48 -07:00
gsxdsm
be1950b79c FN-7843: keep task-detail per-model token tables horizontally scrollable on mobile
Removes the mobile stacked-card override for the Summary tab's per-model token/cost table so it stays a real, horizontally-scrollable table matching the Command Center pattern, and updates the covering tests/changeset accordingly.

- Drop the @media (max-width: 768px) block in TaskDetailModal.css that converted .task-summary-token-table rows into stacked cards (display:block, thead hidden, td::before labels), so the wrapper's overflow-x: auto and table min-width now govern mobile layout.
- Update FNXC:TaskDetailSummaryTokenCost comments to document the new horizontal-scroll contract instead of the removed stacked-card behavior, and refresh the TaskCostTab.css FNXC comment to match.
- Add a new regression test (token-table-mobile-scroll.test.ts) asserting the task-detail token table wrapper keeps overflow-x: auto, the mobile media block no longer stacks rows into cards, and the Command Center .cc-table-wrap stays scrollable.
- Update the existing TaskDetailModal summary-tab test to assert the stacked-card CSS is absent from the mobile block instead of asserting its presence.
- Add a patch changeset describing the fix for end users.

Files changed:
 .changeset/mobile-token-table-scroll.md            |  7 +++
 .../__tests__/token-table-mobile-scroll.test.ts    | 70 +++++++++++++++++++++
 packages/dashboard/app/components/TaskCostTab.css  |  2 +-
 .../dashboard/app/components/TaskDetailModal.css   | 73 ++--------------------
 .../__tests__/TaskDetailModal.summary-tab.test.tsx | 13 ++--
 5 files changed, 90 insertions(+), 75 deletions(-)

Fusion-Task-Id: FN-7843

Fusion-Task-Lineage: bb6dde7c-f205-45f3-984a-0fc52be5d547

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 22:16:48 -07:00
gsxdsm
c7c6c5a8c4 FN-7842: color-code priority icons by urgency across quick add, task form, and task cards
Adds a shared urgency color source to priorityIndicator and wires it into every priority-glyph surface so low/normal/high/urgent read consistently by color, not just icon shape.

- priorityIndicator.tsx: add colorVar (low=info/blue, normal=muted, high=warning/amber, urgent=error/red) and new getPriorityColorVar() export as the single source of truth
- QuickEntryBox: tint the icon-only priority trigger and each option row in the priority picker with the matching urgency color
- TaskForm: tint the New Task inline priority glyph using the same color source
- TaskCard: render a colored priority glyph alongside the existing text label in the card-priority-badge (kept the non-normal visibility gate and badge geometry via a small CSS gap addition)
- Updated/added tests for QuickEntryBox, TaskCard (badge, badge-height, badge-wrap), and priorityIndicator to assert the new colors; added a patch changeset and a dashboard-guide.md doc update

Files changed:
 .changeset/fn-7842-priority-color-coding.md        |  7 +++++
 docs/dashboard-guide.md                            |  7 +++--
 .../dashboard/app/components/QuickEntryBox.tsx     |  7 +++--
 packages/dashboard/app/components/TaskCard.css     |  2 ++
 packages/dashboard/app/components/TaskCard.tsx     |  6 +++-
 packages/dashboard/app/components/TaskForm.tsx     |  7 +++--
 .../components/__tests__/QuickEntryBox.test.tsx    | 17 +++++++++--
 .../__tests__/TaskCard.badge-height.test.tsx       |  5 ++++
 .../__tests__/TaskCard.badge-wrap.test.tsx         |  5 ++++
 .../app/components/__tests__/TaskCard.test.tsx     | 33 +++++++++++++++++++++-
 .../app/utils/__tests__/priorityIndicator.test.tsx | 13 +++++----
 packages/dashboard/app/utils/priorityIndicator.tsx | 16 ++++++++---
 12 files changed, 103 insertions(+), 22 deletions(-)

Fusion-Task-Id: FN-7842

Fusion-Task-Lineage: 0b2d0d15-6e61-45fc-9378-bc09002bef55

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 22:16:48 -07:00
gsxdsm
3da3f377c9 FN-7839: group done-card Archive and Revert actions into one dropdown
Replaces the standalone Archive button on done task cards with an Actions dropdown that groups Archive and Revert, mirroring the existing in-progress "Send back" menu pattern.

- Add a card-done-actions dropdown (Actions trigger + menu) rendered for done cards, reusing card-send-back* styling
- Move Archive into the dropdown menu; add Revert as a menu item when the task is revertable (isRevertable)
- Only render the dropdown trigger when at least one action (archive/revert) is available, avoiding an empty button shell
- Restrict the old inline card-revert-btn to archived cards only (done cards now use the dropdown)
- Add outside-click handling and aria-haspopup/aria-expanded wiring for the new menu
- Add i18n key tasks.doneActions
- Update TaskCard tests to cover the dropdown (archive/revert menu items, empty-state omission) and mock useToast in board-mobile tests for isolated TaskCard renders
- Add changeset for @runfusion/fusion (patch)

Files changed:
 .changeset/fn-7839-done-card-actions-dropdown.md   |  7 ++
 packages/dashboard/app/components/TaskCard.tsx     | 88 ++++++++++++++++++----
 .../app/components/__tests__/TaskCard.test.tsx     | 82 +++++++++++++++-----
 .../app/components/__tests__/board-mobile.test.tsx | 15 +++-
 4 files changed, 157 insertions(+), 35 deletions(-)

Fusion-Task-Id: FN-7839

Fusion-Task-Lineage: 1f8137cb-22b1-43dd-beaa-1bee0387d44b

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 22:16:48 -07:00
gsxdsm
0b5c5517d8 FN-7841: fix mobile Todo single-panel stack to fill full height
Fixes the narrow-container (phone-width) Todo view so the visible list or
detail panel stretches to fill available height instead of inheriting the
tablet two-panel sidebar's max-height cap.

- Scope the single-panel stack rule to .todo-view-layout .todo-view-sidebar /
  .todo-view-main so it wins over the later @media (max-width:768px)
  sidebar max-height cap, and add height:100%/max-height:none.
- Add regression tests asserting the narrow single-panel stack is uncapped
  while the tablet two-panel sidebar keeps its existing height cap.
- Add a patch changeset documenting the fix.

Files changed:
 .changeset/fn-7841-todo-mobile-height.md           |  7 ++++++
 packages/dashboard/app/components/TodoView.css     | 11 ++++++---
 .../__tests__/TodoView.mobile-css.test.ts          | 28 ++++++++++++++++++++++
 3 files changed, 43 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7841
Fusion-Task-Lineage: e6b497ae-2568-4cae-8b48-7f57f45c8a23
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 22:16:48 -07:00
gsxdsm
14b7244bcb FN-7840: suppress advisory merger/pull-request await-confirmation interventions
Stops decidePlannerRecovery from recording noisy advisory confirmation interventions for merger/pull-request stages that never actually block progress when auto-merge will proceed unattended.

- decidePlannerRecovery now returns action "none" (no pending confirmation, no steering comment, no overseer:intervention entry) for merger/pull-request stages when autoMergeWillProceed === true, since this checkpoint is purely advisory in that case
- Genuine human-approval blocks (autoMergeWillProceed === false) and the neutral pure-function default (undefined) keep the await_confirmation decision intact
- Updated planner-recovery.test.ts to assert the new "none" outcome for the advisory case
- Simplified planner-overseer-intervention-wiring.test.ts to match the reduced intervention surface
- Added changeset documenting the fix as a patch-level bug fix

Files changed:
 .changeset/fn-7840-advisory-merger-confirmations.md            |   7 ++
 packages/core/src/__tests__/planner-recovery.test.ts           |  32 ++---
 packages/core/src/planner-recovery.ts                          |  47 ++++---
 packages/engine/src/__tests__/planner-overseer-intervention-wiring.test.ts | 135 +++++----------------
 4 files changed, 79 insertions(+), 142 deletions(-)

Fusion-Task-Id: FN-7840

Fusion-Task-Lineage: 610a9003-f229-4e78-9948-ee0bb85193bc

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 22:16:48 -07:00
gsxdsm
66e91f96ae FN-7837: fix task card size badge wrapping onto a misaligned second row
Groups TaskCard header badges so the id and right-aligned size/actions cluster never wrap, fixing the S/M/L size chip dropping to its own row when extra badges (fast-mode, priority, oversight, PR/GitHub, etc.) are present.

- Introduce hasHeaderBadges/hasHeaderActions guards and wrap the middle badge cluster in a new .card-header-badges container so only .card-header-badges wraps, while .card-id and .card-header-actions stay pinned to the top row
- Update TaskCard.css: .card-header becomes a non-wrapping flex row; .card-header-badges takes over the wrapping/flex-grow behavior previously on .card-header; .card-id gets flex-shrink: 0; .card-header-actions gets flex: 0 0 auto and align-self: flex-start; mobile media query gains .card-header-badges alongside .card-meta-badges
- Add FNXC:TaskCardLayout comments documenting the FN-7837 layout requirement (non-wrapping header row, wrapping badge cluster)
- Extend TaskCard.badge-wrap.test.tsx and TaskCard.test.tsx coverage for the new header grouping/wrap behavior
- Add changeset FN-7837-card-size-badge-alignment.md (patch, fix) for @runfusion/fusion

Files changed:
 .changeset/FN-7837-card-size-badge-alignment.md    |  7 +++
 packages/dashboard/app/components/TaskCard.css     | 29 +++++++--
 packages/dashboard/app/components/TaskCard.tsx     | 38 ++++++++++++
 .../__tests__/TaskCard.badge-wrap.test.tsx         | 70 ++++++++++++++++++++--
 .../app/components/__tests__/TaskCard.test.tsx     | 27 ++++++---
 5 files changed, 156 insertions(+), 15 deletions(-)

Fusion-Task-Id: FN-7837

Fusion-Task-Lineage: 9f70abcf-3b23-41b3-8642-aa34a561996d

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 22:16:47 -07:00
gsxdsm
cc743eec38 FN-7838: make CLI agent cold-start timeouts configurable via env vars
Raises Grok and Droid CLI cold-start timeout defaults from 60s to 120s and lets operators override them via environment variables.
- Grok runtime adapter: new GROK_CLI_FIRST_OUTPUT_TIMEOUT_MS env override for the first-output cold-start guard; default raised 60000ms → 120000ms; invalid/non-positive values fall back to the default
- Droid provider: new PI_DROID_CLI_FIRST_LINE_TIMEOUT_MS env override for the first-line cold-start guard; default raised 60000ms → 120000ms; invalid/non-positive values fall back to the default
- 30-minute inactivity safety net left unchanged on both adapters
- Added/updated unit tests covering the new env-driven timeout resolution and fallback behavior for both plugins
- Documented the new settings in docs/settings-reference.md and both plugin READMEs
- Added a minor changeset for @runfusion/fusion

Files changed:
 .changeset/fn-7838-cli-timeout-configurable.md     |  7 ++
 docs/settings-reference.md                         | 13 ++-
 plugins/fusion-plugin-droid-runtime/README.md      |  8 ++
 .../src/__tests__/provider.test.ts                 | 97 +++++++++++++++++++++-
 .../fusion-plugin-droid-runtime/src/provider.ts    | 26 ++++--
 plugins/fusion-plugin-grok-runtime/README.md       |  8 ++
 .../src/__tests__/runtime-adapter.test.ts          | 52 +++++++++++-
 .../src/runtime-adapter.ts                         | 23 ++++-
 8 files changed, 222 insertions(+), 12 deletions(-)

Fusion-Task-Id: FN-7838

Fusion-Task-Lineage: 7aad4470-b28f-42bd-be01-8363a1dd05e5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 22:16:47 -07:00
gsxdsm
b3ed63dae9 FN-7836: fix Task Documents sidebar cards collapsing to blank rows under flex shrink
Fixes the Task Documents view rendering blank/border-only rows once many task-card groups load in the scrolling sidebar; each card now opts out of flex shrink so overflow clipping no longer compresses group content out of view.

- DocumentsView.css: add `flex: 0 0 auto` to `.documents-task-sidebar-group` so cards keep their natural height instead of being shrunk by the flex column when many groups are loaded
- DocumentsView.test.tsx: add regression test rendering 54 loaded task-document groups, asserting `flex-shrink: 0` and that group heading/content text remains visible and interactive
- Add changeset documenting the patch-level fix

Files changed:
 .changeset/fn-7836-task-documents-rendering.md     |  7 +++
 .../dashboard/app/components/DocumentsView.css     |  4 ++
 .../components/__tests__/DocumentsView.test.tsx    | 71 ++++++++++++++++++++++
 3 files changed, 82 insertions(+)

Fusion-Task-Id: FN-7836

Fusion-Task-Lineage: f07bad59-c6b9-41e3-9475-5a4339044bb4

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 22:16:47 -07:00
gsxdsm
1540473db8 test(dashboard): add Cost (FN-7820) + Terminal (FN-7826) tabs to expected arrays + settings description allowlist 2026-07-11 21:41:30 -07:00
gsxdsm
72aae17200 test(dashboard): mock @fusion/engine in chat.test.ts to stop transitive core-export cascade 2026-07-11 21:41:30 -07:00
gsxdsm
4fb360631c FN-7833: render task Artifacts documents as Markdown, expanded by default
Renders every task document in the Artifacts tab expanded and as rendered Markdown by default, with the Markdown/Plain preference persisted across sessions instead of resetting per document.

- Replace single expandedDocKey/expandedContent state with a multi-key expandedDocKeys Set plus a per-document revisionContentByKey map so multiple documents can be expanded simultaneously.
- Default renderMarkdown to true and persist the operator's Markdown/Plain toggle choice to localStorage (fusion.taskDocuments.renderMarkdown) via readBooleanPref/writeBooleanPref helpers.
- Auto-expand newly loaded documents while preserving collapse state for documents the user has explicitly collapsed, tracked per taskId.
- Update handleStartEdit and handleViewRevision to operate per-document-key instead of a single global expanded document.
- Add changeset (@runfusion/fusion patch) describing the Artifacts-tab default-expanded Markdown behavior.
- Rework TaskDocumentsTab tests for multi-document expand/collapse, per-card markdown rendering, and localStorage-backed preference persistence.

Files changed:
 .changeset/fn-7833-artifacts-tab-markdown-expand-default.md      |   7 +
 packages/dashboard/app/components/TaskDocumentsTab.tsx           | 149 +++++++++-----
 packages/dashboard/app/components/__tests__/TaskDocumentsTab.test.tsx | 223 +++++----------------
 3 files changed, 160 insertions(+), 219 deletions(-)

Fusion-Task-Id: FN-7833

Fusion-Task-Lineage: 1915c594-7191-47a2-962b-18136d572cf1

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 20:50:59 -07:00
gsxdsm
06bf0b85b9 FN-7834: restyle Task Documents sidebar with clearer task-card grouping
Gives the Artifacts view's Task Documents sidebar a distinct card-per-task look with more breathing room between task groups, replacing the flat bordered-row list.

- Restyle .documents-task-sidebar-group into a bordered, rounded card with shadow and inter-group gap instead of a bottom-border-only divider
- Strengthen the group header (bolder task id/title, tinted background) so it reads as a container rather than a peer row
- Add hover/selected background treatment and left-indent to .documents-task-document-item entries, scoped under .documents-task-documents-sidebar so Project Files and Artifacts stay unaffected
- Add a regression test asserting group headers remain non-selectable containers distinct from selectable document rows
- Update dashboard-guide.md wording to describe the new distinct task-card grouping
- Add changeset (patch) documenting the sidebar restyle

Files changed:
 .changeset/fn-7834-task-documents-grouping.md      |  7 +++
 docs/dashboard-guide.md                            |  2 +-
 .../dashboard/app/components/DocumentsView.css     | 38 +++++++++++++---
 .../components/__tests__/DocumentsView.test.tsx    | 50 ++++++++++++++++++++++
 4 files changed, 90 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-7834

Fusion-Task-Lineage: 9bac7666-19ba-410b-81dc-d9201a61d0b5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 20:48:20 -07:00
gsxdsm
49faf0afe2 FN-7832: reorder Task Detail tabs and default terminal picker to task worktree
Reworks the Task Detail terminal experience: the embedded Terminal tab now sits between Comments and Cost, its workspace picker defaults to the task's worktree, and the mobile terminal panel is shorter.

- Move the Terminal tab in Task Detail's tab strip to sit right after Comments and before Cost (previously Cost was earlier and Terminal was near the Session tab)
- TerminalModal now defaults its workspace picker to the useWorkspaces entry whose worktree matches the passed defaultCwd, but only until the operator manually changes the selection; the footer/global terminal still defaults to Project Root since it doesn't pass defaultCwd
- Reduce `.detail-section--worktree-terminal`'s mobile min-height from min(65dvh, 14 * --space-2xl) to min(50dvh, 11 * --space-2xl) so tab context and controls stay reachable above the fold
- Update docs/dashboard-guide.md to describe the new Comments → Terminal → Cost tab order and the worktree-matching picker default
- Add regression tests covering the new tab order and the default terminal workspace selection behavior
- Add a patch changeset describing the user-facing change

Files changed:
 .changeset/FN-7832-task-terminal-picker-and-tab-order.md          |  7 +++
 docs/dashboard-guide.md                                           |  9 +--
 packages/dashboard/app/components/TaskDetailModal.css             |  5 +-
 packages/dashboard/app/components/TaskDetailModal.tsx             | 30 +++++-----
 packages/dashboard/app/components/TerminalModal.tsx                | 19 +++++++
 packages/dashboard/app/components/__tests__/TaskDetailModal.attachments-and-tabs.test.tsx | 15 ++---
 packages/dashboard/app/components/__tests__/TaskDetailModal.worktree-terminal.test.tsx    | 12 ++++
 packages/dashboard/app/components/__tests__/TerminalModal.test.tsx                        | 64 ++++++++++++++++++++++
 8 files changed, 134 insertions(+), 27 deletions(-)

Fusion-Task-Id: FN-7832

Fusion-Task-Lineage: 4ee67a65-8564-49c9-b93c-8c3eab05c073

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 20:46:05 -07:00
gsxdsm
fc07bdfc7e FN-7831: add Reviewing badge for active Plan Review on task cards and list rows
Adds a distinct "Reviewing" status badge that surfaces on TaskCard and ListView rows while a task's optional plan-review workflow step is actively running, reusing the unified progress predicate so board and list surfaces stay in sync.

- Add isPlanReviewRunning(task) helper in taskProgress.ts, derived from getUnifiedTaskProgress's workflow-plan-review item status
- Render a pulsing "Reviewing" badge on TaskCard header (additive to existing status badges, with title/data-testid) while plan-review is running
- Render the matching "Reviewing" badge on both grouped and ungrouped ListView row layouts for parity with TaskCard
- Add supporting CSS for .card-status-badge--reviewing and .list-status-badge--reviewing
- Add unit tests for isPlanReviewRunning and component tests for the new badge across TaskCard and ListView
- Add minor changeset documenting the new operator-facing badge

Files changed:
 .changeset/tidy-reviewing-badges.md                |  7 ++
 packages/dashboard/app/components/ListView.css     | 10 +++
 packages/dashboard/app/components/ListView.tsx     | 22 +++++-
 packages/dashboard/app/components/TaskCard.css     | 10 +++
 packages/dashboard/app/components/TaskCard.tsx     | 25 ++++++-
 .../app/components/__tests__/ListView.test.tsx     | 78 ++++++++++++++++++++++
 .../app/components/__tests__/TaskCard.test.tsx     | 31 +++++++++
 .../app/utils/__tests__/taskProgress.test.ts       | 16 ++++-
 packages/dashboard/app/utils/taskProgress.ts       | 10 +++
 9 files changed, 205 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-7831

Fusion-Task-Lineage: d36f8c63-9b84-400a-8b10-3b9f3b04212b

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 20:37:26 -07:00
gsxdsm
5ed15e27b7 FN-7830: fix Insights view header wrapping on mobile
Give the Insights view header its own dedicated mobile layout so the title no longer collapses to an ellipsis and action buttons no longer crowd together at narrow widths/short heights.

- Extend the mobile header media query to also trigger on short viewports (max-height: 480px), not just narrow widths
- Force the Insights title onto its own full-width row (flex: 1 0 100%) and let it wrap actions below instead of shrinking
- Stop truncating the title span (overflow: visible; text-overflow: clip) so "Insights" is never cut to "I…"
- Let the actions cluster wrap to full width, left-aligned, with no leading margin so touch targets stay usable
- Add regression tests covering the maximal header action cluster and asserting the new mobile/tablet/desktop CSS media-query contracts

Files changed:
 packages/dashboard/app/components/InsightsView.css               | 29 ++++++-
 .../app/components/__tests__/InsightsView.test.tsx                | 88 ++++++++++++++++++++++
 2 files changed, 116 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7830

Fusion-Task-Lineage: 4c92cb43-5c08-4b76-9f51-805ffa5deec9

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 20:32:56 -07:00
gsxdsm
6b506f2c97 FN-7829: move terminal action controls into footer and add tab-strip overflow collapse
Relocates the shared terminal action-control cluster into the bottom status-bar footer at every breakpoint and replaces the fixed tablet-viewport tab collapse with a container-width overflow check.

- Move font-size, Clear, Shortcuts, Preferences, connection status, pin, and pop-out controls out of the desktop header into the `.terminal-status-bar` footer at all widths (desktop/tablet/mobile/floating/docked/pinned/embedded), replacing the prior viewport-tier-based split.
- Replace `isTerminalTabletViewport()` with `evaluateTabsOverflow()`, a container-size (ResizeObserver-driven) check with hysteresis that swaps the `.terminal-tabs` strip for the existing mobile-style `.terminal-mobile-tabs` dropdown whenever the tab strip doesn't fit, independent of viewport breakpoint.
- Update TerminalModal.css to match the new footer-first layout and drop now-unused tablet-tier header rules.
- Update dashboard-guide.md terminal usage steps to describe the new always-footer control location and the width-based (not tablet-only) tab dropdown fallback.
- Expand TerminalModal.test.tsx coverage for the overflow-driven tab collapse/expand behavior and footer control placement.
- Add changeset fn-7829-terminal-shortcuts-footer.md (patch, feature) documenting the footer/tab-dropdown change; resolve an add/add conflict on the pre-existing artifacts-doc-editing-and-comment-fix.md changeset by keeping fusion/fn-7829's summary wording.

Files changed:
 .../artifacts-doc-editing-and-comment-fix.md       |   2 +-
 .changeset/fn-7829-terminal-shortcuts-footer.md    |   7 +
 docs/dashboard-guide.md                            |   9 +-
 .../dashboard/app/components/TerminalModal.css     | 121 +++-----
 .../dashboard/app/components/TerminalModal.tsx     | 336 +++++++++++----------
 .../components/__tests__/TerminalModal.test.tsx    | 185 ++++++++----
 6 files changed, 351 insertions(+), 309 deletions(-)

Fusion-Task-Id: FN-7829

Fusion-Task-Lineage: 443c6e69-8946-4307-8a1a-f4f90681a054

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 20:06:53 -07:00
gsxdsm
4edd8cc293 feat: show Claude Fable weekly window and Grok CLI credit usage in the Usage dropdown
Claude per-model weekly usage is parsed generically from the OAuth payload's
limits[] scoped entries (live probe disproved the seven_day_fable key guess).
Grok now prefers ~/.grok/auth.json OIDC credentials against
cli-chat-proxy.grok.com/v1/billing?format=credits for a real percent-used
weekly credits window, falling back to the xAI API-key validity card.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 19:56:19 -07:00
gsxdsm
b7f82ee9fd fix(changesets): shorten artifacts summary 2026-07-11 19:55:58 -07:00
gsxdsm
b0ca17a1f7 fix(compound-engineering): claim plan handoffs atomically 2026-07-11 19:55:58 -07:00
gsxdsm
337bdcd081 feat(compound-engineering): align the UI with the upstream loop 2026-07-11 19:55:58 -07:00
gsxdsm
3a4fd67718 Address PR review feedback (#2001)
- scope session collections to the active project\n- clean up runtime stage registration in discovery tests\n- model brainstorms and plans as repeatable artifact collections\n- compact the singleton Strategy presentation
2026-07-11 19:55:58 -07:00