Commit Graph

11007 Commits

Author SHA1 Message Date
gsxdsm
57c3d7ceb8 FN-7776: evaluate promptContribution.condition against effective plugin settings
Plugin prompt contributions declared a `condition` field in the SDK, but the host never evaluated it, so gated prompt content always rendered unconditionally.

- Add packages/core/src/plugin-prompt-condition.ts implementing a minimal, non-eval `settings["key"] === "value"` / `!==` condition grammar
- Wire condition evaluation into plugin-runner.ts / agent-instructions.ts / executor.ts / reviewer.ts / triage.ts / agent-heartbeat.ts so prompt contributions are filtered by effective plugin settings at each call site
- Extend plugin-types.ts and core index.ts/index.gate.ts to expose the new evaluator and condition typing
- Document the condition grammar in docs/PLUGIN_AUTHORING.md
- Add regression tests covering the evaluator and its wiring through plugin-runner and agent-instructions
- Add changeset (@runfusion/fusion minor, feature) describing the new gating behavior

Files changed:
 .changeset/fn-7776-prompt-condition.md             |  7 ++
 docs/PLUGIN_AUTHORING.md                           | 13 ++-
 .../src/__tests__/plugin-prompt-condition.test.ts  | 90 ++++++++++++++++++++
 packages/core/src/index.gate.ts                    |  6 ++
 packages/core/src/index.ts                         |  6 ++
 packages/core/src/plugin-prompt-condition.ts       | 51 +++++++++++
 packages/core/src/plugin-types.ts                  | 10 ++-
 .../src/__tests__/agent-instructions.test.ts       | 33 ++++++--
 .../engine/src/__tests__/plugin-runner.test.ts     | 98 +++++++++++++++++++++-
 packages/engine/src/agent-heartbeat.ts             |  2 +-
 packages/engine/src/agent-instructions.ts          |  6 +-
 packages/engine/src/executor.ts                    | 28 +++++--
 packages/engine/src/plugin-runner.ts               | 64 ++++++++++++--
 packages/engine/src/reviewer.ts                    |  2 +-
 packages/engine/src/triage.ts                      |  2 +-
 packages/plugin-sdk/src/index.ts                   |  4 +
 16 files changed, 385 insertions(+), 37 deletions(-)

Fusion-Task-Id: FN-7776

Fusion-Task-Lineage: ba8dcd52-260a-4166-a712-f3dd39b81b15

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 07:46:52 -07:00
gsxdsm
f9641ec76e FN-7774: style the Thinking Level select to match the dark model dropdown
Adds dark-theme CSS styling for the inline Thinking Level <select> so it no longer renders as an OS-default white control across model-picker surfaces, including the quick-add QuickEntryBox and InlineCreateCard popups.

- Add .thinking-level-select rule set in CustomModelDropdown.css mirroring the canonical dark select tokens (background, border, color, focus ring, disabled state, option/optgroup styling)
- Add a custom dropdown chevron indicator via .model-combobox-thinking::after and make the container position: relative
- Add a regression test asserting the select and option rules use the dark theme CSS tokens
- Add a patch changeset for @runfusion/fusion documenting the fix

Files changed:
 .changeset/fn-7774-thinking-level-select-styling.md           |  7 +++
 packages/dashboard/app/components/CustomModelDropdown.css     | 59 ++++++++++++++++++++++
 packages/dashboard/app/components/__tests__/CustomModelDropdown.test.tsx | 16 ++++++
 3 files changed, 82 insertions(+)

Fusion-Task-Id: FN-7774

Fusion-Task-Lineage: 9ef9bf07-dd18-499c-b04d-1b137d200689

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 07:43:08 -07:00
gsxdsm
70330bcffb FN-7779: render No message placeholder for empty assistant chat replies
Empty final assistant chat messages (e.g. Grok CLI runs that finish with no text) now show a muted "No message" placeholder instead of a blank bubble, in both Chat and Planner Chat via the shared StandardChatSurface component.

- Add isEmptyAssistantMessage check in StandardChatMessageItem: only applies to final persisted assistant messages with no content, tool calls, thinking output, attachments, or failure info
- Render a new .chat-message-content--empty block with the "No message" i18n string when the check matches
- Add shared CSS rule combining --waiting and --empty muted/italic styling, switching to var(--font-size-sm)
- Add "chat.noMessage" translation key to en/app.json and regenerate resources.d.ts
- Document the new behavior in docs/dashboard-guide.md
- Add a patch changeset for @runfusion/fusion
- Add StandardChatSurface.empty-message.test.tsx covering empty/whitespace content, populated content, tool calls, thinking output, attachments, failure info, non-assistant roles, and streaming waiting/thinking states

Files changed:
$(cat /tmp/diffstat_fn7779.txt)

Fusion-Task-Id: FN-7779

Fusion-Task-Lineage: d3ae068e-acba-4b4c-85d6-a788aa24a53b

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 07:40:22 -07:00
gsxdsm
2758dde301 FN-7777: fix skill content/file routes double-decoding skill IDs
Fixes Skills view showing "Skill not found" for every skill, including built-in Fusion skills, by removing a redundant URL decode in the content/file lookup routes.
- register-agent-skills-routes.ts: stop calling decodeURIComponent on req.params.id in the /skills/:id/content and /skills/:id/file handlers since Express 5 already decodes route params once; a second decode corrupted encoded source segments so IDs no longer matched computeSkillId's discovery output
- Added FNXC:Skills comments documenting the Express 5 single-decode behavior and why re-decoding breaks plugin/npm/path source IDs
- routes-skills.test.ts: added regression coverage for exact-ID content/file lookups across skill sources
- Added a patch changeset describing the fix for release notes

Files changed:
 .changeset/fn-7777-skills-content-not-found.md     |   7 +
 .../dashboard/src/__tests__/routes-skills.test.ts  | 144 ++++++++++++++++++++-
 .../src/routes/register-agent-skills-routes.ts     |  26 ++--
 3 files changed, 159 insertions(+), 18 deletions(-)

Fusion-Task-Id: FN-7777

Fusion-Task-Lineage: dc190b9a-ac5c-4f8b-9d65-11bfd5598db2

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 07:37:18 -07:00
gsxdsm
1ba588d707 FN-7773: fix mobile Settings footer spacing to prevent version overlap
Tightens the mobile Settings modal footer rail so Version/Help, Import/Export/Reset, and Save no longer overlap or crowd on small viewports.

- Split modal-header and modal-actions padding rules so the mobile footer uses tighter --space-xs block padding independently of the header
- Center-align modal-actions-left/right, footer version, update-check, and version-check-button on the mobile footer rail
- Make the version text and version-check button non-wrapping inline elements with normalized line-height so they stop overlapping neighboring controls
- Add a settings-modal-version rule as a non-wrapping inline-flex box
- Extend settings-mobile.test.tsx with regression coverage for the tightened mobile footer layout
- Add a patch changeset documenting the fix

Files changed:
 .changeset/fn-7773-mobile-settings-footer.md       |  7 +++
 packages/dashboard/app/components/SettingsModal.css | 55 +++++++++++++++----
 packages/dashboard/app/components/__tests__/settings-mobile.test.tsx | 62 +++++++++++++++++-----
 3 files changed, 103 insertions(+), 21 deletions(-)

Fusion-Task-Id: FN-7773

Fusion-Task-Lineage: ea45e7bb-2560-4d17-89dd-9dbc7a307351

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 07:30:08 -07:00
gsxdsm
df8ad460af FN-7772: add per-lane thinking level for workflow model lanes
Adds a per-workflow-lane thinking-level setting so execution, planning, and
review model lanes can each specify their own reasoning-effort/thinking
level, threaded through engine phase precedence so lane-specific settings
override the workflow default.

- Add workflow lane thinking-level settings to builtin workflow settings and
  settings schema, with new types in core.
- Thread lane thinking-level precedence through model-resolution and engine
  phase execution (executor, step-session-executor, triage,
  agent-session-helpers).
- Surface per-lane thinking-level controls in the dashboard
  WorkflowSettingsPanel and ProjectModelsSection.
- Add/adjust tests for workflow settings, agent-session-helpers, and the
  dashboard settings panels.
- Update settings-reference.md and workflow-steps.md docs.
- Add changeset for the new feature (minor).

Files changed:
 .changeset/fn-7772-workflow-lane-thinking.md       |  7 ++++
 docs/settings-reference.md                         | 10 ++---
 docs/workflow-steps.md                             |  4 +-
 .../core/src/__tests__/workflow-settings.test.ts   | 41 ++++++++++++++++++++
 packages/core/src/builtin-workflow-settings.ts     | 27 ++++++++++++-
 packages/core/src/index.ts                         |  4 +-
 packages/core/src/model-resolution.ts              | 45 +++++++++++++++++++++-
 packages/core/src/settings-schema.ts               |  3 ++
 packages/core/src/types.ts                         |  6 +++
 .../app/components/WorkflowSettingsPanel.tsx       | 35 ++++++++++++++---
 .../__tests__/SettingsModal.models-auth.test.tsx   |  7 +++-
 .../__tests__/WorkflowSettingsPanel.test.tsx       | 31 +++++++++++++++
 .../settings/sections/ProjectModelsSection.tsx     | 39 ++++++++++++++++---
 .../src/__tests__/agent-session-helpers.test.ts    | 13 ++++---
 .../engine/src/__tests__/executor-test-helpers.ts  |  1 +
 packages/engine/src/agent-session-helpers.ts       | 19 +++++----
 packages/engine/src/executor.ts                    |  4 +-
 packages/engine/src/step-session-executor.ts       |  2 +-
 packages/engine/src/triage.ts                      |  8 +++-
 19 files changed, 264 insertions(+), 42 deletions(-)

Fusion-Task-Id: FN-7772

Fusion-Task-Lineage: 70aba3a9-66c2-4bb0-aff9-acabc7b98818

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 02:21:01 -07:00
gsxdsm
235ff4c65e FN-7771: add per-node thinking level for workflow model bindings
Adds a per-node thinking-level override (config.thinkingLevel) for workflow IR model bindings so individual workflow nodes can set reasoning effort independently of the global default.

- Extend workflow-ir types/schema and workflow-steps-to-ir conversion to carry config.thinkingLevel per node
- Wire thinkingLevel through executor and step-session-executor so the engine applies the per-node override during model calls
- Add a thinking-level control to WorkflowNodeEditor for authoring per-node overrides in the dashboard
- Add/extend tests covering IR round-trip, steps-to-ir conversion, executor model binding, and the WorkflowNodeEditor UI
- Document the new setting in docs/workflow-steps.md
- Add changeset for @runfusion/fusion (minor)

