Make the right dock a persistent far-right surface with its own collapse control.
- Default the right dock to visible and preserve a collapsed rail instead of hiding it entirely.\n- Remove Header right-dock toggle props and routing so More views remains a menu and left-sidebar mode has no duplicate Header toggle.\n- Update docs, changeset, and regression tests for persistent dock behavior.\n\nFiles changed:\n .changeset/fn-6899-click-revealed-right-dock.md | 5 ++\n docs/dashboard-guide.md | 6 +-\n packages/dashboard/app/App.tsx | 1 -\n .../mobile-feature-access-regression.test.tsx | 32 ++------\n packages/dashboard/app/components/Header.tsx | 57 +++-----------\n packages/dashboard/app/components/RightDock.css | 18 +++++\n packages/dashboard/app/components/RightDock.tsx | 86 ++++++++++++----------\n .../app/components/__tests__/Header.test.tsx | 57 +++-----------\n .../app/components/__tests__/RightDock.test.tsx | 31 ++++++--\n .../app/components/useRightDockController.tsx | 4 +-\n 10 files changed, 132 insertions(+), 165 deletions(-)
Fusion-Task-Id: FN-6899
Fusion-Task-Lineage: 96c4ba70-eb73-4034-8254-6a192402d905
Optimistically attach newly quick-created tasks to the active workflow lane until workflow metadata refetches.
- Update board and list quick-create paths to cache the selected workflow for created tasks immediately.\n- Refresh board-workflows metadata after optimistic assignment so authoritative state reconciles.\n- Cover board/list workflow-lane quick-create visibility with regression tests.\n- Document the workflow-filtered quick-create behavior and add a patch changeset.\n\nFiles changed:\n .../fn-6903-workflow-lane-create-visibility.md | 5 +\n docs/dashboard-guide.md | 2 +-\n packages/dashboard/app/components/Board.tsx | 34 ++-\n packages/dashboard/app/components/ListView.tsx | 36 ++-\n ...d-quickcreate-workflow-lane-visibility.test.tsx | 319 +++++++++++++++++++++\n 5 files changed, 390 insertions(+), 6 deletions(-)
Fusion-Task-Id: FN-6903
Fusion-Task-Lineage: dd2c6fa1-f2e8-4777-aa3c-69d000efb1b1
Add explicit OpenAI Codex pricing so token analytics can estimate Codex run costs.
- Add openai-codex pricing entries for GPT-5 Codex variants and codex-mini-latest.
- Bump the pricing verification date and document why Codex keys must use the openai-codex provider.
- Cover Codex pricing and lookup behavior in model-pricing tests.
- Add a changeset for the published Fusion package.
Files changed:
.changeset/fn-6869-codex-pricing.md | 7 ++++
packages/core/src/__tests__/model-pricing.test.ts | 37 ++++++++++++++++++-
packages/core/src/model-pricing.ts | 44 ++++++++++++++++++++++-
3 files changed, 86 insertions(+), 2 deletions(-)
Fusion-Task-Id: FN-6869
Fusion-Task-Lineage: 4bf119db-0401-4b18-b389-4a762e665cfc
Make dashboard toast status text readable across themed dark and light modes.
- Add toast text tokens and Shadcn-specific success/info color overrides that preserve contrast.
- Cover success, error, and info toast contrast across all Shadcn variants and mobile toast styling.
- Add a patch changeset for the published Fusion package.
Files changed:
.changeset/fn-6858-toast-contrast.md | 5 +
.../app/__tests__/toast-theme-contrast.test.ts | 320 +++++++++++++++++++++
packages/dashboard/app/styles.css | 44 ++-
3 files changed, 368 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-6858
Fusion-Task-Lineage: 1c06e346-9269-4965-a3ae-4ac02b43188e
Update the pi SDK dependency family across Fusion packages and record a patch changeset.
- Bump @earendil-works/pi-ai and @earendil-works/pi-coding-agent to ^0.79.9 where used by CLI, dashboard, and engine packages.
- Refresh pnpm-lock.yaml to resolve the updated pi SDK dependency graph.
- Add a patch changeset for the published @runfusion/fusion package.
Files changed:
.changeset/fn-6853-pi-sdk-bump.md | 5 +
packages/cli/package.json | 4 +-
packages/dashboard/package.json | 2 +-
packages/engine/package.json | 4 +-
pnpm-lock.yaml | 285 +++++++++++++++++++++++++++-----------
5 files changed, 214 insertions(+), 86 deletions(-)
Fusion-Task-Id: FN-6853
Fusion-Task-Lineage: bc2dba95-b8c2-48d1-855d-847e6eec9606
stuckKillCount is a lifetime counter — incremented by self-healing on each stuck-kill
and reset ONLY by a manual retry — so a long task that genuinely advances between
intermittent stalls could be terminalized by accumulation toward maxStuckKills (default 6),
even though it is making progress.
Reset the streak in TaskStore.updateStep when a step reaches a terminal forward status
(done/skipped), the single chokepoint every step-completion surface routes through (legacy
fn_task_update, graph markStepDone, fn_task_done). It deliberately does NOT rescue a task
wedged re-running the same failing step — no step completes between those kills, so it still
terminalizes as designed; it only bounds the budget to consecutive stalls. Complements the
verification fan-out cap (PR #1708) that keeps verification fast in the first place.
New regression suite asserts reset on done/skipped/graph-source-done and NO reset on
in-progress advance or ignored out-of-order transitions. Merge gate + full @fusion/core
suite (6242 tests) + engine self-healing/stuck-detector (442 tests) green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tighten the executor agent guidance and the fn_run_verification tool guidance so
verification stays scoped to changed files instead of running the full workspace
test suite, which (for a foundational-package edit) reverse-expands across the
whole workspace and stalls the task.
- agent-prompts.ts: remove the "during final integration" blanket permission to
run workspace-wide suites; name the forbidden full-run commands explicitly.
- run-verification-tool.ts: strengthen BOUNDED_VERIFICATION_GUIDANCE to forbid
`pnpm test:full` / `pnpm verify:workspace` / whole-package runs as verification.
Engine + core typecheck pass; run-verification-command and executor-review-verdicts
prompt-assertion suites stay green (93 tests).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When the engine aborted in-flight work mid-execution and bounced the task
back to `todo`, the single-session teardown cleared the task `branch` and
re-queued without `preserveResumeState` — resetting every step to `pending`
(store.moveTaskInternal resetAllStepsToPending) and dropping the pointer to
the commits already on the task branch. The next dispatch then re-planned
from Step 0 and the committed work was stranded, observed as FN-6722 losing
all its progress and getting stuck in todo.
The teardown now keeps the branch and moves with `preserveResumeState`
whenever the task has resumable step progress, matching the sibling
step-session (executor ~8065) and pause-park (executor ~1826) paths, so
execute() resumes onto the existing branch from the first incomplete step.
The worktree is still removed to free its concurrency slot (FN-6782) — only
the durable pointers (branch + step state) are kept.
Adds a regression test driving the exact single-session catch teardown.
Fusion-Task-Id: FN-6722
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Many loading states rendered bare "Loading…" text with no spinner
element, and a couple rendered an unstyled `loading-spinner` div with no
matching CSS (invisible). The global spin animation was never broken —
it rotates in Chromium and WebKit — so prior transform-box edits chased
a non-bug, validated only by a string-matching CSS test.
Add a shared <LoadingSpinner> (self-contained animated SVG, no
lucide-react import so it survives partial test mocks) and adopt it
across ~47 loading placeholders so every loading state shows a
consistent animated spinner. Includes a component test that asserts the
svg carries the animate-spin utility.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
discoverDroidModels ran `droid models`/`droid model list`, which aren't real
droid commands — they parse as a prompt and launch a persistent
`droid exec --stream-jsonrpc` agent session that never exits, leaking a process
per call. The dashboard reloads the droid extension on every chat-send, so these
piled into dozens of orphaned `droid` processes.
Switch discovery to parse `droid exec --help` (lists Available + Custom models,
exits cleanly) via new parseDroidModelsFromHelp, and add a SIGKILL-on-timeout
guard so a wedged spawn can never leak. Verified against the real binary: 46
models, 0 leaked processes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The dashboard's engine-availability health check only counted engines
this process started. A second launch (e.g. `pnpm dev dashboard`
alongside an already-running `fusion`) is correctly refused the
per-machine engine singleton lock, so its engine map stays empty and
the dashboard showed a false "engine not running" banner even though an
engine was live on the machine.
ProjectEngineManager now records projects whose singleton lock is held
by another process (via EngineAlreadyRunningError) and exposes
hasRunningEngine(), which the health endpoint consults so the banner
reflects machine-level truth. Reconciliation still retries so this
process takes over if the other exits, and the "refusing to start" log
fires once per project instead of on every 30s reconciliation tick.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
resolveCustomProviderApiType mapped the `anthropic-compatible` provider type
to the api key "anthropic", but pi-ai (@earendil-works/pi-ai) registers the
Anthropic Messages API under "anthropic-messages". Any custom provider
configured as anthropic-compatible selected a model whose `api` did not match
a registered provider, throwing "No API provider registered for api: anthropic"
at stream time (the model registered fine, but failed when a task tried to
stream).
The openai-responses and default (openai-completions) arms already map to real
registry keys and work; only the anthropic arm pointed at an unregistered key.
Extend the existing custom-provider registration test (which covered
openai-compatible and openai-responses but not anthropic-compatible) with a
regression assertion that anthropic-compatible maps to "anthropic-messages".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolve conflicts from main's analytics schema additions (plugin
activations, per-model token buckets) against the PR's contract-assertion
type column:
- db.ts: renumber behavioral-verification migration 124 -> 126, bump
SCHEMA_VERSION to 126 so it follows main's migrations 124/125
- core/roadmap tests: adopt main's SCHEMA_VERSION-constant assertions
instead of stale literal 124
- test-quarantine.json: keep all four quarantine entries from both sides
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Add required `---` frontmatter fences to the changeset so the
changesets CLI picks it up during release (greptile P1).
- Mark the remote version as reloaded only when a reload actually
proceeds, so a pre-existing RELOAD_FLAG no longer permanently
suppresses future reloads for that version (greptile P2).
- Bump service-worker cache to v5 after merging main's v4 and update
the pwa test assertions accordingly.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The dashboard's discovered-skills catalog was built only from the
disk-scanning package manager, so plugin-contributed skills (e.g.
compound-engineering ce-*) — which the engine materializes for executor
sessions separately — never appeared in the editor. Built-in workflow
nodes that reference them (builtin:compound-engineering) showed
"— select skill —" / unresolved.
- skills-adapter: merge plugin skill contributions into the discovered
list (deduped by bare name) via an optional getPluginSkills thunk;
add shared bareSkillName normalizer.
- wire getPluginSkills into all three server entry points: serve,
daemon, and dashboard (the UI-serving command — verified via live
end-to-end that omitting it left the editor catalog empty).
- node-summary + WorkflowNodeEditor: resolve namespaced skillNames
(compound-engineering:ce-work) against the catalog's two-segment
names (ce-work/SKILL.md) so nodes display and select the right skill.
Verified: dashboard + CLI typecheck, 136 dashboard tests, and a live
dashboard E2E (discovered skills 0→11; Plan node resolves to "ce-plan"
in both the canvas label and the inspector dropdown).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>