Commit Graph

951 Commits

Author SHA1 Message Date
gsxdsm
55dae49b37 FN-7704: fix fn agent stop/start hanging up to 60s due to unclosed store handles
Fix CLI process exit so `fn agent stop`/`fn agent start` no longer hang up to 60s and eventually time out on repeated retries against the same agent.

- Root cause: `resolveProject()` cached an unclosed `TaskStore`, and `createAgentStore()` never closed the `AgentStore` it opened, leaving SQLite handles alive after the command's real work was done.
- Add `resolveProjectPathOnly`/`closeProjectStore` helpers in `project-context.ts` so path-only callers never leak a `TaskStore`.
- Explicitly close `AgentStore` on every exit/return path in `agent.ts`, since `process.exit()` skips pending `finally` blocks.
- Add a bounded fast-fail timeout around the state-store write (default 10s, overridable via `FUSION_AGENT_CMD_TIMEOUT_MS`) so a genuinely stuck operation fails fast with a clear error and non-zero exit instead of hanging.
- Add regression tests covering process-exit/store-closing behavior and update CLI reference docs.
- Add changeset for the patch release.

Files changed:
 .changeset/fn-7704-agent-cmd-hang-fix.md           |   7 +
 docs/cli-reference.md                              |   3 +
 .../commands/__tests__/agent-process-exit.test.ts  | 114 +++++++++++
 packages/cli/src/commands/__tests__/agent.test.ts  | 111 +++++++++-
 packages/cli/src/commands/agent.ts                 | 223 ++++++++++++++++-----
 packages/cli/src/project-context.ts                |  44 ++++
 6 files changed, 444 insertions(+), 58 deletions(-)

Fusion-Task-Id: FN-7704
Fusion-Task-Lineage: 4679d1a0-3ab8-48ce-86b7-5919bba805fb
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-08 23:39:34 -07:00
gsxdsm
7cb76669db fix: resolve 3 staff-engineer review findings from #1957 (init_error mislabel, unbounded off-screen polling, duplicate toasts) (#1960)
## Summary

A Staff Engineer pre-landing review (Greptile/CodeRabbit) on #1957
(merged) flagged four structural issues. This PR fixes the three that
were confirmed still present on `main`; the fourth (an unregistered-rule
`eslint-disable-next-line react-hooks/exhaustive-deps` comment) was
already fixed in #1957's second commit before merge and needed no
further change.

1. **`resolvePluginRuntime()` mislabeled "found but failed to init" as
`not_found`.** When a `runtimeHint` plugin registration is found but
`pluginContext`/`createRuntimeContext(...)` comes back falsy, the
resolver returned `reason: "not_found"` — indistinguishable from "never
registered" — defeating the point of a distinct `FallbackReason`. Now
returns `reason: "init_error"`. Updated the existing test that wrongly
asserted `"not_found"` for this path, and added a new test asserting all
three reachable `FallbackReason` values (`not_found`, `init_error`,
`factory_error`) are pairwise distinct.

2. **`ActiveAgentsPanel.tsx`/`AgentsView.tsx` hardcoded
`isInViewport={true}`.** Every agent card (live-agent header, board
card, list card) polled the runtime-fallback endpoint every 30s forever,
even scrolled off-screen — unlike `TaskCard.tsx`'s correct
`IntersectionObserver`-gated pattern. Both files now thread a real
`IntersectionObserver`-backed viewport signal into
`RuntimeFallbackBadge`. Added regression tests proving polling stops
once a badge instance's `isInViewport` transitions to `false` and
resumes once it goes back to `true` (desktop + a mobile-breakpoint
variant), plus verified via `tsc --noEmit` for `@fusion/dashboard`.

3. **Toast dedupe was per-hook-instance, not shared.**
`useRuntimeFallbackStatus`'s `lastToastedEventIdRef` was a local
`useRef`, so the same task rendered simultaneously in two card surfaces
(e.g. `ActiveAgentsPanel` + `AgentsView`) fired two separate toasts for
one fallback event. Dedupe now lives in module-level shared state (a
bounded `Map` keyed by `taskId:eventId`, FIFO-evicted past 500 entries)
so a fallback event toasts exactly once across every
simultaneously-mounted badge instance for the same task. Added a
cross-instance regression test mounting two badges for the same
`taskId`/`eventId` and asserting exactly one toast fires.

## Test evidence

- `pnpm --filter @fusion/engine exec vitest run
src/__tests__/runtime-resolution.test.ts --reporter=dot` — 25/25 pass
- `pnpm --filter @fusion/dashboard exec vitest run
app/components/__tests__/RuntimeFallbackBadge.test.tsx --reporter=dot` —
11/11 pass
- `pnpm --filter @fusion/dashboard run typecheck` — clean
- `pnpm --filter @fusion/engine run typecheck` — clean

## Scope

Isolated 6-file diff on top of current `main`
(`packages/engine/src/runtime-resolution.ts`,
`packages/engine/src/__tests__/runtime-resolution.test.ts`,
`packages/dashboard/app/hooks/useRuntimeFallbackStatus.ts`,
`packages/dashboard/app/components/ActiveAgentsPanel.tsx`,
`packages/dashboard/app/components/AgentsView.tsx`,
`packages/dashboard/app/components/__tests__/RuntimeFallbackBadge.test.tsx`).
No behavior outside the three findings above was touched.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- The desktop dashboard now supports plugin-backed runtime features,
improving how plugin-enabled workflows are loaded and run.
- Agent cards now pause background fallback polling when they’re
off-screen, helping the dashboard feel smoother and more responsive.

- **Bug Fixes**
- Improved runtime fallback handling so missing runtimes and
initialization failures are reported more accurately.
- Toast notifications are now better deduplicated, reducing repeated
alerts when multiple views show the same fallback state.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-08 15:07:56 -07:00
gsxdsm
64d4bb753a FN-7690: fix custom-provider anthropic-compatible apiType resolution
Reconciles a naming drift where resolveApiType() mapped anthropic-compatible custom providers to an unregistered pi-ai api key, causing streaming failures.

- resolveApiType() now maps anthropic-compatible to "anthropic-messages" (was "anthropic"), matching pi.ts's resolveCustomProviderApiType and the built-in Anthropic provider config
- Added FNXC:CustomProviders comment documenting why anthropic-messages is the only key pi-ai's ModelRegistry actually registers
- Added/updated regression tests in custom-provider-registry.test.ts and provider-registration.test.ts
- Added changeset (patch) documenting the fix

Files changed:
 .changeset/fn-7690-apitype-resolver-reconcile.md    |  7 +++++++
 packages/cli/src/commands/__tests__/custom-provider-registry.test.ts | 21 ++++++++++++++++++---
 packages/engine/src/__tests__/provider-registration.test.ts | 20 ++++++++++++++++++++
 packages/engine/src/custom-provider-registry.ts     | 15 ++++++++++++++-
 4 files changed, 59 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-7690

Fusion-Task-Lineage: 461c340f-bc29-44a2-b8ec-19f0b03224d7

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-08 13:06:37 -07:00
ddonaldson130
c3c726cff4 fix(FUX-039): return init_error for found-but-uninitialized plugin runtime
Co-authored-by: Fusion <noreply@runfusion.ai>
2026-07-08 12:29:14 -04:00
gsxdsm
dd9fa2d3cb FN-7661: expose removeLineageReferences on fn_task_archive/fn_task_delete
Fixes fn_task_archive and fn_task_delete rejecting tasks still referenced as a lineage parent, with no tool-exposed way to clear that reference.

- Add optional removeLineageReferences boolean param to fn_task_archive and fn_task_delete tool schemas, forwarded to store.archiveTask/store.deleteTask
- Update tool descriptions and prompt guidelines to advertise the recovery path (removeLineageReferences:true) when a lineage-parent block occurs
- Add task-lineage-unlink.test.ts covering the new parameter behavior
- Document the change in docs/storage.md
- Add changeset (@runfusion/fusion minor, category: fix)

Files changed:
 .changeset/fn-7661-lineage-unlink-tools.md         |   7 +
 docs/storage.md                                    |   1 +
 packages/cli/src/__tests__/task-lineage-unlink.test.ts | 199 +++++++++++++++++++++
 packages/cli/src/extension.ts                      |  28 ++-
 4 files changed, 232 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7661

Fusion-Task-Lineage: 414c046c-43df-4995-85a5-ff00b345de50

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-08 00:33:02 -07:00
gsxdsm
4e8c621e9c FN-7641: fix cards stranded after out-of-band/workspace merges by allowing proven-merge rehome
Fixes a state-machine bug family where cards got stranded after out-of-band or workspace merges landed: store.moveTask now allows a proven-merge recoveryRehome to cross legacy columns (e.g. todo→done), and nodeId='end' finalize no longer silently no-ops — it finalizes on durable merge proof or returns an explicit error, consistently across the dashboard route, the CLI task-update tool, and store.updateTask.