Files changed:
 .changeset/fn-7771-workflow-node-thinking.md       |  7 +++
 docs/workflow-steps.md                             | 10 ++-
 packages/core/src/__tests__/workflow-ir.test.ts    | 42 +++++++++++++
 .../src/__tests__/workflow-steps-to-ir.test.ts     | 15 +++++
 packages/core/src/store.ts                         |  1 +
 packages/core/src/types.ts                         |  9 +++
 packages/core/src/workflow-ir.ts                   | 21 +++++++
 packages/core/src/workflow-steps-to-ir.ts          |  5 ++
 .../app/components/WorkflowNodeEditor.tsx          | 42 ++++++++++++-
 .../__tests__/WorkflowNodeEditor.test.tsx          | 73 ++++++++++++++++++++++
 .../engine/src/__tests__/executor-test-helpers.ts  |  5 ++
 .../__tests__/executor-workflow-step-model.test.ts | 31 +++++++++
 .../src/__tests__/workflow-step-review.test.ts     | 53 ++++++++++++++++
 packages/engine/src/executor.ts                    | 61 ++++++++++++++++--
 packages/engine/src/step-session-executor.ts       | 12 +++-
 packages/engine/src/workflow-node-handlers.ts      | 29 ++++++++-
 16 files changed, 404 insertions(+), 12 deletions(-)

Fusion-Task-Id: FN-7771

Fusion-Task-Lineage: 5dbe3efb-773d-47db-9412-b740eb1d7745

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 01:49:15 -07:00
gsxdsm
5f14a58d3b FN-7770: add per-lane thinking-level overrides for project & global model settings
Adds an optional thinking-effort/reasoning override per model lane in Settings (project and global), resolved with precedence task > lane > global default, and reconciles this work with the already-landed FN-7768 inline thinking-level control on CustomModelDropdown (kept the shared shouldShowThinking/thinkingBadgeLabel implementation to avoid duplicating the selector/badge UI).

- Add lane thinking-level settings schema fields and runtime precedence (task > lane > global default) in @fusion/core
- Wire per-lane thinking selectors into GlobalModelsSection and ProjectModelsSection via CustomModelDropdown's existing showThinkingLevel/thinkingLevel/onThinkingLevelChange/defaultThinkingLevel props
- Resolve merger thinking level from the default lane rather than the title-summarizer lane in engine session helpers/executor/merger/triage
- Update settings-reference docs and add a minor changeset for the new lane thinking overrides
- Add/expand test coverage: settings-parity, store-settings, settings-sections, agent-session-helpers
- Add new i18n key models.options.defaultWithLevel across locales

Files changed:
 .changeset/fn-7770-lane-thinking.md                |   7 ++
 docs/settings-reference.md                         |   8 ++
 .../core/src/__tests__/settings-parity.test.ts     |  17 ++++
 packages/core/src/__tests__/store-settings.test.ts |  42 +++++++++
 packages/core/src/settings-schema.ts               |  14 +++
 packages/core/src/types.ts                         |  16 ++++
 .../app/__tests__/settings-sections.test.tsx       | 100 ++++++++++++++++++---
 .../app/components/CustomModelDropdown.css         |   1 +
 .../dashboard/app/components/SettingsModal.tsx     |  37 ++++++++
 .../settings/sections/GlobalModelsSection.tsx      |   9 +-
 .../settings/sections/ProjectModelsSection.tsx     |  12 ++-
 .../app/components/settings/sections/context.ts    |   2 +
 .../src/__tests__/agent-session-helpers.test.ts    |  36 ++++++++
 packages/engine/src/agent-session-helpers.ts       |  60 +++++++++++++
 packages/engine/src/executor.ts                    |  14 +--
 packages/engine/src/merger-ai.ts                   |  12 ++-
 packages/engine/src/merger.ts                      |  12 +--
 packages/engine/src/pr-response-run-ops.ts         |   4 +-
 packages/engine/src/step-session-executor.ts       |   3 +-
 packages/engine/src/triage.ts                      |   5 +-
 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 +-
 packages/i18n/src/resources.d.ts                   |   3 +
 27 files changed, 390 insertions(+), 42 deletions(-)

Fusion-Task-Id: FN-7770
Fusion-Task-Lineage: 3418c621-ac99-4cd4-a435-9348da03972f
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 01:15:40 -07:00
gsxdsm
3cda9d830a FN-7768: inline thinking-level control in CustomModelDropdown and migrate task/agent surfaces
Adds an inline thinking-level selector to CustomModelDropdown and migrates existing model-selection surfaces (task form, quick entry, new agent dialog, model selection modal/tab) to use it instead of their own bespoke thinking-level controls.

- CustomModelDropdown: add inline thinking-level control (CSS + component logic)
- ModelSelectionModal / ModelSelectorTab: drop local thinking-level UI in favor of the dropdown's inline control
- NewAgentDialog: migrate to the shared inline thinking-level control
- QuickEntryBox: remove now-redundant thinking-level UI, delegate to CustomModelDropdown
- TaskForm: migrate to the shared inline thinking-level control
- Add/update tests for CustomModelDropdown, ModelSelectionModal, ModelSelectorTab, NewAgentDialog, QuickEntryBox, TaskForm
- Add changeset for @runfusion/fusion (feature)
- Update dashboard guide docs

Files changed:
 .changeset/fn-7768-inline-thinking-dropdown.md     |  7 ++
 docs/dashboard-guide.md                            |  1 +
 .../app/components/CustomModelDropdown.css         | 33 +++++++++
 .../app/components/CustomModelDropdown.tsx         | 69 ++++++++++++++++-
 .../app/components/ModelSelectionModal.tsx         | 32 +-------
 .../dashboard/app/components/ModelSelectorTab.tsx  | 33 +--------
 .../dashboard/app/components/NewAgentDialog.tsx    | 18 +----
 .../dashboard/app/components/QuickEntryBox.tsx     | 59 +--------------
 packages/dashboard/app/components/TaskForm.tsx     | 23 +-----
 .../__tests__/CustomModelDropdown.test.tsx         | 72 ++++++++++++++++++
 .../__tests__/ModelSelectionModal.test.tsx         | 48 +++++++++---
 .../components/__tests__/ModelSelectorTab.test.tsx |  3 +-
 .../components/__tests__/NewAgentDialog.test.tsx   | 86 ++++++++++++++++++++++
 .../components/__tests__/QuickEntryBox.test.tsx    | 42 +++++++----
 .../app/components/__tests__/TaskForm.test.tsx     |  7 +-
 15 files changed, 354 insertions(+), 179 deletions(-)

Fusion-Task-Id: FN-7768
Fusion-Task-Lineage: 8f32731b-9865-4902-9420-62d3c0295805
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 00:48:14 -07:00
gsxdsm
167067c5b0 FN-7767: fix Artifacts tab showing 0 count on default-scope dashboards
Fix useArtifacts fetching/subscribing only when a projectId is present, which left the Artifacts tab stuck at 0 on single-project dashboards where currentProject is unset at mount.

- useArtifacts now builds a cache key and fetches/subscribes even without a projectId, scoping the cache under a __default__ key
- SSE subscription omits the projectId query param when unset (default/unscoped /api/events) and only filters incoming events by projectId when one is set
- Added/updated tests covering the default-scope fetch, cache, and SSE subscription paths
- Added a changeset documenting the fix

Files changed:
 .changeset/fn-7767-artifacts-default-scope.md      |  7 ++++
 .../app/hooks/__tests__/useArtifacts.test.ts       | 42 +++++++++++++++++---
 packages/dashboard/app/hooks/useArtifacts.ts       | 37 ++++++------------
 .../__tests__/artifacts-route-integration.test.ts  | 45 ++++++++++++++++++++++
 4 files changed, 100 insertions(+), 31 deletions(-)

Fusion-Task-Id: FN-7767

Fusion-Task-Lineage: b4ea9b1f-2908-4f5b-bf75-d6fdc45f9340

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 00:37:03 -07:00
gsxdsm
059016ef3c FN-7765: fix dashboard chat crash when plugin CLI sessions omit session.state
Fix a "Response failed" crash for plugin CLI runtime chats (grok/droid/cursor) whose sessions expose top-level `messages` and stream via `onText` without a pi-shaped `session.state`.

- Read messages/errorMessage null-safely from `session.state`, falling back to top-level `session.messages` when state is absent, in both the room responder and streaming response extraction paths
- Keep `state.errorMessage` optional so successful streams from state-less sessions no longer throw TypeErrors, while pi/openclaw/hermes provider errors still surface correctly
- Add regression tests covering state-less plugin CLI sessions in chat-manager.test.ts
- Add changeset for the fix

Files changed:
 .changeset/fn-7765-grok-cli-chat-crash.md          |  7 ++
 packages/dashboard/src/__tests__/chat-manager.test.ts | 90 ++++++++++++++++++++++
 packages/dashboard/src/chat.ts                     | 35 ++++++---
 3 files changed, 121 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-7765

Fusion-Task-Lineage: 80e33a97-e971-4aec-a4cf-29d97c5c5e62

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-10 00:22:59 -07:00
gsxdsm
587bdfd394 FN-7764: add cross-type artifact create/list/view test coverage
Extend artifact test coverage to pin creation, listing, and viewing across every artifact type and payload variant on both the agent/dashboard-chat tool surface and the dashboard artifacts route.

- Add a route-level integration test covering list/serve for all artifact types (document, image, video, audio, other) across inline content, uri reference, and binary data payloads, including task-scoped filtering, registry-level (task-less) artifacts, and 404 behavior for uri-only artifacts requested via /media.
- Add an engine-level real-TaskStore test exercising fn_artifact_register/list/view (agent tools) and the dashboard-chat artifact tool for every artifact type and content/uri/dataBase64 variant, asserting list and view output correctness.
- Factor out shared PNG_IMAGE_BYTES fixture and per-type MIME/binary fixtures to keep new assertions concise.

Files changed:
 .../__tests__/artifacts-route-integration.test.ts  | 150 ++++++++++++++++++++-
 .../src/__tests__/agent-artifact-tools.test.ts     | 142 ++++++++++++++++++-
 2 files changed, 287 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-7764

Fusion-Task-Lineage: 187b3f0f-d1b4-42fe-9658-1ee67870b524

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 23:48:45 -07:00
gsxdsm
cc901c2b9d FN-7762: expand update-notification test coverage across CLI, dashboard, and desktop surfaces
Broadens regression coverage for the npm-release update-check invariant so it holds across every consuming surface, not just the reported repro.

- Replace the update-check route/service semver spot-checks with a parametrized case matrix (equal, newer, older, prerelease/build metadata, short/long version segments) to close false-positive/false-negative gaps.
- Add dedicated route-level tests asserting the update-check API route surfaces the same invariant.
- Add CLI update command tests covering notification rendering across version-comparison cases.
- Add desktop native update-check tests covering the same invariant on the desktop shell.
- Add dashboard useUpdateCheck hook tests verifying consistent notification behavior for the hook consumers.

Files changed:
 packages/cli/src/commands/__tests__/update.test.ts | 59 ++++++++++++++++++
 .../app/hooks/__tests__/useUpdateCheck.test.ts     | 25 ++++++++
 .../src/__tests__/update-check-route.test.ts       | 71 ++++++++++++++++++++++
 .../dashboard/src/__tests__/update-check.test.ts   | 42 +++++++------
 packages/desktop/src/__tests__/native.test.ts      | 27 ++++++++
 5 files changed, 206 insertions(+), 18 deletions(-)

