Commit Graph

11102 Commits

Author SHA1 Message Date
gsxdsm
68f4abc574 fix: remount simple canvas per workflow so fitView tracks the new graph
Switching or creating a workflow could leave the simplified canvas fitted to
the previous graph's bounds (an apparently empty canvas after New workflow).
Keying the canvas's ReactFlowProvider on the workflow id forces a fresh
measure + initial fitView per workflow; the in-place refit still handles
inserts/deletes within one workflow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 18:06:22 -07:00
gsxdsm
bcbd97cc1c feat: simplified workflow editor view with Simple/Advanced/List modes
Adds a simplified graphical node editor as the workflow editor's default
view: a modern vertical auto-laid-out React Flow canvas with insert-on-edge
"+" affordances and a searchable, categorized add-step dialog (node kinds +
fragments + step templates). A segmented Simple/Advanced/List switch
(persisted in localStorage) keeps the full advanced canvas untouched and
retains the old compact row editor as the List fallback. Mobile's graph tab
gains the touch-friendly simplified canvas with the row list as fallback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 18:06:22 -07:00
gsxdsm
28ad1fd5f3 Address PR review feedback (#2003)
- parseInsightsContent: only top-level bullets (column 0 on the raw line) start
  a new insight; indented sub-bullets stay inside their parent insight with
  indentation preserved, so counts no longer inflate
- regression test for indented sub-bullets

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 17:16:49 -07:00
gsxdsm
690a49f8da docs: add post-review-fix insights screenshot for PR #2003
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 17:16:49 -07:00
gsxdsm
d44da531ff Address PR review feedback (#2003)
- parseInsightsContent: append continuation lines to the previous bullet so
  multiline insights render in full instead of truncating after the first line
- .memory-insight-item: white-space: pre-wrap so continuation breaks display
- regression tests for per-bullet parsing, counts, and multiline continuations

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 17:16:49 -07:00
gsxdsm
1d2d73ba5c fix(memory): fix insights parsing + modernize Memory, Insights, Todos, and agent Memory UI
- parseInsightsContent stripped bullet prefixes before filtering for them, so every
  insights category rendered as one blob and counts were wrong (5 shown vs 84 real)
- drop dead GET /memory and GET /memory/stats mount fetches from useMemoryData and
  stop refetching the file list on every file selection
- Memory view: full-width layout, accent tabs, 2-column Engines card grid, remove
  duplicated capability badges, correct spacing-token-as-font-size rules
- Todos: single-row items with quiet inline action cluster (stacked on narrow/mobile)
- Insights: flat card list (no card-in-card), 28px/16px actions muted until hover
- Agent Memory tab: shared FileEditor (CodeMirror) for memory files, per-section save
  actions, distinct inline-toggle aria-labels, fix {{date}} i18n interpolation
- PR screenshots under docs/assets/memory-ui-review-2026-07/

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 17:16:49 -07:00
Phil Larson
7f418b7d10 fix(missions): clear terminal fix task links 2026-07-11 17:04:22 -07:00
Phil Larson
6ee86c5db7 fix(missions): address lifecycle review blockers 2026-07-11 17:04:22 -07:00
Phil Larson
c68b053162 fix(missions): reconcile lifecycle invariants 2026-07-11 17:04:22 -07:00
gsxdsm
11fce4e4bb docs(settings): refresh complete screenshot coverage 2026-07-11 17:03:36 -07:00
gsxdsm
3daf29d5dd docs(settings): capture advanced disclosure matrix 2026-07-11 17:03:36 -07:00
gsxdsm
9b22927f3c feat(settings): simplify section details and layout 2026-07-11 17:03:36 -07:00
gsxdsm
19055c6c0e feat(settings): simplify advanced controls 2026-07-11 17:03:36 -07:00
gsxdsm
bf300f3336 test(FN-7811): align document view tests after rebase
Fusion-Task-Id: FN-7811
2026-07-11 00:03:14 -07:00
gsxdsm
6317fcddb5 FN-7813: add embedded worktree-rooted multi-tab Terminal to Task Detail
Add an interactive, worktree-rooted, multi-tab Terminal tab to the Task Detail
view, distinct from the pre-existing CLI-agent Session tab.

- TaskDetailModal gains a new embedded Terminal tab (single non-workspace
  task with one recorded worktree) that mounts TerminalModal in a new
  `embedded` render mode, rooted at the task's worktree
- Rename the existing agent-session tab label to "Session" to disambiguate
  it from the new Terminal tab
- useTerminalSessions gains task-scoped session storage and a `defaultCwd`
  option so embedded terminal tabs persist separately from footer/global
  project terminal tabs and start in the task worktree
- TerminalModal/CSS updated to support the embedded layout mode
- Update lazy-loaded-views docs test and AGENTS.md exclusion list to cover
  the new `LazyTerminalModal` task-detail-internal surface
- Document the new Session/Terminal tab split in docs/dashboard-guide.md
- Add i18n strings for the new Terminal tab across all locales
- Add a changeset (minor) for @runfusion/fusion

Files changed:
 .changeset/FN-7813-worktree-terminal-tab.md        |   7 +
 AGENTS.md                                          |   2 +-
 docs/dashboard-guide.md                            |   3 +
 .../app/__tests__/lazy-loaded-views-docs.test.ts   |   4 +-
 .../dashboard/app/components/TaskDetailModal.css   |  17 +++
 .../dashboard/app/components/TaskDetailModal.tsx   |  41 +++++-
 .../dashboard/app/components/TerminalModal.css     |  51 +++++++
 .../dashboard/app/components/TerminalModal.tsx     |  71 +++++++---
 .../__tests__/TaskDetailModal.test-helpers.ts      |   3 +
 .../TaskDetailModal.worktree-terminal.test.tsx     | 139 ++++++++++++++++++
 .../components/__tests__/TerminalModal.test.tsx    |  29 ++++
 .../hooks/__tests__/useTerminalSessions.test.ts    | 157 +++++++++++++++++++++
 .../dashboard/app/hooks/useTerminalSessions.ts     |  63 ++++++---
 packages/i18n/locales/en/app.json                  |   3 +-
 packages/i18n/locales/es/app.json                  |   3 +-
 packages/i18n/locales/fr/app.json                  |   3 +-
 packages/i18n/locales/ko/app.json                  |   3 +-
 packages/i18n/locales/zh-CN/app.json               |   3 +-
 packages/i18n/locales/zh-TW/app.json               |   3 +-
 19 files changed, 550 insertions(+), 55 deletions(-)

Fusion-Task-Id: FN-7813

Fusion-Task-Lineage: 4ef86a15-347a-4862-b01c-5063d8004cb8

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 00:01:10 -07:00
gsxdsm
bd0e99b31f FN-7814: add xAI/Grok usage card to the Usage dropdown
Adds a Grok (xAI) provider fetcher to the dashboard's usage aggregation so a Grok card now appears in the Usage dropdown when credentials are configured.
- Add fetchGrokUsage() in usage.ts: resolves the API key from GROK_API_KEY env, then ~/.grok/user-settings.json, then grok-cli auth storage, and validates it against GET https://api.x.ai/v1/api-key
- Since xAI exposes no subscription usage meter for inference keys, the card reports auth-validity status (ok/no-auth/error) with an empty usage-window list rather than fabricating quota data
- Surfaces clear error messages for expired/blocked keys and non-200 responses; omits the card entirely when no credentials are found
- Register fetchGrokUsage in fetchAllProviderUsage's parallel provider fetch list alongside Claude, Codex, Gemini, Minimax, Zai, and GitHub Copilot
- Add extensive test coverage in usage.test.ts for key-source precedence, ok/error/no-auth states, and blocked/expired key handling
- Add changeset (.changeset/fn-7814-grok-usage.md) documenting the new minor feature

Files changed:
 .changeset/fn-7814-grok-usage.md               |   7 ++
 packages/dashboard/src/__tests__/usage.test.ts | 157 +++++++++++++++++++++++++
 packages/dashboard/src/usage.ts                |  95 ++++++++++++++-
 3 files changed, 257 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7814

Fusion-Task-Lineage: cac497a9-5a57-4ba5-a7ea-8a01b89a0cbd

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 00:01:10 -07:00
gsxdsm
56b20a76af FN-7812: extend select-to-comment popover to Task Documents right pane
Adds select-to-comment parity to the Task Documents right pane in the Artifacts view, reusing the existing Project Files selection-comment pattern (useSelectionComment/SelectionCommentPopover) so operators can highlight task-document content and send it to a new task.

- Add markdown/plain preview refs and useSelectionComment hooks scoped to the selected Task Document, following the existing Plain/Markdown render toggle
- Gate the Task Documents selection popover on activeTab === "tasks" and the selected task document (separate from the Project Files popover, which stays gated on activeTab === "project") so tab switches never cross-render popovers
- Compose the New Task description source as `taskId/key` for task-document selections, mirroring the file-path convention used for Project Files
- Add regression tests covering plain/markdown task-document selection, empty-pane gating, tab isolation between Task Documents and Project Files popovers, and the mobile detail pane
- Update dashboard-guide.md to document select-to-comment support for Task Documents alongside Project Files
- Add a minor changeset for @runfusion/fusion documenting the feature (depends on FN-7811)

Files changed:
 .changeset/fn-7812-task-documents-select-to-comment.md            |  7 ++
 docs/dashboard-guide.md                                           |  4 +-
 packages/dashboard/app/components/DocumentsView.tsx                | 37 ++++++---
 packages/dashboard/app/components/__tests__/DocumentsView.test.tsx | 93 ++++++++++++++++++++++
 4 files changed, 130 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-7812

Fusion-Task-Lineage: ace10d70-35fd-42fe-8a4a-e2c2c7c7c27b

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 00:01:10 -07:00
gsxdsm
595d323ce6 FN-7811: convert Task Documents tab to left-sidebar list + right-pane viewer
Reworks the Artifacts view's Task Documents tab to reuse the Project Files left-sidebar/right-pane layout instead of expandable task-grouped cards, giving both tabs a consistent browsing pattern.

- Replace the collapsible TaskGroup/DocumentCard components with a documents-project-layout sidebar listing documents grouped by task (with revision metadata and task status badges) and a right pane rendering the selected document's content
- Add separate selectedTaskDocumentId selection state so tab switching never leaks Project Files content into Task Documents (and vice versa), with desktop/mobile gating matching the Project Files pattern
- Preserve the existing Plain/Markdown render toggle for task document content; select-to-comment stays Project-Files-only for this change (tracked as follow-up)
- Update DocumentsView.css for the new sidebar/right-pane structure and rewrite DocumentsView.test.tsx coverage for the new interaction model
- Update docs/dashboard-guide.md to describe the shared sidebar/right-pane browsing pattern for Task Documents
- Add changeset fn-7811-task-documents-sidebar.md (minor)

Files changed:
 .changeset/fn-7811-task-documents-sidebar.md       |   7 +
 docs/dashboard-guide.md                            |   4 +-
 .../dashboard/app/components/DocumentsView.css     | 181 ++++--------
 .../dashboard/app/components/DocumentsView.tsx     | 308 ++++++++++-----------
 .../components/__tests__/DocumentsView.test.tsx    | 116 ++++++--
 5 files changed, 299 insertions(+), 317 deletions(-)

Fusion-Task-Id: FN-7811

Fusion-Task-Lineage: e943ebf8-6e8e-4f5f-a55c-99c949be2624

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-11 00:01:10 -07:00
gsxdsm
281d1a3371 FN-7809: collapse List view to single-pane layout on tablet-narrow widths
Fixes the List view's two-pane split layout clipping primary controls and the
expanded quick-add composer on tablet-width viewports (769-1024px) by
switching those widths to the same single-pane card/detail layout already
used on mobile.

- Add `useSinglePaneList` gate in ListView.tsx (`viewportMode === "mobile" || "tablet"`) driving split-vs-single-pane structure, detail routing, and resize-handle wiring, while touch-only long-press behavior stays on `isMobile`.
- Extend the mobile-only responsive CSS breakpoints in ListView.css from `max-width: 768px` to `max-width: 1024px` so tablet gets the same toolbar/card scaffolding as mobile, while desktop split rules remain unchanged above that tier.
- Add `list-view--single-pane` root class and route tablet clicks through the single-pane `onOpenDetail` path instead of the desktop split-pane selection.
- Update docs/dashboard-guide.md to describe the tablet single-pane behavior and add an FNXC:ListView comment recording the FN-7809 rationale.
- Add regression tests covering tablet single-pane rendering, tablet detail-open routing, and updated CSS-fixture assertions for the widened breakpoint.
- Add a patch changeset describing the fix for @runfusion/fusion release notes.

Files changed:
 .changeset/fn-7809-list-tablet-single-pane.md      |  7 +++
 docs/dashboard-guide.md                            |  6 +-
 packages/dashboard/app/components/ListView.css     | 11 ++--
 packages/dashboard/app/components/ListView.tsx     | 49 ++++++++-------
 .../app/components/__tests__/ListView.test.tsx     | 69 +++++++++++++++++++++-
 5 files changed, 112 insertions(+), 30 deletions(-)

Fusion-Task-Id: FN-7809
Fusion-Task-Lineage: 9e5f8bb7-13ee-4a58-81b1-eb5a9911bd4e
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 23:57:59 -07:00
gsxdsm
c530b238b4 FN-7810: fix stale-echo detection to preserve trailing newline edits in FileEditor
Replace the FileEditor's bounded self-echo Set with monotonic edit versions so trailing-newline edits (e.g. after a markdown header or at end-of-file) are never dropped when an older content prop races the live CodeMirror document.

- Track a monotonic localEditVersionRef and a contentEditVersionsRef map (content -> version) instead of a size-capped Set of echoed strings, avoiding eviction of stale values during long editing sessions.
- Compare a stale prop's known edit version against the live document's version and the last accepted prop version to decide if it is a stale self-echo, at any session length.
- Update FNXC:FileViewer comment to document the FN-7810 rationale for switching from bounded-Set self-echo detection to edit-version comparison.
- Add regression tests covering trailing markdown-header and plain-text newline edits across markdown/non-markdown file paths, and a long-session (20+ edit) case that previously could evict the self-echo tracking.

Files changed:
 packages/dashboard/app/components/FileEditor.tsx                | 32 +++++++----
 .../app/components/__tests__/FileEditor.test.tsx                 | 64 +++++++++++++++++++++-
 2 files changed, 83 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-7810
Fusion-Task-Lineage: 9dd68746-e772-4fa3-b648-6f3138d1e36e
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 23:57:59 -07:00
gsxdsm
e90a9c4f51 fix: auto-heal wedged SQLite connections in place instead of wedging until process restart
A long-lived connection can go SQLITE_NOTADB ('file is not a database' on
every query) while the on-disk file stays intact — observed 2026-07-10 on the
live dashboard, which then failed every API request and poll cycle until the
process was restarted, because all corruption recovery ran at open time only.

The sqlite adapter now detects connection-corruption errors, closes the dead
handle, reopens the same path, replays connection-scoped PRAGMAs, verifies
with quick_check, and retries the failed operation once when outside an
explicit transaction. Prepared statements are generation-tracked and
re-prepare transparently after a reopen; a lost transaction's unwind is
absorbed so the original error propagates cleanly. Reopens are rate-limited,
and real on-disk corruption still defers to the open-time recovery machinery.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 23:57:59 -07:00
gsxdsm
7d29367bc5 fix(FN-7786): hide sub-cent partial costs
Fusion-Task-Id: FN-7786
2026-07-10 23:50:15 -07:00
gsxdsm
9bed076ab0 fix(FN-7786): handle mixed zero cost feedback
Fusion-Task-Id: FN-7786
2026-07-10 23:50:15 -07:00
gsxdsm
fbea66d0f2 fix(FN-7786): show partial Command Center costs
Fusion-Task-Id: FN-7786
2026-07-10 23:50:15 -07:00
Phil Larson
122e404494 docs: clarify overseer badge access paths 2026-07-10 23:47:55 -07:00
Phil Larson
42a606ab5c docs: address overseer badge review notes 2026-07-10 23:47:55 -07:00
Phil Larson
dbb29d449a docs: explain planner overseer eye badge 2026-07-10 23:47:55 -07:00
gsxdsm
8fa2ad0ecd Address PR review feedback (#1996)
- contain fn_artifact_register path payloads: realpath-canonicalized
  containment before stat/read — relative paths require and must stay
  inside baseDir, absolute paths allowed only under baseDir or the OS
  temp dir (deliberate allowance for browser/screenshot tooling);
  the process.cwd() fallback is gone, symlink escapes rejected
- bind task-scoped heartbeat artifact registration to the acquired
  worktree (baseDir: sessionCwd rebind after acquisition); no-task
  heartbeat prompt now says to pass absolute temp-dir paths
- enforce exactly-one payload source (content/uri/dataBase64/path);
  content+uri combos are now rejected to match the documented contract
- add FNXC rationale comments at both visual-artifact instruction sites
  in the planning prompts (sync contract with the executor prompt)
- media route: statSync -> await stat from node:fs/promises
- range tests ride the in-memory MockSocket harness (TestResponse gains
  binary-safe bodyBuffer; real-TCP helper deleted) and assert the full
  206 Content-Range/Content-Length contract for every range form
- add PdfViewer coverage (iframe src/title) in DocumentsView tests

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 23:42:10 -07:00
gsxdsm
324a794d62 feat: draggable/resizable artifact viewer windows, Artifacts-first landing tab, uniform mobile tabs
- artifact viewers (image/video lightbox, PDF viewer, doc viewer) now host in
  the shared FloatingWindow: draggable by the viewer header, resizable by
  edge/corner handles, geometry persisted per viewer kind, closed by button
  or Escape; FloatingWindow gains an ariaLabel prop so headerless windows
  keep an accessible dialog name
- the Artifacts view leads with the Artifacts tab and always lands on it;
  Project Files and Task Documents are secondary tabs (the old auto-select
  effect is gone)
- mobile tab buttons rendered at mismatched heights (two-line "Project
  Files"/"Task Documents" grew past 44px while one-line "Artifacts" stayed
  at 44px); tabs now pin to the uniform 44px control height with
  non-wrapping labels in a scrollable row

Verified live: window dragged (264,146 -> 144,164) and resized
(1024x720 -> 872x618) in a real browser; mobile 390x844 lands on Artifacts
with uniform tab buttons.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 23:42:10 -07:00
gsxdsm
a8eafbbb14 feat: video, HTML mockup, and PDF artifact support end-to-end
Video was registrable but effectively unusable, and HTML/PDF deliverables
had no first-class path from agents to the gallery.

- media route now serves HTTP byte ranges (Accept-Ranges, 206 +
  Content-Range, 416 on unsatisfiable) so <video>/<audio> seeking works
  and Safari plays media at all
- video attachments (mp4/webm/mov, 100MB cap vs 5MB for other types)
  bridge into the artifact registry like images; multer transport ceiling
  raised to 100MB with per-type caps enforced in the store
- fn_artifact_register path payloads are signature-validated for video
  (ftyp box / EBML header) and PDF (%PDF- prefix), mirroring images
- HTML doc artifacts (mimeType text/html) render as live sandboxed
  iframe previews by default in the doc viewer, with a Preview/Source
  toggle and the same FileEditor edit mode
- executor/heartbeat/planning prompts and tool descriptions now cover
  the full type matrix: images, videos, audio, HTML mockups, PDFs, and
  markdown docs, each with the registration recipe

Verified live: range requests (200/206/416) via curl, an ffmpeg-generated
mp4 playing to completion in the gallery lightbox, and an interactive
HTML mockup rendering in the sandboxed preview.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 23:42:10 -07:00
gsxdsm
9024f3a639 feat: agent-created visual artifacts end-to-end + redesigned category gallery with doc editing
Agents could never get screenshots/wireframes/mocks into the Artifacts view:
fn_artifact_register was gated on assignedAgentId (never set in default
ephemeral mode), the only image payload source was inline base64, and no
prompt ever told agents to register visual deliverables.

- always expose fn_artifact_register to executor sessions ("executor" author
  fallback), resolve relative paths against the task worktree, and default
  taskId to the executing task (heartbeat task lane too)
- add a `path` payload source: file read with 50MB cap, extension MIME
  inference, PNG/JPEG/GIF/WebP signature + SVG sniff validation, persisted
  through managed artifact storage
- executor/heartbeat/planning prompts + engine-tools reference now instruct
  agents to register screenshots, wireframes, mockups, and recordings
- new ArtifactsGallery: Images/Docs/PDFs/Videos/Audio/Other category sections
  and filter chips, visual tile grid + lightbox, embedded PDF viewer, audio
  player rows, download rows; mobile-responsive down to the 768px breakpoint
- doc artifacts open a full viewer rendered as markdown by default with an
  in-place edit mode using the shared CodeMirror FileEditor; persisted via new
  GET/PATCH /api/artifacts/:id + TaskStore.updateArtifact and live-refreshed
  through the new artifact:updated SSE event

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 23:42:10 -07:00
Phil Larson
d116018ed4 fix(FN-1997): bind stranded AI merge recovery to reviewed commit 2026-07-10 23:32:57 -07:00
Phil Larson
e7549e354f Recover AI merge commits before pruning clean rooms 2026-07-10 23:32:57 -07:00
Phil Larson
93d4be7b99 Recover stranded approved AI merge commits 2026-07-10 23:32:57 -07:00
gsxdsm
49f03f8440 test(engine): add getBranchGroup to shared createMockStore (FN-7750 shared-branch-group integration) 2026-07-10 23:21:37 -07:00
gsxdsm
f05f54c86a test(engine): update grok-runtime-routing for single-JSON parse contract (FN-7796) 2026-07-10 23:21:37 -07:00
gsxdsm
1c3eceec5b test(engine): complete agent-session-helpers thinking-level resolver set + pi mocks (restart/mcp-pr/triage) 2026-07-10 23:21:37 -07:00
gsxdsm
86aad86f4e test(dashboard): fix useToast mocks + SettingsModal CSS token regex (shard 4) 2026-07-10 23:21:37 -07:00
gsxdsm
f164837e0f test(engine): add resolveExecutorThinkingLevel to step-session agent-session-helpers mock 2026-07-10 23:21:37 -07:00
gsxdsm
7d5f8ee9ea test(engine): add describeModel to heartbeat pi.js mocks (heartbeat-executor + heartbeat-skills) 2026-07-10 23:21:37 -07:00
gsxdsm
1bf52758e4 test(cli): fix stale project-context/desktop/core mocks + version pin + engine-tools doc (shard 3) 2026-07-10 23:21:37 -07:00
gsxdsm
a734f0093e update readme 2026-07-10 22:25:21 -07:00
gsxdsm
21fb8f6786 FN-7802: recover phantom-worktree tasks stuck merge-active with scopeOverride
Fixes phantom-worktree context bleed where the engine refused to start a
coding agent in a missing worktree for in-review/merge-active tasks even
when scopeOverride=1, stranding them past the normal recovery paths and
retry budget.

- Add isMergeActiveMissingWorktreeSessionStartFailure/isInReviewMissingWorktreeSessionStartFailure classifiers and MERGE_ACTIVE_MISSING_WORKTREE_STATUSES (merging/merging-pr/merging-fix) in restart-recovery-coordinator.ts, exported from @fusion/engine.
- Self-healing: reorder missing-worktree-review-failures sweep earlier, extend the in-review sweep to also match merge-active missing-worktree failures with a triple-proof-guarded, bounded (recoveryRetryCount) stale-metadata clear and fresh session-start retry budget reset.
- Self-healing: extend scopeOverride worktree-metadata reconciliation to safely clear phantom worktree/branch/session metadata for in-review tasks stuck in a merge-active sub-status, narrowly scoped to avoid clobbering genuinely live in-progress/mid-step tasks (FN-5256 guard preserved).
- CLI (task.ts), pi extension (extension.ts), and dashboard route (register-task-workflow-routes.ts) retry paths now bypass the merge-active status gate via a signature-only check, clearing worktree/branch/sessionFile and requeuing to todo while preserving progress.
- Add regression coverage across self-healing.test.ts, restart-recovery-coordinator.test.ts, extension.test.ts, task-retry.test.ts, and routes-tasks-ops.test.ts; update mockCoreEngine.ts test scaffolding.
- Update docs/architecture.md, docs/self-healing-backward-move-audit.md, docs/task-management.md, and AGENTS.md to describe the new merge-active missing-worktree recovery behavior.
- Add changeset (patch) for @runfusion/fusion.

Files changed:
 .changeset/fn-7802-phantom-worktree-merge-active-recovery.md      |   7 +
 AGENTS.md                                                          |   1 +
 docs/architecture.md                                               |   4 +-
 docs/self-healing-backward-move-audit.md                           |   5 +-
 docs/task-management.md                                            |   2 +-
 packages/cli/src/__tests__/extension.test.ts                       |  64 +++++
 packages/cli/src/__tests__/task-retry.test.ts                      |  49 ++++
 packages/cli/src/commands/task.ts                                  |  28 +-
 packages/cli/src/extension.ts                                      |  26 +-
 packages/dashboard/src/__tests__/routes-tasks-ops.test.ts          |  52 ++++
 packages/dashboard/src/routes/register-task-workflow-routes.ts     |  25 +-
 packages/dashboard/src/test/mockCoreEngine.ts                      |  11 +
 packages/engine/src/__tests__/restart-recovery-coordinator.test.ts |  20 ++
 packages/engine/src/__tests__/self-healing.test.ts                 | 297 +++++++++++++++++++++
 packages/engine/src/index.ts                                       |  13 +
 packages/engine/src/restart-recovery-coordinator.ts                |  19 +-
 packages/engine/src/self-healing.ts                                | 157 +++++++++--
 17 files changed, 744 insertions(+), 36 deletions(-)

Fusion-Task-Id: FN-7802

Fusion-Task-Lineage: 5897105b-6b5c-49d5-a8e8-519902182861

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 22:25:21 -07:00
gsxdsm
378e225d35 FN-7808: fix stale-echo overwrite dropping newlines in FileEditor
Prevent the controlled FileEditor from clobbering fast local typing (including newlines) with a stale content prop echoed back from an async parent update loop.

- Track the last emitted content and a small rolling set of recently emitted self-echoes in FileEditor.
- Skip re-syncing the CodeMirror document when the incoming content prop matches a known self-echo instead of a genuinely external change.
- Clamp the previous selection into the new document length when an external content change is applied, so the caret stays valid.
- Add regression tests covering stale self-echo renders (markdown and non-markdown files) and external content changes with clamped caret preservation.

Files changed:
 packages/dashboard/app/components/FileEditor.tsx   | 34 +++++++++++++--
 .../app/components/__tests__/FileEditor.test.tsx   | 49 ++++++++++++++++++++++
 2 files changed, 80 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7808

Fusion-Task-Lineage: 08d4f826-f637-428c-8b67-dacdb878bf4a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 22:25:21 -07:00
gsxdsm
c1b14c2d08 FN-7806: hide Gemini usage card when unconfigured or unauthenticated
Reclassifies Gemini usage fetch outcomes so unconfigured/unauthenticated Gemini no longer shows a noisy error card in the usage dropdown; transient failures of a configured token still surface as errors.

- fetchGeminiUsage() in packages/dashboard/src/usage.ts now sets status to `no-auth` (instead of `error`) for unsupported auth types (api-key/vertex-ai) and for HTTP 401/403 auth-expired responses, so fetchAllProviderUsage omits Gemini from the aggregate list in those cases
- HTTP 5xx, network, timeout, and parse failures for a configured Gemini token remain `error` and visible, per the existing FN-7798 keep-auth-expired-visible convention for other providers
- Added FNXC:UsageProviders comments documenting why Gemini deliberately diverges from that convention
- Updated packages/dashboard/src/__tests__/usage.test.ts to cover the new no-auth classification
- Added changeset .changeset/fn-7806-gemini-usage.md (patch) documenting the fix for release notes

Files changed:
 .changeset/fn-7806-gemini-usage.md             |   7 +
 packages/dashboard/src/__tests__/usage.test.ts | 211 +++++++++++++++----------
 packages/dashboard/src/usage.ts                |  15 +-
 3 files changed, 148 insertions(+), 85 deletions(-)

Fusion-Task-Id: FN-7806

Fusion-Task-Lineage: e86b23ea-14e9-472d-8b44-3951fa02ae6c

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 22:25:21 -07:00
gsxdsm
60b8b4e4c5 FN-7805: redesign quick-add priority indicators as icon-only controls
Redesigns the Quick Add composer's priority selector to icon-only glyph buttons and relocates GitHub tracking beside attach, backed by a new shared priorityIndicator helper.

- Add packages/dashboard/app/utils/priorityIndicator.tsx as the single source of ArrowUp/ArrowDown/Flag/TriangleAlert priority glyphs, shared by QuickEntryBox and TaskForm
- Rework QuickEntryBox.tsx to render icon-only priority/Fast controls and move GitHub tracking + Priority into the .quick-entry-primary-group, with matching QuickEntryBox.css layout updates
- Update TaskForm.tsx to reuse the new priorityIndicator helper instead of duplicating icon/label logic
- Update quick-entry height-parity/trigger-height tests and QuickEntryBox/TaskForm/NewTaskModal tests for the new icon-only layout
- Add priorityIndicator.test.tsx covering the shared helper
- Update docs/dashboard-guide.md and add changeset fn-7805-quick-add-priority-indicators.md (patch, feature)

Files changed:
 .../fn-7805-quick-add-priority-indicators.md       |   7 +
 docs/dashboard-guide.md                            |   3 +-
 .../quick-entry-action-row-height-parity.test.tsx  |  13 +-
 .../quick-entry-workflow-trigger-height.test.tsx   |  10 +-
 .../dashboard/app/components/QuickEntryBox.css     |  19 +-
 .../dashboard/app/components/QuickEntryBox.tsx     | 197 +++++++++++----------
 packages/dashboard/app/components/TaskForm.tsx     |  33 ++--
 .../app/components/__tests__/NewTaskModal.test.tsx |   3 +
 .../components/__tests__/QuickEntryBox.test.tsx    | 113 ++++++++----
 .../app/components/__tests__/TaskForm.test.tsx     |   3 +
 .../app/utils/__tests__/priorityIndicator.test.tsx |  21 +++
 packages/dashboard/app/utils/priorityIndicator.tsx |  30 ++++
 12 files changed, 300 insertions(+), 152 deletions(-)

Fusion-Task-Id: FN-7805

Fusion-Task-Lineage: 404fe8d6-0851-44cb-b31d-f47896aaaaba

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 22:25:21 -07:00
gsxdsm
367f5915bf FN-7804: show compact version label in mobile Settings footer
Mobile Settings footer now shows a compact "vX.Y.Z" version label instead of the full "Version X.Y.Z" wording, freeing horizontal space on small viewports while desktop/tablet keep the full label.

- SettingsModal renders settings.footer.versionShort ("v{{version}}") when viewportMode === "mobile", falling back to the existing settings.footer.version label otherwise
- Added settings.footer.versionShort translation key to en and fr locale files
- Updated settings-mobile tests: renamed/adjusted the mobile version test to assert the compact label and added a new test asserting the full label is kept outside the mobile viewport
- Added a patch changeset documenting the fix

Files changed:
 .changeset/fn-7804-mobile-settings-version.md          |  7 +++++++
 packages/dashboard/app/components/SettingsModal.tsx    | 10 +++++++++-
 .../app/components/__tests__/settings-mobile.test.tsx  | 18 +++++++++++++++---
 packages/i18n/locales/en/app.json                      |  1 +
 packages/i18n/locales/fr/app.json                      |  1 +
 5 files changed, 33 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-7804

Fusion-Task-Lineage: 3ff5af53-3242-44b8-b8d8-6b81f416a333

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 22:25:21 -07:00
gsxdsm
23dd0fcdf4 test: fix stale refinement-title assertions after FN-7165
Two store-comments refinement tests located the auto-created refinement task by
`title.includes("Refinement")`, but FN-7165 (34efa8b89) intentionally changed
refinement titles to `${sourceId}: ${feedback}` for traceability. The refinement
task is still created correctly (the length assertion passes); only the
identifying substring was stale, so the tests failed on `expect(refinement)
.toBeDefined()`. Match the refinement by its feedback-derived title instead.
No product behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 21:37:37 -07:00
gsxdsm
6e74eedf2d fix: make explicit prompt write atomic with the task-row commit (greptile P1)
updateTask now performs the explicit updates.prompt write (and its File Scope
validation) BEFORE committing the task row / task.json, instead of after. A
failed prompt write (EACCES/EISDIR/disk-full) or invalid File Scope now aborts
the whole update atomically rather than leaving the field changes committed with
a stale PROMPT.md and returning an error — the write counterpart to the
read-resilience guards in getTask/updateStep. Adds an atomicity regression test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 21:36:43 -07:00
gsxdsm
4fd6317aa4 fix: accurate error when updateStep can't read prompt-derived steps (greptile P1)
When a task's steps live only in an unreadable PROMPT.md, updateStep still can't
resolve step 0 — but it now throws an error naming PROMPT.md as the cause instead
of a misleading "task has 0 steps". The operation genuinely cannot succeed (no
step data), so this is accurate reporting, not a silent success. The reachable
reset path (which derives its loop from getTask's steps) remains unaffected.
Adds a test asserting the PROMPT.md-attributed error.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 21:36:43 -07:00