- packages/core/src/store.ts: allow proven-merge recoveryRehome moves across legacy columns (e.g. todo→done) instead of rejecting them
- packages/core/src/node-override-guard.ts: nodeId='end' finalize now checks for durable merge proof and returns an explicit error instead of silently no-op'ing
- packages/dashboard/src/routes/register-task-workflow-routes.ts: dashboard workflow route surfaces the new explicit finalize error/behavior
- packages/cli/src/extension.ts: CLI task-update tool surfaces the same explicit finalize error/behavior
- docs/task-management.md: documented the updated finalize/rehome behavior
- Added regression tests across core (node-override-guard, store-movement, task-node-override), dashboard (register-task-workflow-routes.nodeid-finalize), engine (merger-merge-lifecycle), and CLI (extension) covering the stranded-card invariant
- Added changeset for @runfusion/fusion (patch)

Files changed:
 .changeset/fn-7641-stranded-cards-after-merge.md   |  7 ++
 docs/task-management.md                            |  2 +
 packages/cli/src/__tests__/extension.test.ts       | 59 ++++++++++++++
 packages/cli/src/extension.ts                      | 10 +++
 .../core/src/__tests__/node-override-guard.test.ts | 93 +++++++++++++++++++++
 packages/core/src/__tests__/store-movement.test.ts | 94 ++++++++++++++++++++++
 .../core/src/__tests__/task-node-override.test.ts  | 73 +++++++++++++++++
 packages/core/src/node-override-guard.ts           | 69 +++++++++++++++-
 packages/core/src/store.ts                         | 69 +++++++++++++++-
 ...er-task-workflow-routes.nodeid-finalize.test.ts | 90 +++++++++++++++++++++
 .../src/routes/register-task-workflow-routes.ts    | 10 +++
 .../src/__tests__/merger-merge-lifecycle.test.ts   | 58 +++++++++++++
 12 files changed, 631 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7641

Fusion-Task-Lineage: 48ea7851-ee68-48f1-92f9-302d0da5acff

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-07 22:06:20 -07:00
gsxdsm
26f22861fa FN-7637: port bundled-plugin auto-install into @fusion/core for the desktop runtime
Move the host-agnostic bundled-plugin auto-install logic (manifest loading, entry-path
resolution, install/update/enable flow) out of the CLI package into @fusion/core so the
desktop embedded runtime can auto-install bundled runtime plugins without depending on
the CLI package; the CLI module becomes a thin adapter that supplies its own bundle-dir
resolution to the shared helper.

- Add packages/core/src/plugins/bundled-plugin-install.ts with the shared, host-agnostic
  ensureBundledPluginInstalled / ensureBundledDependencyGraphPluginInstalled /
  ensureBundledCursorRuntimePluginInstalled implementation and BUNDLED_PLUGIN_IDS/
  isBundledPluginId/resolvePluginEntryPath, exported from @fusion/core's index.
- Slim packages/cli/src/plugins/bundled-plugin-install.ts to a CLI-specific
  candidate-bundle-dir resolver that delegates to @fusion/core and re-exports the same
  public surface dashboard.ts/serve.ts/daemon.ts already depend on.
- Remove the now-redundant packages/cli/src/plugins/__tests__/resolve-plugin-entry-path-sync.test.ts
  (coverage moved with the implementation to @fusion/core).
- Add packages/desktop/src/bundled-plugin-dirs.ts to resolve each bundled plugin's staged
  package directory via import.meta.resolve, mirroring the CLI's dist/plugins/<id> resolver.
- Wire local-runtime.ts and local-server.ts to call ensureBundledPluginInstalled before
  loadAllPlugins() and expose a lazy-install callback for PUT /api/plugins/:id/settings,
  mirroring the CLI dashboard command's startup auto-install pass.
- Update docs/PLUGIN_AUTHORING.md to describe the shared bundled-plugin-install location.

Files changed:
 docs/PLUGIN_AUTHORING.md                           |  11 +
 .../__tests__/bundled-plugin-install.test.ts       | 619 ++-------------------
 .../resolve-plugin-entry-path-sync.test.ts         |  97 ----
 packages/cli/src/plugins/bundled-plugin-install.ts | 250 +--------
 packages/core/src/index.ts                         |   8 +
 .../__tests__/bundled-plugin-install.test.ts       | 391 +++++++++++++
 .../core/src/plugins/bundled-plugin-install.ts     | 186 +++++++
 .../src/__tests__/bundled-plugin-dirs.test.ts      |  59 ++
 .../desktop/src/__tests__/local-runtime.test.ts    | 183 +++++-
 .../desktop/src/__tests__/local-server.test.ts     |  96 +++-
 packages/desktop/src/bundled-plugin-dirs.ts        |  61 ++
 packages/desktop/src/local-runtime.ts              |  66 ++-
 packages/desktop/src/local-server.ts               |  36 +-
 13 files changed, 1171 insertions(+), 892 deletions(-)

Fusion-Task-Id: FN-7637

Fusion-Task-Lineage: 953c5b82-a079-4600-b3af-45c974cd5014

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-07 22:06:16 -07:00
gsxdsm
fe5a595984 FN-7622: unify desktop and CLI provider seeding to fix truncated provider list
The Electron desktop app's in-process dashboard server skipped the CLI's provider seeding sequence, so /api/providers and /api/models returned a truncated catalog (missing built-in API-key providers and user customProviders[]) compared to the identical config on the web build.

- Move provider-auth.ts and custom-provider-registry.ts from @fusion/cli into @fusion/engine as the single shared implementation
- Add engine/src/provider-registration.ts exposing seedDashboardProviders(), mirroring the CLI's exact startup order (built-in Zai provider registration -> wrapAuthStorageWithApiKeyProviders -> model merge/refresh -> registerCustomProviders -> settings:updated resubscription)
- Update desktop/src/local-runtime.ts and local-server.ts to call the shared seedDashboardProviders() helper instead of constructing a raw authStorage/modelRegistry
- Convert packages/cli/src/commands/provider-auth.ts and custom-provider-registry.ts into re-export shims preserving unchanged observable behavior
- Add engine/src/__tests__/provider-registration.test.ts and expand desktop local-runtime/local-server tests to cover the shared seeding path
- Add changeset for @runfusion/fusion (patch)

Files changed:
 .changeset/fn-7622-desktop-provider-parity.md      |   7 +
 .../cli/src/commands/custom-provider-registry.ts   | 122 +----
 packages/cli/src/commands/provider-auth.ts         | 517 +--------------------
 .../desktop/src/__tests__/local-runtime.test.ts    |  93 ++++
 .../desktop/src/__tests__/local-server.test.ts     |  62 ++-
 packages/desktop/src/local-runtime.ts              |  33 +-
 packages/desktop/src/local-server.ts               |  21 +-
 .../src/__tests__/provider-registration.test.ts    | 192 ++++++++
 packages/engine/src/custom-provider-registry.ts    | 117 +++++
 packages/engine/src/index.ts                       |  18 +
 packages/engine/src/provider-auth.ts               | 513 ++++++++++++++++++++
 packages/engine/src/provider-registration.ts       | 105 +++++
 12 files changed, 1172 insertions(+), 628 deletions(-)

Fusion-Task-Id: FN-7622
Fusion-Task-Lineage: fb6fbbf3-745e-4623-b7af-11471e13f138
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-07 22:04:51 -07:00
gsxdsm
ca8447304f FN-7619: guard fn_task_attach against worktree boundary bypass
Add a path-containment check to fn_task_attach so it can no longer read files outside the task's worktree via traversal or absolute paths.

- Resolve the requested path and confine it to ctx.cwd (the task worktree) before any readFile call, rejecting "../" traversal, absolute paths, and other boundary-escaping inputs
- Add regression tests in extension.test.ts covering traversal/absolute-path attack vectors
- Add changeset (patch, category: security) documenting the fix

Files changed:
 .changeset/fn-7619-attach-boundary.md        |   7 ++
 packages/cli/src/__tests__/extension.test.ts | 133 ++++++++++++++++++++++++++-
 packages/cli/src/extension.ts                |  23 ++++-
 3 files changed, 161 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7619
Fusion-Task-Lineage: d35d9218-d678-4989-945d-6c1e1a322c5c
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-06 19:03:07 -07:00
gsxdsm
203f879c8f FN-7611: respect workflow intake column on task creation
Task creation surfaces stopped hardcoding column:"triage", so new tasks now land in the selected-or-default workflow's resolved intake column instead of always jumping to Planning/triage.