Fusion-Task-Id: FN-7762

Fusion-Task-Lineage: 6ab34312-fb4e-487a-aefc-2ab133bf79af

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 23:46:21 -07:00
gsxdsm
18841d76a0 FN-7761: fix Grok CLI auth to use logged-in CLI instead of requiring API key
Packaged fn serve/daemon/dashboard hosts previously failed with a misleading missing-API-key error for grok-cli agents even though the operator was already logged in via the Grok CLI. This fixes routing so those hosts eagerly ensure the bundled Grok Runtime plugin is installed/loaded before session creation, and no longer silently falls back to the key-requiring direct endpoint when no key is visible.

- Eagerly ensure the bundled fusion-plugin-grok-runtime in serve, daemon, and dashboard commands before loadAllPlugins() so runtime id "grok" is available on fresh installs without manual plugin-settings setup.
- agent-session-helpers.ts: deriveGrokRuntimeHintForNoVisibleKey now throws an actionable error (naming both remediations: install/enable the Grok CLI runtime plugin, or set GROK_API_KEY) instead of silently falling through to the key-requiring pi/openai-completions path when the runtime can't be loaded.
- Update docs/grok-cli-contract.md to document the FN-7761 packaged-host wiring and new no-silent-fallback behavior.
- Add regression tests for the packaged bootstrap behavior and bundled-plugin install path.
- Add changeset for @runfusion/fusion (patch, category: fix).

Files changed:
 .changeset/fn-7761-grok-cli-packaged-routing.md    |  7 +++++
 docs/grok-cli-contract.md                          | 19 +++++++++----
 .../__tests__/grok-runtime-bootstrap.test.ts       | 31 ++++++++++++++++++++++
 packages/cli/src/commands/daemon.ts                | 17 +++++++++++-
 packages/cli/src/commands/dashboard.ts             | 20 +++++++++++++-
 packages/cli/src/commands/serve.ts                 | 19 +++++++++++--
 .../__tests__/bundled-plugin-install.test.ts       | 17 ++++++++++++
 .../src/__tests__/grok-runtime-routing.test.ts     | 17 ++++++------
 packages/engine/src/agent-session-helpers.ts       | 15 +++++++++--
 9 files changed, 142 insertions(+), 20 deletions(-)

Fusion-Task-Id: FN-7761
Fusion-Task-Lineage: 3be5f054-965c-4e8a-ad91-6e61d4dc4a42
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 23:43:15 -07:00
gsxdsm
f6fd6aced4 FN-7763: fix oversized icons and spacing on MCP servers settings page
Fixes inline lucide icons on the MCP servers settings card that rendered oversized (24px default) and misaligned since .btn > svg is intentionally unsized globally.

- Size inline lucide icons in McpServersCard with new --icon-size-sm/md-aligned constants (14px/16px) instead of relying on unsized default
- Apply sizing to Add secret reference, Add server, Scan again, Test, Override, Edit, Upload JSON, and Copy Fusion MCP JSON buttons
- Add regression test coverage in SettingsModal.mcp.test.tsx asserting icon sizes
- Add changeset documenting the fix

Files changed:
 .changeset/fn-7763-mcp-layout.md                   |  7 +++++
 .../__tests__/SettingsModal.mcp.test.tsx           | 34 ++++++++++++++++++++++
 .../settings/sections/McpServersCard.tsx           | 23 ++++++++++-----
 3 files changed, 56 insertions(+), 8 deletions(-)

Fusion-Task-Id: FN-7763

Fusion-Task-Lineage: 163dcba0-5189-49dd-9100-8a0bd3bc92b1

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 23:40:02 -07:00
gsxdsm
150227f808 FN-7760: fix mobile model dropdown list not scrolling via touch
Adds an explicit touch-scroll contract to the portaled model combobox list so it remains scrollable on mobile despite the global mobile lockdown that hides body/root overflow and defaults gestures to vertical panning.

- Add -webkit-overflow-scrolling: touch, overscroll-behavior: contain, and touch-action: pan-y to .model-combobox-list so the fixed-position dropdown owns its own touch scrolling on mobile.
- Add regression tests covering the mobile scroll contract for CustomModelDropdown.
- Add a patch changeset documenting the fix for release notes.

Files changed:
 .changeset/fn-7760-mobile-model-dropdown-scroll.md |  7 +++
 packages/dashboard/app/components/CustomModelDropdown.css         |  7 +++
 packages/dashboard/app/components/__tests__/CustomModelDropdown.test.tsx | 70 ++++++++++++++++++++++
 3 files changed, 84 insertions(+)

Fusion-Task-Id: FN-7760

Fusion-Task-Lineage: e135ff47-275b-4606-aef2-c9859aeaa418

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 23:29:47 -07:00
gsxdsm
fed5d3d951 FN-7759: fix GPT-5.6 codex models missing from model dropdown
Ensure GPT-5.6 codex models (luna, sol, terra) actually surface in the codex model picker by validating the openai-codex supplemental merge against the real pi-coding-agent ModelRegistry instead of only a mocked one.

- Harden openai-models.ts supplemental merge logic against real ModelRegistry auth filtering, registerProvider full-replacement, and OAuth provider validation
- Add @earendil-works/pi-coding-agent devDependency to @fusion/core for real-registry testing
- Add regression test (openai-models.test.ts) exercising the real registry path
- Extend register-model-routes-openai-codex-supplemental.test.ts dashboard test coverage
- Update docs/settings-reference.md
- Add changeset fn-7759-codex-gpt-5-6-dropdown.md (patch, fix)

Files changed:
 .changeset/fn-7759-codex-gpt-5-6-dropdown.md       |   7 ++
 docs/settings-reference.md                         |   2 +-
 packages/core/package.json                         |   1 +
 packages/core/src/__tests__/openai-models.test.ts  |  68 +++++++++++++
 packages/core/src/openai-models.ts                 | 107 ++++++++++++++++-----
 ...-model-routes-openai-codex-supplemental.test.ts |  77 +++++++++++++--
 pnpm-lock.yaml                                     |  68 +++++++++++++
 7 files changed, 300 insertions(+), 30 deletions(-)

Fusion-Task-Id: FN-7759

Fusion-Task-Lineage: 4c03838f-b8d8-4f6f-ae55-c3356c1c3176

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 23:12:02 -07:00
gsxdsm
2be6040b02 FN-7758: route Grok CLI fallback models through the CLI runtime when no API key is visible
Fix Grok CLI 'missing API key' false-positive by extending the no-visible-key routing invariant to configured fallback models, not just the default provider.
- deriveGrokRuntimeHintForNoVisibleKey now also triggers when the fallback provider is grok-cli
- new applyGrokCliNoKeyRuntimeOptions promotes a grok-cli fallback model into the primary session (stripping the provider-qualified model prefix) instead of leaving it as an unused fallback
- docs/grok-cli-contract.md updated to describe the fallback-routing contract
- added regression tests in grok-runtime-routing.test.ts, chat-manager.test.ts, and chat-manager-room-hybrid.test.ts
- added changeset fn-7758-grok-cli-no-key-routing.md (patch)

Files changed:
 .changeset/fn-7758-grok-cli-no-key-routing.md      |   7 ++
 docs/grok-cli-contract.md                          |  29 +++--
 .../src/__tests__/chat-manager-room-hybrid.test.ts |  36 +++++++
 .../dashboard/src/__tests__/chat-manager.test.ts   |  41 +++++++
 packages/dashboard/src/chat.ts                     |  16 ++-
 .../src/__tests__/grok-runtime-routing.test.ts     | 118 +++++++++++++++++++++
 packages/engine/src/agent-session-helpers.ts       |  36 ++++++-
 7 files changed, 266 insertions(+), 17 deletions(-)

Fusion-Task-Id: FN-7758

Fusion-Task-Lineage: 6b564b21-50ab-4c3e-b0d7-7fded2091d90

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 22:19:22 -07:00
gsxdsm
b4b183fcd0 FN-7757: add missing openai-codex model pricing entries to fix empty estimated costs
Fixes the dashboard showing empty/dash estimated costs for runs on newer OpenAI Codex models, whose pricing was missing from the static model-pricing table.

- Add pricing entries for gpt-5.3-codex-spark, gpt-5.4, gpt-5.4-mini, and gpt-5.5 under the openai-codex provider, sourced from the pinned pi-ai 0.80.5 model catalog.
- Correct the previously-guessed gpt-5.6-luna/sol/terra rates to match their actual distinct published rates instead of all sharing the gpt-5.3-codex rate.
- Update/add tests across model-pricing, team-analytics, token-analytics, and workflow-analytics to cover the new/corrected pricing entries.
- Add dashboard tests (TaskSummaryTab prior attempts, CommandCenter mobile scroll, TokensArea, task-planner chat metrics) verifying costs render correctly instead of falling back to unavailable.
- Add a patch changeset documenting the estimated-cost fix.

Files changed:
$(cat /tmp/diffstat.txt)

Fusion-Task-Id: FN-7757

Fusion-Task-Lineage: e0f2e9d5-e922-4878-82d0-40c7d9899fdb

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 21:40:58 -07:00
gsxdsm
f7c6f560c0 FN-7753: route grok-cli execution through the grok CLI when no Fusion-visible GROK_API_KEY resolves
Route grok-cli model selections through the grok CLI runtime when no Fusion-visible GROK_API_KEY is available.

- Add read-only isGrokApiKeyFusionVisible() in packages/core/src/grok-provider.ts, refactored to share user-settings-file reading with hydrateGrokApiKeyFromUserSettings without mutating process.env or logging key material.
- In packages/engine/src/agent-session-helpers.ts, auto-derive the existing "grok" runtimeHint when defaultProvider is grok-cli, no key is Fusion-visible, and the grok plugin runtime is registered; explicit runtime hints and mock/test-mode routing remain unchanged, and the provider-qualified model prefix is stripped before handoff.
- Normalize provider-qualified model ids (grok-cli/<id>, grok/<id>) in the grok-runtime plugin's runtime-adapter and CLI stream spawn so the concrete model reaches `grok --model`, with the historical grok/default fallback preserved for the no-model path.
- Update docs (grok-cli-contract.md, settings-reference.md, plugin README) and add/extend tests covering the new fallback behavior, model normalization, and CLI streaming.
- Add changeset fn-7753-grok-cli-no-key-fallback.md (patch, fix).

