Commit Graph

4840 Commits

Author SHA1 Message Date
gsxdsm
dcb049587f FN-6298: fix agent heartbeat timestamp badges
Fix agent heartbeat card badges to use dedicated timestamp translation keys.

- Use separate Last/Next heartbeat timestamp keys so existing label strings do not collide with interpolated badge text.
- Add localized timestamp strings for all app locales.
- Cover desktop and mobile agent cards against raw placeholder or missing timestamp regressions.

Files changed:
 packages/dashboard/app/components/AgentsView.tsx   |  4 ++--
 .../app/components/__tests__/AgentsView.test.tsx   | 25 +++++++++++++++++++---
 .../__tests__/agents-view-mobile.test.tsx          | 23 ++++++++++++++++++--
 packages/i18n/locales/en/app.json                  |  2 ++
 packages/i18n/locales/es/app.json                  |  2 ++
 packages/i18n/locales/fr/app.json                  |  2 ++
 packages/i18n/locales/ko/app.json                  |  2 ++
 packages/i18n/locales/zh-CN/app.json               |  2 ++
 packages/i18n/locales/zh-TW/app.json               |  2 ++
 9 files changed, 57 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-6298

Fusion-Task-Lineage: 1561bcdc-83c9-4a81-aa7b-09d0c441ac1a
2026-06-12 09:46:46 -07:00
gsxdsm
cdcfa20ce0 FN-6297: make mobile edge details full-screen
Makes workflow edge details behave like a full-screen mobile editor stage while keeping the mobile tabs visible.

- Add a mobile edge-detail editor body state that hides the canvas and expands the inspector.\n- Add a dismiss control to the mobile edge inspector.\n- Preserve the top mobile tab row sizing and cover the edge-detail/mobile-tab CSS contracts with tests.

Files changed:\n .../app/components/WorkflowNodeEditor.css          | 19 +++++++++++++\n .../app/components/WorkflowNodeEditor.tsx          | 22 ++++++++++++---\n .../__tests__/WorkflowNodeEditor.css.test.ts       | 11 ++++++++\n .../__tests__/WorkflowNodeEditor.test.tsx          | 31 ++++++++++++++++++++++\n 4 files changed, 80 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-6297

Fusion-Task-Lineage: be7cea97-0790-4d88-9fa5-3d484b4d3dfb
2026-06-12 09:38:03 -07:00
gsxdsm
70655195f2 fix: stop iOS chat keyboard collapse from position:fixed scroll lock
The mobile chat keyboard collapsed the instant it opened on iOS because
the keyboard scroll-lock pinned body to position:fixed a beat after the
composer was already focused — pinning an ancestor to position:fixed
after focus blurs the input on iOS Safari (no visible jump, since the
dashboard base layout is already at scrollY 0).

Add useMobileKeyboardViewportLock: an overflow-only viewport lock
(overflow:hidden on html/body + scrollTo(0,0)) that does NOT touch
position, mirroring the working Quick Chat panel. App-level and ChatView
keyboard pins use it now; modals keep the position:fixed lock unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 09:03:40 -07:00
gsxdsm
cbc315772e fix: keep iOS mobile chat keyboard up and reopen Quick Chat FAB
Two iOS Safari-specific fixes for mobile chat:

- ChatView: the main chat keyboard collapsed the instant it opened
  because .chat-thread--keyboard-active declared transform/will-change in
  CSS, keeping a non-none transform on an ancestor of the focused
  composer textarea. iOS blurs a focused input when an ancestor
  establishes a transform containing block. Drive the drift transform in
  JS only when iOS actually shifts the viewport (offsetTop > 0); the
  ancestor stays transform:none on focus so the keyboard stays up.

- QuickChatFAB: the FAB never opened on iPhone because the drag hook
  calls setPointerCapture() in pointerdown, which makes WebKit swallow
  the synthetic click. Fire the open/close toggle from the drag hook's
  pointerup on a tap (a real gesture, so stealth-input focus still raises
  the keyboard); keep onClick for mouse/tests with a timer-cleared dedupe.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 08:45:27 -07:00
gsxdsm
ab040885fb fix: stop iOS chat keyboard collapse by removing destructive resync
The mobile chat keyboard would not reliably stay up on iOS. The cause was
the visibilitychange/pageshow 'resync' effect in ChatView: it only ever
ran while the composer was already focused (its activeElement guard), and
on iOS a programmatic focus() fired from setTimeout has no user-gesture
context, so it could not re-raise the keyboard after the blur(). Every
spurious iOS visibilitychange (Control Center, notification banners, app
switches) therefore dismissed the keyboard mid-session and never restored
it.

Remove the blur()+focus() resync. The visualViewport half-state it
targeted is already handled by useMobileKeyboard, which re-snapshots vv
metrics on visibilitychange/pageshow via its settle tail + rAF stability
poll without ever touching textarea focus.
2026-06-12 08:03:33 -07:00
gsxdsm
df2a0a1b5d fix: keep mobile chat keyboard up by gating iOS-only resync
The mobile resync effect did an unconditional textarea blur()+focus() on
every visibilitychange/pageshow across all platforms. On Android,
focus() after blur() cannot re-raise the soft keyboard, so spurious
visibilitychange events (including those fired mid-keyboard-transition)
collapsed the keyboard. Gate the resync to iOS only (its documented
purpose) and only run it when the document is actually becoming visible.
2026-06-12 08:00:48 -07:00
gsxdsm
7ffea9f4a6 FN-6290: expose Google Generative AI custom providers
Expose Google Generative AI as a selectable custom-provider API type across settings UI and docs.