- Removed hardcoded column:"triage" override in engine's createTaskCreateTool (fn_task_create), letting TaskStore.createTask resolve the landing column from the workflow's intake-trait column.
- Removed the equivalent hardcoded override in the pi extension's fn_task_create, and updated its response text to echo the actual landing column instead of a fixed "Column: triage" string.
- Fixed signal-route, GitHub-import, and planning-subtask-route task creation to stop forcing column when no workflowId is given (or, for planning subtask routes, even when one is provided).
- Custom workflows with a non-triage intake column (e.g. Inbox) now correctly capture new cards inert until released, while the default builtin:coding workflow still resolves to "triage" byte-identically.
- Added regression coverage (agent-tools-intake-column.test.ts, extension-workflow-tools.test.ts) and a patch changeset documenting the fix.

Files changed:
 .changeset/fn-7611-intake-column.md                |   7 ++
 .../src/__tests__/extension-workflow-tools.test.ts |  70 +++++++++++
 packages/cli/src/extension.ts                      |  10 +-
 .../src/__tests__/register-signal-routes.test.ts   |   8 +-
 .../dashboard/src/__tests__/routes-github.test.ts  |   2 -
 .../dashboard/src/routes/register-git-github.ts    |  16 ++-
 .../src/routes/register-planning-subtask-routes.ts |  24 +++-
 .../dashboard/src/routes/register-signal-routes.ts |   8 +-
 .../__tests__/agent-tools-intake-column.test.ts    | 138 +++++++++++++++++++++
 packages/engine/src/__tests__/agent-tools.test.ts  |   1 -
 packages/engine/src/agent-tools.ts                 |  21 +++-
 11 files changed, 288 insertions(+), 17 deletions(-)

Fusion-Task-Id: FN-7611

Fusion-Task-Lineage: daf7f755-b1c7-4859-b74f-f15593d5e79e

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-06 19:03:07 -07:00
gsxdsm
60081fb1f4 FN-7610: route workspace-mode tasks around PR-merge auto-merge strategy
Fixes workspace-mode (workspaceWorktrees) tasks failing auto-merge under mergeStrategy=pull-request, where processPullRequestMergeTask threw "could not determine repository" because the workspace root is a container of independent git sub-repos, not itself a git repo.

- Hoist an isWorkspaceTask check in ProjectEngine's merge dispatch (project-engine.ts) before the mergeStrategy branch, so workspace tasks always fall through to the existing direct/landWorkspaceTask path regardless of configured mergeStrategy.
- Add processPullRequestMergeTask and syncGroupPrCallback defense-in-depth guards (task-lifecycle.ts) that throw the new named WorkspaceTaskMergeError if a workspace task ever reaches the PR-merge path.
- Add engine tests covering multi-repo, single-repo, and zero-commit no-op workspace tasks under mergeStrategy=pull-request, plus a non-regression test for the legacy single-worktree PR path.
- Add CLI tests asserting the new guards throw WorkspaceTaskMergeError.
- Add a patch changeset describing the fix.

Files changed:
 .changeset/fn-7610-workspace-pr-merge-routing.md   |   7 ++
 .../src/commands/__tests__/task-lifecycle.test.ts  |  56 +++++++++
 packages/cli/src/commands/task-lifecycle.ts        |  33 ++++-
 .../engine/src/__tests__/project-engine.test.ts    | 140 +++++++++++++++++++++
 packages/engine/src/project-engine.ts              |  18 ++-
 5 files changed, 252 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7610
Fusion-Task-Lineage: 31768b77-d9a9-4a79-a055-bbc6b228a1c4
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-06 19:03:06 -07:00
gsxdsm
196abb5af9 FN-7576: delegate anthropic-subscription getApiKey to engine authStorage
Reads for the anthropic-subscription provider now delegate to the real engine authStorage so expired OAuth tokens are refreshed instead of silently failing.

- mergeAuthStorageReads getApiKey("anthropic-subscription") now calls target.getApiKey(providerId) directly, triggering the engine's refresh-token HTTP round trip, instead of a local static Date.now() >= credential.expires check
- Falls back to the read-only fallback storages' local resolution only when the primary engine call yields no key
- Added regression tests exercising the wrapper directly against the engine delegation and fallback behavior
- Added a patch changeset documenting the fix for @runfusion/fusion

Files changed:
 .changeset/fn-7576-cli-wrapper-subscription-getapikey-delegation.md               |   7 +
 packages/cli/src/commands/__tests__/provider-auth.test.ts                         | 148 +++++++++++++++++++++
 packages/cli/src/commands/provider-auth.ts                                        |  12 +-
 3 files changed, 166 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7576

Fusion-Task-Lineage: 31e495ec-8487-468b-9b80-36e8d0f53806

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 11:31:46 -07:00
gsxdsm
71dfd3aeca FN-7568: rename CLI release binary assets to fn-cli-<platform>
Renames the downloadable GitHub Release CLI binaries so they don't collide with other well-known fn-named tools on a user's PATH; the local dev binary name is unchanged.

- Update binaryNameForTarget in packages/cli/build.ts to emit fn-cli-<suffix> instead of fn-<suffix> (local dev binary stays fn/fn.exe)
- Update release.yml and test-release.yml build matrices to use fn-cli-linux-x64, fn-cli-linux-arm64, fn-cli-darwin-arm64, fn-cli-windows-x64.exe
- Update build-exe-cross, ci-workflow, and package-config tests to assert the new fn-cli-<platform> asset names
- Add changeset documenting the release-asset rename

Files changed:
 .changeset/fn-7568-fn-cli-release-asset.md         |  7 +++++++
 .github/workflows/release.yml                      |  8 ++++----
 .github/workflows/test-release.yml                 |  8 ++++----
 packages/cli/build.ts                              | 10 ++++++++--
 packages/cli/src/__tests__/build-exe-cross.test.ts | 14 +++++++-------
 packages/cli/src/__tests__/ci-workflow.test.ts     |  8 ++++----
 packages/cli/src/__tests__/package-config.test.ts  | 10 +++++-----
 7 files changed, 39 insertions(+), 26 deletions(-)

Fusion-Task-Id: FN-7568

Fusion-Task-Lineage: 1c04d763-5e2f-43e3-84b7-df8dcff8467f

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 11:31:45 -07:00
gsxdsm
36bd74e337 FN-7532: stamp branch group merge attribution
Ensure shared branch group members record merge attribution so completion checklists reflect real landed state.

- Route AI merges through branch-group merge routing before selecting the integration target.
- Stamp mergeDetails merge target fields for both landed and no-op finalize paths.
- Record shared-group member landing state and best-effort managed PR checklist sync after AI merges.
- Cover dashboard, CLI lifecycle, and merger scenarios for accurate branch-group completion counts.

Files changed:
 .changeset/fn-7532-branch-group-completion.md      |  7 ++
 docs/dashboard-guide.md                            |  2 +
 .../src/commands/__tests__/task-lifecycle.test.ts  | 29 +++++++
 .../src/__tests__/routes-branch-groups.test.ts     | 45 +++++++++++
 packages/engine/src/__tests__/merger-ai.test.ts    | 68 +++++++++++++++-
 packages/engine/src/merger-ai.ts                   | 90 +++++++++++++++++++++-
 6 files changed, 235 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-7532

Fusion-Task-Lineage: cd65c18a-f1ad-4f8b-99b2-2e61e233f042

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-04 21:28:15 -07:00
gsxdsm
b545083249 FN-7530: isolate flaky dist-barrel extension test
Restore the stable extension suite by quarantining only the dist-barrel recompilation case.

- Move the built @fusion/core dist-barrel extension test into its own file.
- Re-admit extension.test.ts while keeping the isolated dist-barrel file quarantined.
- Update the quarantine ledger and velocity baseline to reflect the narrowed quarantine.

Files changed:
 docs/test-velocity-baseline.md                     |  10 +-
 .../src/__tests__/extension-dist-barrel.test.ts    | 230 +++++++++++++++++++++
 packages/cli/src/__tests__/extension.test.ts       | 103 +--------
 packages/cli/vitest.config.ts                      |   5 +-
 scripts/lib/test-quarantine.json                   |   4 +-
 5 files changed, 247 insertions(+), 105 deletions(-)

Fusion-Task-Id: FN-7530

Fusion-Task-Lineage: 7b07540f-689b-4133-b590-a39427095397

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-04 14:04:29 -07:00
gsxdsm
1a5f7e3b52 fix: add missing vitest aliases and mock export for CI test failures
Three root causes behind CI run 28695362549 failures:

1. droid-cli: 8 tests fail with 'Failed to resolve entry for
   @fusion-plugin-examples/droid-runtime'. The droid-cli vitest config
   had no source alias for the droid-runtime plugin, so Vite tried to
   resolve non-existent dist/ exports.

2. CLI: multiple tests fail with 'Failed to resolve entry for
   @fusion-plugin-examples/roadmap'. The CLI vitest config was missing
   source aliases for the roadmap plugin (., /server, /roadmap-suggestions).