Files changed:
 .changeset/fn-7753-grok-cli-no-key-fallback.md     |   7 ++
 docs/grok-cli-contract.md                          |  83 ++++++++++------
 docs/settings-reference.md                         |   6 +-
 .../__tests__/grok-provider-user-settings.test.ts  |  46 +++++++++
 packages/core/src/grok-provider.ts                 |  39 +++++++-
 packages/core/src/index.gate.ts                    |   1 +
 packages/core/src/index.ts                         |   1 +
 .../src/__tests__/grok-runtime-routing.test.ts     | 107 +++++++++++++++++++--
 packages/engine/src/agent-session-helpers.ts       |  52 +++++++++-
 plugins/fusion-plugin-grok-runtime/README.md       |  46 +++++----
 .../src/__tests__/cli-stream.test.ts               |  70 ++++++++++++++
 .../src/__tests__/runtime-adapter.test.ts          |  28 ++++++
 .../fusion-plugin-grok-runtime/src/cli-stream.ts   |   6 ++
 .../src/runtime-adapter.ts                         |  24 ++++-
 14 files changed, 443 insertions(+), 73 deletions(-)

Fusion-Task-Id: FN-7753

Fusion-Task-Lineage: 30ef7265-1ba9-47fd-8c4e-87b02f6a1d78

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 21:36:14 -07:00
gsxdsm
28c82331e7 FN-7755: upgrade bundled pi SDK to 0.80.6
Bumps the pi SDK dependencies to 0.80.6 across the CLI, dashboard, engine, and pi-claude-cli packages, and adapts the Claude CLI thinking-effort mapper for the new `max` ThinkingLevel.

- Bump @earendil-works/pi-ai and @earendil-works/pi-coding-agent from ^0.80.5 to ^0.80.6 in packages/cli, packages/dashboard, packages/engine, and packages/pi-claude-cli (dependency/peerDependency/devDependency entries)
- Regenerate pnpm-lock.yaml for the new SDK versions
- Map the new `max` ThinkingLevel in packages/pi-claude-cli/src/thinking-config.ts: non-Opus models downgrade to `high` (effort max unsupported), Opus models map to `max`
- Extend packages/pi-claude-cli/src/__tests__/thinking-config.test.ts with coverage for the `max` level
- Add .changeset/fn-7755-pi-sdk-bump.md (patch) documenting the SDK bump

Files changed:
 .changeset/fn-7755-pi-sdk-bump.md                  |  7 ++
 packages/cli/package.json                          |  4 +-
 packages/dashboard/package.json                    |  2 +-
 packages/engine/package.json                       |  4 +-
 packages/pi-claude-cli/package.json                |  8 +-
 .../src/__tests__/thinking-config.test.ts          | 12 +++
 packages/pi-claude-cli/src/thinking-config.ts      | 10 ++-
 pnpm-lock.yaml                                     | 92 +++++++++++-----------
 8 files changed, 82 insertions(+), 57 deletions(-)

Fusion-Task-Id: FN-7755

Fusion-Task-Lineage: f6a9084b-dfb9-4ad5-bd99-4627dae4c666

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 21:32:59 -07:00
gsxdsm
d2c2a4cab1 FN-7754: seed OpenAI GPT-5.6 Codex models into pi createFnAgent registry
Wires the GPT-5.6 codenamed OpenAI Codex models (gpt-5.6-luna/sol/terra) into the engine pi model-registry seeding surface, mirroring the dashboard's /api/models supplemental merge so the models are no longer missing from pi.

- Call mergeSupplementalOpenAiCodexModels() in createFnAgent (packages/engine/src/pi.ts) alongside the existing Anthropic supplemental merge
- Add regression tests covering synthesis of missing GPT-5.6 rows and dedupe against pinned catalog entries
- Update docs/settings-reference.md to describe the additive surfacing on both /api/models and the engine/pi registry-seeding path
- Add a patch changeset for @runfusion/fusion

Files changed:
 .changeset/fn-7754-openai-gpt-5-6-pi-surface.md    |  7 +++
 docs/settings-reference.md                         |  2 +-
 .../src/__tests__/pi-create-fn-agent.test.ts       | 63 ++++++++++++++++++++++
 packages/engine/src/pi.ts                          |  6 +++
 4 files changed, 77 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7754

Fusion-Task-Lineage: b61b6812-c94b-46d8-b187-445ccdd6e4e9

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 21:30:34 -07:00
gsxdsm
9ce0b49054 FN-7752: tighten mobile Settings modal layout
Squashes FN-7752, improving the mobile Settings modal layout to reduce chrome and simplify section navigation on small screens.

- Replace the mobile section-picker button row with a compact dropdown-only selector, keeping an accessible aria-label
- Slim down the header and footer, collapsing footer actions to a single row on mobile
- Tighten SettingsModal.css breakpoint rules (≤768px) for header/footer sizing and spacing
- Update settings-mobile tests to cover the new dropdown-only picker and single-row footer behavior
- Add changeset documenting the mobile layout fix

Files changed:
 .changeset/fn-7752-mobile-settings-layout.md       |  7 +++
 .../dashboard/app/components/SettingsModal.css     | 62 ++++++++++++++++------
 .../dashboard/app/components/SettingsModal.tsx     | 19 +++++--
 .../components/__tests__/settings-mobile.test.tsx  | 26 +++++++--
 4 files changed, 90 insertions(+), 24 deletions(-)

Fusion-Task-Id: FN-7752

Fusion-Task-Lineage: 5dea597c-19f7-49c4-979a-7528d84fa6c5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 21:19:40 -07:00
gsxdsm
547740bb66 FN-7751: move mobile settings search toggle inline with section picker
Relocates the mobile-only settings search icon toggle so it sits inline next to the section dropdown instead of its own row above it, tightening the mobile Settings header.

- Move the settings-search-toggle button out of the standalone .settings-search row into a new .settings-mobile-section-picker-control-row alongside the mobile section <select>.
- Preserve FN-7713 expand/hide toggle behavior and active-query preservation; desktop/tablet layout unaffected.
- Add CSS for .settings-mobile-section-picker-control-row to lay out the select and toggle button inline.
- Update settings-mobile tests to assert the toggle renders next to the section picker.
- Add changeset (patch) documenting the fix.

Files changed:
 .../fn-7751-mobile-settings-search-inline.md       |  7 ++
 docs/dashboard-guide.md                            |  4 +-
 .../dashboard/app/components/SettingsModal.css     | 23 ++++--
 .../dashboard/app/components/SettingsModal.tsx     | 89 +++++++++++-----------
 .../components/__tests__/settings-mobile.test.tsx  | 38 ++++++++-
 5 files changed, 105 insertions(+), 56 deletions(-)

Fusion-Task-Id: FN-7751

Fusion-Task-Lineage: 8bb9a32b-80f4-4b73-a366-d23e97106b73

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 20:13:20 -07:00
gsxdsm
eb377ba831 FN-7750: gate shared-branch-group auto-merge exemption on live groups
Fixes autoMerge=false being bypassed for engine-created branch-group member tasks whose branch group had already dissolved/finalized.

- Add isLiveSharedBranchGroupMemberIntegration(task, group) in @fusion/core, requiring the branch group's status be "open" before the shared-branch-member exemption bypasses the global/task autoMerge:false hold.
- Export the new helper from packages/core/src/index.ts and index.gate.ts.
- Thread the live-group check through packages/engine/src/project-engine.ts (allowInReviewMergeProcessing, enqueueEligibleInReviewTasks, merge-confirmed fast-path branch routing, and merge handoff paths).
- Add TaskExecutor.isLiveSharedBranchGroupMember helper in packages/engine/src/executor.ts and use it in retryable pre-merge remediation, no-op finalize, benign pause-abort classification, and merge-processing gates.
- Keep self-healing.ts's solo no-op finalize predicate on the pure branchContext-shape check (isSharedBranchGroupMemberIntegration) intentionally, so stale shared-group members stay excluded from solo finalize regardless of group liveness.
- Add regression tests covering the executor and project-engine auto-merge-hold behavior for stale/dissolved branch groups.
- Add a patch changeset documenting the fix.

Files changed:
 .../fn-7750-automerge-hold-stale-branch-group.md   |  7 ++
 packages/core/src/__tests__/task-merge.test.ts     | 42 +++++++++--
 packages/core/src/index.gate.ts                    |  1 +
 packages/core/src/index.ts                         |  1 +
 packages/core/src/task-merge.ts                    | 13 +++-
 ...cutor-live-branch-group-auto-merge-hold.test.ts | 85 ++++++++++++++++++++++
 .../engine/src/__tests__/project-engine.test.ts    | 37 +++++++++-
 packages/engine/src/executor.ts                    | 22 ++++--
 packages/engine/src/project-engine.ts              | 32 +++++---
 packages/engine/src/self-healing.ts                |  1 +
 10 files changed, 214 insertions(+), 27 deletions(-)

Fusion-Task-Id: FN-7750

Fusion-Task-Lineage: d61f8847-0b09-49b5-b66a-00018c8738bb

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:08 -07:00
gsxdsm
786a274ae6 FN-7749: fix benign pause/resume abort marking manual merge holds as failed
Fixes tasks in auto-merge-off manual merge hold getting incorrectly marked failed by a benign pause/resume abort, which blocked Merge & Close.

- Add isBenignManualMergeHoldPauseAbort classifier in executor.ts: recognizes a hard-cancel pause-abort at a merge-region node while auto-merge is off (or processing is disallowed) as benign, and preserves the in-review row instead of failing/re-enqueueing it.
- Clear stale pause-abort status/error and suppress the failure notification when this benign manual-hold case is detected, per FN-5147's no-backward-move/no-reenqueue contract.
- Extend self-healing.ts recovery to handle this manual-hold case alongside existing paused-abort recovery paths.
- Add/extend tests in merge-node-paused-abort-retryable.test.ts and self-healing-paused-abort-recovery.test.ts covering the new benign classification.
- Document the fix in docs/architecture.md.
- Add changeset (patch) describing the user-facing fix.

Files changed:
 .changeset/fn-7749-manual-merge-hold-false-failure.md                                   |  7 +++
 docs/architecture.md                                                                    |  4 +-
 packages/engine/src/__tests__/reliability-interactions/merge-node-paused-abort-retryable.test.ts | 50 +++++++++++++++++----
 packages/engine/src/__tests__/self-healing-paused-abort-recovery.test.ts                | 49 ++++++++++++++++++++-
 packages/engine/src/executor.ts                                                         | 51 +++++++++++++++++++++-
 packages/engine/src/self-healing.ts                                                     | 23 ++++++++--
 6 files changed, 168 insertions(+), 16 deletions(-)

Fusion-Task-Id: FN-7749
Fusion-Task-Lineage: 6d90adc3-6cd9-463d-b9d0-7a5c3069c1a5
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:08 -07:00
gsxdsm
6a13ad175e FN-7732: remove dangling release-authorization UI/i18n/docs scaffolding
Narrative: The triage release-authorization gate itself was already removed in b5b0458; this cleans up the leftover scaffolding it left behind — an unemitted activity type, a dead TaskCard badge/label/CSS, orphaned i18n keys across all 6 locales, and a stale solutions doc — so the codebase no longer references a gate that no longer exists.