- Add Google Generative AI options to custom-provider add and edit dropdowns.
- Cover add, edit, and existing Google-provider selection behavior with dashboard tests.
- Document the supported API type and add localized provider labels.
- Add a changeset for the published Fusion package.

Files changed:
 .changeset/fn-6290-expose-google-generative-ai.md  |  5 ++
 docs/dashboard-guide.md                            |  5 +-
 docs/settings-reference.md                         |  2 +-
 .../app/components/CustomProvidersSection.tsx      |  2 +
 .../__tests__/CustomProvidersSection.test.tsx      | 62 ++++++++++++++++++++++
 packages/i18n/locales/en/app.json                  |  1 +
 packages/i18n/locales/es/app.json                  |  1 +
 packages/i18n/locales/fr/app.json                  |  1 +
 packages/i18n/locales/ko/app.json                  |  1 +
 packages/i18n/locales/zh-CN/app.json               |  1 +
 packages/i18n/locales/zh-TW/app.json               |  1 +
 11 files changed, 79 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-6290

Fusion-Task-Lineage: 295cbba2-cae1-4998-9456-d6a306be6e34
2026-06-12 07:13:00 -07:00
gsxdsm
3bd8353fc2 FN-6288: fix mobile viewport screen mocking
Align the mobile auto-merge integration test viewport mock with screen dimensions.\n\n- Add explicit mobile width and height media-query handling to the viewport mock.\n- Mock window.screen dimensions alongside innerWidth and innerHeight.\n- Restore the original screen object after each test.\n\nFiles changed:\n ...-merge-toggle-blank.mobile-integration.test.tsx | 23 ++++++++++++++++++++++\n 1 file changed, 23 insertions(+)

Fusion-Task-Id: FN-6288

Fusion-Task-Lineage: 3c929d54-b482-41f3-a03e-0a22df0aa9e9
2026-06-12 06:08:37 -07:00
gsxdsm
0077b10ef7 Fix masked API key echoed back when editing custom providers
The custom provider edit form seeded the API key input with the masked
value (e.g. "abc•••••wxyz") returned by the sanitized GET. Saving or
running "Detect Models" without retyping echoed that mask back — the
probe endpoint rejects it and a persisted mask broke HTTP header
encoding. The field now starts blank with a "leave blank to keep" hint;
an empty field omits apiKey so the stored credential is preserved.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 01:06:33 -07:00
gsxdsm
f0d2415c20 Fix custom provider sends failing on masked API key
The settings UI displays saved API keys masked with '•' (U+2022). Saving
a provider without retyping the key echoed that mask back, and the PUT
handler persisted it as the real credential. The masked key then flowed
into an Authorization/x-api-key header, throwing "Cannot convert argument
to a ByteString ... value 8226" at request time.

Treat masked values echoed back on update as "unchanged" so the stored
key is preserved, and reject masked values on create/probe. Add tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 00:10:38 -07:00
gsxdsm
a83c2d89fe Fix custom provider models missing from model dropdowns
The /models endpoint restricted results to providers configured in
Fusion's auth.json/models.json stores, but custom providers live in
global settings and register under customProviderRegistryKey(). Their
keys were never added to the allowlist, so their models were filtered
out before reaching the dropdowns. Add the custom provider registry
keys to the configured-providers set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 00:05:10 -07:00
gsxdsm
22d6562494 FN-6261: map IR-only workflow nodes to editor types
Normalize graph-only workflow node kinds before rendering them in the workflow editor.\n\n- Add a typed mapping from IR-only merge, retry, recovery, branch, and PR node kinds to supported editor node kinds.\n- Keep same-kind editor node handling type-safe and fall back unknown graph-only kinds to prompt nodes.\n- Cover policy-node, foreach-template, merge-seam, and PR special cases in workflow-flow mapping tests.\n\nFiles changed:\n .../__tests__/workflow-flow-mapping.test.ts        | 101 ++++++++++++++++++++-\n .../app/components/workflow-flow-mapping.ts        |  71 ++++++++++-----\n 2 files changed, 149 insertions(+), 23 deletions(-)

Fusion-Task-Id: FN-6261

Fusion-Task-Lineage: 7c7ccb71-77b6-4759-95ab-6f577473fdb6
2026-06-11 22:55:48 -07:00
gsxdsm
b4dcd291eb FN-6256: enforce recursive raw rgba CSS hygiene
Extend the dashboard component CSS hygiene guard so raw rgb/rgba checks cover nested component styles.

- Recursively discover dashboard component CSS files instead of only scanning the top-level components directory.
- Report stable component-relative paths for violations across nested folders.
- Add focused coverage for raw rgba detection while preserving var() fallback allowance.

Files changed:
 .../__tests__/component-css-no-raw-rgba.test.ts    | 85 +++++++++++++++++-----
 1 file changed, 65 insertions(+), 20 deletions(-)

Fusion-Task-Id: FN-6256

Fusion-Task-Lineage: c8e84ab4-1da9-4cf0-9e04-d8ca4038eafa
2026-06-11 22:36:22 -07:00
gsxdsm
d23c5d901f FN-6247: refresh PR controls from live auto-merge setting
Keep task detail PR and review affordances synchronized with the current project auto-merge setting.

- Thread the live auto-merge value into task detail modals and list split-pane detail views.
- Prefer the live auto-merge setting over the stale fetched modal snapshot while preserving task-level overrides.
- Cover PR and review tab behavior for auto-merge on/off and document the dashboard behavior.
- Evict flaky engine gate entries and add a patch changeset for the published CLI package.