3. CLI: 73 bin.test.ts tests fail with 'No runTaskImportFromGitLab export
   is defined on the ../commands/task.js mock'. The GitLab import command
   was added to bin.ts and task.ts but the bin.test.ts mock was not
   updated to include the new export.
2026-07-03 22:40:36 -07:00
gsxdsm
d97e66a657 fix(desktop): sync lockfile, gate Windows GPU flags, document desktop hardening
- Regenerate pnpm-lock.yaml for the new electron@^33.4.11 CLI dependency so
  --frozen-lockfile stops failing every PR-check job.
- Gate the GPU/sandbox-disabling Electron flags (--no-sandbox, --disable-gpu,
  etc.) to Windows only via os.platform(); applying them on macOS/Linux was a
  security and rendering regression. This also resolves the unused os import
  that failed lint.
- Add FNXC comments for the Windows GPU flags, desktop user-data isolation, and
  CLI dashboard-server reuse per project comment convention.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 08:13:06 -07:00
gsxdsm
6d7715fe9e Merge branch 'main' into desktop-release-issues-report 2026-07-03 07:48:51 -07:00
ddonaldson130
4bad0920e2 docs(desktop): field report for Windows desktop release issues
Add reports/desktop-release-issues-2026-07-03.md documenting the
regressions observed in the Fusion 0.52.0 Windows desktop release,
including:

- fusion desktop fails to launch because electron is a devDependency
- native launcher walks ancestor dirs and fails on unrelated workspace JSON
- Manage Projects opens Settings instead of overview
- Windows Terminal Help version dialogs on dashboard load
- packaged preload.cjs missing in unpacked release layout
- port collisions and dashboard/gateway drift on Windows
- GPU/sandbox rendering instability on Windows Electron
- isolated user-data path needed
- CLI desktop command not reusing an already-running dashboard server

Also include the two experimental mitigations we applied locally:
- disable GPU/sandbox Electron flags in desktop.ts
- skip embedded local runtime when FUSION_SERVER_PORT is already set