- Drop the unused `task:release-authorization-required` ActivityEventType and its label/rendering in ActivityFeed.tsx and ActivityLogModal.tsx
- Remove the dead `isReleaseAuthorizationHold` badge logic and `.awaiting-release-authorization` CSS class from TaskCard.tsx/TaskCard.css
- Simplify TaskDetailModal.tsx comments/logic now that legacy release-authorization holds render as ordinary manual plan-approval holds
- Delete orphaned i18n keys `tasks.awaitingReleaseAuthorization` and `taskDetail.plan.releaseAuthorizationHold` across en/es/fr/ko/zh-CN/zh-TW locales and resources.d.ts
- Delete the stale docs/solutions/architecture-patterns/release-triage-requires-user-authorization.md doc
- Update docs/workflow-steps.md and docs/settings-reference.md to describe the gate as removed (superseded by FN-7732) instead of documenting still-active behavior
- Add changeset for @runfusion/fusion (patch/internal)

Files changed:
 .changeset/fn-7732-remove-release-authorization-block.md |  7 +++++
 docs/settings-reference.md                                |  2 +-
 docs/solutions/architecture-patterns/release-triage-requires-user-authorization.md | 33 ----------------------
 docs/workflow-steps.md                                    |  6 ++--
 packages/core/src/types.ts                                 |  8 ++++--
 packages/dashboard/app/components/ActivityFeed.tsx         |  5 ----
 packages/dashboard/app/components/ActivityLogModal.tsx     |  6 ----
 packages/dashboard/app/components/TaskCard.css             | 11 --------
 packages/dashboard/app/components/TaskCard.tsx              | 13 +++------
 packages/dashboard/app/components/TaskDetailModal.tsx       | 14 +++------
 packages/i18n/locales/en/app.json                           |  3 --
 packages/i18n/locales/es/app.json                           |  5 +---
 packages/i18n/locales/fr/app.json                           |  5 +---
 packages/i18n/locales/ko/app.json                           |  5 +---
 packages/i18n/locales/zh-CN/app.json                        |  5 +---
 packages/i18n/locales/zh-TW/app.json                        |  5 +---
 packages/i18n/src/resources.d.ts                            |  3 --
 17 files changed, 30 insertions(+), 106 deletions(-)

Fusion-Task-Id: FN-7732

Fusion-Task-Lineage: d4137bd8-9056-4062-9f2a-c6f5d47295f4

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:07 -07:00
gsxdsm
2c4052c76b FN-7746: Add thinking level selector to model pickers
Adds a thinking-level (reasoning-effort) selector to the quick-create model pickers, matching the levels already available in the full task pickers.

- ModelSelectionModal: adds optional thinking-level <select> (off/minimal/low/medium/high/xhigh) with a status badge, rendered only when onThinkingLevelChange is supplied
- QuickEntryBox: wires thinking-level state through to ModelSelectionModal and persists the override with quick-created tasks
- InlineCreateCard: same thinking-level wiring for the inline task creation card
- Adds i18n strings for the new thinking-level labels across en/es/fr/ko/zh-CN/zh-TW locale files
- Adds test coverage in InlineCreateCard.test.tsx, ModelSelectionModal.test.tsx, and QuickEntryBox.test.tsx for the new selector

Files changed:
 .../dashboard/app/components/InlineCreateCard.tsx  | 16 ++++-
 .../app/components/ModelSelectionModal.tsx         | 47 +++++++++++++-
 .../dashboard/app/components/QuickEntryBox.tsx     | 67 ++++++++++++++++++-
 .../components/__tests__/InlineCreateCard.test.tsx | 70 ++++++++++++++++++++
 .../__tests__/ModelSelectionModal.test.tsx         | 69 ++++++++++++++++++++
 .../components/__tests__/QuickEntryBox.test.tsx    | 75 ++++++++++++++++++++++
 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 +
 12 files changed, 351 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-7746

Fusion-Task-Lineage: 4a221203-0222-47d6-93f8-632638bcfbfe

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:07 -07:00
gsxdsm
f9307904c2 FN-7745: add GPT-5.6 codenamed model variants to model selector
Registers the three GPT-5.6 codenamed OpenAI Codex model variants (luna, sol, terra) so they appear in the model picker, since pricing alone did not make them selectable.

- Add packages/core/src/openai-models.ts with SUPPLEMENTAL_OPENAI_CODEX_PROVIDER_REGISTRATION and mergeSupplementalOpenAiCodexModels(), mirroring the existing Anthropic supplemental-merge seam; additive and dedupe-safe against the pinned pi-ai catalog
- Wire mergeSupplementalOpenAiCodexModels into GET /api/models via packages/dashboard/src/routes/register-model-routes.ts, alongside the existing Anthropic supplemental merge
- Export new symbols from packages/core/src/index.ts and packages/core/src/index.gate.ts
- Add unit tests for the merge helper (packages/core/src/__tests__/openai-models.test.ts) and the route wiring (packages/dashboard/src/__tests__/register-model-routes-openai-codex-supplemental.test.ts)
- Document the new supplemental catalog entries in docs/settings-reference.md
- Add changeset .changeset/fn-7745-gpt-5-6-codenamed-model-selector.md (minor, @runfusion/fusion)

Files changed:
 .../fn-7745-gpt-5-6-codenamed-model-selector.md    |   7 +
 docs/settings-reference.md                         |   2 +
 packages/core/src/__tests__/openai-models.test.ts  | 134 +++++++++++++++++
 packages/core/src/index.gate.ts                    |   9 ++
 packages/core/src/index.ts                         |   9 ++
 packages/core/src/openai-models.ts                 | 166 +++++++++++++++++++++
 ...-model-routes-openai-codex-supplemental.test.ts | 143 ++++++++++++++++++
 .../dashboard/src/routes/register-model-routes.ts  |  10 +-
 8 files changed, 479 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7745

Fusion-Task-Lineage: 74c83182-df81-4606-a4dc-0da3ee4cae83

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:07 -07:00
gsxdsm
0e90578122 FN-7737: Add file_scope agent permission category with default allow disposition
Introduces a new file_scope sensitive-action category to the agent permission policy model so file-scope-related FN tools are classified and gated distinctly from other categories, defaulting to allowed under the grant-all preset.

- Add file_scope to AGENT_PERMISSION_POLICY_ACTION_CATEGORIES in @fusion/core types
- Classify FILE_SCOPE_FN_TOOLS in both agent-action-gate and permanent-agent-gating with a uniform preset disposition (no review_gate_bypass-style override)
- Update AgentDetailView and AgentPermissionPolicyEditor to surface the new category in the dashboard UI
- Add/extend unit tests across core, engine, and dashboard packages covering the new category's resolution, gating, and UI rendering
- Update docs/agents.md and docs/settings-reference.md to document the new permission category
- Regenerate i18n locale strings (en/es/fr/ko/zh-CN/zh-TW) and resources.d.ts for the new category labels
- Add changeset for @runfusion/fusion (minor) describing the new File Scope permission category

Files changed:
 .../fn-7737-file-scope-permission-category.md      |   7 +
 docs/agents.md                                     |  10 +-
 docs/settings-reference.md                         |   8 +-
 .../agent-permission-policy-resolution.test.ts     |  13 +
 .../src/__tests__/agent-permission-policy.test.ts  |  45 +++
 packages/core/src/types.ts                         |   7 +
 .../dashboard/app/components/AgentDetailView.tsx   |   2 +
 .../app/components/AgentPermissionPolicyEditor.tsx |   8 +
 .../__tests__/AgentPermissionPolicyEditor.test.tsx |  37 +++
 .../engine/src/__tests__/agent-action-gate.test.ts |  46 +++
 .../src/__tests__/gating-classifications.test.ts   |  67 +++++
 .../src/__tests__/permanent-agent-gating.test.ts   |  41 +++
 packages/engine/src/agent-action-gate.ts           |   7 +
 packages/engine/src/gating-classifications.ts      |   6 +
 packages/engine/src/permanent-agent-gating.ts      |   6 +
 packages/i18n/locales/en/app.json                  |   4 +
 packages/i18n/locales/es/app.json                  |   4 +
 packages/i18n/locales/fr/app.json                  |   4 +
 packages/i18n/locales/ko/app.json                  |   4 +
 packages/i18n/locales/zh-CN/app.json               |   4 +
 packages/i18n/locales/zh-TW/app.json               |   4 +
 packages/i18n/src/resources.d.ts                   | 310 +++++++++++++++------
 22 files changed, 550 insertions(+), 94 deletions(-)

Fusion-Task-Id: FN-7737

Fusion-Task-Lineage: 7b161fb3-7dd9-4860-aa4d-0cb35f38ea5b

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:07 -07:00
gsxdsm
1fa4a69dde FN-7747: derive dashboard authStorage fallback from engine.getAuthStorage()
Fixes desktop provider API keys not persisting when a host wires an engine into createServer() but forgets to pass its own authStorage, which previously caused register-auth-routes.ts to throw "Authentication is not configured".

- Add ProjectEngine.getAuthStorage() exposing the OAuth subsystem's raw createFusionAuthStorage() instance
- In createServer(), derive options.authStorage from engine.getAuthStorage() when not explicitly provided (mirrors existing engine-derivation pattern for onMerge/automationStore/etc.); explicit authStorage still overrides
- Add regression tests covering the fallback-derivation and explicit-override behavior
- Add changeset (patch) documenting the fix for @runfusion/fusion

Files changed:
 .changeset/fn-7747-derive-authstorage-from-engine.md |   7 ++
 packages/dashboard/src/__tests__/server.test.ts      | 119 +++++++++++++++++++++
 packages/dashboard/src/server.ts                     |  28 ++++-
 packages/engine/src/project-engine.ts                |  25 +++++
 4 files changed, 178 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7747

Fusion-Task-Lineage: f8e72b15-d084-4e8d-89db-47453d57b41b

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:07 -07:00
gsxdsm
2ff8e2e13e FN-7743: detect and recover stalled in-progress executor tasks in overseer
Fix the planner overseer's executor-stage stall detection so hung in-progress tasks get unstuck instead of being reported as progressing forever.

- Add configurable stuck-detection: the executor-stage overseer observation now emits signal: "stuck" once an in-progress task has been inactive past a new plannerOverseerExecutorStuckAfterMs threshold, feeding the existing decidePlannerRecovery -> bounded inject_guidance recovery path.
- Register the new plannerOverseerExecutorStuckAfterMs setting in builtin-workflow-settings.ts and export it via core index.ts/index.gate.ts.
- Preserve human-control withholds (user-paused / approval-blocked / autoMerge-off) taking precedence over stuck detection.
- Add/extend tests covering planner-overseer, planner-recovery-controller, planner-recovery, and builtin-workflow-settings-triage.
- Document the new setting in docs/architecture.md and docs/settings-reference.md.
- Add changeset fn-7743-overseer-executor-stall.md (patch).