Files changed:
 .changeset/fn-6247-automerge-off-modal-stale.md    |   5 +
 docs/dashboard-guide.md                            |   1 +
 packages/dashboard/app/App.tsx                     |   3 +-
 packages/dashboard/app/components/AppModals.tsx    |   2 +
 packages/dashboard/app/components/ListView.tsx     |   3 +
 .../dashboard/app/components/TaskDetailModal.tsx   |   4 +-
 .../__tests__/TaskDetailModal.create-pr.test.tsx   | 171 ++++++++++++++++++++-
 packages/engine/vitest.config.ts                   |   2 -
 8 files changed, 182 insertions(+), 9 deletions(-)

Fusion-Task-Id: FN-6247

Fusion-Task-Lineage: 1321c03a-216d-4b15-bf4f-95621d68c9ae
2026-06-11 22:11:44 -07:00
gsxdsm
65251d2e6b FN-6252: stop agent pauses from pausing tasks
Agent pause and sleep flows now leave task pause state under explicit task controls.\n\n- Remove automatic task pausing from heartbeat pauseAgent and dashboard fallback state changes.\n- Default resume task cascade to off while retaining legacy opt-in unpause cleanup.\n- Cover agent sleep, heartbeat execution, and dashboard fallback pause behavior with regression tests.\n- Document task pause ownership and add a patch changeset.\n\nFiles changed:\n .changeset/fn-6252-no-agent-task-autopause.md      |  5 ++\n docs/agents.md                                     |  2 +-\n docs/architecture.md                               |  4 ++\n .../src/__tests__/routes-agent-runs.test.ts        | 32 +++++++++\n .../src/routes/register-agent-runtime-routes.ts    | 17 -----\n .../src/__tests__/heartbeat-executor.test.ts       | 75 ++++++++++++++++++++--\n packages/engine/src/agent-heartbeat.ts             | 29 +++------\n 7 files changed, 121 insertions(+), 43 deletions(-)

Fusion-Task-Id: FN-6252

Fusion-Task-Lineage: f7a0ef30-0c99-4f9c-b0c1-43217d613187
2026-06-11 22:03:29 -07:00
gsxdsm
c0ff360737 FN-6243: keep mobile auto-merge toggles visible
Keep the mobile dashboard pinned while offscreen auto-merge controls are toggled.

- Reset document horizontal scroll during mobile board stabilization and immediately after auto-merge toggles.
- Cover portrait and landscape mobile scroll realignment in the auto-merge integration test.
- Document the real-browser blank-dashboard root cause and add a patch changeset.

Files changed:
 .changeset/FN-6243-mobile-auto-merge-blank.md      |  5 ++
 ...bile-auto-merge-toggle-document-scroll-blank.md | 55 ++++++++++++++++++++++
 packages/dashboard/app/components/Board.tsx        | 47 ++++++++++++++++--
 ...-merge-toggle-blank.mobile-integration.test.tsx | 49 +++++++++++++++++++
 4 files changed, 152 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-6243

Fusion-Task-Lineage: 91f74de2-667f-4732-a840-47b792288bec
2026-06-11 21:26:59 -07:00
gsxdsm
143a724a99 FN-6239: map workflow merge nodes in the editor
Render workflow-owned merge and recovery IR nodes with existing dashboard editor shapes.

- Map merge gate, retry, recovery, and branch-group IR node kinds to supported editor node types.
- Update the workflow mapping assertion for merge-attempt failure routing.
- Quarantine the flaky QuickEntryBox dashboard test without reintroducing the rescued self-healing quarantine entry.

Files changed:
 .../app/components/__tests__/WorkflowNodeEditor.test.tsx    |  2 +-
 packages/dashboard/app/components/workflow-flow-mapping.ts  | 13 +++++++++++++
 packages/dashboard/vitest.config.ts                         |  2 +-
 scripts/lib/test-quarantine.json                            |  5 +++++
 4 files changed, 20 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-6239

Fusion-Task-Lineage: 2ab31bd4-6fd7-4b71-b7cd-6cc99cce3bbb
2026-06-11 21:22:06 -07:00
gsxdsm
64d831576d FN-6225: persist workflow model lanes on Settings save
Persist default workflow model lane edits through the Settings modal's primary save path.

- Register a Project Models section save handler so workflow lane overrides flush before closing Settings.
- Surface typed workflow setting rejections without closing the modal or showing a success toast.
- Remove the separate workflow-model save button and update coverage/docs for the unified save behavior.

Files changed:
 docs/dashboard-guide.md                            |  2 +-
 docs/settings-reference.md                         | 17 +++++---
 .../dashboard/app/components/SettingsModal.tsx     | 11 ++++-
 .../components/__tests__/SettingsModal.test.tsx    | 50 ++++++++++++++++------
 .../settings/sections/ProjectModelsSection.tsx     | 42 ++++++++++--------
 .../app/components/settings/sections/context.ts    |  3 ++
 6 files changed, 83 insertions(+), 42 deletions(-)

Fusion-Task-Id: FN-6225

Fusion-Task-Lineage: 98338f85-c742-46c2-8bdf-f676a6f7e32e
2026-06-11 20:21:30 -07:00
gsxdsm
40cb0d3d45 FN-6223: keep usage dialog near the top
Keep usage dialog positioning consistently top-biased across viewport surfaces.

- Clamp desktop popover placement to the upper viewport while preserving anchor alignment and saved sizing.
- Add overlay styling so modal and mobile sheet presentations start near the top.
- Extend UsageIndicator tests across desktop, mobile, saved-size, and data-state surfaces.
- Add a patch changeset for the published Fusion package.

