Commit Graph

10520 Commits

Author SHA1 Message Date
gsxdsm
00ce5d6a27 FN-7414: refresh test velocity quarantine baseline
Refresh the velocity baseline artifacts so live quarantine counts are reflected consistently.

- Add regression coverage for live quarantine ledger counts overriding stale report and history values.
- Update the weekly velocity baseline report to show the current quarantine count and deltas.
- Append the latest measured velocity history row with quarantine count one.

Files changed:
 docs/test-velocity-baseline.md                    |  22 ++---
 scripts/__tests__/test-velocity-baseline.test.mjs |  75 +++++++++++++++
 scripts/test-velocity-history.json                | 112 ++++++++++++++++++++++
 3 files changed, 198 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-7414

Fusion-Task-Lineage: 7c6cd47c-482d-426c-a714-79da33d4591d

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-02 11:38:31 -07:00
gsxdsm
85809103cd FN-7413: configure agent permissions across lifetimes
Enable explicit capability grants and runtime permission policies for both durable and ephemeral agents.

- Persist normalized agent capability grants and leave missing permission policies to inherit project defaults at runtime.
- Apply action and tool approval gates to permanent agents, ephemeral agents, and fallback task workers.
- Add Agent Detail controls, translations, docs, tests, and a changeset for cross-lifetime agent permissions.

Files changed:
 .changeset/fn-7413-agent-permissions.md            |  7 ++
 docs/agents.md                                     | 12 ++--
 docs/settings-reference.md                         | 11 ++-
 packages/core/src/__tests__/agent-store.test.ts    | 65 +++++++++++++----
 packages/core/src/agent-store.ts                   | 31 ++++++---
 packages/core/src/types.ts                         | 10 +--
 .../dashboard/app/components/AgentDetailView.css   | 48 +++++++++++++
 .../dashboard/app/components/AgentDetailView.tsx   | 81 +++++++++++++++++++++-
 .../settings/sections/AgentPermissionsSection.tsx  |  2 +-
 .../dashboard/src/__tests__/routes-agents.test.ts  |  8 +--
 .../src/routes/register-agent-core-routes.ts       | 32 ++++++---
 .../src/__tests__/heartbeat-executor.test.ts       | 14 +++-
 packages/engine/src/agent-heartbeat.ts             | 17 ++---
 packages/engine/src/executor.ts                    | 57 +++++++--------
 packages/i18n/locales/en/app.json                  | 12 +++-
 packages/i18n/locales/es/app.json                  | 12 +++-
 packages/i18n/locales/fr/app.json                  | 12 +++-
 packages/i18n/locales/ko/app.json                  | 12 +++-
 packages/i18n/locales/zh-CN/app.json               | 12 +++-
 packages/i18n/locales/zh-TW/app.json               | 12 +++-
 20 files changed, 363 insertions(+), 104 deletions(-)

Fusion-Task-Id: FN-7413
Fusion-Task-Lineage: bc004572-bde8-4d33-bb27-e941a5bc8884
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-02 11:38:31 -07:00
gsxdsm
9ee33f9551 FN-7412: connect template block boundary guides
Connect workflow template containers to their internal entry and exit steps with visual-only boundary guides.

- Generalize optional-group boundary metadata and generated guide edges to foreach and loop template containers.
- Render non-connectable template boundary handles on foreach, loop, and optional-group nodes while keeping saved IR free of visual-only topology.
- Add coverage for stepwise foreach rendering, live boundary refresh, mobile graph filtering, and changeset release notes.

Files changed:
 .changeset/fn-7412-template-boundary-connectors.md |   7 ++
 .../app/components/WorkflowNodeEditor.tsx          |  13 +-
 .../__tests__/WorkflowNodeEditor.test.tsx          |  16 +--
 .../__tests__/workflow-flow-mapping.test.ts        | 135 +++++++++++++++++++--
 .../__tests__/workflow-mobile-graph.test.ts        |  20 +++
 .../app/components/nodes/WorkflowNodeTypes.tsx     |  25 ++--
 .../app/components/workflow-flow-mapping.ts        | 117 +++++++++---------
 7 files changed, 245 insertions(+), 88 deletions(-)

Fusion-Task-Id: FN-7412

Fusion-Task-Lineage: 2b36de80-b1d0-4a43-85e5-ce47ba9ac7ff

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-02 11:38:30 -07:00
gsxdsm
377eee64af FN-7410: allow archived task deletion
Allow archived task snapshots to be deleted while preserving soft-delete tombstones.

- Restore cold archived snapshots into the tasks table before applying delete tombstones.
- Remove archive snapshots after deletion and preserve allowResurrection semantics.
- Cover archived deletion through store, API, UI menu, docs, and changeset updates.

Files changed:
 .changeset/fn-7410-delete-archived-tasks.md        |   7 ++
 docs/task-management.md                            |   3 +-
 .../core/src/__tests__/soft-delete-tasks.test.ts   | 129 +++++++++++++++++++++
 packages/core/src/store.ts                         |  25 +++-
 .../components/__tests__/TaskContextMenu.test.tsx  |  19 +++
 .../src/__tests__/routes-tasks-ops.test.ts         |  24 ++++
 6 files changed, 204 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7410