Files changed:
 .changeset/fn-7743-overseer-executor-stall.md      |   7 +
 docs/architecture.md                               |  31 +++++
 docs/settings-reference.md                         |   3 +-
 .../builtin-workflow-settings-triage.test.ts       |  22 ++++
 .../core/src/__tests__/planner-recovery.test.ts    |  12 ++
 packages/core/src/builtin-workflow-settings.ts     |  26 ++++
 packages/core/src/index.gate.ts                    |   1 +
 packages/core/src/index.ts                         |   1 +
 .../engine/src/__tests__/planner-overseer.test.ts  | 146 +++++++++++++++++++++
 .../__tests__/planner-recovery-controller.test.ts  |  52 +++++++-
 packages/engine/src/planner-overseer.ts            |  88 ++++++++++++-
 packages/engine/src/project-engine.ts              |  11 +-
 12 files changed, 391 insertions(+), 9 deletions(-)

Fusion-Task-Id: FN-7743

Fusion-Task-Lineage: 791852a2-5b77-48de-955a-1b3916616dfa

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:07 -07:00
gsxdsm
9d7b087188 FN-7742: bump pi SDK to 0.80.5 and add GPT-5.6 codex-tier model pricing
Updates the @earendil-works/pi SDK dependency and adds pricing entries for the new GPT-5.6 codex-tier models so Command Center reports real cost instead of unavailable.

- Bump @earendil-works/pi-ai and @earendil-works/pi-coding-agent from ^0.80.3 to ^0.80.5 in packages/cli, packages/dashboard, packages/engine, and packages/pi-claude-cli
- Add openai-codex:gpt-5.6-luna, openai-codex:gpt-5.6-sol, and openai-codex:gpt-5.6-terra pricing entries to model-pricing.ts, mirroring the existing gpt-5.3-codex rate
- Bump pricingAsOf to 2026-07-09
- Add regression tests covering the new GPT-5.6 pricing entries
- Add changeset (minor) for @runfusion/fusion
- Update pnpm-lock.yaml for the dependency bump

Files changed:
 .changeset/fn-7742-pi-sdk-gpt-5-6.md              |   7 +
 packages/cli/package.json                         |   4 +-
 packages/core/src/__tests__/model-pricing.test.ts |  14 +
 packages/core/src/model-pricing.ts                |  35 ++-
 packages/dashboard/package.json                   |   2 +-
 packages/engine/package.json                      |   4 +-
 packages/pi-claude-cli/package.json               |   8 +-
 pnpm-lock.yaml                                    | 323 ++++++++++++----------
 8 files changed, 246 insertions(+), 151 deletions(-)

Fusion-Task-Id: FN-7742

Fusion-Task-Lineage: 2fae3ac1-0877-4d12-b08f-d53d261f2fea

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:07 -07:00
gsxdsm
4726af673a FN-7740: fix store-leak and no-retry-on-lock gaps in research/settings-import/agent-export/git/project CLI commands
Close leaked TaskStore/AgentStore handles and retry lock errors across fn research, settings import, agent export, git, and project CLI commands.

- fn research create/list/show/export/cancel/retry now close their resolved store on every exit path except the intentional fire-and-forget --wait-for-completion-less create, which stays open to avoid truncating the background run
- fn settings import retries importSettings through a momentary database-is-locked window and closes the store before every process.exit()
- fn agent export closes both the project TaskStore and the AgentStore it opens on every exit path, including the no-agents-to-export guard
- fn git status/fetch/pull/push and fn agent export switch to a path-only project resolution helper so no cached, never-closed TaskStore is left behind for these read/write-nothing-to-board commands
- fn project list/show compute per-project task counts against an uncached TaskStore that is now closed after every call, and the count read retries a momentary lock instead of silently reporting zero tasks
- Adds dedicated lock-retry regression tests for each touched command plus a changeset documenting the fix

Files changed:
 .changeset/fn-7740-cli-cmd-lock-retry.md           |   7 +
 docs/cli-reference.md                              |  28 +++
 .../__tests__/agent-export-lock-retry.test.ts      | 122 ++++++++++
 .../src/commands/__tests__/git-lock-retry.test.ts  | 129 +++++++++++
 packages/cli/src/commands/__tests__/git.test.ts    |  12 +
 .../commands/__tests__/project-lock-retry.test.ts  | 195 ++++++++++++++++
 .../cli/src/commands/__tests__/project.test.ts     |   8 +
 .../commands/__tests__/research-lock-retry.test.ts | 248 ++++++++++++++++++++
 .../cli/src/commands/__tests__/research.test.ts    |  16 +-
 .../__tests__/settings-import-lock-retry.test.ts   | 170 ++++++++++++++
 .../src/commands/__tests__/settings-import.test.ts |  34 +++
 packages/cli/src/commands/agent-export.ts          |  67 ++++--
 packages/cli/src/commands/git.ts                   |  18 +-
 packages/cli/src/commands/project.ts               |  40 +++-
 packages/cli/src/commands/research.ts              | 254 ++++++++++++++-------
 packages/cli/src/commands/settings-import.ts       |  61 ++++-
 16 files changed, 1284 insertions(+), 125 deletions(-)

Fusion-Task-Id: FN-7740

Fusion-Task-Lineage: 5c572332-b81c-4e16-9748-ce8639f53ff3

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:06 -07:00
gsxdsm
5304af8d0e FN-7739: retry locked store access in backup/mcp/db CLI commands
Audits and hardens `fn backup`, `memory-backup`, `mcp`, and `db vacuum` CLI commands so they retry a locked board database instead of hanging, and reliably close store handles on every exit path.

- Add retryOnLock + closeProjectStore/asLocalProjectContext pattern to backup.ts, memory-backup.ts, mcp.ts, and db.ts (following the FN-7731/FN-7738 pattern)
- Close cached, uncached CWD-fallback, and ad-hoc MCP secrets TaskStores on every exit path (success, error, early-return)
- Retry MCP settings writes and DB VACUUM on lock contention, honoring FUSION_CLI_LOCK_RETRY_MS
- Add lock-retry regression test suites for backup, db, mcp, and memory-backup commands
- Update docs/cli-reference.md with the new retry/lock behavior
- Add changeset (patch) documenting the fix

Files changed:
 .changeset/fn-7739-cli-cmd-lock-retry.md           |   7 +
 docs/cli-reference.md                              |  17 +
 .../commands/__tests__/backup-lock-retry.test.ts   | 202 +++++++++++
 packages/cli/src/commands/__tests__/backup.test.ts |  15 +
 .../src/commands/__tests__/db-lock-retry.test.ts   | 182 ++++++++++
 packages/cli/src/commands/__tests__/db.test.ts     |  15 +
 .../src/commands/__tests__/mcp-lock-retry.test.ts  | 234 ++++++++++++
 packages/cli/src/commands/__tests__/mcp.test.ts    |  14 +
 .../__tests__/memory-backup-lock-retry.test.ts     | 201 +++++++++++
 .../src/commands/__tests__/memory-backup.test.ts   |  15 +
 packages/cli/src/commands/backup.ts                | 252 +++++++++----
 packages/cli/src/commands/db.ts                    |  62 +++-
 packages/cli/src/commands/mcp.ts                   | 391 +++++++++++++++------
 packages/cli/src/commands/memory-backup.ts         | 179 +++++++---
 14 files changed, 1538 insertions(+), 248 deletions(-)

Fusion-Task-Id: FN-7739

Fusion-Task-Lineage: 6dbab086-2bf8-4cd4-950b-04fe39131933

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:06 -07:00
gsxdsm
bab42b40dd FN-7736: prevent recovery/oversight from resuming approval-blocked tasks
Introduces a canonical awaiting-approval pause reason and predicate so recovery and oversight paths treat approval-blocked tasks as terminal-until-approved instead of eligible for early rebound.

- Add isTaskBlockedOnApproval predicate and canonical "awaiting-approval" pause reason in @fusion/core (store.ts, task-merge.ts, index.ts/index.gate.ts)
- Exclude approval-blocked tasks from paused-scope-decay rebound in self-healing.ts
- Keep the planner overseer withholding oversight for approval-blocked tasks (overseer-human-control-policy.ts)
- Executor and agent-heartbeat now recognize the approval-blocked state and avoid resuming it
- Add regression tests across store-persistence, task-merge, overseer-human-control-policy, paused-scope-decay, and self-healing-paused-abort-recovery
- Update docs/architecture.md with the new approval-hold invariant
- Add changeset fn-7736-approval-hold.md (patch)

Files changed:
 .changeset/fn-7736-approval-hold.md                |  7 +++
 docs/architecture.md                               | 64 ++++++++++++++++++++--
 .../core/src/__tests__/store-persistence.test.ts   | 18 ++++++
 packages/core/src/__tests__/task-merge.test.ts     | 34 ++++++++++++
 packages/core/src/index.gate.ts                    |  2 +
 packages/core/src/index.ts                         |  2 +
 packages/core/src/store.ts                         | 18 +++++-
 packages/core/src/task-merge.ts                    | 34 ++++++++++++
 .../executor-approval-gate-suspend.test.ts         |  5 +-
 .../src/__tests__/heartbeat-executor.test.ts       |  5 +-
 .../overseer-human-control-policy.test.ts          | 44 +++++++++++++++
 .../paused-scope-decay.test.ts                     | 44 +++++++++++++++
 .../self-healing-paused-abort-recovery.test.ts     | 21 +++++++
 packages/engine/src/agent-heartbeat.ts             |  8 ++-
 packages/engine/src/executor.ts                    | 13 ++++-
 .../engine/src/overseer-human-control-policy.ts    | 45 +++++++++++----
 packages/engine/src/self-healing.ts                | 12 +++-
 17 files changed, 351 insertions(+), 25 deletions(-)

Fusion-Task-Id: FN-7736

Fusion-Task-Lineage: 67e05b7f-f621-4f9b-bc01-721ff05d715b

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:06 -07:00
gsxdsm
86bd434c11 FN-7738: retry locked board DB in fn branch-group/pr CLI commands
Audit non-task.ts CLI command families for store-leak / no-retry-on-lock gaps and fix branch-group.ts and pr.ts to match the FN-7731 retryOnLock + closeProjectStore pattern.

- Add retryOnLock handling (honoring FUSION_CLI_LOCK_RETRY_MS) around board DB access in branch-group.ts and pr.ts so a locked store retries and exits promptly instead of hanging.
- Ensure both cached and uncached CWD-fallback project stores are closed on every exit path (success, error, early return) to stop store leaks.
- Extend project-context.ts with shared helpers used by both commands.
- Add regression tests: branch-group-lock-retry.test.ts and pr-lock-retry.test.ts, plus additional coverage in branch-group.test.ts.
- Document the new lock-retry behavior in docs/cli-reference.md.
- Add a patch changeset for @runfusion/fusion describing the user-facing fix.

Files changed:
 .changeset/fn-7738-cli-cmd-lock-retry.md           |   7 +
 docs/cli-reference.md                              |  11 +
 .../__tests__/branch-group-lock-retry.test.ts      | 221 ++++++++
 .../src/commands/__tests__/branch-group.test.ts    |  10 +
 .../src/commands/__tests__/pr-lock-retry.test.ts   | 226 ++++++++
 packages/cli/src/commands/branch-group.ts          | 389 +++++++++-----
 packages/cli/src/commands/pr.ts                    | 575 +++++++++++++--------
 packages/cli/src/project-context.ts                |  26 +
 8 files changed, 1122 insertions(+), 343 deletions(-)