Files changed:
 .changeset/top-usage-dialog.md                     |   5 +
 .../dashboard/app/components/UsageIndicator.css    |   8 ++
 .../dashboard/app/components/UsageIndicator.tsx    |  18 ++-
 .../components/__tests__/UsageIndicator.test.tsx   | 139 ++++++++++++++++++++-
 4 files changed, 162 insertions(+), 8 deletions(-)

Fusion-Task-Id: FN-6223

Fusion-Task-Lineage: a35e82f4-ddef-4d68-81f0-6fee420f0392
2026-06-11 20:14:54 -07:00
gsxdsm
1c2b68386b FN-6210: cap chat sidebar width during keyboard flicker
Keep the chat sidebar bounded when tablet keyboard viewport changes briefly report mobile sizing.

- Add a desktop max-width guard to the chat sidebar with a mobile override.
- Cover simulated tablet keyboard viewport-mode flicker in the mobile render tests.
- Document the ChatView sidebar defense alongside the tablet viewport-mode solution.

Files changed:
 .../ui-bugs/tablet-keyboard-viewport-mode-flip.md  |  3 ++
 packages/dashboard/app/components/ChatView.css     |  2 +
 .../__tests__/ChatView.mobile-render.test.tsx      | 53 ++++++++++++++++++++++
 3 files changed, 58 insertions(+)

Fusion-Task-Id: FN-6210

Fusion-Task-Lineage: b3aca9d5-dc16-45e2-8f2c-5c2d51c7d021
2026-06-11 19:51:19 -07:00
gsxdsm
02ae5a9340 FN-6213: prevent keyboard from forcing mobile layout
Keep tablet and desktop layouts stable when the virtual keyboard shrinks viewport height.

- Gate short-height mobile detection on phone-class physical screen size.
- Reuse the shared mobile viewport helper across board, terminal, and workflow editor layout decisions.
- Cover tablet keyboard and landscape phone viewport behavior with regression tests and document the UI bug pattern.
- Preserve quarantine exclusions while resolving the squash merge conflict.

Files changed:
 .../ui-bugs/tablet-keyboard-viewport-mode-flip.md  | 54 +++++++++++++
 packages/dashboard/app/components/Board.tsx        |  4 +-
 .../dashboard/app/components/SessionTerminal.tsx   | 16 +---
 .../app/components/WorkflowNodeEditor.tsx          | 41 +++++-----
 .../__tests__/SessionTerminal.mobile.test.tsx      | 57 ++++++++++----
 .../app/hooks/__tests__/useViewportMode.test.ts    | 90 +++++++++++++++++++++-
 packages/dashboard/app/hooks/useViewportMode.ts    | 26 ++++++-
 packages/engine/vitest.config.ts                   |  1 +
 scripts/lib/test-quarantine.json                   |  5 ++
 9 files changed, 239 insertions(+), 55 deletions(-)

Fusion-Task-Id: FN-6213

Fusion-Task-Lineage: 01af6489-8c34-4318-9cff-1bceb1fa5a5d
2026-06-11 19:37:25 -07:00
gsxdsm
3cb0f9f371 FN-6231: enlarge tablet modal and expose triage prompt
Increase tablet task detail modal height while keeping triage prompt contracts testable.\n\n- Set tablet task detail modal height to 92vh with a dynamic viewport max-height guard.\n- Add CSS regression coverage for desktop, tablet, mobile, and embedded modal height invariants.\n- Export the standard triage prompt and include it in invariant wording tests.\n\nFiles changed:\n .../dashboard/app/components/TaskDetailModal.css   |   2 +\n .../__tests__/core-modals-mobile.test.tsx          |  74 ++++-\n packages/engine/src/__tests__/triage.test.ts       |   5 +-\n packages/engine/src/triage.ts                      | 333 +++++++++++++++++++++\n 4 files changed, 406 insertions(+), 8 deletions(-)

Fusion-Task-Id: FN-6231

Fusion-Task-Lineage: 58e990dd-2dbb-4c6e-869d-661b02699cef
2026-06-11 17:15:24 -07:00
gsxdsm
8eb99ed0f8 FN-6217: prevent visibility-driven quick entry focus
Limit Quick Entry focus restoration to successful submissions instead of dashboard visibility changes.

- Gate desktop focus restoration behind an in-component successful submit marker.
- Remove the stale touch-driven suppressRefocus blur/timer path so touch actions do not force unexpected blurs.
- Cover mount, remount, mobile, submit, duplicate-confirm, Escape, Plan, and Subtask focus behavior in QuickEntryBox tests.
- Add a patch changeset for the published CLI package.

Files changed:
 .changeset/FN-6217-quick-entry-focus.md            |   5 +
 .../dashboard/app/components/QuickEntryBox.tsx     |  36 ++---
 .../components/__tests__/QuickEntryBox.test.tsx    | 167 +++++++++++++++++++--
 3 files changed, 174 insertions(+), 34 deletions(-)

Fusion-Task-Id: FN-6217

Fusion-Task-Lineage: cf8c55c0-583e-42f5-98af-8f3406c86d8c
2026-06-11 14:55:19 -07:00
gsxdsm
7923148490 FN-6211: prevent QuickEntry option taps from refocusing input
Prevents mobile option taps from re-opening the QuickEntry textarea keyboard.

- suppresses textarea refocus briefly while QuickEntry action buttons handle touch interactions
- only prevents default touch behavior when the textarea is already focused
- adds mobile regression coverage for blurred action toggles, menus, attachments, refine, planning, subtasks, and save flows

Files changed:
 .../dashboard/app/components/QuickEntryBox.tsx     |  17 ++-
 .../components/__tests__/QuickEntryBox.test.tsx    | 148 +++++++++++++++++++++
 2 files changed, 164 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-6211