Fusion-Task-Lineage: fa7d9983-e62c-4849-89d8-1ae5f6134815
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-02 11:38:30 -07:00
gsxdsm
2d8f087a9d fix: resolve all failing full-suite CI tests on main (#1874)
## Summary

Fixes all failing tests in the non-blocking full-suite CI run
[28561416741](https://github.com/Runfusion/Fusion/actions/runs/28561416741)
on main.

## Root causes and fixes

### 1. Missing `formatModelMarkerDetails` mock export (5 files, 17
tests)

Production code in `reviewer.ts` and `triage.ts` calls
`formatModelMarkerDetails()` after resolving an agent session to build a
model-marker log line. Five test files mocked `../pi.js` without
exporting this function, so every reviewer/triage/restart path threw
`[vitest] No "formatModelMarkerDetails" export is defined` before
reaching finalization assertions.

**Files:** `reviewer-prompt-single-source`,
`plan-review-unavailable-recovery`, `triage-fast-mode-workflow-variant`,
`triage-stuck-requeue-preserve-draft`, `restart.integration`

### 2. Outdated worktree acquisition assertions (2 files, 5 tests)

A production fix added `git symbolic-ref --short
refs/remotes/origin/HEAD` resolution to ensure fresh task worktrees
never inherit the root checkout's ambient HEAD. The tests didn't account
for this new exec call or the appended start point.

**Files:** `worktree-acquisition-backend`,
`worktree-acquisition-worktrunk`

### 3. Stale workflow compiler tests (1 file, 2 tests)

FN-7360 removed the linear `WorkflowStep` compiler and `/compile`
endpoint, making `parseWorkflowIr` the sole validity gate. Branching
custom workflows are now valid on the graph interpreter. Two dashboard
tests still asserted 422 for branching IR.

**File:** `workflow-routes`

### 4. Graph cutover production fixes + test migrations (from closed PR
#1869)

- `executor.ts`: `safeLogEntry()` wrapper prevents synchronous
`store.logEntry` throws from aborting pause/abort/finalize control flow
- `workflow-authoritative-driver.ts`: built-in auxiliary custom nodes
(completion-summary, optional-groups) pass through as success instead of
throwing
- Test migrations across engine, CLI, dashboard, and desktop for
graph-native runtime paths

## Verification

- All affected tests pass: engine (87 tests across 7 files), dashboard
(53 tests), plus the cherry-picked migration tests
- Merge gate (`pnpm test:gate`): 319 engine-core + 63 CI-shape tests
green


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

## Summary by CodeRabbit

* **New Features**
* Added support for branching workflow content in more places, including
workflow creation and selection.
* Added a new shared runtime tool available to plan/review agents for
writing task prompts.

* **Bug Fixes**
* Improved task failure handling so retries now end cleanly instead of
bouncing through extra states.
* Made pause, recovery, and worktree-related behavior more reliable
during long-running operations and restarts.
  * Updated Android release automation to use JDK 21.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-02 08:45:33 -07:00
gsxdsm
f8ff0e6f5c test: fix remaining CI full-suite failures after graph cutover
Missing mock export (5 files, 17 tests):
- reviewer-prompt-single-source, plan-review-unavailable-recovery,
  triage-fast-mode-workflow-variant, triage-stuck-requeue-preserve-draft,
  restart.integration: add formatModelMarkerDetails to the ../pi.js mock.
  Production code calls this after resolving an agent session, but the test
  mocks were missing the export, causing all reviewer/triage/restart paths
  to throw before reaching finalization assertions.

Outdated worktree assertions (2 files, 5 tests):
- worktree-acquisition-backend, worktree-acquisition-worktrunk: update
  assertions for the new git symbolic-ref origin/HEAD resolution call and
  the appended start point in git worktree add (worktree isolation fix).

Stale workflow compiler tests (1 file, 2 tests):
- workflow-routes: FN-7360 removed the linear compiler /compile endpoint
  and made parseWorkflowIr the sole validity gate. Branching custom
  workflows are now valid on the graph interpreter. Updated the two stale
  tests that asserted 422 for branching IR to assert 201/200 instead.
2026-07-02 07:41:15 -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
84a40dd82e chore(release): v0.54.0
Version bump via changesets.
2026-07-02 00:22:58 -07:00
gsxdsm
98704282ac FN-7409: Restore board search reopen button
Restore the board/list search affordance after users dismiss an active desktop search.

- Keep the non-mobile open-search button available once a closed search has an empty query.
- Cover empty-close and parent-cleared populated search flows in Header tests.
- Add a patch changeset for the published Fusion package.

Files changed:
 .changeset/restore-board-search-trigger.md         |  7 ++++
 packages/dashboard/app/components/Header.tsx       | 13 +++++---
 .../app/components/__tests__/Header.test.tsx       | 38 ++++++++++++++++++----
 3 files changed, 46 insertions(+), 12 deletions(-)

Fusion-Task-Id: FN-7409
Fusion-Task-Lineage: 9cb4ff80-8490-43be-8d18-a3f292603ecb
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 23:58:55 -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
1a523e7d1b FN-7407: enable done-task planner refinements
Enable planner chat on completed tasks and let clear follow-up requests create refinements.

- Allow task-planner chat sessions for done tasks while keeping archived tasks blocked.
- Add a task-scoped refinement tool that creates follow-up tasks only from completed source tasks.
- Render refinement creation, pending, and failure states in the planner chat transcript.
- Extend planner-chat context, route, manager, and component tests for done-task chat and refinement behavior.
- Document the completed-task planner chat behavior and add a patch changeset.

Files changed:
 .changeset/fn-7407-done-planner-chat.md            |   7 ++
 docs/dashboard-guide.md                            |   5 +-
 .../app/components/TaskPlannerChatTab.tsx          |  50 +++++++-
 .../__tests__/TaskPlannerChatTab.test.tsx          |  66 ++++++++++-
 .../dashboard/src/__tests__/chat-manager.test.ts   | 126 ++++++++++++++++++++-
 .../dashboard/src/__tests__/chat-routes.test.ts    |  41 ++++++-
 .../__tests__/task-planner-chat-context.test.ts    |   5 +-
 packages/dashboard/src/chat.ts                     |  66 ++++++++++-
 .../dashboard/src/routes/register-chat-routes.ts   |   9 +-
 .../dashboard/src/task-planner-chat-context.ts     |   5 +-
 10 files changed, 360 insertions(+), 20 deletions(-)

Fusion-Task-Id: FN-7407

Fusion-Task-Lineage: b3214d89-a59c-4682-b5cd-98d7d6cc09e2

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 23:44:05 -07:00
gsxdsm
b6da7fafd5 FN-7408: normalize task detail tab padding
Normalize task detail tab padding so chat-like views reuse the standard modal body inset.

- Remove Activity and planner Chat body padding overrides while preserving their flex and internal-scroll behavior.
- Strengthen CSS contract tests for desktop, expanded, and mobile task-detail tab spacing.
- Add a patch changeset for the published Fusion package.

Files changed:
 .changeset/fn-7408-task-detail-tab-padding.md      |  7 ++++++
 .../dashboard/app/components/TaskDetailModal.css   | 26 ++++----------------
 .../TaskDetailModal.attachments-and-tabs.test.tsx  | 10 +++++++-
 .../__tests__/TaskDetailModal.css.test.ts          | 28 ++++++++++++++++++++++
 ...etailModal.responsive-and-dependencies.test.tsx | 26 ++++++++++++--------
 5 files changed, 64 insertions(+), 33 deletions(-)

Fusion-Task-Id: FN-7408

Fusion-Task-Lineage: ffff5aed-ebb9-4f81-b90c-8d58d218cd95

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 23:36:35 -07:00
gsxdsm
9464f31caf FN-7406: fix All workflows dropdown counts
Ensure All workflows dropdown counters report the shared aggregate without double-counting tasks.

- Reuse computeWorkflowStatusCounts directly in Board instead of re-summing a map that already includes the All workflows sentinel.
- Document the aggregate count invariant and add a published patch changeset.
- Extend Board, List, header, graph, and workflow count tests to cover exact All workflows totals.

Files changed:
 .changeset/fn-7406-workflow-dropdown-counts.md     |  7 +++
 docs/dashboard-guide.md                            |  5 +-
 packages/dashboard/app/components/Board.tsx        | 17 +++---
 .../app/components/__tests__/Board.test.tsx        | 56 ++++++++++++++++++-
 .../__tests__/GraphWorkflowSwitcherSlot.test.tsx   |  8 ++-
 .../__tests__/HeaderWorkflowSwitcherSlot.test.tsx  |  8 ++-
 .../app/components/__tests__/ListView.test.tsx     | 62 ++++++++++++++++++++++
 .../__tests__/workflowStatusCounts.test.ts         | 48 +++++++++++++++--
 8 files changed, 188 insertions(+), 23 deletions(-)

Fusion-Task-Id: FN-7406

Fusion-Task-Lineage: bb344c03-c349-47ea-9e8c-c445975f8e02

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 23:15:12 -07:00
gsxdsm
eedf526e7f FN-7405: preserve scoped task detail model saves
Preserve scoped task-detail model saves so project tasks update without false not-found errors.

- Thread the active project id from TaskDetailModal into ModelSelectorTab updates.
- Pass project scope for executor, reviewer, planning, and thinking model saves and clears.
- Cover scoped success paths and real reviewer-update failures with dashboard tests.
- Add a patch changeset for the published Fusion package.

Files changed:
 .../fn-7405-task-detail-model-project-scope.md     |   7 ++
 .../dashboard/app/components/ModelSelectorTab.tsx  |  15 ++-
 .../dashboard/app/components/TaskDetailModal.tsx   |   8 +-
 .../components/__tests__/ModelSelectorTab.test.tsx | 127 ++++++++++++++++++++-
 ...lModal.inline-editing-and-integrations.test.tsx |  76 +++++++++++-
 5 files changed, 222 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-7405

Fusion-Task-Lineage: 59a18549-40fb-436d-a6f9-ec9f49f4a82f

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 23:01:45 -07:00
gsxdsm
3167dbc839 fix: lenient review-verdict parsing + clear stale gate failures on retry
Reviews no longer fail on formatting. Three changes to how reviewer/gate
verdicts are parsed and how retries reset state:

- Approval leniency: a review that clearly approves in prose passes even
  without a structured verdict (proseSignalsClearApproval, with a
  revise/reject/negated-approval guard so a rejection is never flipped). Any
  APPROVE*/APPROVAL verdict token classifies as approved. Shared by the
  reviewer/plan-review parser and the code-review/browser-verification gate.
- Prose + trailing JSON: extractJsonObjectCandidates does a string-aware
  balanced-brace scan and prefers the last object, so a model that emits
  reasoning prose then a trailing {"verdict":...} payload parses correctly.
  An explicit "Verdict:" heading/line still takes precedence over an
  incidental/example JSON object.
- Malformed handling: executeWorkflowStep retries the fallback model on
  malformed output (not just timeout); malformed gate output becomes a
  non-blocking advisory (a genuine parsed REVISE still blocks).
- Retry clears prior terminal step failures (incl. optional gate nodes like
  code-review) after the task leaves the mergeable in-review column, so a
  retry starts clean without an auto-merge race.

Fail-closed merge / PR-review / mission-verification gates are unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 22:31:27 -07:00
gsxdsm
074462eade fix: stop planning mode from creating a draft per keystroke
The initial-plan textarea gated duplicate createPlanningDraft calls only
on draftSessionIdRef, which is populated after the create round-trip
resolves. Keystrokes arriving while a create was in flight each passed the
guard and spawned a fresh draft. Add a synchronous draftCreateInFlightRef
sentinel that suppresses concurrent creates and clears on failure so a
later keystroke can retry. Includes an in-flight-concurrency regression test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 21:43:07 -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
gsxdsm
ca88a6c6a2 fix: don't flag a task failed while its code-review remediation is still executing
A pre-merge-remediation/plan-replan node (e.g. code-review-remediation) is a
fire-and-forget async scheduler with no failure out-edge. When its schedule call
can't re-arm (missing rehydrated failureContext after restart,
remediation-not-scheduled, or an exhausted rework budget), the failure bubbled
out as the terminal graph outcome and handleGraphFailure stamped status:"failed"
— surfacing a spurious "Task Failed" even while the previously-scheduled
fix/reviewer session was still live.