These changes are intended as supporting evidence and starting points
for the Fusion team, not as a final fix.
2026-07-03 03:36:10 -04:00
gsxdsm
96b2df115e fix(desktop): heal launch-mode/shell split-brain hanging Windows local runtime + fix Windows root build (#1878)
## Windows: local runtime hung at "Starting local Fusion runtime…"

### Root cause
Desktop startup had two independent persisted sources of truth that
could disagree:
- `desktop-launch-mode.json` — decides whether **main** *starts* the
embedded local runtime
- `shell-connections.json` (`desktopMode`) — decides whether the
renderer **launch gate** *waits* for it

`shell:setDesktopMode` persists shell settings **before** the fallible
`startLocalRuntimeOnce()` / `saveDesktopLaunchMode()`. So a first
"local" selection whose runtime start threw or was interrupted left
`shell=local` / `launch-mode=choose` **permanently**. Every later launch
then sat at "Starting local Fusion runtime…" polling a runtime nobody
started → 30s timeout.

### Fix (defense in depth) — `78f0bc31`
- `initializeApp` reconciles: a completed shell `local` selection is
authoritative → heals the launch-mode file and starts the runtime.
- `onDesktopModeChange` / `onDesktopLaunchModeChange` persist
launch-mode **before** the fallible start so it can't re-desync.
- `DesktopLaunchGate` no longer assumes main started the runtime — if
it's not running/starting it actively `setDesktopMode("local")` before
polling.
- Env-gated startup trace (`FUSION_STARTUP_TRACE`) so packaged builds
(which log nothing) are diagnosable.
- Regression tests: split-brain → runtime starts + file heals;
agreement-on-choose → no start.

**Verified end-to-end under real Electron 35 / Node 22.16**: from the
exact split-brain state the runtime now reaches `RUNNING` and the
launch-mode file heals.

### Also: Windows root-build breakages — `bd24bd4c8`
- `scripts/build-workspace.mjs` "run as main" guard compared
`import.meta.url` to `` `file://${process.argv[1]}` ``, which never
matches on Windows → root `pnpm build` silently no-opped (exit 0, no
dist). Now uses `pathToFileURL(process.argv[1]).href`.
- `spawn('pnpm', …)` without `shell:true` (ENOENT on Windows) in
`build-workspace.mjs` and `packages/cli/tsup.config.ts` → pass `shell`
on win32.

### Notes
- `@fusion/desktop` and `@fusion/dashboard` are private → no changeset.
- Build the Windows installer via the `desktop-windows` workflow
(`electron-builder --projectDir deploy`); local `pnpm deploy` staging
hits an unrelated directory-rename race on managed-workspace
filesystems.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added optional desktop runtime startup tracing (enabled via
environment variable).
* **Bug Fixes**
* Improved local desktop handoff to prevent reload loops and navigate
directly to the embedded local runtime.
* Added “split-brain” healing between persisted launch mode and shell
settings.
* Prevented auto-registration of runtime root/CWD during
desktop/dashboard startup.
* Improved Windows compatibility for CLI/workspace command spawning and
npm install process handling.
* **Tests**
* Expanded local/Electron integration, navigation, and onboarding
regression coverage; improved async flushing for more reliable
initialization.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-03 00:17:58 -07:00
gsxdsm
b331f26f3d fix(desktop,cli): never auto-create a project in home/cwd; onboard instead
The desktop embedded runtime auto-registered its runtime root (the user's HOME directory) as a
project on first launch, and bare `fusion` / `fn` / `fn dashboard` / `fusion dashboard`
auto-registered the CWD as a project. Both silently created a "cwd-mode" project the operator
never chose and dropped them onto a board for it.

- Desktop: replace ensureDesktopRuntimeProject (which registered home) with
  resolveDesktopRuntimePrimaryProject, which only PICKS an already-registered project as the
  primary engine target and registers nothing. With no projects the server starts engine-less
  (createServer's engine is optional) and the dashboard shows its onboarding empty state.
  Applied to both the primary (local-runtime) and legacy (local-server) desktop server paths.
- CLI dashboard command: ensureCwdProjectRegistered now runs with autoRegister:false, so it uses
  the CWD project only if already registered, else starts with none and the dashboard onboards.
  (serve/daemon keep their existing --no-auto-register flag; the CLI `desktop` launcher unchanged.)

Verified: with zero projects the embedded server starts, /api/health -> 200, /api/projects -> [],
/ serves the client. Unit test asserts resolveDesktopRuntimePrimaryProject registers nothing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 20:16:42 -07:00
gsxdsm
dfb6e5270d FN-7443: add bundled Linear import plugin
Add a plugin-owned Linear importer that creates Fusion tasks from Linear issues.

- Add the fusion-plugin-linear-import package with settings, Linear GraphQL client, import routes, tools, and dashboard UI.
- Bundle and register the Linear import plugin in the CLI and dashboard plugin view registry.
- Document bundled plugin authoring details and cover duplicate detection, routes, tools, UI, and packaging with tests.

Files changed:
 .changeset/fn-7443-linear-import-plugin.md         |   7 +
 docs/PLUGIN_AUTHORING.md                           |   7 +
 docs/task-management.md                            |   2 +
 packages/cli/src/__tests__/bundle-output.test.ts   |  22 ++
 .../__tests__/bundled-plugin-install.test.ts       |  29 +++
 packages/cli/src/plugins/bundled-plugin-install.ts |   1 +
 .../cli/src/plugins/staged-bundled-plugin-ids.ts   |   1 +
 packages/cli/tsup.config.ts                        |   8 +
 .../__tests__/registerBundledPluginViews.test.tsx  |   9 +-
 .../app/plugins/registerBundledPluginViews.ts      |  18 ++
 .../app/types/plugin-dashboard-views.d.ts          |   9 +
 .../src/__tests__/routes-plugin-registry.test.ts   |   5 +
 .../runtime-plugin-alias-regression.test.ts        |  12 +
 packages/dashboard/src/registry-manifest.json      |  10 +
 packages/dashboard/vite.config.ts                  |   8 +
 packages/dashboard/vitest.config.ts                |   8 +
 plugins/fusion-plugin-linear-import/README.md      |  75 ++++++
 plugins/fusion-plugin-linear-import/manifest.json  |  48 ++++
 plugins/fusion-plugin-linear-import/package.json   |  38 +++
 .../scripts/copy-css.mjs                           |  11 +
 .../src/LinearImportView.css                       | 167 +++++++++++++
 .../src/LinearImportView.tsx                       | 263 +++++++++++++++++++++
 .../src/__tests__/LinearImportView.test.tsx        | 124 ++++++++++
 .../src/__tests__/import-linear.test.ts            |  78 ++++++
 .../src/__tests__/linear-client.test.ts            |  81 +++++++
 .../src/__tests__/routes.test.ts                   |  90 +++++++
 .../src/__tests__/tools.test.ts                    |  79 +++++++
 .../src/dashboard-interop.d.ts                     |  13 +
 .../src/dashboard-view.tsx                         |  10 +
 .../src/import-linear.ts                           | 154 ++++++++++++
 plugins/fusion-plugin-linear-import/src/index.ts   |  45 ++++
 .../src/linear-client.ts                           | 247 +++++++++++++++++++
 plugins/fusion-plugin-linear-import/src/routes.ts  | 149 ++++++++++++
 .../fusion-plugin-linear-import/src/settings.ts    |  68 ++++++
 plugins/fusion-plugin-linear-import/src/tools.ts   | 138 +++++++++++
 plugins/fusion-plugin-linear-import/tsconfig.json  |  14 ++
 .../fusion-plugin-linear-import/vitest.config.ts   |  40 ++++
 pnpm-lock.yaml                                     |  40 ++++
 pnpm-workspace.yaml                                |   1 +
 39 files changed, 2128 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7443
Fusion-Task-Lineage: a016a9d4-84a4-4a0b-b9b6-b9a2886da49a
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-02 14:31:16 -07:00
gsxdsm
91fb53f3c7 FN-7440: add agent update tool
Add a Fusion extension tool for updating existing agent configuration in place.

- Register fn_agent_update with editable agent fields, validation, and non-ephemeral guards.
- Enforce org-scoped authorization for agent callers and privileged manager-clearing semantics for operators.
- Cover update success, hierarchy denial, cycle prevention, and runtime/instruction edits in extension tests.
- Document the new tool in agent and Fusion skill references and add a published package changeset.

Files changed:
 .changeset/fn-7440-agent-update-tool.md            |   7 +
 docs/agents.md                                     |  21 +-
 package.json                                       |   1 +
 packages/cli/skill/fusion/SKILL.md                 |   2 +-
 .../cli/skill/fusion/references/extension-tools.md |  21 ++
 .../skill/fusion/references/fusion-capabilities.md |   1 +
 .../src/__tests__/extension-agent-update.test.ts   | 351 +++++++++++++++++++++
 packages/cli/src/extension.ts                      | 230 ++++++++++++++
 pnpm-lock.yaml                                     |   1 +
 9 files changed, 628 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-7440

Fusion-Task-Lineage: a6f4c928-5a63-4cf1-aa0b-4e38b536e965

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-02 13:16:07 -07:00
gsxdsm
c49a933fb0 FN-7428: add GitLab tracking coverage and reconciliation support
Add GitLab tracking persistence, analytics, and reconciliation coverage across core, dashboard, and CLI paths.

- Store GitLab tracking and closed-at metadata when importing issues and merge requests from CLI, extension tools, and dashboard routes.
- Add GitLab source-issue analytics, Command Center GitLab signal surfaces, CSV export fields, and a closed-at backfill route.
- Cover GitLab tracking storage, reconciliation, CLI imports, dashboard import UI, route behavior, and Command Center signals with focused tests.

Files changed:
 .changeset/fn-7428-gitlab-import-tracking.md       |   7 +
 .../__tests__/extension-gitlab-tracking.test.ts    | 140 ++++++++++++
 .../__tests__/task-command-gitlab-import.test.ts   |  18 +-
 packages/cli/src/commands/task.ts                  |   1 +
 packages/cli/src/extension.ts                      |   2 +-
 .../src/__tests__/gitlab-issue-analytics.test.ts   | 243 +++++++++++++++++++++
 .../__tests__/gitlab-source-issue-storage.test.ts  | 128 +++++++++++
 .../store-gitlab-tracking-reconcile.test.ts        | 125 +++++++++++
 packages/core/src/gitlab-issue-analytics.ts        | 227 +++++++++++++++++++
 packages/core/src/index.ts                         |   8 +
 packages/core/src/store.ts                         |  21 +-
 .../__tests__/GitHubImportModal.test.tsx           |  46 ++++
 .../components/__tests__/gitlabTracking.test.tsx   |  43 ++++
 .../components/command-center/CommandCenter.tsx    |   5 +
 .../components/command-center/areas/GitlabArea.tsx | 126 +++++++++++
 .../areas/__tests__/areas.gitlab-signals.test.tsx  |  83 +++++++
 .../gitlab-source-issue-reconciler.test.ts         | 187 ++++++++++++++++
 .../register-command-center-routes.test.ts         |  52 +++++
 .../__tests__/register-git-gitlab.backfill.test.ts | 116 ++++++++++
 .../dashboard/src/__tests__/routes-gitlab.test.ts  |  59 +++--
 packages/dashboard/src/command-center-csv.ts       |  21 ++
 .../src/gitlab-source-issue-reconciler.ts          | 104 +++++++++
 packages/dashboard/src/gitlab.ts                   |  16 +-
 .../src/routes/register-command-center-routes.ts   |  25 +++
 packages/dashboard/src/routes/register-gitlab.ts   |  29 +++
 25 files changed, 1800 insertions(+), 32 deletions(-)

Fusion-Task-Id: FN-7428

Fusion-Task-Lineage: 7b0ebb5c-c6e7-42a9-a339-b2dd1d4e263a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-02 12:34:35 -07:00
gsxdsm
865dec235b FN-7424: add GitLab task imports
Adds GitLab-backed task import flows across the CLI, extension, API, and dashboard.

- Add GitLab client normalization, provenance, duplicate detection, and import routes for project issues, group issues, and merge requests.
- Extend the dashboard import modal with a GitLab provider, resource tabs, previews, imported-state detection, and import actions.
- Add CLI and extension task import commands plus usage event/gating classifications and operator documentation.
- Cover GitLab fetch/import behavior with dashboard, CLI, and gating tests.

Files changed:
 .changeset/fn-7424-gitlab-imports.md               |   7 +
 docs/cli-reference.md                              |  11 +-
 docs/gitlab-parity-inventory.md                    |  10 +-
 docs/task-management.md                            |   6 +-
 packages/cli/skill/fusion/SKILL.md                 |   2 +-
 .../cli/skill/fusion/references/extension-tools.md |  60 ++++
 .../skill/fusion/references/fusion-capabilities.md |   6 +
 packages/cli/src/__tests__/extension.test.ts       |   6 +
 .../__tests__/task-command-gitlab-import.test.ts   |  97 ++++++
 packages/cli/src/bin.ts                            |  25 +-
 packages/cli/src/commands/task.ts                  |  58 ++++
 packages/cli/src/extension.ts                      | 106 +++++++
 packages/core/src/__tests__/usage-events.test.ts   |   2 +
 packages/core/src/types.ts                         |   7 +
 packages/core/src/usage-events.ts                  |   3 +
 packages/dashboard/app/api/legacy.ts               |  52 ++++
 .../dashboard/app/components/GitHubImportModal.css |  41 +++
 .../dashboard/app/components/GitHubImportModal.tsx | 143 ++++++++-
 .../__tests__/GitHubImportModal.test.tsx           |  33 ++
 packages/dashboard/src/__tests__/gitlab.test.ts    |  56 ++++
 .../dashboard/src/__tests__/routes-gitlab.test.ts  |  99 ++++++
 packages/dashboard/src/gitlab.ts                   | 334 +++++++++++++++++++++
 packages/dashboard/src/index.ts                    |  15 +
 packages/dashboard/src/routes.ts                   |   2 +
 packages/dashboard/src/routes/register-gitlab.ts   | 192 ++++++++++++
 .../engine/src/__tests__/agent-action-gate.test.ts |   4 +
 .../gating-classifications-provisioning.test.ts    |  13 +-
 .../src/__tests__/gating-classifications.test.ts   |   6 +
 packages/engine/src/gating-classifications.ts      |   9 +
 29 files changed, 1388 insertions(+), 17 deletions(-)

Fusion-Task-Id: FN-7424
Fusion-Task-Lineage: 8012425c-21d5-4b20-adb7-07d2e5aa1cef
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-02 11:38:34 -07:00
gsxdsm
855061db5f fix: harden workflow graph cutover paths and migrate cutover-era tests
Production fixes:
- executor.ts: add safeLogEntry() wrapper so synchronous throws from
  store.logEntry don't abort pause/abort/finalize control flow.
- workflow-authoritative-driver.ts: pass built-in auxiliary custom nodes
  (task-summary nodes, bypassable optional-groups) through as success
  instead of throwing.

Test migrations for graph-native runtime (cherry-picked from closed PR #1869):
- executor-prompt: two-party barrier for global-pause disposal test.
- executor-task-done-invariant: assert merge-node boundary moveTask.
- workflow-graph-merge-region-collapse: updated for merge-region node shapes.
- executor-worktree/worktree-liveness/implicit-task-done-budget: graph-aware.
- CLI extension tests: shared engine-workflow-authoring-mock helper.
- Dashboard/desktop/reliability tests: cutover-aware assertion updates.
2026-07-02 07:32:47 -07:00
gsxdsm
22261b683f FN-7411: prevent task-bound self deletion
Prevent task-bound callers from soft-deleting the task they are currently executing.

- Add a TaskSelfDeleteError guard in TaskStore.deleteTask before mutation or audit emission.
- Pass the current task id through the fn_task_delete audit context so CLI tool calls inherit the store invariant.
- Cover self-delete rejection and cross-task deletion allowance in core and CLI tests.
- Add a patch changeset for the published CLI package.

Files changed:
 .changeset/fn-7411-self-delete-guard.md            |  7 +++
 .../task-delete-allow-resurrection.test.ts         | 48 ++++++++++++++++-
 packages/cli/src/extension.ts                      |  2 +
 .../src/__tests__/store-self-delete-guard.test.ts  | 60 ++++++++++++++++++++++
 packages/core/src/store.ts                         | 22 +++++++-
 5 files changed, 136 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7411

Fusion-Task-Lineage: 50028769-5396-4435-84fb-2ae182315e81

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 23:53:10 -07:00
gsxdsm
40b44e40b9 fix: enforce ephemeralAgentsEnabled across the workflow engine
Add TaskExecutor.blockOuterDispatchWhenEphemeralDisabled, gating all three
workflow dispatch paths (graph / authoritative / work-engine) on
ephemeralAgentsEnabled at the top of execute(). Previously the toggle was
enforced only on the legacy scheduler/EphemeralWorkerManager path — whose
onTaskStart spawn refusal is a fire-and-forget callback that runs after
execution begins — so unassigned tasks reaching execute() off a non-scheduler
path still ran. Unassigned tasks are now re-queued for permanent-agent
assignment; permanent-agent-bound tasks still run. Adds regression coverage
across all three entry points.

Also includes the ephemeralAgentsCanCreateTasks project setting (default on)
gating fn_task_create for ephemeral callers in both the pi extension and the
executor task-worker tool.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 21:31:34 -07:00
Phil Larson
c46d11f0a3 test(cli): keep extension engine mocks current 2026-07-01 16:34:02 -07:00
gsxdsm
e85d25e383 FN-7395: fix packaged desktop launch assets
Fix installed desktop launches so they use packaged runtime assets without parsing caller workspaces.

- Resolve normal desktop launches from packaged CLI desktop assets, with explicit override and dev paths.
- Stage desktop runtime assets into the published CLI package and include them in npm files.
- Route desktop --no-auth into the embedded dashboard server and document installed/dev launch behavior.
- Cover invalid JSON caller directories, missing packaged assets, package contents, and CLI routing in tests.

Files changed:
 .changeset/fn-7395-desktop-launcher.md             |   7 ++
 docs/cli-reference.md                              |  12 +-
 packages/cli/package.json                          |   1 +
 packages/cli/src/__tests__/bin.test.ts             |  19 +++
 packages/cli/src/__tests__/package-config.test.ts  |  11 ++
 packages/cli/src/bin.ts                            |  10 +-
 .../cli/src/commands/__tests__/desktop.test.ts     | 132 ++++++++++++++++++---
 packages/cli/src/commands/desktop.ts               |  85 ++++++++-----
 packages/cli/tsup.config.ts                        |  60 ++++++++++
 9 files changed, 285 insertions(+), 52 deletions(-)

Fusion-Task-Id: FN-7395

Fusion-Task-Lineage: e7a8d065-0d41-4fa3-9cea-1cfb5b466d16

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 15:39:34 -07:00
gsxdsm
37027632e0 FN-7378: upgrade pi SDK dependencies
Upgrade the bundled pi SDK packages and compatibility imports for the 0.80.3 release.

- Bump @earendil-works/pi-ai and @earendil-works/pi-coding-agent consumers to ^0.80.3.
- Update pi SDK import paths for the new compatibility and API export map layout.
- Refresh dependency contract tests and add a patch changeset for the published CLI package.

Files changed:
 .changeset/fn-7378-pi-sdk-upgrade.md               |   7 ++
 packages/cli/package.json                          |   4 +-
 packages/cli/src/__tests__/package-config.test.ts  |   8 +-
 packages/dashboard/package.json                    |   2 +-
 packages/engine/package.json                       |   4 +-
 .../custom-providers-openai-completions.test.ts    |   8 +-
 pnpm-lock.yaml                                     | 108 ++++++++++-----------
 7 files changed, 72 insertions(+), 69 deletions(-)

Fusion-Task-Id: FN-7378

Fusion-Task-Lineage: ed8847dc-2adf-4ede-aa75-045f2e2436a0

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 10:37:44 -07:00
gsxdsm
a9e2baa9f8 FN-7367: link imported GitHub issues to tracking
Imported GitHub issues can now adopt their source issue as the tracking issue without changing ordinary task defaults.

- Add the project-scoped githubLinkImportedIssuesToTracking setting with docs, Settings UI, and defaults.
- Honor the import-only setting across dashboard, CLI, and extension GitHub issue import paths.
- Cover saved settings and import tracking behavior with CLI, dashboard, and parity tests.
- Add a minor changeset for the published CLI package.

Files changed:
 .changeset/fn-7367-github-import-tracking.md       |  7 +++
 docs/settings-reference.md                         |  3 +-
 packages/cli/src/__tests__/extension.test.ts       | 73 ++++++++++++++++++++++
 .../task-command-github-import-tracking.test.ts    | 16 +++++
 packages/cli/src/commands/__tests__/task.test.ts   | 28 +++++++++
 packages/cli/src/commands/task.ts                  | 45 +++++++------
 packages/cli/src/extension.ts                      | 45 +++++++------
 .../core/src/__tests__/settings-parity.test.ts     |  4 ++
 packages/core/src/settings-schema.ts               |  1 +
 packages/core/src/types.ts                         |  6 ++
 .../app/__tests__/settings-save-split.test.ts      | 19 ++++++
 .../dashboard/app/components/SettingsModal.tsx     |  6 ++
 .../__tests__/SettingsModal.general.test.tsx       | 59 +++++++++++++++++
 .../__tests__/SettingsModal.test-harness.tsx       |  1 +
 .../settings/sections/GeneralSection.tsx           |  9 +++
 .../dashboard/src/__tests__/routes-github.test.ts  | 45 +++++++++++++
 .../dashboard/src/routes/register-git-github.ts    |  7 +++
 17 files changed, 325 insertions(+), 49 deletions(-)

Fusion-Task-Id: FN-7367
Fusion-Task-Lineage: 43671cdf-7e0d-4b7a-9ba2-54c9a367dfec
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 09:50:57 -07:00
gsxdsm
c93f2d4da0 FN-7346: fix TUI settings arrow editing
Fix Settings keyboard handling so arrow keys edit selected enum values in the terminal dashboard.

- Keep Tab as the Settings pane switcher so arrow keys remain scoped to the active pane.
- Route detail-pane left/right arrows and h/l keys through enum setting cycling and remote provider activation.
- Add terminal dashboard coverage for list navigation and enum cycling, plus CLI docs and release note coverage.

Files changed:
 .changeset/fn-7346-tui-settings-arrows.md          |   7 ++
 docs/cli-reference.md                              |   5 +
 .../commands/dashboard-tui/__tests__/app.test.tsx  | 121 ++++++++++++++++++++-
 packages/cli/src/commands/dashboard-tui/app.tsx    | 119 ++++++++++----------
 4 files changed, 186 insertions(+), 66 deletions(-)

Fusion-Task-Id: FN-7346

Fusion-Task-Lineage: c67861a7-7bb3-408d-926c-e85a44fe2dec

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 07:33:56 -07:00
Phil Larson
9432339363 fix: keep dashboard available after planning failures 2026-06-30 23:35:27 -07:00
gsxdsm
94ddfe1064 FN-7274: document workflow tools in Fusion skill
Document the workflow-authoring tool surface in the packaged Fusion skill references.

- Add workflow tools to the generated Fusion skill category and capability tables.
- Teach the skill sync script to read workflow tool specs from extension and engine agent tool sources.
- Cover workflow tool documentation and cache inputs with sync tests.
- Add a changeset for the published CLI skill update.

Files changed:
 .changeset/fn-7274-workflow-skill-tools.md         |   7 +
 packages/cli/skill/fusion/SKILL.md                 |   1 +
 .../cli/skill/fusion/references/engine-tools.md    |   4 +-
 .../cli/skill/fusion/references/extension-tools.md |  83 +++++++++-
 .../skill/fusion/references/fusion-capabilities.md |   8 +
 packages/cli/src/__tests__/skill-sync.test.ts      |  60 ++++++-
 scripts/__tests__/skill-sync-cache.test.mjs        |   5 +
 scripts/sync-fusion-skill-tools.mjs                | 172 ++++++++++++++++++---
 8 files changed, 312 insertions(+), 28 deletions(-)

Fusion-Task-Id: FN-7274

Fusion-Task-Lineage: e1cd6bd8-aecc-49ca-96ed-a937a15a18a4

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-30 08:04:12 -07:00
gsxdsm
b5da5d310a FN-7263: refresh custom provider model lists
Refresh persisted custom-provider model lists from saved endpoints and expose manual refresh controls.

- Add dashboard API helpers and routes to refresh one or all custom-provider model lists while preserving concurrent settings edits.
- Start background model refresh from serve, dashboard, and daemon startup paths after the server begins listening.
- Add Settings UI refresh actions, row-level status messaging, styles, docs, and regression coverage for refresh behavior.

Files changed:
 .changeset/fn-7263-custom-provider-model-refresh.md       |   7 +
 docs/dashboard-guide.md                            |   6 +-
 docs/settings-reference.md                         |   2 +-
 packages/cli/src/commands/__tests__/daemon.test.ts |  59 +++++
 .../cli/src/commands/__tests__/dashboard.test.ts   |  51 ++++
 packages/cli/src/commands/__tests__/serve.test.ts  |  59 ++++-
 packages/cli/src/commands/daemon.ts                |  39 +++-
 packages/cli/src/commands/dashboard.ts             |  10 +
 packages/cli/src/commands/serve.ts                 |  11 +-
 .../app/__tests__/api-custom-providers.test.ts     |  43 ++++
 packages/dashboard/app/api/legacy.ts               |  11 +
 .../app/components/CustomProvidersSection.css      |  41 +++-
 .../app/components/CustomProvidersSection.tsx      |  68 +++++-
 .../__tests__/CustomProvidersSection.test.tsx      | 227 ++++++++++++++++++
 packages/dashboard/src/index.ts                    |   6 +
 .../__tests__/custom-provider-routes.test.ts       | 255 ++++++++++++++++++++
 .../src/routes/__tests__/custom-providers.test.ts  |  12 +
 .../src/routes/register-custom-provider-routes.ts  | 259 ++++++++++++++++-----
 18 files changed, 1101 insertions(+), 65 deletions(-)

Fusion-Task-Id: FN-7263

Fusion-Task-Lineage: 60ee0637-ac85-409f-a376-c01f4bc8e8c5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-30 01:23:09 -07:00
gsxdsm
f01e5c9651 FN-7247: document current workflow behavior
Refresh workflow documentation to match the latest runtime, dashboard, and agent tool behavior.

- Add a current workflow behavior inventory covering built-ins, fail-closed runtime semantics, optional gates, settings, tools, routing, and create forwarding.
- Clarify dashboard All workflows aggregation, workflow badges, and workflow-aware task creation behavior.
- Expand editor, agent, CLI, and settings docs for governed workflow authoring, values, trait inspection, and selection boundaries.
- Add docs drift tests requiring workflow docs index coverage and current behavior markers.

Files changed:
 docs/agents.md                                     |  5 +-
 docs/cli-reference.md                              | 11 ++-
 docs/dashboard-guide.md                            | 10 ++-
 docs/settings-reference.md                         |  5 ++
 docs/workflow-editor.md                            | 15 +++-
 docs/workflow-steps.md                             | 48 ++++++++---
 .../cli/src/__tests__/docs-readme-index.test.ts    |  4 +
 .../src/__tests__/workflow-docs-current.test.ts    | 95 ++++++++++++++++++++++
 8 files changed, 172 insertions(+), 21 deletions(-)

Fusion-Task-Id: FN-7247
Fusion-Task-Lineage: 72bf0c89-80a3-440c-b6aa-1aea315279f5
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-29 19:46:23 -07:00
gsxdsm
03d4f95e8a FN-7224: separate Anthropic subscription and API-key auth
Separate Claude subscription OAuth from raw Anthropic API-key authentication surfaces.

- Add synthetic Anthropic Subscription and Anthropic API Key provider IDs while preserving upstream credential storage compatibility.\n- Map dashboard auth routes, CLI auth storage, Settings, and onboarding flows so OAuth login/logout and API-key save/clear no longer share one user-facing card.\n- Extend auth tests, docs, icons, and the release changeset for the split Anthropic authentication behavior.\n\nFiles changed:\n .changeset/fn-7224-separate-anthropic-api-key.md   |   7 +\n docs/dashboard-guide.md                            |   2 +-\n docs/settings-reference.md                         |   2 +-\n .../src/commands/__tests__/provider-auth.test.ts   | 233 +++++++++++++++++++--\n packages/cli/src/commands/provider-auth.ts         | 202 +++++++++++++++---\n packages/dashboard/app/api/legacy.ts               |   2 -\n .../app/components/ModelOnboardingModal.tsx        | 146 ++++---------\n packages/dashboard/app/components/ProviderIcon.tsx |   7 +\n .../__tests__/AuthenticationSection.test.tsx       |  89 ++++----\n .../__tests__/SettingsModal.models-auth.test.tsx   |  77 ++++---\n .../components/__tests__/onboarding-flow.test.tsx  |  29 ++-\n .../components/__tests__/settings-mobile.test.tsx  |  17 +-\n .../settings/sections/AuthenticationSection.tsx    |  20 +-\n .../dashboard/src/__tests__/routes-auth.test.ts    | 111 ++++++----\n .../dashboard/src/routes/register-auth-routes.ts   |  93 +++++---\n 15 files changed, 713 insertions(+), 324 deletions(-)

Fusion-Task-Id: FN-7224

Fusion-Task-Lineage: a2db2cf6-3452-4516-81e5-41dcdf47e1d2

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-29 18:32:36 -07:00
Phil Larson
4c31441f58 fix: reset PR fixture git remote mock consistently 2026-06-29 17:18:59 -07:00
Phil Larson
6763584f64 fix: align dashboard PR fixture cwd mock 2026-06-29 17:17:35 -07:00
Phil Larson
bdd0a1cc2c test(cli): stabilize dashboard pr repository fixtures 2026-06-29 17:17:35 -07:00
gsxdsm
42226edde1 FN-7245: expose workflow authoring tools to agents
Expose workflow authoring and selection tools through agent-visible extension surfaces.

- Register workflow list/get/create/update/delete/settings/select and trait-list tools in the published pi extension.
- Export shared workflow tool schemas/factories and include workflow settings in centralized authoring tool sets.
- Update action-gate classifications, permission examples, docs, tests, and the changeset for the new agent workflow surface.

Files changed:
 .changeset/FN-7245-workflow-tools.md               |   7 +
 docs/agents.md                                     |   4 +-
 docs/cli-reference.md                              |  17 ++
 docs/workflow-steps.md                             |   9 +-
 .../src/__tests__/extension-workflow-tools.test.ts | 244 +++++++++++++++++++++
 packages/cli/src/__tests__/extension.test.ts       |   8 +
 packages/cli/src/extension.ts                      | 142 ++++++++++++
 packages/core/src/types.ts                         |   6 +-
 .../dashboard/src/__tests__/chat-manager.test.ts   |   9 +-
 .../planning-document-tools-exposure.test.ts       |  19 +-
 .../engine/src/__tests__/agent-action-gate.test.ts |   8 +
 .../agent-workflow-tools-exposure.test.ts          |  30 ++-
 .../src/__tests__/gating-classifications.test.ts   |  13 +-
 .../src/__tests__/permanent-agent-gating.test.ts   |   4 +-
 packages/engine/src/agent-tools.ts                 |  13 +-
 packages/engine/src/gating-classifications.ts      |   6 +-
 packages/engine/src/index.ts                       |   7 +
 17 files changed, 506 insertions(+), 40 deletions(-)

Fusion-Task-Id: FN-7245

Fusion-Task-Lineage: 82501602-7177-4ee8-a67b-32de35aa73de

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-29 16:35:51 -07:00
gsxdsm
013d50fe8b FN-7206: add Anthropic API-key authentication
Add Anthropic API-key authentication alongside the existing OAuth flow.

- Expose Anthropic as a built-in API-key provider without hiding its OAuth controls.
- Render dual-auth Anthropic cards in Settings and model onboarding with key hints, save, and clear actions.
- Cover API status, CLI provider classification, desktop/mobile settings, and onboarding flows with tests and docs.

Files changed:
 .changeset/fn-7206-anthropic-api-key.md            |   7 +
 docs/dashboard-guide.md                            |   2 +
 docs/settings-reference.md                         |   4 +
 .../src/commands/__tests__/provider-auth.test.ts   |  51 ++++---
 packages/cli/src/commands/provider-auth.ts         |  10 +-
 packages/dashboard/app/api/legacy.ts               |   2 +
 .../app/components/ModelOnboardingModal.tsx        | 121 +++++++++++++++-
 .../__tests__/AuthenticationSection.test.tsx       | 141 +++++++++++++++++++
 .../__tests__/SettingsModal.models-auth.test.tsx   |  51 +++++++
 .../__tests__/SettingsModal.test-harness.tsx       |   2 +
 .../components/__tests__/onboarding-flow.test.tsx  |  28 ++++
 .../components/__tests__/settings-mobile.test.tsx  |  16 ++-
 .../settings/sections/AuthenticationSection.tsx    | 153 ++++++++++-----------
 .../dashboard/src/__tests__/routes-auth.test.ts    |  70 ++++++++++
 .../dashboard/src/routes/register-auth-routes.ts   |  17 ++-
 15 files changed, 569 insertions(+), 106 deletions(-)

Fusion-Task-Id: FN-7206

Fusion-Task-Lineage: 3559b7ea-47c6-4f8c-9aa1-5318f47ce07e

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-28 17:03:11 -07:00
gsxdsm
bc38f0c842 FN-7209: require JDK 21 for Android CI builds
Align Android Gradle build environments with Capacitor's Java 21 source compatibility.

- Update mobile, release, and test-release workflows to provision Temurin JDK 21.
- Document Java 21 as the required Android Gradle build JDK.
- Add CI workflow coverage that checks Android build jobs satisfy @capacitor/android sourceCompatibility.

Files changed:
 .github/workflows/mobile.yml                   |  6 +-
 .github/workflows/release.yml                  |  6 +-
 .github/workflows/test-release.yml             |  6 +-
 MOBILE.md                                      |  4 +-
 packages/cli/src/__tests__/ci-workflow.test.ts | 99 +++++++++++++++++++++++++-
 5 files changed, 112 insertions(+), 9 deletions(-)

Fusion-Task-Id: FN-7209

Fusion-Task-Lineage: d9e50bee-d7f8-4e87-b33e-136ffffc93af

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-28 16:56:35 -07:00
gsxdsm
2be00efc04 fix(cli): stop engine teardown logs repainting shell after TUI quit
Root cause of "the TUI keeps rendering after I get my terminal back": on
quit, dispose() called logSink.releaseConsole() (re-pointing console.* at
the real terminal) and then tui.stop() left the alt-screen and restored the
user's shell. Every log line from the slow engine/mesh/dev-server teardown
that followed then painted over the recovered prompt.

dispose() now calls a new logSink.silence() instead, which drops all sink
and console.* output from quit through process exit. Shutdown-step
diagnostics (timeShutdownStep + the watchdog stall line) are gated behind
FUSION_DEBUG_SHUTDOWN so a normal quit is pristine; the 3s hard-exit
watchdog still guarantees the process dies.

Adds a silence() regression guard to log-sink.test.ts asserting sink
methods and captured console.* both go silent across surfaces.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 10:56:38 -07:00
gsxdsm
524c15c2fd FN-7188: prevent agents from pausing failed tasks
Clarify agent heartbeat and tool guidance so failures surface through recovery paths instead of task pauses.

- Update heartbeat prompts to prohibit failure/blocker handling via fn_task_pause.
- Clarify fn_task_pause tool copy as explicit user-requested manual control only.
- Refresh generated Fusion skill docs and add regression coverage for the guidance.
- Add a patch changeset for the published CLI package.

Files changed:
 .changeset/FN-7188-no-pause-on-failure.md                    |  7 +++++++
 packages/cli/skill/fusion/references/best-practices.md       |  6 +++---
 packages/cli/skill/fusion/references/extension-tools.md      |  2 +-
 packages/cli/skill/fusion/references/fusion-capabilities.md  |  2 +-
 packages/cli/skill/fusion/workflows/task-management.md       |  2 +-
 packages/cli/src/__tests__/extension.test.ts                 |  8 ++++++++
 packages/cli/src/extension.ts                                | 10 ++++++++--
 .../engine/src/__tests__/heartbeat-session-prompt.test.ts    | 10 ++++++++++
 packages/engine/src/agent-heartbeat.ts                       | 12 ++++++++++--
 9 files changed, 49 insertions(+), 10 deletions(-)

Fusion-Task-Id: FN-7188
Fusion-Task-Lineage: 29df6168-7920-49d5-9c11-804727033721
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-28 01:22:43 -07:00
gsxdsm
a95cfa7f92 FN-7160: unify live agent counts and fix use markers
Unifies running-agent slot accounting across engine, CLI, and dashboard surfaces.

- Add shared core helpers for identifying and counting active top-level agent tasks, including in-review reviewer, merger, fix, and PR merge states.
- Reuse the shared count in engine semaphore repair, project health displays, and dashboard project-store routes.
- Correct Command Center utilization markers to use a zero-based active/cap ratio.
- Cover the shared predicate and affected CLI, dashboard, and engine behaviors with regression tests.

Files changed:
 .changeset/fn-7160-running-agent-count.md          |  7 ++++
 docs/dashboard-guide.md                            |  2 +-
 .../cli/src/commands/__tests__/project.test.ts     | 40 ++++++++++++++----
 packages/cli/src/commands/project.ts               | 15 +++----
 .../core/src/__tests__/live-agent-count.test.ts    | 47 ++++++++++++++++++++++
 packages/core/src/index.ts                         |  2 +
 packages/core/src/live-agent-count.ts              | 30 ++++++++++++++
 packages/core/src/types.ts                         |  2 +-
 .../command-center/CommandCenterControls.tsx       | 14 ++++---
 .../__tests__/CommandCenterControls.test.tsx       | 22 +++++++++-
 .../dashboard/src/__tests__/project-routes.test.ts | 31 +++++++++-----
 .../src/__tests__/project-store-resolver.test.ts   | 20 ++++++---
 packages/dashboard/src/project-store-resolver.ts   |  9 ++---
 .../src/routes/register-project-routes.ts          |  7 ++--
 packages/engine/src/__tests__/concurrency.test.ts  | 18 +++++++++
 packages/engine/src/concurrency.ts                 | 12 +++---
 16 files changed, 220 insertions(+), 58 deletions(-)

Fusion-Task-Id: FN-7160

Fusion-Task-Lineage: f48332f8-ac5d-46eb-b975-d2f6c880ddd5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-27 21:39:40 -07:00
gsxdsm
aeafee75e5 test: remove dead post-await sleeps in skills install tests
runSkillsInstall already awaits the spawned child exit event, so the
fixed 100ms post-await sleeps were redundant wall-clock time (FN-5048).
Removes ~400ms of dead waits; assertions unchanged, 22 tests still pass.
2026-06-27 17:03:55 -07:00
gsxdsm
6f46fa17dd FN-7138: show task column context in agent assignments
Agent Current Task output now includes linked task column context to distinguish active execution from parked or stale links.

- Add shared Current Task formatting for active, terminal, and unresolved task links.
- Show linked task columns in engine and CLI agent list/show surfaces.
- Cover parked, active, terminal, and missing task-link display cases with tests.
- Document the durable agent task-link invariant and release the CLI fix.

Files changed:
 .changeset/fn-7138-agent-current-task-context.md   |  7 ++++
 docs/agents.md                                     |  1 +
 docs/architecture.md                               |  2 +-
 packages/cli/src/__tests__/extension.test.ts       | 44 ++++++++++++++++++++++
 packages/cli/src/extension.ts                      | 35 +++++++++++++++--
 packages/core/src/agent-store.ts                   | 30 +++++++++++++++
 packages/core/src/index.ts                         |  2 +-
 .../src/__tests__/agent-tools-delegation.test.ts   | 44 +++++++++++++++++++++-
 packages/engine/src/agent-tools.ts                 | 15 ++++++--
 9 files changed, 169 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-7138
Fusion-Task-Lineage: 0ea97b4c-d4f8-4289-a5b6-e5c51b47b768
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-27 16:16:25 -07:00
gsxdsm
63b44b819a FN-7133: fix PR merge status repository lookup
Fix PR-mode auto-merge status checks to query GitHub with the project repository.

- Resolve the current project owner/repo once from the task cwd before PR status checks.
- Pass owner/repo/number to getPrMergeStatus for shared-group, task, and retry paths.
- Cover repository resolution and PR status argument behavior in lifecycle tests.
- Add a patch changeset for the published CLI fix.

Files changed:
 .changeset/FN-7133-pr-merge-status-repo-args.md    |  7 ++++
 .../src/commands/__tests__/task-lifecycle.test.ts  | 39 +++++++++++++++++++++-
 packages/cli/src/commands/task-lifecycle.ts        | 17 +++++++---
 3 files changed, 58 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-7133
Fusion-Task-Lineage: 3f9bfd65-6950-40dc-9505-53140bd6a6a1
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-27 13:28:47 -07:00