Fusion-Task-Lineage: 9e20c4e3-8b19-4374-b492-745a92c7bb10
2026-06-11 14:03:16 -07:00
gsxdsm
28e74c74db FN-6212: cap chat input height on tablets
Limit the chat composer growth on tablet viewports while preserving desktop autosizing.

- Add a tablet-specific 200px max height for the chat input textarea.
- Apply the same cap in ChatView autosize calculations when tablet mode is active.
- Generalize chat input height helpers and cover the tablet cap in autosize tests.

Files changed:
 packages/dashboard/app/components/ChatView.css       |  9 +++++++++
 packages/dashboard/app/components/ChatView.tsx       | 20 +++++++++++++-------
 packages/dashboard/app/components/QuickChatFAB.tsx   |  4 ++--
 .../__tests__/ChatView.chat-input-autosize.test.tsx  | 14 ++++++++++++++
 4 files changed, 38 insertions(+), 9 deletions(-)

Fusion-Task-Id: FN-6212

Fusion-Task-Lineage: b11cd658-8289-4795-8e39-7d03a1d51d41
2026-06-11 09:21:23 -07:00
gsxdsm
d68fe3e9f8 FN-6209: fix tablet tab overflow in agent detail
Keep agent detail tabs usable without page-wide horizontal scrolling at tablet widths.

- Make the agent detail tabs row horizontally scrollable with hidden scrollbars and touch momentum.
- Prevent tab labels from wrapping so the tab strip can overflow within its own container.
- Add a regression test covering tablet-width tab overflow styles.

Files changed:
 .../dashboard/app/components/AgentDetailView.css   |  8 +++++
 .../AgentDetailView.mobile-scroll.test.tsx         | 34 +++++++++++++++++++++-
 2 files changed, 41 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-6209

Fusion-Task-Lineage: 7646bea2-b63a-460f-813b-cf9808680d46
2026-06-11 09:21:23 -07:00
gsxdsm
07d5262a83 FN-6208: sync workflow settings across nodes
Synchronize workflow setting values through node settings sync.

- Include workflow settings in settings payloads, diffs, status responses, and API types.
- Apply inbound and pulled workflow settings through the TaskStore while ignoring rejected setting ids.
- Add core, route, hook, API, and Nodes view coverage for workflow settings sync behavior.
- Add a patch changeset for the published Fusion package.

Files changed:
 .changeset/loud-nodes-sync.md                      |   5 +
 packages/core/src/__tests__/central-core.test.ts   |  37 ++++
 packages/core/src/central-core.ts                  |  13 +-
 packages/core/src/types.ts                         |   4 +
 packages/dashboard/app/__tests__/api-node.test.ts  |   4 +-
 packages/dashboard/app/api-node.ts                 |   3 +
 .../app/components/__tests__/NodesView.test.tsx    |   8 +-
 .../hooks/__tests__/useNodeSettingsSync.test.ts    |  33 +++-
 .../dashboard/app/hooks/useNodeSettingsSync.ts     |   4 +-
 .../__tests__/routes-nodes-sync-contract.test.ts   |  18 +-
 .../src/__tests__/routes-nodes-sync.test.ts        | 191 ++++++++++++++++++++-
 .../src/routes/register-settings-memory-routes.ts  |   7 +-
 .../register-settings-sync-inbound-routes.ts       |  73 +++++++-
 .../src/routes/register-settings-sync-routes.ts    | 128 ++++++++++++--
 14 files changed, 488 insertions(+), 40 deletions(-)

Fusion-Task-Id: FN-6208

Fusion-Task-Lineage: 9b5e7e56-6287-4bc5-966a-2bcc2ba292a7
2026-06-11 09:21:23 -07:00
gsxdsm
74c63a75d0 FN-6205: skip custom providers in settings save split
Prevent the settings save split from serializing custom provider definitions through the global or project patch paths.

- skip `customProviders` when building global settings patches
- skip `customProviders` when building project settings patches
- add a regression test that keeps custom providers out of both serialized patches

Files changed:
 .../app/__tests__/settings-save-split.test.ts      | 24 ++++++++++++++++++++++
 .../app/components/settings/save-split.ts          |  4 ++++
 2 files changed, 28 insertions(+)

Fusion-Task-Id: FN-6205

Fusion-Task-Lineage: 84c3f42b-c621-44ff-b977-ecd3a6729e04
2026-06-11 09:21:23 -07:00
gsxdsm
045a74d249 chore(release): v0.41.0
Version bump via changesets.
2026-06-10 19:05:55 -07:00
gsxdsm
4151a19e84 feat: bump pi coding agent to 0.79.1 for Claude Fable 5 support
Update @earendil-works/pi-coding-agent and @earendil-works/pi-ai from
^0.78.0 to ^0.79.1 across cli, engine, and dashboard. This brings in
Claude Fable 5 (claude-fable-5) on the Anthropic and Amazon Bedrock
providers.

Fusion's model picker is registry-driven (/api/models -> pi ModelRegistry,
filtered by provider, not model id), so Fable surfaces automatically for
users with Anthropic or Claude CLI auth configured — no Fusion-side model
list change needed.

Verified: all core packages typecheck clean against 0.79.1; boot smoke
(fn --help, /api/health 200, clean shutdown) passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 18:51:36 -07:00
gsxdsm
f0d6d70a32 chore(release): v0.40.1
Version bump via changesets.
2026-06-10 18:08:04 -07:00
gsxdsm
9f38b0d090 chore(release): v0.40.0
Version bump via changesets.
2026-06-10 17:58:39 -07:00
gsxdsm
0b299ee5fc FN-6201: move Authentication after General in settings
Move Authentication into the Global settings group after General.