Guard the terminal sink: skip the failed park when the failed node is a
remediation node AND a live agent session surface is still registered for the
task. Scoped via isRemediationGraphNode (IR workflowAction + built-in node-id
fallback) and hasLiveTaskSessionSurface; genuine execute/merge failures and
remediation failures with no live session still park failed unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 21:30:48 -07:00
gsxdsm
69f754f868 fix: anchor task Activity view dropdown under its tab
The Activity view menu (Live/Feed/Raw) is position:fixed and portaled to
<body>, so it is anchored to the layout viewport. It was clamped using
window.visualViewport width/offset, which under pinch-zoom or an open mobile
keyboard diverges from the layout viewport and shoved the popup to the left of
the modal. Position it purely from the layout viewport
(document.documentElement.clientWidth/clientHeight) with no visual-viewport
offset so it stays under the "Activity" trigger.

Adds a regression test asserting the menu anchors under the trigger even when
the visual viewport diverges.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 20:42:23 -07:00
gsxdsm
abd596b700 fix: pack full desktop dependency closure + resolve bun/desktop plugin loading on Windows
Desktop "Local" mode crashed with ERR_MODULE_NOT_FOUND because electron-builder's
pnpm collector drops `deduped` subtrees, so engine's transitive closure
(@modelcontextprotocol/sdk, pi-ai provider SDKs, etc.) was never packed. Stage the
complete flat prod closure with `pnpm deploy --legacy --config.node-linker=hoisted`
and package it via `electron-builder --projectDir deploy`, bypassing the lossy
collector entirely.