Fusion-Task-Id: FN-7738

Fusion-Task-Lineage: 0bbc8fa2-c4f9-49ed-adb6-7dab57eaee13

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:06 -07:00
gsxdsm
1e79a236b2 FN-7734: generalize lock-retry and store-close pattern across all fn task subcommands
Applies the FN-7731 retryOnLock + closeProjectStore pattern to the ~26 runTask* handlers in task.ts so every 'fn task' subcommand retries a momentarily locked board database and exits promptly instead of hanging or leaking a store handle.

- Generalize retryOnLock/closeProjectStore usage across all runTask* handlers in packages/cli/src/commands/task.ts
- Honor FUSION_CLI_LOCK_RETRY_MS for configurable retry timing
- Close both cached and uncached CWD-fallback stores on exit
- Multi-step flows (create/retry/delete/merge/imports) retry each discrete write independently instead of retrying the whole flow
- Add task-lock-retry.test.ts covering the new retry/close behavior across subcommands
- Update docs/cli-reference.md and task.test.ts for the new behavior
- Add changeset fn-7734-task-cmd-lock-retry-generalized.md (patch)

Files changed:
 .../fn-7734-task-cmd-lock-retry-generalized.md     |    7 +
 docs/cli-reference.md                              |   18 +-
 .../src/commands/__tests__/task-lock-retry.test.ts |  282 ++++
 packages/cli/src/commands/__tests__/task.test.ts   |    9 +-
 packages/cli/src/commands/task.ts                  | 1541 +++++++++++---------
 5 files changed, 1173 insertions(+), 684 deletions(-)

Fusion-Task-Id: FN-7734

Fusion-Task-Lineage: cd5c864b-8a33-4962-803e-bbb353a41085

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:06 -07:00
gsxdsm
21d1201de1 FN-7713: collapse mobile Settings search row behind an expand/hide toggle
Mobile Settings modal now hides the search row by default and exposes a toggle icon to expand/hide it, keeping desktop layout unchanged.

- Add mobile-only searchRowExpanded state and toggle affordance in SettingsModal.tsx
- Add toggle icon styling in SettingsModal.css
- Update dashboard-guide.md docs to describe the new mobile behavior
- Add/extend tests covering the collapsed-by-default state and toggle interaction
- Add changeset (feature, no release wording) for @runfusion/fusion

Files changed:
 .../fn-7713-mobile-settings-search-toggle.md       |   7 ++
 docs/dashboard-guide.md                            |   3 +
 .../dashboard/app/components/SettingsModal.css     |  31 ++++++
 .../dashboard/app/components/SettingsModal.tsx     | 112 ++++++++++++++-------
 .../__tests__/SettingsModal.general.test.tsx       |   7 ++
 .../components/__tests__/settings-mobile.test.tsx  |  69 +++++++++++++
 6 files changed, 192 insertions(+), 37 deletions(-)

Fusion-Task-Id: FN-7713

Fusion-Task-Lineage: 4ce90317-28ce-45b4-a1d7-8fd662a922ae

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:06 -07:00
gsxdsm
e4a59f7269 fix: remove over-firing triage release-authorization gate
The triage release-authorization gate (FN-6481/FN-6469) false-flagged any
spec that merely mentioned release tooling (scripts/release.mjs, pnpm release)
and, because non-user sources made the in-band authorization marker inert,
stranded ordinary tasks in awaiting-approval with no exit.

- Delete triage-release-authorization.ts + its test and the finalizeApprovedTask
  parking block; release-class specs now flow through triage normally.
- Remove the dashboard approve/reject-plan API guards and UI gating so tasks
  still carrying the legacy awaitingApprovalReason="release-authorization" hold
  render as ordinary manual plan-approval holds and can be resolved.
- Keep the awaitingApprovalReason field + activity label for backward-compat.
- Replace the engine gate with agent instruction (AGENTS.md -> Releasing):
  agents must never run a release from inside a Fusion task.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 19:58:06 -07:00
gsxdsm
7420abe80e FN-7731: add CLI-level lock retry for task show/move commands
Add bounded exponential-backoff retry above the DB layer so `fn task show`/`fn task move` ride out transient SQLite lock contention instead of failing outright or hanging.