- remove the standalone Account header from the settings sidebar
- place Authentication immediately after Global General in the Global group
- update the section inventory comments to match the new grouping, including runtime sections

Files changed:
 packages/dashboard/app/components/SettingsModal.tsx | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-6201

Fusion-Task-Lineage: 4cae66aa-43c5-4436-957b-4059915c2884
2026-06-10 12:10:02 -07:00
gsxdsm
747bbf51f1 FN-6194: fix archived GitHub issue reconciliation
Handle archived task transitions consistently for linked GitHub issues.

- close tracked and source issues when archived tasks should land closed, including not_planned vs completed reasons
- reopen linked issues when archived tasks move back to done or active work resumes
- extend dashboard reconciler and state coverage to include archived tasks and source issue handling

Files changed:
 .../__tests__/github-source-issue-close.test.ts    | 70 +++++++++++++++++++++-
 .../__tests__/github-tracking-reconciler.test.ts   | 60 ++++++++++++++++++-
 .../src/__tests__/github-tracking-state.test.ts    | 10 +++-
 .../dashboard/src/github-source-issue-close.ts     | 32 ++++++----
 .../dashboard/src/github-tracking-reconciler.ts    | 14 +++--
 packages/dashboard/src/github-tracking-state.ts    |  4 ++
 6 files changed, 167 insertions(+), 23 deletions(-)

Fusion-Task-Id: FN-6194

Fusion-Task-Lineage: 867527a0-6eb9-416e-b1eb-d690fa029d60
2026-06-10 10:34:36 -07:00
gsxdsm
b6243d68fe FN-6197: suppress tab-resume fetch errors in dashboard
Keep cached dashboard data visible while reconnecting after transient tab-resume fetch failures.

- detect likely tab suspension and visibility-resume fetch errors across dashboard data hooks
- suppress transient "Failed to fetch" errors when cached project and node data already exist
- show a "Connecting…" executor status state instead of surfacing raw resume-time fetch errors
- add dashboard tests covering visibility suspension handling and executor reconnect rendering
- add a patch changeset for the published CLI package

Files changed:
 .changeset/tame-tab-resume-fetch.md                |   5 +
 packages/dashboard/app/App.tsx                     |  16 ++-
 .../dashboard/app/components/ExecutorStatusBar.css |  19 ++-
 .../dashboard/app/components/ExecutorStatusBar.tsx |  12 ++
 .../__tests__/ExecutorStatusBar.test.tsx           |  20 ++-
 .../dashboard/app/hooks/__tests__/useNodes.test.ts | 149 ++++++++++++++++++++-
 .../app/hooks/__tests__/useProjects.test.ts        |  72 +++++++++-
 .../hooks/__tests__/visibilitySuspension.test.ts   |  13 ++
 packages/dashboard/app/hooks/useExecutorStats.ts   |  15 ++-
 .../dashboard/app/hooks/useManagedDockerNodes.ts   |  25 +++-
 packages/dashboard/app/hooks/useMeshState.ts       |  25 +++-
 packages/dashboard/app/hooks/useNodes.ts           |  25 +++-
 packages/dashboard/app/hooks/useProjectHealth.ts   |  18 ++-
 packages/dashboard/app/hooks/useProjects.ts        |  27 +++-
 packages/dashboard/app/hooks/useUsageData.ts       |  24 +++-
 .../dashboard/app/hooks/visibilitySuspension.ts    |   4 +
 16 files changed, 435 insertions(+), 34 deletions(-)

Fusion-Task-Id: FN-6197

Fusion-Task-Lineage: 834f56d8-8391-414f-8cbd-7e626c5724d0
2026-06-10 09:21:48 -07:00
gsxdsm
f7ae18a49f fix: make mobile workflow node details full height 2026-06-10 08:37:01 -07:00
gsxdsm
529851a8fe FN-6191: unquarantine WorkflowNodeEditor inspector test
Rescue the WorkflowNodeEditor quarantine by waiting for inspector fields before asserting.

- make the foreach inspector Mode assertion wait for the panel to finish rendering
- wait for the code node Source and Timeout inputs before editing them to avoid the inspector race
- remove WorkflowNodeEditor.test.tsx from the dashboard quarantine config and ledger

Files changed:
 .../app/components/__tests__/WorkflowNodeEditor.test.tsx          | 6 +++---
 packages/dashboard/vitest.config.ts                               | 4 +---
 scripts/lib/test-quarantine.json                                  | 8 +-------
 3 files changed, 5 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-6191

Fusion-Task-Lineage: 57fb1dcc-3e50-4ba1-8488-fcff204c1d76
2026-06-10 07:11:19 -07:00
gsxdsm
49fdd8f41f FN-6190: replace remaining raw rgba styles with color-mix tokens
Tokenize the last non-token dashboard rgba() styles and guard them with regression coverage.

- replace remaining modal, sidebar, tooltip, dependency dropdown, and refine menu raw rgba() usages in styles.css with color-mix() design tokens
- align overlay, background, and shadow treatments with existing semantic CSS variables instead of hard-coded rgba() values
- add a CSS fixture regression test that bans non-:root raw rgba() usage and verifies the converted selectors stay tokenized

Files changed:
 .../__tests__/styles-css-rgba-tokenization.test.ts | 122 +++++++++++++++++++++
 packages/dashboard/app/styles.css                  |  14 +--
 2 files changed, 129 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-6190