Also make the dashboard-imported example plugins loadable under plain Node (the
Electron main runtime): cursor/droid/roadmap now expose compiled `dist` on the
`import` condition (keeping `source`→src for the bun CLI) and are built during the
desktop build. Add `source` conditions to paperclip/agent-browser/even-cards/
even-realities-glasses/whatsapp-chat so the bun `--conditions=source` Windows CLI
compile resolves them from source.

Validated on macOS: @fusion/core|engine|dashboard import cleanly from the staged
deploy; packing yields a complete 705-package asar; bun-windows-x64 cross-compiles
with all plugin dist removed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 20:40:02 -07:00
gsxdsm
7488e0971f chore(release): v0.53.1
Version bump via changesets.
2026-07-01 19:38:51 -07:00
gsxdsm
bb1de8a6bd fix: add source export condition to hermes/openclaw plugins for bun Windows build
The CLI bun `--compile --conditions=source` build could not resolve
@fusion-plugin-examples/hermes-runtime and openclaw-runtime (statically imported
by dashboard routes.ts): those plugins lacked a `source` export condition and
fell through to `import`->dist/index.js, absent on the Windows runner. Add
`"source": "./src/index.ts"` (matching core/dashboard/engine/plugin-sdk) so bun
bundles their TS source directly, independent of dist.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 19:34:11 -07:00
gsxdsm
3aef6dd5cf fix: build @fusion/core and @fusion/engine dist in desktop packaging
The packaged desktop "Local" runtime dynamically imports @fusion/engine, whose
tsc dist is gitignored. desktop-windows.yml built only `@fusion/desktop build`
(no root `pnpm build`), so it packaged an empty engine/dist and the app crashed
on Local mode with ERR_MODULE_NOT_FOUND for app.asar/node_modules/@fusion/engine.

Make the desktop build self-contained (build core then engine before packaging)
and add the parity `pnpm build` step to desktop-windows.yml.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 19:34:11 -07:00
gsxdsm
8bb18d9d61 chore(release): v0.53.0
Version bump via changesets.
2026-07-01 18:31:44 -07:00
gsxdsm
dbe637f2c9 FN-7402: publish workflow step activity runs
Publish workflow step lifecycle activity so dashboard analytics can count graph-owned execution.

- Emit best-effort agentRuns rows when workflow step sessions start and finish.
- Include task lineage, step metadata, terminal status, and token usage in workflow step activity records.
- Cover workflow step activity analytics and document dashboard Activity/Overview counting behavior.

Files changed:
 .changeset/fn-7402-workflow-step-activity.md       |   7 +
 docs/dashboard-guide.md                            |   5 +-
 .../core/src/__tests__/activity-analytics.test.ts  |  44 +++++++
 .../src/__tests__/step-session-executor.test.ts    | 145 +++++++++++++++++++++
 packages/engine/src/step-session-executor.ts       | 104 ++++++++++++++-
 5 files changed, 300 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-7402
Fusion-Task-Lineage: ecb2810d-da05-4fd0-a3bd-da72cae99a31
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 18:27:32 -07:00
gsxdsm
a4049971e5 FN-7401: add Glass Silver dashboard theme
Adds a frosted silver/gray dashboard color theme across app, desktop, and release metadata.

- Register glass-silver in shared theme types, selector options, and startup validation hooks.
- Add Glass Silver CSS tokens, swatch styling, and dashboard/desktop stylesheet preload coverage.
- Cover theme registration, dropdown/selector rendering, theme persistence, and CSS token invariants with tests.
- Document the new dashboard theme and publish a minor changeset for @runfusion/fusion.

Files changed:
 .changeset/fn-7401-glass-silver-theme.md           |   7 +
 docs/dashboard-guide.md                            |   3 +-
 packages/core/src/types.ts                         |   2 +
 .../app/__tests__/glass-silver-theme.test.ts       | 155 ++++++++++++++++++++
 .../dashboard/app/components/ThemeSelector.css     |  14 ++
 .../components/__tests__/ThemeDropdown.test.tsx    |  13 ++
 .../components/__tests__/ThemeSelector.test.tsx    |  16 +++
 packages/dashboard/app/components/themeOptions.ts  |   1 +
 .../dashboard/app/hooks/__tests__/useTheme.test.ts |  15 ++
 packages/dashboard/app/index.html                  |   2 +-
 packages/dashboard/app/public/theme-data.css       | 156 +++++++++++++++++++++
 packages/desktop/src/renderer/index.html           |   1 +
 12 files changed, 383 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7401