- Add packages/cli/src/lock-retry.ts: retries a thunk on SQLite lock errors (via @fusion/core's isSqliteLockError) with exponential backoff capped by a wall-clock deadline (default 15s, override via FUSION_CLI_LOCK_RETRY_MS); non-lock errors propagate immediately; raises LockRetryExhaustedError on deadline exhaustion.
- Wire lock-retry into packages/cli/src/commands/task.ts for the show/move task-store operations, and close the resolved TaskStore for deterministic exit.
- Export isSqliteLockError from packages/core/src/index.ts for CLI reuse.
- Add packages/cli/src/commands/__tests__/task-lock-retry.test.ts covering retry/backoff/deadline/error-passthrough behavior; extend task.test.ts.
- Document the new behavior/env var in docs/cli-reference.md.
- Add changeset (@runfusion/fusion: patch).

Files changed:
 .changeset/fn-7731-task-cmd-lock-retry.md          |   7 +
 docs/cli-reference.md                              |   9 +
 .../src/commands/__tests__/task-lock-retry.test.ts | 430 +++++++++++++++++++++
 packages/cli/src/commands/__tests__/task.test.ts   |  11 +
 packages/cli/src/commands/task.ts                  | 117 +++++-
 packages/cli/src/lock-retry.ts                     | 117 ++++++
 packages/core/src/index.ts                         |   5 +
 7 files changed, 688 insertions(+), 8 deletions(-)

Fusion-Task-Id: FN-7731

Fusion-Task-Lineage: 85543164-10d6-4da9-8c3c-a84cd86827aa

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:05 -07:00
gsxdsm
badb86a965 FN-7726: unify fs.watch/poll logic between TaskStore and AgentStore
Extracted the duplicated file-watch-with-polling-fallback logic from TaskStore and AgentStore into a shared controller.

- Added packages/core/src/fs-watch-poll-controller.ts implementing a reusable fs.watch + polling-fallback controller
- Refactored packages/core/src/store.ts (TaskStore) to use the shared controller instead of its own watch/poll implementation
- Refactored packages/core/src/agent-store.ts (AgentStore) to use the shared controller instead of its own watch/poll implementation
- Added packages/core/src/__tests__/fs-watch-poll-controller.test.ts covering the new controller's behavior
- Updated docs/architecture.md to document the shared controller

Files changed:
 docs/architecture.md                               |   1 +
 .../src/__tests__/fs-watch-poll-controller.test.ts | 187 +++++++++++++++++++++
 packages/core/src/agent-store.ts                   |  66 +++-----
 packages/core/src/fs-watch-poll-controller.ts      | 123 ++++++++++++++
 packages/core/src/store.ts                         |  66 +++-----
 5 files changed, 364 insertions(+), 79 deletions(-)

Fusion-Task-Id: FN-7726
Fusion-Task-Lineage: 69be6dc3-5414-44f2-a3f1-3eb72c2d7391
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:05 -07:00
gsxdsm
5663067e62 FN-7733: remove GitLab browse tools from task_agent_mutation policy examples
Fixes a task_agent_mutation policy example drift: the read-only GitLab browse
tools were incorrectly listed as mutation examples even though they were
never part of ACTION_GATE_TASK_AGENT_MANAGEMENT_TOOLS and are already
classified read-only.

- Remove fn_task_browse_gitlab_project_issues, fn_task_browse_gitlab_group_issues,
  and fn_task_browse_gitlab_merge_requests from AGENT_PERMISSION_POLICY_CATEGORY_TOOL_EXAMPLES.task_agent_mutation
  in packages/core/src/types.ts, keeping the mutating fn_task_import_gitlab_* variants
- Add an FNXC:ToolGovernance comment documenting the invariant and rationale
- Add regression coverage asserting the browse tools are excluded from
  task_agent_mutation examples and are pinned as READONLY_FN_TOOLS

Files changed:
 .../src/__tests__/agent-permission-policy.test.ts     | 19 +++++++++++++++++++
 packages/core/src/types.ts                            |  6 ++----
 2 files changed, 21 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-7733

Fusion-Task-Lineage: 3a54faa1-89dd-48bc-978a-4a53f06706be

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:05 -07:00
gsxdsm
927741a8cf FN-7727: persist failed workflow step history across self-healing retries
Preserves prior failed pre-merge review attempts instead of overwriting them when self-healing re-runs a failed workflow step.

- Add optional bounded `priorAttempts?: WorkflowStepResult[]` field to `WorkflowStepResult` (capped at `MAX_WORKFLOW_STEP_PRIOR_ATTEMPTS`)
- Add shared pure `upsertWorkflowStepResult(existing, incoming, opts?)` helper in `@fusion/core` (packages/core/src/workflow-step-results.ts)
- Route the executor graph adapter's `recordWorkflowStepResult` and triage's `recordPlanReviewWorkflowResult` through the new helper so a self-healing recovery re-run snapshots the prior failed/advisory_failure attempt into `priorAttempts` instead of dropping it
- Selection logic (self-healing, merge-blocker, progress/timing) is unchanged and still reads only the current entry
- Surface prior failed attempts in the TaskDetailModal Summary tab's Workflow results list as a collapsed "previous failed attempts" disclosure
- Add core/engine/dashboard tests covering the upsert helper, self-healing recovery snapshotting, and the UI disclosure
- Document the behavior in docs/workflow-steps.md
- Add changeset for @runfusion/fusion (patch)

Files changed:
 .changeset/fn-7727-persist-failed-step-history.md  |   7 ++
 docs/workflow-steps.md                             |  15 +++
 .../src/__tests__/workflow-step-results.test.ts    | 138 +++++++++++++++++++++
 packages/core/src/index.gate.ts                    |   4 +
 packages/core/src/index.ts                         |   4 +
 packages/core/src/types.ts                         |  19 +++
 packages/core/src/workflow-step-results.ts         |  99 +++++++++++++++
 .../dashboard/app/components/TaskDetailModal.css   |  55 ++++++++
 .../dashboard/app/components/TaskSummaryTab.tsx    |  42 ++++++-
 .../TaskSummaryTab.prior-attempts.test.tsx         |  89 +++++++++++++
 .../clear-terminal-workflow-step-failures.test.ts  |  27 ++++
 packages/engine/src/__tests__/self-healing.test.ts |  50 ++++++++
 ...flow-step-results-self-healing-recovery.test.ts | 115 +++++++++++++++++
 packages/engine/src/executor.ts                    |  29 +++--
 packages/engine/src/triage.ts                      |  14 ++-
 15 files changed, 688 insertions(+), 19 deletions(-)

Fusion-Task-Id: FN-7727
Fusion-Task-Lineage: 7316fb18-bc92-426d-91f4-b1a4ad41c9b1
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:05 -07:00
gsxdsm
5a9f354e9a FN-7730: fix linked-worktree project-root resolution so board writes don't silently land in the wrong .fusion.db
Board mutations (fn_task_update, CEO override, direct SQL) issued from a pi-extension tool session could silently write into a task's throwaway, never-synced worktree-local .fusion/fusion.db instead of the true project root when git CLI resolution failed (missing git binary, Docker "dubious ownership" refusal, or a non-default settings.worktreesDir). This fixes root-cause resolution and adds regression coverage plus a docs writeup.

- getProjectRootFromGitLinkedWorktree now resolves a linked worktree's project root from git's own on-disk .git/commondir metadata via pure filesystem reads before falling back to the git rev-parse CLI, so writes no longer fall through to a local hydrated copy on git-invocation failure.
- Added getMainRepoRootFromGitFile and resolveCommonGitDirFromWorktreeGitFile helpers with FNXC:Storage comments documenting the FN-7730 root cause and fix rationale.
- Added packages/core/src/__tests__/pi-extensions-write-path-durability.test.ts regression coverage for the write-path durability invariant.
- Extended packages/core/src/__tests__/pi-extensions.test.ts with additional resolution-path assertions.
- Documented the failure mode and fix in docs/storage.md ("Silent board-mutation write loss (FN-7730)").
- Added a patch changeset for @runfusion/fusion describing the user-facing fix.

Files changed:
 .changeset/fn-7730-worktree-project-root-resolution.md              |   7 ++
 docs/storage.md                                                     |  54 ++++++++++
 packages/core/src/__tests__/pi-extensions-write-path-durability.test.ts | 98 ++++++++++++++++++
 packages/core/src/__tests__/pi-extensions.test.ts                   |  87 +++++++++++++++-
 packages/core/src/pi-extensions.ts                                  | 114 +++++++++++++++++++++
 5 files changed, 359 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7730
Fusion-Task-Lineage: 00753a2d-a934-42cf-8fde-0f9b8ad98142
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:05 -07:00
gsxdsm
d44dbaab15 FN-7728: add review_gate_bypass RBAC category for fn_task_bypass_review
Introduces a dedicated review_gate_bypass permission-policy category so operators can govern who may bypass a failed pre-merge review gate independently of ordinary task-mutation permissions.

- Add review_gate_bypass as a new sensitive-action category in packages/core/src/types.ts, distinct from task_agent_mutation, with fn_task_bypass_review as its sole example tool
- Default review_gate_bypass to require-approval even under the unrestricted preset (stricter than the preset's uniform disposition) in packages/core/src/agent-permission-policy.ts, while approval-required/locked-down already cover it uniformly
- Classify fn_task_bypass_review into the new category via a shared REVIEW_GATE_BYPASS_FN_TOOLS set in packages/engine/src/gating-classifications.ts, consumed identically by both evaluateAgentActionGate and the permanent-agent gate to prevent path drift
- Render the new category as its own row in the dashboard's project-default and per-agent AgentPermissionPolicyEditor, surfaced in AgentDetailView
- Update docs/settings-reference.md and add unit tests across core/engine/dashboard covering the new category, its stricter default, and gate-classification alignment
- Add changeset (@runfusion/fusion: minor) documenting the new operator-facing permission category

Files changed:
 .changeset/fn-7728-review-gate-bypass-rbac.md      |  7 +++
 docs/settings-reference.md                         |  8 +--
 .../src/__tests__/agent-permission-policy.test.ts  | 54 ++++++++++++++++++-
 packages/core/src/agent-permission-policy.ts       | 12 ++++-
 packages/core/src/types.ts                         |  8 +++
 .../dashboard/app/components/AgentDetailView.tsx   |  2 +
 .../app/components/AgentPermissionPolicyEditor.tsx |  8 +++
 .../__tests__/AgentPermissionPolicyEditor.test.tsx |  5 ++
 .../engine/src/__tests__/agent-action-gate.test.ts | 45 ++++++++++++++++
 .../src/__tests__/gating-classifications.test.ts   | 63 ++++++++++++++++++++++
 .../src/__tests__/permanent-agent-gating.test.ts   | 41 ++++++++++++++
 packages/engine/src/agent-action-gate.ts           |  7 +++
 packages/engine/src/gating-classifications.ts      |  8 ++-
 packages/engine/src/permanent-agent-gating.ts      |  6 +++
 14 files changed, 266 insertions(+), 8 deletions(-)

Fusion-Task-Id: FN-7728

Fusion-Task-Lineage: 100c8563-2897-4d53-9546-5c2faa6ab7d8

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:05 -07:00
gsxdsm
1fc615d0da FN-7724: bridge Grok CLI tool_use NDJSON events in GrokRuntimeAdapter
Bridges Grok CLI tool execution events (tool_use start/result) from the NDJSON stream into the runtime adapter's onToolStart/onToolEnd callbacks, alongside existing text bridging.

- GrokRuntimeAdapter.promptWithFallback now parses and bridges tool_use NDJSON events into onToolStart/onToolEnd callbacks
- Tool name/args/result pass through unchanged (no Grok→pi tool-name mapping, since the verified contract doesn't pin a vocabulary)
- step_finish/error remain non-terminal per-step events, not bridged to any callback; only subprocess close/error finalizes (unchanged from FN-7722)
- Extended stream-parser.ts to recognize tool_use event shapes
- Added new types for tool event payloads in types.ts
- Updated docs/grok-cli-contract.md and plugin README to document tool event bridging
- Added changeset for @runfusion/fusion (minor)
- Added/extended tests in runtime-adapter.test.ts and stream-parser.test.ts (fixture-based, no live binary)

Files changed:
 .changeset/fn-7724-grok-cli-tool-bridging.md       |   7 ++
 docs/grok-cli-contract.md                          |  16 ++-
 plugins/fusion-plugin-grok-runtime/README.md       |  12 +++
 .../src/__tests__/runtime-adapter.test.ts          | 120 +++++++++++++++++++++
 .../src/__tests__/stream-parser.test.ts            |  33 ++++++
 .../src/runtime-adapter.ts                         |  83 +++++++++++---
 .../src/stream-parser.ts                           |  10 ++
 plugins/fusion-plugin-grok-runtime/src/types.ts    |  23 ++++
 8 files changed, 287 insertions(+), 17 deletions(-)

Fusion-Task-Id: FN-7724

Fusion-Task-Lineage: 73abbf2a-6dcd-44fb-86be-71d4788c92d2

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:05 -07:00
gsxdsm
e5c3ffbb39 FN-7725: wire Grok CLI runtime adapter routing end-to-end with tests and docs
Formalizes and tests the existing agent Runtime-mode picker path as the decided Grok CLI routing wiring.

- Add FNXC decision note at the extractRuntimeHint seam documenting the Grok CLI routing chain (agent-session-helpers.ts)
- Add routing test verifying runtimeHint="grok" resolves through resolveRuntime/resolvePluginRuntime to GrokRuntimeAdapter (grok-runtime-routing.test.ts)
- Update docs/grok-cli-contract.md with the wiring decision and documented limitations
- Update plugins/fusion-plugin-grok-runtime/README.md with routing guidance
- Add changeset for the new opt-in Grok CLI streaming runtime routing feature

Files changed:
 .changeset/fn-7725-grok-cli-routing.md             |   7 +
 docs/grok-cli-contract.md                          | 106 ++++++--
 .../src/__tests__/grok-runtime-routing.test.ts     | 275 +++++++++++++++++++++
 packages/engine/src/agent-session-helpers.ts       |  12 +
 plugins/fusion-plugin-grok-runtime/README.md       |  38 ++-
 5 files changed, 414 insertions(+), 24 deletions(-)

Fusion-Task-Id: FN-7725

Fusion-Task-Lineage: f5210793-59d0-4a0c-8152-4c5ef61ca737

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:04 -07:00
gsxdsm
626e00288c FN-7720: add operator review-lane bypass for stranded pre-merge review failures
Add a policy-gated review-lane bypass primitive so operators can unstick cards stranded by a failed pre-merge review step (e.g. the no-feedback review-engine defect), without exposing it to agent-driven lanes.

- Add `store.bypassFailedPreMergeReviewStep(id, { reason, actor })` in @fusion/core plus `getLatestFailedPreMergeReviewStep` in task-merge.ts, and new `bypassedBy`/`bypassedAt`/`bypassReason`/`bypassedFromStatus`/`bypassedFromVerdict` fields on `WorkflowStepResult`
- Add operator-only `fn_task_bypass_review` CLI/pi-extension tool; explicitly withheld from executor/reviewer/triage agent tool lists
- Add `POST /tasks/:id/bypass-review` dashboard API route and wire it through `register-task-workflow-routes.ts` and legacy API compatibility layer
- Add dashboard UI affordance (context menu action + task detail modal + right-dock controller wiring) to trigger the bypass with a reason
- Add i18n strings for the bypass action/labels across en/es/fr/ko/zh-CN/zh-TW locales
- Update `gating-classifications.ts` to recognize the bypassed state
- Add unit tests: `store-bypass-review.test.ts`, `task-merge-bypass.test.ts`, extension test coverage, and `useTasks` hook test coverage
- Update docs (`docs/workflow-steps.md`, `docs/dashboard-guide.md`, AGENTS.md, fusion skill references) to describe the new bypass tool/route
- Add changeset `.changeset/fn-7720-review-lane-bypass-primitive.md` (minor)

Files changed:
$(git diff --cached --stat)

Fusion-Task-Id: FN-7720

Fusion-Task-Lineage: 590b020a-ae02-4b51-8189-df8f54bf3044

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:04 -07:00
gsxdsm
e657d3b965 FN-7723: add cross-process agent state change notification bus
Adds opt-in cross-process change detection to AgentStore so the engine reacts to CLI-driven agent stop/start mutations promptly instead of waiting for the periodic audit sweep.

- AgentStore gains fs.watch-based (with poll fallback) cross-process notification, modeled on TaskStore's existing mechanism
- Re-emits existing agent:updated/agent:stateChanged events in the engine process when another process (the fn CLI) mutates an agent row
- HeartbeatTriggerScheduler listeners now fire immediately instead of waiting up to 60s for the auditTimerRegistrations sweep; the sweep remains as durable backstop
- in-process-runtime.ts wires up the new notification bus
- Adds unit tests for agent-store cross-process notifications and heartbeat-scheduler reaction behavior
- Updates docs/agents.md and docs/architecture.md
- Adds changeset (patch) for @runfusion/fusion

Files changed:
 .changeset/fn-7723-cross-process-agent-notify.md   |   7 +
 docs/agents.md                                     |   1 +
 docs/architecture.md                               |   1 +
 packages/core/src/__tests__/agent-store.test.ts    | 177 +++++++++++++++++
 packages/core/src/agent-store.ts                   | 210 ++++++++++++++++++++-
 .../src/__tests__/heartbeat-scheduler.test.ts      | 162 ++++++++++++++++
 packages/engine/src/runtimes/in-process-runtime.ts |  30 +++
 7 files changed, 587 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7723
Fusion-Task-Lineage: d3a7fa05-b40d-4388-8e98-140f9d8861c9
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:04 -07:00