Fusion-Task-Lineage: 478465a7-8ec4-4482-8e1c-478d86c1ac08
2026-06-10 06:48:56 -07:00
gsxdsm
f79adafcc1 FN-6189: add moved-task coverage to GitHub delete test
Extend the delete-flow regression test to cover tasks that pass through active workflow states before completion.

- move the tracked task through todo and in-progress before marking it done
- verify the delete-path close behavior still uses the linked GitHub issue after those state transitions

Files changed:
 packages/dashboard/src/__tests__/github-tracking-delete.test.ts | 2 ++
 1 file changed, 2 insertions(+)

Fusion-Task-Id: FN-6189

Fusion-Task-Lineage: 986497ff-c45c-4c0b-9d50-87d9f6570bf1
2026-06-10 06:21:51 -07:00
gsxdsm
7e903494ec FN-6186: tokenized dashboard accent text colors
Add a dashboard CSS hygiene scan and align accent text colors with the CTA text token.

- add a dashboard CSS hygiene regression scan for recent component styles
- assert tokenized focus styles, mobile breakpoints, and no raw hex or rgba colors in scanned CSS
- replace hardcoded white text with var(--cta-text) in background task, pull request, task card, and task field accent surfaces

Files changed:
 .../app/__tests__/css-hygiene-scan.test.ts         | 191 +++++++++++++++++++++
 .../app/components/BackgroundTasksIndicator.css    |   2 +-
 .../dashboard/app/components/PullRequestView.css   |   2 +-
 packages/dashboard/app/components/TaskCard.css     |   2 +-
 .../dashboard/app/components/TaskFieldsSection.css |   2 +-
 5 files changed, 195 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-6186

Fusion-Task-Lineage: c579bcda-01f9-4495-bf59-78d1dfef816c
2026-06-10 06:02:12 -07:00
gsxdsm
af0be9dd32 FN-6184: log forwarded vitest wrapper signals
Improve dashboard vitest wrapper diagnostics so transient SIGTERM handling is easier to trace.

- track the last signal and reason forwarded from the heap wrapper to the vitest process group
- log when the wrapper receives SIGINT or SIGTERM and when timeout shutdown escalates
- extend wrapper tests to assert process-group leadership and emitted diagnostic stderr

Files changed:
 .../scripts/__tests__/run-vitest-with-heap.test.ts | 25 +++++++++++++++++++---
 .../dashboard/scripts/run-vitest-with-heap.mjs     | 19 ++++++++++++----
 2 files changed, 37 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-6184

Fusion-Task-Lineage: b276d88e-a22d-4fdf-a533-c4b0aa4e199d
2026-06-10 01:23:59 -07:00
gsxdsm
fc9f6fe271 FN-6185: replace dashboard rgba fallbacks with color-mix
Convert remaining dashboard component rgba() fallbacks to color-mix() and extend the audit to cover the touched stylesheets.

- replace rgba() fallback colors with color-mix() in language selector, pull request, workflow, and settings component CSS
- expand the dashboard color tokenization audit to include the newly cleaned component stylesheets
- make the audit resolve settings component CSS from nested paths so SettingsFieldRow coverage works

Files changed:
 .../dashboard-component-color-tokenization.test.ts | 31 ++++++++++++++++------
 .../dashboard/app/components/LanguageSelector.css  |  2 +-
 .../dashboard/app/components/PullRequestView.css   | 20 +++++++-------
 .../app/components/WorkflowFieldsPanel.css         |  2 +-
 .../app/components/WorkflowNodeEditor.css          |  4 +--
 .../app/components/WorkflowSettingsPanel.css       |  2 +-
 .../app/components/settings/SettingsFieldRow.css   |  2 +-
 7 files changed, 39 insertions(+), 24 deletions(-)

Fusion-Task-Id: FN-6185

Fusion-Task-Lineage: b1938669-5ebb-4569-864b-bd64543ec843
2026-06-10 01:10:11 -07:00
gsxdsm
5e35385594 FN-6183: preserve mobile mailbox scroll on refresh
Keep the mobile mailbox list anchored after refreshes and SSE updates.

- capture the mobile mailbox content scroll position before inbox, outbox, agent, and approval reloads
- restore the saved scroll position after refreshed mailbox data renders and wire the content container through a ref
- allow vertical scrolling in the mailbox view content area and cover the SSE refresh behavior with a mobile regression test

Files changed:
 packages/dashboard/app/components/MailboxModal.css |  3 +-
 packages/dashboard/app/components/MailboxView.tsx  | 58 +++++++++++++++++++---
 .../app/components/__tests__/MailboxView.test.tsx  | 35 +++++++++++++
 3 files changed, 89 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-6183

Fusion-Task-Lineage: ea8be80b-4834-4b77-96cd-254e6b0b0795
2026-06-10 00:25:10 -07:00
gsxdsm
c9d48fb750 FN-6180: fix stale dashboard asset reload handling
Prevent rebuilt dashboard tabs from reusing stale cached assets after a deploy.

- revalidate service-worker asset requests against the network before falling back to cache and bump the cache version
- suppress repeated version-change reloads for the same remote build and cover the new behavior with dashboard tests
- update engine heartbeat test expectations for summarized task creation metadata and add the published package changeset

Files changed:
 .changeset/fn-blank-page-service-worker-assets.md  |  3 ++
 packages/dashboard/app/__tests__/pwa.test.ts       | 11 ++++++
 packages/dashboard/app/__tests__/versionCheck.test.ts   | 28 ++++++++++++++
 packages/dashboard/app/public/sw.js                | 37 +++++++++++++++++-
 packages/dashboard/app/versionCheck.ts             | 45 ++++++++++++++++++++++
 packages/engine/src/__tests__/heartbeat-executor.test.ts |  3 +-
 packages/engine/src/__tests__/heartbeat-session-prompt.test.ts |  7 +++-
 7 files changed, 131 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-6180