Fusion-Task-Lineage: e64f14cc-590e-458b-adf6-7c9baa488157

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 18:01:17 -07:00
gsxdsm
615431b1fb fix: stop triage loop at completion-summary node + i18n object-key crashes (#1863) (#1866)
Fixes #1863.

The issue conflated **two distinct v0.52.0 regressions** (the reporter's
i18n root-cause guess was only half of it).

## 1. The real triage loop — engine (primary fix)
The `completion-summary` graph node was added to every built-in workflow
in v0.52.0 (FN-7228/FN-7233), wired with a **success-only edge — no
failure edge**. It's a *best-effort* node
(`ensureWorkflowCompletionSummary` already backfills `task.summary`),
but two failure paths bypass its advisory `!blocking → success`
coercion:

- a **thrown handler exception** (e.g. missing worktree) →
`executeNodeWithRetries` returns `value:"exception"`
- a **failed summary projection write** →
`publishTaskProjectionFromResult` returns `value:"projection-error"`

With no failure edge, either **terminates the graph at
`completion-summary`**. `routeGraphFailureToExecutionResume` then treats
the in-review failure as recoverable and moves the task back to `todo`,
which replays the already-passed nodes (0 new tokens) and fails again —
the **infinite `triage → in-progress → todo` loop** in the report (token
usage 0, execution NOT STARTED).

**Fix:** the graph executor now degrades a `completion-summary` node
failure to `success` so the graph always advances, with a
`routeGraphFailureToExecutionResume` backstop that parks `failed`
instead of looping. Shared `isCompletionSummaryNode` predicate exported
from `@fusion/core`.

## 2. The i18n crash the reporter saw — dashboard
`t("taskDetail.executionMode")` resolves to a **nested object** (the
inline mode-toggle copy), so i18next returns *"key
'taskDetail.executionMode (en)' returned an object instead of string"*
and crashes the Stats tab — the exact error in the report. Surface
enumeration found **two more** callers of the same class:
`routing.source` and `nodes.dockerHost`. Added leaf label keys across
all 6 locales and switched the callers.

## Tests
- `workflow-graph-completion-summary-nonfatal.test.ts` — a failing
summary node (both modes) never terminates/loops the graph, a
non-summary node still fails, and all 5 built-ins have no failure edge.
**Fails without the engine fix.**
- `i18n-string-keys-not-objects.test.ts` — invariant guard scanning
every `t("literal")` caller against the real `en/app.json`. **Catches a
reverted caller.**
- `TaskTokenStatsPanel.test.tsx` — reproduces the exact i18next error
against the real bundle.

## Verification
- Merge gate: **317 engine-core + 63 CI-shape pass**
- Core/engine typecheck clean; i18n parity + typecheck pass; changeset
validates
- All touched dashboard/core/engine suites green

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

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

* **Bug Fixes**
* Fixed an issue where completion-summary failures could cause tasks to
loop indefinitely during resume.
* Made completion-summary behavior best-effort so workflows keep
progressing even when summary handling fails.
* Prevented dashboard crashes by ensuring UI labels use leaf translation
keys (not nested objects).

* **New Features**
* Added missing i18n label keys for Docker host, routing source, and
execution mode across multiple languages.

* **Tests**
* Added regression coverage for completion-summary non-fatal handling
and translation-key validation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-01 17:31:43 -07:00
gsxdsm
704e891f57 Merge origin/main into feature/fix-triage
Resolves the pnpm-lock.yaml conflict. Main's #1865 (review-checkout routing)
auto-merged cleanly with the completion-summary backstop in executor.ts.

Main independently pinned pi-claude-cli's pi-ai/pi-coding-agent to ^0.80.3
(e15489259) but kept the top-level `getModels` import, which 0.80.3 removed —
this branch's migration to `getBuiltinModels` from `/providers/all` is retained
as the working fix. Lockfile regenerated against the merged package.json.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 17:11:37 -07:00
gsxdsm
98db2874cc fix(pi-claude-cli): pin pi-ai/pi-coding-agent to ^0.80.3 and migrate to getBuiltinModels
The Typecheck CI gate was failing because pi-claude-cli declared pi-ai and
pi-coding-agent as unpinned "*" peers. pi-ai 0.80 was published and, via
hoisting/non-frozen resolution, the bare `@earendil-works/pi-ai` import floated
to 0.80.3 — which moved the top-level `getModels` export to the deprecated
`/compat` shim ("has no exported member named 'getModels'").

Migrate forward to the latest, consistent with cli/engine which already pin
^0.80.3:
- Pin pi-ai and pi-coding-agent to ^0.80.3 (peer + dev) so the whole extension
  resolves one pi-ai version; pinning pi-coding-agent too avoids the
  AssistantMessageEventStream type skew that a pi-ai-only bump reintroduced.
- Import the canonical `getBuiltinModels` from
  `@earendil-works/pi-ai/providers/all` (identical signature to the old
  `getModels`; the top-level export is now the deprecated compat alias).
- Update the provider test mock to the new subpath.

Behavior-preserving: getBuiltinModels === getModels. Typecheck, the full
recursive typecheck, and all 347 pi-claude-cli tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 17:05:23 -07:00
gsxdsm
a03aae7f66 fix(engine): route review via explicit external checkout metadata (#1865)
## Summary
- Add explicit `sourceMetadata.externalReviewCheckout` review routing
with fail-closed validation.
- Log the selected review checkout so operator/runtime tasks can verify
where review ran.
- Cover metadata extraction, invalid metadata fallback,
`fn_review_step`, and workflow `stepReview` routing.

## Test Plan
- `cd packages/engine && corepack pnpm exec vitest run
src/__tests__/review-checkout.test.ts
src/__tests__/reviewer-workspace.test.ts`


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

* **New Features**
* Review routing now supports explicit external checkout overrides via
review checkout metadata, using the resolved external checkout as the
review working directory when valid.
* Logging now highlights the selected review routing target and warns
when external checkout metadata is present but invalid.

* **Bug Fixes**
* Missing/blank/invalid/relative/nonexistent/non-git paths now fail
closed to the task worktree instead of falling back.
* Metadata priority is enforced strictly (custom fields → branch context
→ source metadata → root), preventing lower-priority fallback when
higher-priority data is invalid.

* **Tests**
* Added/expanded automated coverage for override and fail-closed
behavior, including workspace-mode routing semantics.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-01 17:02:30 -07:00
gsxdsm
38841695c8 fix: stop triage loop at completion-summary node and i18n object-key crashes (#1863)
Two distinct v0.52.0 regressions reported in issue #1863.

1. Triage loop (engine): the best-effort completion-summary graph node is
   wired into every built-in workflow with a success-only edge. A thrown
   handler exception or a failed summary projection write bypassed the
   advisory `!blocking -> success` coercion, terminated the graph at
   'completion-summary', and routeGraphFailureToExecutionResume bounced the
   in-review task back to todo forever (token usage 0, execution NOT STARTED).
   The graph executor now degrades a completion-summary node failure to
   success (ensureWorkflowCompletionSummary still backfills task.summary), with
   a routeGraphFailureToExecutionResume backstop. Shared isCompletionSummaryNode
   predicate exported from @fusion/core.

2. i18n object-key crashes (dashboard): three views called t() with keys that
   resolve to nested objects (taskDetail.executionMode, routing.source,
   nodes.dockerHost), so i18next returned "returned an object instead of
   string" and crashed the render. Added leaf label keys across all locales and
   switched the callers.

Tests: engine non-fatal completion-summary regression (fails without the fix),
dashboard invariant guard scanning t("literal") callers against real en/app.json,
and a Stats-panel reproduction against the real bundle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 16:43:08 -07:00
gsxdsm
c59ae0b969 fix(anthropic): restore direct OAuth execution for Claude subscriptions (#1862)
## Problem

Claude **subscription** (Max/Pro) chats fail with a rotating `404 / 502
/ 429` cascade — the same symptom as #1857, which was reported fixed.
Raw `ANTHROPIC_API_KEY` and explicit Claude CLI usage work; direct OAuth
does not.

## Root cause (proven against git history)

- **v0.51.0 (worked):** `packages/core/src/anthropic-models.ts` didn't
exist. `getApiKey("anthropic")` returned the subscription **OAuth**
access token and pi-ai's built-in `anthropic` provider POSTed it to
`api.anthropic.com/v1` with **Claude Code identity headers** (`Bearer` +
`anthropic-beta: claude-code-20250219,oauth-2025-04-20`). Direct OAuth
worked — **not** via the CLI.
- **The regression chain:** #1857 mis-concluded "0.51.0 uses the CLI /
OAuth is blocked on /v1" (its `grep` missed the runtime-appended `/v1`;
a naive curl repro lacked pi-ai's full impersonation). FN-7291 → FN-7391
→ FN-7396 were built on that wrong premise. FN-7396's
`registerAnthropicSubscriptionProvider` rerouted subscription OAuth to a
new `anthropic-subscription` provider **still pointed at
`api.anthropic.com/v1`** — reintroducing #1857.

## Fix — restore the v0.51.0 path (three independent surfaces, no
rerouting)

- **`auth-storage.ts`** — `getApiKey("anthropic")` resolves
subscription/legacy OAuth again (raw API key still takes precedence), so
the built-in provider receives the token.
- **`pi.ts`** — remove the runtime reroute and the `/v1`-based
`anthropic-subscription` execution provider; `anthropic/*` selections
stay on the built-in OAuth-capable provider.
- **`register-model-routes.ts`** — advertise `anthropic` in the picker
for OAuth users so direct OAuth is selectable.
- Result: **direct OAuth**, **raw `ANTHROPIC_API_KEY`** (precedence),
and **explicit `pi-claude-cli`** all work independently.

## Verification

- `packages/engine`: `auth-storage.test.ts` +
`pi-create-fn-agent.test.ts` — **137 passed** (assertions restored to
the correct invariant; the FN-7391/FN-7396 tests encoded the bug).
- `packages/dashboard`: `routes-auth.test.ts` + `usage.test.ts` — **352
passed**.
- `pnpm --filter @fusion/engine build` clean.
- Docs (`settings-reference.md`, `dashboard-guide.md`) + changeset
updated.

Fixes #1857

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

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

* **Bug Fixes**
* Restored Anthropic Claude subscription chat reliability by reverting
the OAuth execution behavior to the expected direct runtime flow.
* Improved Anthropic credential precedence and provider visibility
across direct API key, subscription OAuth, and Claude CLI modes.
* Reinstated Claude Sonnet 5 in the model picker with correct
catalog/pricing.
* **Documentation**
* Updated the OAuth re-login banner guide and settings reference to
clarify Anthropic credential behavior and precedence.
* **Tests**
* Updated authentication, model discovery, session routing, and pricing
expectations for Anthropic scenarios.
* **Chores**
* Tightened peer dependency version constraints for the Claude CLI
package.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-01 16:40:36 -07:00
Phil Larson
87ce37831c fix(engine): address review checkout routing feedback 2026-07-01 16:38:27 -07:00
Phil Larson
c46d11f0a3 test(cli): keep extension engine mocks current 2026-07-01 16:34:02 -07:00
gsxdsm
e154892596 Align pi-claude-cli peer deps to pi-ai 0.80.3
The vendored pi-claude-cli extension declared `@earendil-works/pi-ai` and
`pi-coding-agent` as `*` peers, so its dev/workspace resolution drifted to
0.77.0 while the rest of the workspace is on ^0.80.3. Pin both peers to
^0.80.3 so the extension's `getModels("anthropic")` catalog (which feeds the
pi-claude-cli picker rows) matches the engine/cli — 0.80.3 ships
claude-sonnet-5 natively. Behavior-preserving; the bundled CLI already
provided 0.80.3 at runtime.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 16:30:52 -07:00
Phil Larson
b58d9b5d2f chore: add review checkout routing changeset 2026-07-01 16:27:21 -07:00
Phil Larson
f76d2f3609 fix(engine): route review via explicit external checkout metadata 2026-07-01 16:26:54 -07:00
gsxdsm
b7c6443a7b Restore Claude Sonnet 5 in the picker + address PR review feedback (#1862)
Sonnet 5 had disappeared from every surface: pi-ai 0.79.9 (the installed
version) lacks it, and FN-7374 removed the static row expecting the live
registry to carry it. Live-verified that claude-sonnet-5 returns 200 on
api.anthropic.com/v1 with a raw ANTHROPIC_API_KEY and runs via the Claude
CLI (it 403s on subscription-OAuth /v1 — scope-gated; runtime fallback
applies). Note: pi-ai 0.80.3 ships sonnet-5 natively, so this SUPPLEMENTAL
row dedupes once the install catches up.

- core: re-add claude-sonnet-5 to SUPPLEMENTAL_ANTHROPIC_PROVIDER_REGISTRATION
  and restore its static pricing (revert FN-7374); update pricing tests.
- engine/dashboard tests: flip the FN-7374 "withheld" assertions to the
  restored "advertised" behavior.

PR feedback:
- Trim the two FNXC comments (auth-storage.ts, pi.ts) to concise
  requirement prose per coding guidelines (CodeRabbit).
- Replace the now-inert getApiKey mock in two subscription routing tests
  with a clarifying note (Greptile).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 16:19:03 -07:00
gsxdsm
a1af5de609 fix(anthropic): restore direct OAuth execution for Claude subscriptions
Claude subscription (Max/Pro) chats regressed to 404/502/429 because
FN-7396 rerouted subscription OAuth to a /v1-based `anthropic-subscription`
runtime provider — reintroducing issue #1857 that FN-7391 had fixed. Both
routed the OAuth token to api.anthropic.com/v1, the surface that broke.

Proven in code that v0.51.0 (working) sent subscription OAuth directly to
/v1 via pi-ai's built-in `anthropic` provider (Claude Code impersonation:
Bearer + anthropic-beta oauth headers), NOT through the CLI. Restore that:

- auth-storage: getApiKey("anthropic") resolves subscription/legacy OAuth
  again (raw API key still wins), so the built-in provider gets the token.
- pi.ts: remove the runtime reroute and the /v1 `anthropic-subscription`
  execution provider so anthropic/* selections stay on the built-in provider.
- register-model-routes: advertise `anthropic` for OAuth users so direct
  OAuth is selectable in the picker.

Three independent surfaces, no rerouting: direct OAuth, raw ANTHROPIC_API_KEY
(precedence), and explicit pi-claude-cli.

Fixes #1857

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 15:40:16 -07:00
gsxdsm
20e42c65d1 FN-7400: enforce JSON protocol for CE debug launches
Prevent Compound Engineering Debug stages from failing launch when skill guidance would otherwise produce prose.

- Prioritize the interactive JSON question/complete protocol over loaded skill instructions in CE stage prompts.
- Document CE Debug dashboard protocol requirements in the bundled debug skill.
- Add regression coverage for Debug stage startup, malformed-output errors, and session list/delete handling.
- Add a patch changeset for the published Fusion package.

Files changed:
 .changeset/fn-7400-compound-debug-stage-json.md    |  7 ++
 .../src/__tests__/session-routes.test.ts           | 89 +++++++++++++++++++++-
 .../src/__tests__/stage-launch-guard.test.ts       | 78 +++++++++++++++++++
 .../src/session/orchestrator.ts                    |  7 +-
 .../src/skills/ce-debug/SKILL.md                   |  5 ++
 5 files changed, 184 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7400

Fusion-Task-Lineage: 7d37660b-1073-489f-8115-20f07c8b05a4

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 15:39:34 -07:00
gsxdsm
9c2a264322 FN-7398: restore Anthropic model selection
Restore Anthropic model selector discovery across API-key, OAuth subscription, and Claude CLI flows.

- Read injected auth storage when building /api/models so Settings connection state feeds model availability.
- Keep Anthropic subscription OAuth separate from direct Anthropic API-key rows while allowing enabled Claude CLI models to appear.
- Add regression coverage for selector rendering, stale empty catalog refresh, and authenticated model-route filtering.
- Document the restored Anthropic provider surfaces and add a patch changeset.

Files changed:
 .changeset/fn-7398-anthropic-model-selector.md     |   7 ++
 docs/settings-reference.md                         |   4 +-
 .../components/__tests__/ModelSelectorTab.test.tsx | 105 +++++++++++++++++
 .../app/hooks/__tests__/useModelsCache.test.ts     |  40 +++++++
 .../dashboard/src/__tests__/routes-auth.test.ts    | 125 ++++++++++++++++++++-
 .../dashboard/src/routes/register-model-routes.ts  |  60 +++++++++-
 6 files changed, 333 insertions(+), 8 deletions(-)

Fusion-Task-Id: FN-7398

Fusion-Task-Lineage: 5d1b1b8e-9b8b-40fe-b76f-7d6142e0e21f

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 15:39:34 -07:00
gsxdsm
f998fe3ffc FN-7397: pass plugin context to lifecycle hooks
Ensure task lifecycle plugin hooks receive a PluginContext when fired through runtime event bridges.

- Append the plugin context for task-created, task-moved, and task-completed hooks when callers only provide raw lifecycle arguments.
- Preserve existing explicit-context hook calls and add coverage for loader and runner lifecycle dispatch paths.
- Cover Compound Engineering sync completion handling so taskStore is available in onTaskCompleted.

Files changed:
 .changeset/fn-7397-plugin-hook-context.md          |  7 +++
 packages/core/src/__tests__/plugin-loader.test.ts  | 52 +++++++++++++++++++++-
 packages/core/src/plugin-loader.ts                 | 34 +++++++++++++-
 .../engine/src/__tests__/plugin-runner.test.ts     | 25 ++++++++++-
 .../src/__tests__/sync.test.ts                     | 29 +++++++++++-
 5 files changed, 141 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-7397

Fusion-Task-Lineage: 7661714c-cf2a-4f4d-bec1-fc6bc11c0613

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 15:39:34 -07:00
gsxdsm
07aa1a0085 FN-7399: widen Project Models model menus
Make Project Models dropdown menus easier to scan without changing shared selector defaults.

- Add an opt-in readable menu width mode to the shared custom model dropdown.
- Apply the wider menu only to Project Models lane, workflow, and preset model selectors.
- Cover readable sizing, viewport clamping, and default trigger-width behavior with dashboard tests.
- Add a patch changeset for the published Fusion package.

Files changed:
 .changeset/wide-project-model-dropdowns.md         |   7 +
 .../app/__tests__/settings-sections.test.tsx       |  66 ++++++-
 .../app/components/CustomModelDropdown.tsx         |  17 +-
 .../__tests__/CustomModelDropdown.test.tsx         | 210 +++++++++++++++++++++
 .../settings/sections/ProjectModelsSection.tsx     |   8 +-
 5 files changed, 301 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-7399

Fusion-Task-Lineage: 40aae990-37bc-4ed8-8e2a-7e78a543053b

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 15:39:34 -07:00
gsxdsm
519d8dfbc8 FN-7394: stabilize broad App test setup
Stabilize App.test.tsx by resetting shared dashboard shell mocks for broad runs.

- Add default workflow and dashboard health API mock responses for App-level setup.
- Keep the default project list, current project, and persisted project view mode aligned between tests.
- Use persistent auth/settings mocks where App onboarding checks can re-fetch state.

Files changed:
 .../app/components/__tests__/App.test.tsx          | 65 ++++++++++++++++++----
 1 file changed, 55 insertions(+), 10 deletions(-)

Fusion-Task-Id: FN-7394

Fusion-Task-Lineage: 9b59ad83-817d-4285-940d-42d1bec29c20

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 15:39:34 -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
19e59ec6c8 FN-7396: separate Anthropic OAuth routing paths
Separate Anthropic subscription OAuth execution from raw API-key and Claude CLI routing.

- Route subscription-backed Anthropic selections through a dedicated anthropic-subscription provider instead of raw anthropic API-key storage or implicit CLI execution.
- Preserve Anthropic OAuth refresh, status, usage, and re-login banner behavior across separated and legacy credential rows.
- Add dashboard and engine coverage for OAuth subscription auth, raw API-key isolation, and explicit Claude CLI routing.
- Document the separated Anthropic subscription, API-key, and CLI surfaces and add a release changeset.

Files changed:
 .../fn-7396-anthropic-oauth-cli-api-paths.md       |   7 ++
 docs/dashboard-guide.md                            |   4 +-
 docs/settings-reference.md                         |  12 ++-
 .../__tests__/OAuthReloginBanner.test.tsx          | 118 +++++++++++++++++++++
 .../dashboard/src/__tests__/routes-auth.test.ts    |  29 +++++
 packages/dashboard/src/__tests__/usage.test.ts     | 109 ++++++++++++++++++-
 .../dashboard/src/routes/register-auth-routes.ts   |  20 +++-
 packages/dashboard/src/usage.ts                    |  21 +++-
 packages/engine/src/__tests__/auth-storage.test.ts |  65 ++++++++++++
 .../src/__tests__/pi-create-fn-agent.test.ts       |  55 ++++++++--
 packages/engine/src/auth-storage.ts                |  61 +++++++++--
 packages/engine/src/pi.ts                          |  70 ++++++++----
 12 files changed, 521 insertions(+), 50 deletions(-)

Fusion-Task-Id: FN-7396

Fusion-Task-Lineage: f5f42a40-b855-46ad-b2ae-3509e903f286

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 15:39:34 -07:00
gsxdsm
1ccef81950 FN-7393: add planner chat task metrics access
Planner chat can now answer read-only task usage and timing questions with scoped metrics context.

- Add a task-scoped metrics tool for token, cost, runtime, timing-event, workflow-step, and per-model usage summaries.
- Wire planner chat to expose the metrics tool only for task-detail planner sessions.
- Cover metric aggregation, stale pricing uncertainty, chat tool routing, and planner context behavior with dashboard tests.
- Document planner chat metrics support and add a published package changeset.

Files changed:
 .changeset/fn-7393-planner-metrics.md              |   7 +
 docs/dashboard-guide.md                            |   2 +-
 .../dashboard/src/__tests__/chat-manager.test.ts   | 153 +++++++
 .../__tests__/task-planner-chat-metrics.test.ts    | 243 +++++++++++
 packages/dashboard/src/chat.ts                     |  61 ++-
 .../dashboard/src/task-planner-chat-context.ts     |   5 +-
 .../dashboard/src/task-planner-chat-metrics.ts     | 445 +++++++++++++++++++++
 7 files changed, 912 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-7393

Fusion-Task-Lineage: aed7574e-67cf-49af-982f-dfd4620ebe0a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 15:39:34 -07:00
gsxdsm
4beae7130d FN-7392: suppress hidden planner chat unread badges
Suppress hidden task-planner chat replies from triggering the global unread badge while preserving opt-in common-feed behavior.

- Enrich chat message SSE payloads with session agent metadata and task chat common-feed visibility.
- Ignore hidden `task-planner:` assistant events in the chat unread badge hook.
- Cover hidden, visible, and legacy payload behavior with dashboard SSE and hook tests.
- Document the unread badge scope and add a patch changeset for the published CLI package.

Files changed:
 .changeset/fn-7392-planner-chat-unread.md          |   7 +
 docs/dashboard-guide.md                            |   2 +-
 .../app/components/__tests__/App.test.tsx          |  55 ++++++++
 .../app/hooks/__tests__/useChatUnreadBadge.test.ts | 110 ++++++++++++++++
 packages/dashboard/app/hooks/useChatUnreadBadge.ts |  32 ++++-
 packages/dashboard/src/__tests__/sse.test.ts       | 141 ++++++++++++++++++++-
 packages/dashboard/src/sse.ts                      |  36 +++++-
 7 files changed, 378 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-7392

Fusion-Task-Lineage: 13fd5c51-eefa-4088-979b-005c8b217f89

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 15:39:34 -07:00
gsxdsm
bfe5ceddc8 FN-7389: dedupe Claude CLI Sonnet 5 models
Keep Claude Sonnet 5 visible only through eligible provider catalogs without duplicate picker rows.

- Dedupe API model rows by provider/model after registry and supplemental catalog merges.
- Cover Claude CLI Sonnet 5 visibility, disabled-toggle filtering, and duplicate suppression in API tests.
- Add dropdown coverage for stale direct-Anthropic favorite shells when Claude CLI Sonnet 5 is selected.
- Add a patch changeset for the model picker fix.

Files changed:
 .changeset/fn-7389-sonnet-5-model-list.md          |  7 +++++
 .../__tests__/CustomModelDropdown.test.tsx         | 33 ++++++++++++++++++++++
 .../dashboard/src/__tests__/routes-auth.test.ts    | 15 ++++++++--
 .../dashboard/src/routes/register-model-routes.ts  | 12 ++++++++
 4 files changed, 65 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7389

Fusion-Task-Lineage: d41b422e-60f9-46c3-9c6f-d115a86e9e2a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 15:39:33 -07:00
gsxdsm
775ff5fb9c FN-7391: route Anthropic subscription chats through Claude CLI
Keep Anthropic OAuth subscription credentials away from the direct /v1 provider while preserving raw API-key routing.

- Treat direct anthropic auth as raw API-key-only in auth storage and model discovery.
- Re-route persisted anthropic model selections to the Claude CLI provider when no raw Anthropic API key is configured.
- Add regression coverage for OAuth-only routing, raw API-key preservation, and provider list separation.
- Document the distinct raw API key, OAuth subscription, and Claude CLI routes.

Files changed:
 .../fn-7391-anthropic-subscription-cli-routing.md  |   7 ++
 docs/settings-reference.md                         |   2 +-
 .../dashboard/src/__tests__/routes-auth.test.ts    |  74 ++++++++++++++
 .../dashboard/src/routes/register-model-routes.ts  |  27 +++++-
 packages/engine/src/__tests__/auth-storage.test.ts | 108 +++++++--------------
 .../src/__tests__/pi-create-fn-agent.test.ts       | 100 +++++++++++++++++++
 packages/engine/src/auth-storage.ts                |  45 ++++-----
 packages/engine/src/pi.ts                          |  61 ++++++++++++
 8 files changed, 319 insertions(+), 105 deletions(-)

Fusion-Task-Id: FN-7391

Fusion-Task-Lineage: d1fecc2d-7f31-408c-bf65-0e65b7fd88b1

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 15:39:33 -07:00