Fusion-Task-Lineage: 4f07e5f0-56c7-4241-8719-f576dfd8613e
2026-06-10 00:20:35 -07:00
gsxdsm
17363928e9 FN-6178: hide chat sidebar when tablet keyboard opens
Keep the chat sidebar from crowding tablet chat while the software keyboard is open.

- extend mobile keyboard detection so tablet chat can react to visual viewport keyboard changes
- hide the chat sidebar and resize handle while the tablet keyboard is open, then restore prior visibility when it closes
- add regression coverage for tablet keyboard behavior plus desktop and mobile guardrails

Files changed:
 packages/dashboard/app/components/ChatView.tsx     |  39 +++++-
 packages/dashboard/app/components/__tests__/ChatView.mobile-render.test.tsx      | 139 ++++++++++++++++++++-
 packages/dashboard/app/hooks/useMobileKeyboard.ts  |   7 +-
 3 files changed, 171 insertions(+), 14 deletions(-)

Fusion-Task-Id: FN-6178

Fusion-Task-Lineage: 7acdb76a-135f-4b9c-ab50-708eec03b2c6
2026-06-10 00:16:35 -07:00
gsxdsm
de7b1109e2 FN-6179: fix tablet nodes overlay stacking
Prevent the NodesView tablet overlay from letting underlying content bleed through.

- make the tablet nodes management overlay fixed, fullscreen, and scrollable with the app background
- add a regression test that asserts the tablet overlay media query and rule properties
- add a patch changeset for the published CLI package bundle

Files changed:
 .changeset/fn-6179-tablet-nodes-overlay.md         |  5 +++++
 packages/dashboard/app/components/NodesView.css    | 12 ++++++++++-
 .../app/components/__tests__/NodesView.test.tsx    | 23 ++++++++++++++++++++--
 3 files changed, 37 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-6179

Fusion-Task-Lineage: 9455b38e-c32f-4865-917a-a06c1cb38840
2026-06-09 23:52:37 -07:00
gsxdsm
b84f416e07 FN-6175: stabilize TerminalModal mobile tab regression tests
Harden TerminalModal mobile keyboard regression coverage against async tab setup and xterm mock issues.

- add missing xterm terminal mock methods used by mobile tab interactions
- replace anonymous constructor mock implementations with named function mocks for Terminal and FitAddon
- wait for second-session callbacks before simulating viewport and keyboard transitions in mobile tab-switch tests

Files changed:
 packages/dashboard/app/components/__tests__/TerminalModal.test.tsx | 48 ++++++++++++++++++----
 1 file changed, 39 insertions(+), 9 deletions(-)

Fusion-Task-Id: FN-6175

Fusion-Task-Lineage: fc95f3d6-586a-475c-a226-be1a57c88ff4
2026-06-09 23:32:57 -07:00
gsxdsm
827b7d934d FN-6171: move GitHub tracking below prompt details
Move the task detail modal's GitHub tracking section to render after the prompt/spec content.

- relocate the GitHub tracking section in TaskDetailModal so it appears beneath prompt details in read mode
- preserve the existing GitHub tracking controls, status, and expand/collapse behavior while changing only section order
- add a regression test that asserts the prompt content appears before the GitHub tracking section

Files changed:
 .../dashboard/app/components/TaskDetailModal.tsx   | 274 ++++++++++-----------
 ...lModal.inline-editing-and-integrations.test.tsx |  28 +++
 2 files changed, 165 insertions(+), 137 deletions(-)

Fusion-Task-Id: FN-6171

Fusion-Task-Lineage: dac8ac54-655d-4403-9e7d-6aad446da793
2026-06-09 23:21:46 -07:00
gsxdsm
d7e14542a9 FN-6170: make mobile nodes view fullscreen
Make the mobile Nodes screen open as a full-screen overlay above the header and nav.

- add a mobile-only fixed fullscreen overlay style for the nodes management panel
- preserve safe-area spacing and scroll behavior while keeping the overlay above mobile navigation
- add a NodesView regression test that asserts the mobile overlay CSS contract and close control rendering

Files changed:
 .changeset/fn-6170-mobile-nodes-fullscreen.md      |  5 +++
 packages/dashboard/app/components/NodesView.css    | 11 +++++
 .../app/components/__tests__/NodesView.test.tsx    | 52 ++++++++++++++++++++++
 3 files changed, 68 insertions(+)

Fusion-Task-Id: FN-6170

Fusion-Task-Lineage: 16995d9f-6b5e-4f15-9367-7eccbd3153d0
2026-06-09 23:16:11 -07:00
gsxdsm
3f6e1c6e40 FN-6169: open script commands in a new terminal tab
Open fresh tabs for follow-up script launches instead of reusing the current terminal.

- track whether an initial command arrived with modal open versus after the terminal was already active
- create a new terminal tab for later script commands, wait for that tab to become active, then send the command there
- expand TerminalModal coverage for first-open versus follow-up script execution and clarify modal-manager script handoff expectations

Files changed:
 packages/dashboard/app/components/TerminalModal.tsx     |  80 ++++++++++-
 .../components/__tests__/TerminalModal.test.tsx    | 150 ++++++++++++++++++---
 .../app/hooks/__tests__/useModalManager.test.ts    |   4 +-
 3 files changed, 207 insertions(+), 27 deletions(-)

Fusion-Task-Id: FN-6169

Fusion-Task-Lineage: a7e57a9b-dc3a-432f-bff1-195b62555852
2026-06-09 23:03:51 -07:00