Commit Graph

2161 Commits

Author SHA1 Message Date
gsxdsm
99b80ad748 feat(dashboard): add opt-in auto-update and harden restart supervision
Add the `autoUpdateAndRestart` global setting (default off, Settings ->
General next to Release channel). When enabled, the dashboard host installs
available updates on the selected channel by itself and requests the
supervised in-place restart. Supervised hosts only: without a parent to
respawn, installing would leave a running process whose code no longer
matches its own install.

Fix two ways the restart affordance could silently do nothing:

- The supervisor now stamps FUSION_SUPERVISOR_PID and supervision is only
  counted when that pid is the real parent. FUSION_RESTART_SUPERVISED is
  inherited by every process Fusion spawns, so `fn dashboard` launched from
  an agent terminal skipped its own supervisor while still advertising
  restart support -- a restart request then killed it for good.
- Settings and the update banner probe /system/info on mount and treat
  capability as advisory: the button always issues the request and shows the
  server's actual refusal instead of sitting disabled after a failed probe.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 22:52:53 -07:00
gsxdsm
41d60f0355 feat(board): explain the unplanned promote rejection and let operators force past it
Promote on a held card printed the raw i18n key `board.rejection.unplannedForExecution`:
FN-8471 added the server-side code without a client case or catalog entry, so
translateRejection fell through to `t(messageKey, messageKey)`.

- Add the explicit rejection case (both translate helpers) plus the en catalog
  entry and secondary-locale stubs.
- promoteHeldTask(..., { force }) waives ONLY the unplanned-for-execution gate;
  hold membership, capacity and slot reservation still arbitrate. It clears a
  needs-replan/plan-review-unavailable status so triage rediscovery cannot pull
  the card back into the waived replan, and emits task:promote-forced-unplanned.
- POST /tasks/:id/promote accepts { force: true }; the board asks for explicit
  confirmation first and only offers the override for this rejection.

Force stays operator-only — the sweep, the webhook release and fn_task_promote
never set it, so FN-7648 still holds for every automatic surface.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 19:56:54 -07:00
gsxdsm
e4fb3f994e fix(dashboard): one Planning add-comment trigger, shown when the selection is done
The plan review pane rendered both the document-adjacent and the action-rail
"Add comment to selection" triggers, so operators saw duplicate buttons. Delete
the document variant and its --document/--mobile CSS pair; the rail button is
now the single control at every breakpoint.

Selection capture also ran on every mid-drag selectionchange, which mounted and
unmounted the trigger as the user dragged. Gate quote writes between pointerdown
and pointerup inside the plan document so the control appears once, on release.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 10:02:02 -07:00
gsxdsm
13ff8850f4 fix(dashboard): restore System panel "Restart all agents" under PostgreSQL
POST /system/agents/restart-all constructed its AgentStore from rootDir alone,
with no AsyncDataLayer, so it fell through to the sync SQLite Database path
deleted under VAL-REMOVAL-005 and threw instead of bouncing agents. It now
builds the store against the scoped project's PostgreSQL layer via
requireAsyncLayer, failing loudly when project wiring is incomplete rather
than reading a SQLite shadow. This was the last unmigrated AgentStore call
site; the route test harness lacked getAsyncLayer, which is why nothing
caught it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 09:05:41 -07:00
gsxdsm
3597d06380 FN-8578: pin verified Parakeet v3 model asset
Enable secure downloads of the upstream Parakeet v3 voice model.

- Pin the archive URL, filename, SHA-256, expected files, and nested extraction layout.
- Accept the archive's BSD tar timestamp format while preserving safe extraction checks.
- Cover download gates and installation behavior, and document the verified model asset.

Files changed:
 .changeset/fn-8578-parakeet-v3-asset-pin.md        |  7 ++++
 docs/dashboard-guide.md                            |  2 +-
 docs/settings-reference.md                         |  8 ++--
 .../src/stt/__tests__/model-manager.test.ts        | 46 ++++++++++++++++++++++
 .../dashboard/src/stt/__tests__/voice-stt.test.ts  | 33 +++++++++++++++-
 packages/dashboard/src/stt/model-manager.ts        | 13 +++---
 packages/dashboard/src/stt/types.ts                | 18 +++++++--
 7 files changed, 114 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-8578

Fusion-Task-Lineage: ab397190-fa0c-491e-b0f8-0ab6641be95a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-25 08:21:00 -07:00
gsxdsm
9a2aea6120 FN-8571: add Parakeet STT transcription backend
Add a configurable sherpa-onnx Parakeet v3 speech-to-text service and dashboard API.

- Add model download, validation, caching, and lifecycle management for the bundled STT runtime.
- Register multipart-safe voice transcription routes with request-size handling and service-backed responses.
- Expose STT settings, documentation, release metadata, and focused integration coverage.

Files changed:
 .changeset/fn-8571-voice-stt-backend.md            |   7 +
 docs/settings-reference.md                         |  12 +
 .../core/src/__tests__/settings-parity.test.ts     |  10 +
 packages/core/src/index.ts                         |   2 +-
 packages/core/src/settings-schema.ts               |   2 +
 packages/core/src/types.ts                         |   2 +
 packages/core/src/types/settings-scope.ts          |  19 ++
 packages/dashboard/package.json                    |   3 +
 .../voice-body-parser-integration.test.ts          |  67 ++++++
 packages/dashboard/src/routes.ts                   |   2 +
 packages/dashboard/src/routes/README.md            |  74 +++---
 .../routes/__tests__/register-voice-routes.test.ts | 159 ++++++++++++
 .../src/routes/create-api-routes-mount-sequence.ts |   2 +-
 .../dashboard/src/routes/register-voice-routes.ts  |  92 +++++++
 packages/dashboard/src/server.ts                   |  21 +-
 .../src/stt/__tests__/model-manager.test.ts        | 171 +++++++++++++
 .../dashboard/src/stt/__tests__/voice-stt.test.ts  |  48 ++++
 packages/dashboard/src/stt/model-manager.ts        | 268 +++++++++++++++++++++
 packages/dashboard/src/stt/parakeet-service.ts     |  77 ++++++
 packages/dashboard/src/stt/types.ts                |  14 ++
 pnpm-lock.yaml                                     |  65 +++++
 21 files changed, 1086 insertions(+), 31 deletions(-)

Fusion-Task-Id: FN-8571

Fusion-Task-Lineage: b11e0cea-9c9c-41d4-a141-c47e5ed56dba

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-25 02:17:31 -07:00
gsxdsm
190cc041bc fix(lanes): resolve a model pair everywhere a session is constructed
Audit of the class behind the planning bug: createFnAgent forwards no model
unless both defaultProvider and defaultModelId are set, after which
pi-coding-agent picks its own built-in default (anthropic/claude-opus-4-8).
Seven lanes resolved no pair at all, so they hit that path on every call --
a permanent 401 invalid x-api-key for custom-provider and subscription
operators, and a hole in test-mode forcing:

- milestone/slice interviews (no model plumbing at all)
- subtask breakdown, triage and streaming paths
- agent generation
- text refine and goal drafting
- agent reflection (optional ctor pair no production caller supplies)

Two more resolved the halves independently, which the runtime treats as
unset: research synthesis defaults and pr-conflict-resolver's hand-rolled
copy of resolveProjectDefaultModel (which also skipped test-mode overrides).

Add lane-session-model.ts as the shared resolver and a source ratchet that
fails when a dashboard session is constructed from an inline literal with no
model decision.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 22:32:49 -07:00
gsxdsm
1959e7c02c fix(planning): keep the selected model pair on rebuilt planning agents
ensureSessionAgent rebuilt the agent with an empty provider/model pair while
preserving draftThinkingLevel, so resumed turns (respond, retry, rewind, drafts
resumed after the in-memory agent was dropped) fell through to the runtime's
built-in default model (anthropic/claude-opus-4-8) and hit api.anthropic.com
with a key the operator never configured. The non-streaming start had the same
hole. Resolve the pair from the persisted draft, then the lane's settings, on
every rebuild and start.

Also route planning through createResolvedAgentSession like chat/executor/merger
so CLI and plugin runtimes can own their own auth and planning emits
session:runtime-resolved.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 22:17:39 -07:00
gsxdsm
e3dba364d1 FN-8564: update bundled Pi runtime to 0.82.0
Update Fusion's matched Pi dependencies and compatibility coverage for version 0.82.0.

- Pin Pi AI and coding-agent packages to the exact 0.82.0 release pair.
- Refresh provider catalog, supplemental model, auth storage, and Droid thinking coverage.
- Add the published CLI patch changeset.

Files changed:
 .changeset/fn-8564-pi-082.md                       |   7 +
 packages/cli/package.json                          |   4 +-
 packages/cli/src/__tests__/package-config.test.ts  |   2 +-
 packages/core/package.json                         |   2 +-
 packages/dashboard/package.json                    |   2 +-
 ...ister-model-routes-kimi-k3-supplemental.test.ts |   6 +-
 packages/engine/package.json                       |   4 +-
 .../src/__tests__/provider-registration.test.ts    |   4 +-
 packages/engine/src/auth-storage.ts                |  11 +-
 packages/engine/src/pi.ts                          |   6 +
 packages/pi-claude-cli/package.json                |   8 +-
 .../src/thinking-config.ts                         |  10 +-
 pnpm-lock.yaml                                     | 176 +++++++++++----------
 pnpm-workspace.yaml                                |   6 +-
 .../__tests__/check-pi-versions-pinned.test.mjs    |   8 +-
 15 files changed, 142 insertions(+), 114 deletions(-)

Fusion-Task-Id: FN-8564

Fusion-Task-Lineage: 543c5e17-4cb2-446f-9a1c-ec7ec8b8117a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-24 19:06:14 -07:00
gsxdsm
a9d5b06013 FN-8562: add tags to chat conversations
Enable project-scoped reusable tags for Direct chat sessions.

- Add tag storage, migrations, and scoped assignment APIs.
- Add chat sidebar tag creation, assignment, and filtering controls.
- Document tag behavior and cover schema and chat interactions.
- Establish the session project/id candidate key before creating scoped tag foreign keys.

Files changed:
 .changeset/fn-8562-chat-conversation-tags.md       |   7 ++
 docs/dashboard-guide.md                            |   4 +
 docs/storage.md                                    |   2 +
 .../src/__tests__/postgres/schema-applier.test.ts  |   8 +-
 packages/core/src/async-chat-store.ts              | 117 ++++++++++++++++++++-
 packages/core/src/chat-store.ts                    |  32 ++++++
 packages/core/src/chat-types.ts                    |  14 +++
 packages/core/src/index.gate.ts                    |   3 +
 packages/core/src/index.ts                         |   3 +
 .../postgres/migrations/0036_chat_session_tags.sql |  64 +++++++++++
 packages/core/src/postgres/schema-applier.ts       |  16 ++-
 packages/core/src/postgres/schema/project.ts       |  34 ++++++
 packages/dashboard/app/api.ts                      |   1 +
 packages/dashboard/app/api/chat.ts                 |  18 ++++
 packages/dashboard/app/components/ChatView.css     |  17 +++
 packages/dashboard/app/components/ChatView.tsx     |  70 +++++++++++-
 .../__tests__/ChatView.core-interactions.test.tsx  |  27 +++++
 .../dashboard/app/hooks/__tests__/useChat.test.ts  |   1 +
 packages/dashboard/app/hooks/useChat.ts            |  52 ++++++++-
 .../dashboard/src/routes/register-chat-routes.ts   |  70 ++++++++++++
 20 files changed, 550 insertions(+), 10 deletions(-)

Fusion-Task-Id: FN-8562

Fusion-Task-Lineage: 4efe798c-0865-451a-adbd-6b85f9f8b149

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-24 18:09:32 -07:00
gsxdsm
c60b6bf2f7 fix(dashboard-tests): harden planning-browser-e2e Chromium launch for CI runners
On GitHub runners headless system Chrome dies at launch without --no-sandbox
and --disable-dev-shm-usage, cascading all five tests as "browser has been
closed" (run 30081843074). The lane had been masked by the shard-4 watchdog
kill since the file landed, so it had never actually executed on CI. Flags
apply only under CI; local launches keep the default sandbox.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 02:39:18 -07:00
gsxdsm
12fa85eefb fix(dashboard-tests): finish the FN-8491 mock backlog; contain FN-8557 innerWidth leakage
Nine more api-lane files get the established getProjectScopedPluginMcpServers
stub (includes shared-branch-group-entry-points, whose two current failures
were FN-8491 500s — the historical per-task-derived pair is gone). App lane:
FN-8557 made window.innerWidth<=768 a mobile signal, so leaked innerWidth=375
defineProperty stamps flipped later ListView/settings tests into mobile
layout (reset in beforeEach), and useModalResizePersist's 700px "mobile"
fixture became tablet-class (now a phone-class 375px viewport).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 02:14:26 -07:00
gsxdsm
16d30ee7b0 fix(dashboard-tests): clear the FN-8491 plugin-MCP mock backlog unmasked by the watchdog fix
The core watchdog kill had been hiding everything scheduled after it in
shard 4; with the budget fixed, 15 api-lane files surfaced. Thirteen needed
the established FN-8491 recipe (mock stores expose
getProjectScopedPluginMcpServers so the binder short-circuits). Also:
mcp-lane-forwarding tracks resolveManualAiPromptMcpServers' move to
automation-step-execution and FN-8538's getSettings on planning stores;
planning-answered-question-reemit handles PR #2417's synchronous single-turn
admission with a bounded onceAdmitted retry (admission rejections are
side-effect free); routes-system tracks getProjectPluginLoader resolution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 01:33:29 -07:00
gsxdsm
fa6e4fef22 fix(dashboard-tests): satisfy FN-8491 plugin-MCP store contract across route suites; align planning create-task envelope
- routes-auth/automation/git/github/tasks: FN-8491 binds the plugin-MCP
  provider on every project-context resolution; mock stores now expose
  getProjectScopedPluginMcpServers so routes stop 500ing.
- routes-github: stub FN-8442 durable planning-claim plumbing whose internal
  getSession bypassed the namespace spy; the scoped-store routing contract
  is asserted unchanged.
- api-git: POST /planning/create-task now returns the FN-8442
  {task, alreadyCreated} envelope; mock matches.
- TaskDetailModal.tab-persistence: settle-then-requery before clicking the
  Session tab (detached-node race under CI load).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 23:51:29 -07:00
gsxdsm
d7752931b0 fix(dashboard-tests): align remote-access mock store with FN-8491, ChatView mobile with FN-8502, and de-race planning claim tests
- remote-access-routes: FN-8491 made every project-context resolution call the
  plugin-MCP binder; the mock store now satisfies the runtime-owned-store guard.
- ChatView.mobile: sendMessage gained the FN-8502 {onDelivered,onFailed} arg.
- PlanningModeModal.planning-flow: settle-then-requery before clicking Proceed
  (detached-node race under CI load, same class 5a5796bca fixed for Stop/Refine)
  and await the create-dispatch mock signal instead of the DOM alone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 23:09:59 -07:00
gsxdsm
0412113de7 fix(dashboard,cli): un-dead-end deleted plan tasks; harden fn task plan per review
Reported bug (screenshot): deleting the task created from a plan left the
session permanently stuck on PLANNING_CREATED_TASK_MISSING — Retry create
replayed the same 409 forever. A linked task absent from the
include-archived scan (task-row authority; a successful scan proves
deletion, not a flaky read) now clears the stale linkage and creates a
fresh task, in both the create-task route and createTaskFromPlanSession;
a still-listed-but-unreadable task keeps failing closed.

Multi-agent review of fdd120232 (correctness/adversarial/reliability):
- P1: CLI planning sessions were memory-only — setAiSessionStore only ran
  in the dashboard server, so --resume could never find a session across
  invocations. New ensureDurablePlanningSessionStore wires the durable
  AiSessionStore over the board store's public asyncLayer in runTaskPlan.
- P1: resume failures now THROW instead of process.exit (fn_task_plan
  runs inside the pi host — an exit killed the whole agent session), and
  a no-question resume requires an explicit refine focus (the provided
  description) so merely resuming never rotates the epoch.
- P2: claim and finalize CAS gained the same expected-epoch WHERE guard
  as reconcile, so a stale-epoch creator can no longer finalize an
  old-epoch task onto a rotated session.
- Side-effect failures (documents, logEntry, validate, reconcile) are now
  logged instead of swallowed; post-insert failures no longer mislabel
  the just-created task alreadyCreated:true; the keep-refining readline
  closes on thrown prompts and a failed refine after creation returns the
  created task id with a resume hint; cross-process generating guard
  added to createTaskFromPlanSession.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 20:19:18 -07:00
gsxdsm
fdd1202328 feat(cli): claim-aware multi-task planning parity for fn task plan
Closes the P1 agent-native gap from the multi-task review: the CLI and
fn_task_plan pi tool created tasks via a raw store.createTask with no
proposalClaimId — no idempotency, no session linkage, and tasks outside
the epoch sequence, so a later dashboard Proceed would duplicate them.

- New shared createTaskFromPlanSession in @fusion/dashboard/planning:
  the agent-surface twin of POST /planning/create-task (epoch-derived
  claim key, claim/finalize/reconcile/release CAS lifecycle with the 30s
  stale-lease takeover, formatPlanningPlanMd task shape, plan/original-
  description documents, validate-on-create, generating guard).
- runTaskPlan creates through it (making the FN-7734 retry wrapper
  genuinely safe), prints the session id, and offers an interactive
  keep-refining loop that creates further tasks from the evolved plan.
- fn task plan --resume <sessionId> / fn_task_plan resumeSessionId reopen
  an existing session — even a validated one whose task exists — and the
  no-question resume regenerates the interview via a refine turn, which
  rotates the creation epoch server-side.

Tests: CLI suite pins claim-aware creation, the continue prompt, and the
resume flow; dashboard suite pins createTaskFromPlanSession idempotent
replay and epoch-aware second creation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 20:01:50 -07:00
gsxdsm
ca4639bb67 feat(dashboard): allow multiple tasks from one plan via epoch-scoped claims
One planning session can now create multiple tasks. Task-creation claims
are epoch-scoped: proposalClaimId stays planning-session:{id} for epoch 0
and becomes planning-session:{id}#N after the plan is edited past a
created task (rotateTaskCreationEpochOnReopen archives createdTaskId into
createdTaskIds and resets claim state). Unedited Proceed replays stay
idempotent within an epoch; crash-after-insert dedup still reconciles via
the epoch-keyed task row. Complete sessions resume to an editable plan
review with a linked-task banner; the task-created handoff gains a
Continue planning action.

Hardening from the multi-agent code review (9 reviewers):
- Reopen + rotation run only AFTER turn admission, so a rejected request
  never burns a phantom rotation (P1, 3 reviewers).
- Claim-lifecycle CAS writes are surgical jsonb merges and reconcile takes
  an expected-epoch guard, so a concurrent rotation can never be reverted
  or an archived task re-linked to a new epoch.
- create-task 409s while the session is still generating (turn-completion
  persist could tear the fresh linkage).
- Durable-read fallback in create-task now logs before trusting the
  in-memory epoch.
- linkedTaskId no longer leaks across session switches; the banner
  resolves the just-created Task before the tasks prop refreshes and
  falls back to the newest archived task after rotation; Continue
  planning re-registers the active session.
- Shared applyCompletePlanningResume helper replaces triplicated resume
  view-transitions; stale one-task-per-session comment corrected.

Tests: post-rotation replay idempotency and epoch-keyed crash reconcile
(e2e), rewind rotation + rejected-rewind non-rotation + payload
normalization round-trip (unit), Continue planning + banner-leak (UI),
create-task 409 (routes), and a new PG integration suite pinning the
surgical CAS merge and reconcile epoch guard.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 19:37:49 -07:00
gsxdsm
0e6108a1a5 fix(dashboard): Stop cancels pending initial planning turns per-session
stopGeneration only aborted generations with an activeGenerations record.
A just-started session whose initial turn was still pending (registered
by start-streaming, not yet consumed by a stream connect) returned false
from Stop and the "stopped" generation sprang back to life on the next
stream connect. Stop now discards the pending turn too, and remains
strictly keyed to its session id so stopping one plan never affects other
concurrently generating sessions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 18:52:19 -07:00
gsxdsm
370a7a645d fix(dashboard): a validated plan stays readable, editable, and creatable
A finished plan must never land on a do-nothing screen:

- submitResponse/rewindSession REOPEN a validated session (clear the
  terminal marker; the turn's persistSession durably writes it) instead
  of rejecting with "already been validated". validateSession remains the
  only terminalizer.
- A complete session with no created task resumes into the full plan
  review workspace (read plan, Refine/comments, Proceed) instead of the
  create-only retry card; task-linked sessions still resume to the task
  handoff, preserving the never-rotated one-task-per-session claim.
- The live create-failure screen gains a Back to plan action.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 18:52:19 -07:00
gsxdsm
7cb87e7687 fix(dashboard): regenerate interview questions in mission/milestone/onboarding too
Extends the Planning Mode no-active-question fix to the other three
interview lanes: a LIVE session (no summary yet) that receives a
submission with no active question now reprompts the agent to continue
the interview and ask a fresh question — carrying the submitted input as
context — instead of throwing "No active question in session". Completed
interviews (summary present) still reject late submissions, preserving
the existing contract.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 18:39:10 -07:00
gsxdsm
64b20c8be3 fix(dashboard): regenerate a planning question instead of "No active question in session"
Refining a plan (or submitting any input) while the session had no active
question — e.g. after a failed retry cleared summary/currentQuestion —
threw InvalidSessionStateError("No active question in session") at the
operator. Now the interview continues instead:

- The refine and contextual-comment branches no longer require
  session.summary; they fall back to a running summary rebuilt from
  persisted history.
- A submission with no active question reprompts the agent via
  formatQuestionRegenerationForAgent to produce a fresh option-driven
  question, carrying the submitted operator input along as context.
- The Planning modal forwards no-question submissions to the server
  (loading view + SSE) instead of dead-ending with a local error.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 18:29:59 -07:00
gsxdsm
b462978e92 fix(dashboard): emit planning terminal error exactly once on stream reconnect
Code-review follow-up to 716e69862: the terminal-error reconcile ran after
the Last-Event-ID replay, so a reconnecting client received a buffered
error event from the replay AND again from the reconcile block (double
onError, duplicate auto-retry triggers). The reconcile now runs before the
replay and skips it for terminal sessions, writing the newest buffered
error event (or a fresh broadcast when the bounded buffer evicted it)
exactly once, gated on lastEventId.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 18:18:04 -07:00
gsxdsm
716e698628 fix(dashboard): stop Planning Mode hanging on provider errors mid-generation
Provider errors thrown between persistSession("generating") and the turn's
own error handling (agent rebuild in ensureSessionAgent, history replay,
legacy sync createSession first turn) escaped to the route and left the
session row "generating" forever with no error, no SSE event, and no
watchdog — the modal hung on "Thinking/Generating plan" because its SSE
reconnect loop and 8s poll both treat a persisted "generating" row as
healthy.

- submitResponse/retrySession/createSession now convert any non-abort
  escape after entering "generating" into the standard persisted retryable
  error + SSE error broadcast before rethrowing.
- The SSE stream route reconciles settled/stranded sessions on connect
  (reconcileStalePlanningGeneration): a terminal error is replayed and the
  stream closed; a "generating" session with no live/pending turn past the
  watchdog window is converted to a retryable interrupted error.
- Provider failures on the JSON reformat retry now surface as themselves
  instead of a misleading "no valid JSON" parse error.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 18:14:29 -07:00
gsxdsm
45da5f71d3 fix(dashboard): keep planning comment composer above the keyboard
Pin the selection comment editor as a fixed panel on tablet and phone, and
lift it with visualViewport keyboard metrics so the first focus no longer
hides the form under the OS keyboard (or off-screen on tablet).
2026-07-23 17:56:05 -07:00
gsxdsm
b15fd2b498 fix(dashboard): stack mobile Add comment above Refine/Proceed
Phone no longer pins Add comment under the action rail as a fixed bar. It
uses the same full-width in-flow footer row as tablet, above Refine and
Proceed. The composer stays fixed when open.
2026-07-23 17:43:27 -07:00
gsxdsm
28e2cd587c fix(dashboard): put plan-review Add comment above actions on tablet
Tablet (≤1024px) now uses the action-rail Add-comment control as a full-width
row above Refine/Proceed instead of the document-end trigger. Phone keeps the
fixed bar above the mobile nav; desktop keeps the in-document control.
2026-07-23 17:36:10 -07:00
gsxdsm
0307476f35 fix(tests): restore listTasks hot-path contract and PG harness fs isolation
- usage-limit-detector + provider-health-monitor: make three bare listTasks()
  callers explicit with { slim: true }, restoring the architecture-hot-paths
  contract (they only read scalar pause/column/model-provider fields).
- pg-test-harness beforeEach: wipe <rootDir>/.fusion/tasks after TRUNCATE ...
  RESTART IDENTITY so filesystem isolation matches the id reset; stale task
  dirs from prior tests no longer collide with reused IDs (fixes
  store-reservation-atomicity rollback assertions).
2026-07-23 17:27:59 -07:00
gsxdsm
62c52972fc fix(dashboard): keep mobile plan-review selection comments on-screen
Plan review Add-comment controls now track document-level selectionchange so
they appear as soon as text is selected and dismiss when the selection ends.
On mobile the trigger and composer are fixed above the nav (with width auto)
so operators no longer need to scroll to reach them.
2026-07-23 17:19:26 -07:00
gsxdsm
dfb9ca6630 FN-8543: enforce bounded generated-fix remediation
Keep generated fix chains within their root retry budget and preserve intervention stops.

- Track retry counts and stop reasons on the canonical root feature.
- Persist project-isolated lineage stops across generated-fix removal and archive paths.
- Serialize stop recording with generated-fix admission and expose conflict-safe mission resume behavior.

Files changed:
 .changeset/fn-8543-bounded-fix-lineage.md          |   7 +
 docs/missions.md                                   |   6 +-
 .../__tests__/postgres/mission-store.pg.test.ts    |  72 +++++++
 packages/core/src/async-mission-store-queries.ts   |  91 ++++++++-
 packages/core/src/async-mission-store.ts           | 206 ++++++++++++++++++---
 packages/core/src/index.ts                         |   2 +-
 packages/core/src/mission-store.ts                 |  10 +
 packages/core/src/mission-types.ts                 |   7 +
 .../0035_fn_8543_mission_lineage_stop.sql          |  31 ++++
 packages/core/src/postgres/schema-applier.ts       |  18 +-
 packages/core/src/postgres/schema/project.ts       |  21 +++
 .../core/src/task-store/archive-lifecycle-2.ts     |  15 +-
 .../core/src/task-store/async-archive-lineage.ts   |  10 +-
 packages/dashboard/src/mission-routes.ts           |  14 +-
 packages/engine/src/mission-execution-loop.ts      |  30 ++-
 15 files changed, 495 insertions(+), 45 deletions(-)

Fusion-Task-Id: FN-8543

Fusion-Task-Lineage: 24c03d63-5914-4072-aa17-16862432fc78

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 16:12:44 -07:00
gsxdsm
94644ef849 fix(planning): mark session complete after Proceed-with-plan task creation
Proceed with plan called /api/planning/create-task without the legacy
/validate step, so the persisted AI session stayed awaiting_input and the
session list/needs-input banner kept advertising a finished session. The
create-task route now terminalizes the session via validateSession on every
path that ends with a created task, including alreadyCreated reconciliation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:45:39 -07:00
gsxdsm
e5caea542a FN-8544: gate mission remediation behind autopilot
Keep mission validation report-only until an operator explicitly enables autopilot.

- Gate validator-created remediation features and task dispatch behind mission autopilot.
- Audit attributed status and autopilot transitions atomically across mission stores.
- Expose mission autonomy controls and document the opt-in lifecycle.

Files changed:
 .changeset/fn-8544-mission-autonomy-audit.md       |   7 ++
 docs/missions.md                                   |  10 +-
 packages/cli/src/extension.ts                      |  26 ++++-
 .../__tests__/postgres/mission-store.pg.test.ts    |  27 +++++
 packages/core/src/async-mission-store.ts           |  70 +++++++++++--
 packages/core/src/index.gate.ts                    |   3 +
 packages/core/src/index.ts                         |   3 +
 packages/core/src/mission-store.ts                 | 113 +++++++++++++--------
 packages/core/src/mission-types.ts                 |  22 ++++
 .../dashboard/app/components/MissionManager.tsx    |   1 +
 packages/dashboard/src/mission-routes.ts           |  25 +++--
 .../src/__tests__/agent-mission-tools.test.ts      |  17 +++-
 .../src/__tests__/mission-execution-loop.test.ts   |  21 ++++
 packages/engine/src/agent-heartbeat.ts             |   4 +-
 packages/engine/src/agent-tools.ts                 |  30 +++++-
 packages/engine/src/executor.ts                    |   5 +-
 packages/engine/src/mission-autopilot.ts           |  51 +++++-----
 packages/engine/src/mission-execution-loop.ts      |  49 ++++++---
 packages/engine/src/triage.ts                      |   5 +-
 19 files changed, 377 insertions(+), 112 deletions(-)

Fusion-Task-Id: FN-8544

Fusion-Task-Lineage: 23a69923-5a19-407e-9fe2-8973c166ee9a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 15:25:09 -07:00
gsxdsm
2978ec4973 FN-8551: add accessible agent heartbeat controls
Add per-agent and project-wide heartbeat enablement controls.

- Add preserved runtime configuration helpers and heartbeat controls across agent list, board, and org-chart views.
- Add bulk enable/disable actions, accessible labels, localized copy, documentation, and release metadata.
- Cover heartbeat mutations through dashboard, route, scheduler, and layout smoke tests.

Files changed:
 .changeset/fn-8551-agent-heartbeat-controls.md     |   7 +
 docs/dashboard-guide.md                            |   2 +
 packages/dashboard/app/api/agents.ts               |  12 ++
 packages/dashboard/app/api/legacy.ts               |   2 +
 .../dashboard/app/components/AgentDetailView.tsx   |  14 +-
 packages/dashboard/app/components/AgentsView.css   |  11 ++
 packages/dashboard/app/components/AgentsView.tsx   | 186 ++++++++++++++++-----
 .../AgentDetailView.advanced-settings.test.tsx     |  29 ++++
 .../__tests__/AgentDetailView.test-helpers.ts      |   2 +
 .../app/components/__tests__/AgentsView.test.tsx   |  68 ++++++++
 .../dashboard/scripts/browser-layout-smoke.mjs     |  54 ++++++
 .../src/routes/__tests__/agent-core-routes.test.ts |  69 ++++++++
 .../src/__tests__/heartbeat-scheduler.test.ts      |  21 +++
 packages/i18n/locales/en/app.json                  |  19 ++-
 packages/i18n/locales/es/app.json                  |  19 ++-
 packages/i18n/locales/fr/app.json                  |  19 ++-
 16 files changed, 484 insertions(+), 50 deletions(-)

Fusion-Task-Id: FN-8551

Fusion-Task-Lineage: 2d4c8a15-a444-47b6-b57c-f41fc4163155

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 14:32:58 -07:00
gsxdsm
c4292b25ef FN-8539: make Planning Mode selection-driven
Make Planning Mode refine repository-grounded plans through successive operator choices.

- Offer concrete directions and Other for vague planning openers
- Rebuild running plans around selected options, multi-selections, and Other responses
- Add selection-loop coverage and operator documentation

Files changed:
 .changeset/fn-8539-option-driven-planning.md       |   7 ++
 docs/dashboard-guide.md                            |   2 +-
 .../__tests__/planning-infinite-interview.test.ts  | 131 ++++++++++++++++++++-
 .../planning-interview-formatters.test.ts          |  37 ++++--
 packages/dashboard/src/planning.ts                 |  34 +++---
 5 files changed, 185 insertions(+), 26 deletions(-)

Fusion-Task-Id: FN-8539

Fusion-Task-Lineage: 585bae1e-6d9e-4733-b787-77b70a7d1259

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 12:08:58 -07:00
gsxdsm
3f976e3dca FN-8538: give Planning Mode a dedicated collaborative prompt
Planning Mode now uses a standalone collaborative prompt rather than inherited task-triage instructions.

- Resolve the Planning Mode default independently of workflows and triage assignments.
- Preserve explicit full-system prompt overrides and update prompt-setting documentation.
- Cover dedicated prompt behavior and add the published-package changeset.

Files changed:
 .changeset/fn-8538-planning-prompt.md              |  7 +++
 docs/dashboard-guide.md                            |  3 +-
 .../core/src/__tests__/prompt-overrides.test.ts    |  7 +++
 packages/core/src/prompt-overrides.ts              |  8 ++-
 packages/dashboard/app/utils/builtinPrompts.ts     |  8 ++-
 .../__tests__/planning-infinite-interview.test.ts  | 60 +++++++++++++++++++++-
 .../__tests__/planning-prompt-resolution.test.ts   | 47 ++++++++++-------
 packages/dashboard/src/planning.ts                 | 46 +++++------------
 8 files changed, 130 insertions(+), 56 deletions(-)

Fusion-Task-Id: FN-8538

Fusion-Task-Lineage: 36e0665d-7995-4bc5-9c73-948f7f4e9131

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 11:41:15 -07:00
gsxdsm
d6d8a5e919 FN-8537: keep planning actions visible on mobile
Keep Planning Refine and Proceed controls visible across mobile plan-review hosts.

- Make the plan document pane the responsive scroll owner while preserving its action rail.
- Cover portrait and short-landscape embedded and modal layouts with CSS and browser tests.
- Add a patch changeset for the mobile planning action fix.

Files changed:
 .changeset/fn-8537-mobile-planning-actions.md      |  7 ++++++
 .../dashboard/app/components/PlanningModeModal.css | 25 ++++++++++++++++++++++
 .../__tests__/PlanningModeModal.css.test.ts        | 17 +++++++++++++++
 .../src/__tests__/planning-browser-e2e.test.ts     | 20 +++++++++++++++--
 4 files changed, 67 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-8537

Fusion-Task-Lineage: 7a53aa74-859d-4c76-bf26-ab6ea72873dd

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 11:03:33 -07:00
gsxdsm
42fe154abe FN-8533: add mobile planning comment actions
Make contextual plan comments reachable from the mobile action rail and restore focus after editing.

- Add responsive desktop and mobile comment triggers with contextual styling and documentation.
- Preserve the selected quote and restore the remounted trigger after canceling or adding a comment.
- Cover action placement, focus restoration, and browser interaction behavior.

Files changed:
 .changeset/fn-8533-mobile-planning-comments.md     |   7 ++
 docs/dashboard-guide.md                            |   2 +-
 .../dashboard/app/components/PlanningModeModal.css |  20 ++++
 .../dashboard/app/components/PlanningModeModal.tsx |  44 ++++++-
 .../__tests__/PlanningModeModal.css.test.ts        |  10 ++
 .../PlanningModeModal.planning-flow.test.tsx       |  40 +++++--
 .../PlanningModeModal.ui-interactions.test.tsx     |   5 +
 .../dashboard/app/planning-browser-e2e-fixture.tsx |   3 +-
 .../src/__tests__/planning-browser-e2e.test.ts     | 133 +++++++++++++++++++--
 packages/dashboard/vitest.config.ts                |  11 +-
 scripts/lib/test-quarantine.json                   |   5 -
 11 files changed, 242 insertions(+), 38 deletions(-)

Fusion-Task-Id: FN-8533
Fusion-Task-Lineage: e0d561be-ecc8-456e-807e-a1dc677b5d9c
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 09:33:25 -07:00
gsxdsm
d2e41e490f FN-8534: honor workflow planning-model precedence
Honor selected workflow planning models for Planning Mode sessions.

- Resolve selected workflow planning lanes against the project baseline.
- Route complete request and workflow pairs through canonical planning-model resolution.
- Cover new and draft planning sessions, test mode, and settings documentation.

Files changed:
 .changeset/fn-8534-planning-workflow-model.md      |  7 ++
 docs/settings-reference.md                         |  2 +
 .../__tests__/workflow-settings-resolver.test.ts   | 73 ++++++++++++++++
 packages/core/src/index.gate.ts                    |  1 +
 packages/core/src/index.ts                         |  1 +
 packages/core/src/workflow-settings-resolver.ts    | 80 +++++++++++-------
 .../src/__tests__/routes-planning.test.ts          | 97 ++++++++++++++++++++++
 .../src/routes/register-planning-subtask-routes.ts | 48 ++++++++---
 8 files changed, 267 insertions(+), 42 deletions(-)

Fusion-Task-Id: FN-8534

Fusion-Task-Lineage: e6b5b546-b9f1-49c5-b680-90f24e856458

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 08:53:06 -07:00
gsxdsm
575171c54c FN-8532: fix planning stream validation state
Keep planning streams non-terminal until explicit validation.

- Clear stale generation metadata when validating a planning session
- Cover replay and response flows that defer completion until validation

Files changed:
 .../src/__tests__/routes-planning.test.ts          | 113 ++++++++++++++++-----
 packages/dashboard/src/planning.ts                 |  10 ++
 2 files changed, 97 insertions(+), 26 deletions(-)

Fusion-Task-Id: FN-8532

Fusion-Task-Lineage: 8c0ec4fc-c438-47c9-b0b0-12b116a2debd

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 01:46:50 -07:00
gsxdsm
3b45364180 FN-8531: fix planning route test plugin store setup
Restore planning route fixtures for the plugin-store context binding and current validation checkpoint flow.

- provide inert plugin-store and durable planning creation mocks
- update planning stream and response assertions for validation questions
- keep terminal stream fixtures settled before completion events

Files changed:
 .../src/__tests__/routes-planning-tracking.test.ts | 13 ++++
 .../src/__tests__/routes-planning.test.ts          | 73 ++++++++++++++++------
 2 files changed, 66 insertions(+), 20 deletions(-)

Fusion-Task-Id: FN-8531

Fusion-Task-Lineage: e1e2fae5-2410-4b02-a2e6-6994f936ee56

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 01:28:41 -07:00
gsxdsm
ebbb5948ab FN-8529: add contextual plan review comments
Enable operators to submit selected-plan suggestions through the existing Planning Mode revision flow.

- Capture text selections, batch suggestions, and retain retryable comment submissions in the Planning Mode UI.
- Validate bounded comment payloads and format them for the existing planning session update path.
- Document the workflow and add coverage for ordering, retry behavior, and selection boundaries.

Files changed:
 .changeset/fn-8529-planning-comments.md            |   7 +
 docs/dashboard-guide.md                            |   4 +
 packages/dashboard/app/api/legacy.ts               |   1 +
 packages/dashboard/app/api/planning.ts             |   9 +-
 .../dashboard/app/components/PlanningModeModal.css |  86 ++++++++++++
 .../dashboard/app/components/PlanningModeModal.tsx | 144 ++++++++++++++++++++-
 .../PlanningModeModal.planning-flow.test.tsx       |  39 ++++++
 .../PlanningModeModal.ui-interactions.test.tsx     |  10 ++
 .../__tests__/planning-infinite-interview.test.ts  |  62 +++++++++
 packages/dashboard/src/planning.ts                 |  76 ++++++++++-
 .../src/routes/register-planning-subtask-routes.ts |  27 +++-
 11 files changed, 455 insertions(+), 10 deletions(-)

Fusion-Task-Id: FN-8529

Fusion-Task-Lineage: c7064d76-effd-4597-a2b4-03f344dd59b9

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 00:56:47 -07:00
gsxdsm
016221c6a8 feat(chat): ground agent chat answers in live codebase investigation (#2416)
## Summary

- Add `CHAT_CODEBASE_ACCURACY_GUIDANCE` so agent chat (direct +
multi-agent rooms) investigates the live checkout with tools before
answering code/architecture questions.
- Soften chat’s pure brevity default for repo questions: still lead
short, but keep real path/symbol evidence (parity with the investigation
pressure that makes Planning Mode more accurate).
- Cover the constant and assembly via unit tests; include a patch
changeset for `@runfusion/fusion`.

## Why

Users reported Planning Mode was more accurate about the codebase than
agent chat. Plan mode inherits the triage seam’s “read/grep first, name
real files” contract; chat only had a short helpful-assistant persona
plus a brevity default, so models often answered from priors.

## Test plan

- [x] `pnpm --filter @fusion/dashboard exec vitest run
src/__tests__/chat-system-prompt.test.ts
src/__tests__/chat-manager.test.ts`
- [ ] Manually ask agent chat a project-specific architecture question
and confirm it greps/reads before answering with real paths
- [ ] Confirm non-code chat still stays short/crisp
- [ ] Confirm multi-agent room responders also receive the new guidance

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

* **Improvements**
* Improved repository/code answers by investigating the live codebase
first and prioritizing verified paths and symbols over speculation.
* Refined response-length behavior so code questions stay
evidence-focused, while non-code questions remain concise.
* Applied consistent accuracy guidance across both direct and room-based
conversations.
* **Bug Fixes**
* Prevented chat instructions from depending on unavailable mailbox
functionality, improving reliability for agentless/room flows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-23 00:00:22 -07:00
gsxdsm
fc4f5aa0e4 fix(dashboard): stop Planning Mode duplicate generations, 'AI returned no valid JSON' errors, and context-overflow failures (#2417)
## Symptom

Users reported Planning Mode regularly failing with **"AI returned no
valid JSON.. Retry this planning session or start a new one."**, and
that leaving and returning to the interface mid-generation **duplicates
the generation — infinitely**. Every app-tab switch unmounts the
Planning view, so the leave/return path is the *normal* path, not an
edge case.

## Root causes

1. **Check-then-act turn admission.** `activeGenerations.has()` was
checked at turn entry, but the record was only created inside
`runGenerationWithTimeout`, after several awaits. Overlapping turn
entries (remounted view re-submitting, racing auto-retries, duplicate
start of an existing session) both passed the guard; the second
displaced the first, and the displaced teardown disposed the
**session-shared agent the surviving turn was actively prompting** —
which then read an empty assistant message and failed parse with "AI
returned no valid JSON".
2. **Per-mount auto-retry budget.** The client reset its 3-attempt
auto-retry budget on every mount, so each return to an errored session
re-ran a full-turn regeneration (agent rebuild + complete history
replay) — forever.
3. **SSE replay appended onto existing output.** Fresh stream
connections replay buffered thinking; the client pre-seeded from
persisted `thinkingOutput` (or kept prior output on silent reconnect)
and then appended the replay — visibly doubling the generation on every
reconnect. The 100-event buffer only held a suffix of a turn, forcing
that pre-seed.
4. **Raw `session.prompt()` at context limits.** A long interview that
overflowed the model's context window errored terminally, and auto-retry
replayed the full history into a fresh agent — overflowing again,
unrecoverably.

## Fix

- Synchronous per-session **turn reservation** shared by
`submitResponse`, `retrySession`, `startExistingSession`, and the
initial turn; losers get `GenerationInProgressError` instead of
displacing the winner. Duplicate starts of a generating session are
no-ops. Rewind aborts an active generation through its own teardown
first.
- Client auto-retry budget is **module-scoped per session** (survives
remounts); exhausted budget shows the error view instead of a stuck
spinner. Retry rejections for "already in progress" rejoin the live run.
- Fresh SSE connections **clear streamed output before the buffered
replay**; buffer deepened to a full turn (2000 events); rejoin paths
reconnect cleanly instead of seeding persisted thinking.
- All six planning prompt sites route through the engine's
**`promptWithFallback`**, recovering context-window overflows via
prompt/memory compaction and `session.compact()`.
- Cosmetic: no more doubled period in the retryable parse error message.

## Symptom Verification

- **Original symptom:** "AI returned no valid JSON" after answering
questions; generations duplicating on leave/return.
- **Exact reproduction:** concurrent turn entries on one session
(submit×2, retry×2, start-while-generating) — previously
displaced/disposed the live agent mid-prompt.
- **Assertion it is gone:** `planning-turn-admission.test.ts` asserts
exactly one turn is admitted per race, the winner completes with a
question and no session error, and the shared agent is never disposed;
`planning-context-compaction.test.ts` asserts every planning prompt
routes through `promptWithFallback` (signal forwarded) and that a
recovered context overflow leaves the turn healthy.

## Verification

- `vitest run` on all 7 planning server test files + the 2 new
regression files: **40/40 pass**.
- `routes-planning*` failures at main tip are pre-existing (identical
103/126 + 3/6 counts with and without this diff; main is mid-refactor on
route wiring). `planning-answered-question-reemit` 3 timeouts also
reproduce on clean main.
- `pnpm verify:fast` green; dashboard `tsconfig.json` +
`tsconfig.app.json` typechecks clean; eslint clean on touched files.

🤖 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**
* Prevented Planning Mode from duplicating generations and triggering
“AI returned no valid JSON” errors when leaving and re-entering mid-run.
* Made planning turn handling concurrency-safe and idempotent across
submit, retry, rewind, and duplicate start actions.
* Improved SSE reconnect recovery: clearer replay after reconnect, no
duplicated “thinking” output, and preserved auto-retry limits across
remounts.
* Improved long-context recovery via fallback prompting and cleaned up
retry error formatting.

* **Tests**
* Expanded coverage for concurrent Planning actions, reconnect replay,
context compaction, rewind behavior, and retry formatting; improved
parallel test-harness reliability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 23:59:31 -07:00
gsxdsm
de5d446b5c FN-8526: add custom workflow column descriptions
Enable custom workflow authors to define and display descriptions for board columns.

- Persist optional descriptions in workflow column definitions and API responses.
- Add editor controls and board tooltips for column descriptions.
- Cover validation, API, and dashboard behavior with tests and documentation.

Files changed:
 .changeset/fn-8526-workflow-column-descriptions.md |  7 +++
 docs/dashboard-guide.md                            |  4 ++
 .../src/__tests__/workflow-ir-validation.test.ts   | 30 +++++++++++
 packages/core/src/workflow-ir-types.ts             |  4 ++
 packages/core/src/workflow-ir.ts                   |  9 ++++
 packages/dashboard/app/api/board-workflows.ts      |  2 +
 packages/dashboard/app/components/Board.tsx        |  3 ++
 packages/dashboard/app/components/Column.tsx       | 14 +++--
 .../app/components/WorkflowColumnPanel.tsx         | 31 ++++++++++++
 .../app/components/WorkflowNodeEditor.css          | 41 +++++++++++++++
 .../app/components/__tests__/Column.test.tsx       | 19 +++++++
 .../__tests__/WorkflowColumnPanel.test.tsx         | 38 ++++++++++++++-
 .../app/components/__tests__/WorkflowNodeEditor.test.tsx | 19 +++++++
 .../app/components/workflow-flow-mapping.ts        |  1 +
 packages/dashboard/app/styles.css                  |  8 +++
 .../src/__tests__/board-workflows.test.ts          | 59 ++++++++++++++++++++++
 packages/dashboard/src/routes/board-workflows.ts   |  3 ++
 17 files changed, 288 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-8526

Fusion-Task-Lineage: df26b7c0-301c-4875-b100-d63d0cfecf85

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-22 22:37:51 -07:00
gsxdsm
adf51e21d7 fix(dashboard): dispatch plugin routes dynamically per request
Plugin-defined HTTP routes were a boot-time snapshot of the launch
project's PluginLoader, while dashboard views/UI slots resolve a
project-scoped loader live per request. Two failure modes survived the
961edf214 no-engine mount fix: a plugin enabled after boot rendered its
view while every API route 404'd until restart, and a plugin enabled
only in a non-launch project never got routes mounted at all (Compound
Engineering "Failed to load sessions: Not found" on v0.73.0-beta.3).

Routes are now dispatched per request through the same
getProjectPluginLoader cache (moved from the plugins registrar into
routes/context.ts) that serves dashboard-views and enable/disable, with
the host loader + PluginRunner tables unioned in (project entries win,
loader beats runner). The compiled dispatch sub-router is cached per
resolved loader and rebuilt only when the route signature changes, so
views and routes agree by construction.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 22:11:31 -07:00
gsxdsm
1cd06746fe FN-8502: add photo and file attachments to Chat and Quick Add
Enable supported photo and file attachment workflows across Quick Add and Chat.

- Expand Quick Add and Chat picker, paste, and drag/drop attachment intake.
- Preserve pending attachments until direct and room sends are accepted, with accessible previews and retry support.
- Align Chat MIME and size validation with task attachments, including video, Markdown, and TOML support.
- Add regression coverage for attachment previews, delivery behavior, and accepted MIME types.

Files changed:
 .changeset/fn-8502-chat-quick-add-attachments.md   |   7 ++
 docs/dashboard-guide.md                            |   5 +-
 ... quick-entry-attachment-preview-modal.test.tsx} |  50 ++++++--
 packages/dashboard/app/components/ChatView.tsx     |  80 +++++++++++--
 .../dashboard/app/components/InlineCreateCard.tsx  |   6 +-
 .../app/components/PendingAttachmentPreviews.css   |  60 ++++++++++
 ...ePreviews.tsx => PendingAttachmentPreviews.tsx} |  68 ++++++-----
 .../app/components/PendingImagePreviews.css        |  35 ------
 .../dashboard/app/components/QuickEntryBox.tsx     | 127 +++++++++++++--------
 packages/dashboard/app/components/TaskForm.tsx     |   6 +-
 .../__tests__/ChatView.core-interactions.test.tsx  |  61 ++++++++--
 .../__tests__/ChatView.mobile-render.test.tsx      |  20 +++-
 .../components/__tests__/ChatView.rooms.test.tsx   |  27 ++++-
 .../components/__tests__/QuickEntryBox.test.tsx    |  59 ++++++++--
 packages/dashboard/app/hooks/useChat.ts            |  41 ++++++-
 .../src/__tests__/chat-attachment-content.test.ts  |  17 +++
 packages/dashboard/src/chat-attachment-content.ts  |   4 +-
 .../dashboard/src/routes/chat-attachment-config.ts |  16 +++
 .../src/routes/register-chat-room-routes.ts        |   9 +-
 .../dashboard/src/routes/register-chat-routes.ts   |  11 +-
 20 files changed, 534 insertions(+), 175 deletions(-)

Fusion-Task-Id: FN-8502

Fusion-Task-Lineage: 0205187c-7e5b-45f8-a71d-fcfd9fb01e65

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-22 18:46:46 -07:00
gsxdsm
3cd023fa43 FN-8491: add declarative plugin MCP server registrations
Enable plugins to declare per-project MCP server registrations.

- Add plugin MCP server contribution types, loading, and resolution across core and engine runtimes.
- Expose resolved plugin registrations through project configuration APIs and MCP settings UI.
- Document the declarative contribution API and add release metadata and regression coverage.

Files changed:
 .changeset/plugin-mcp-servers.md                   |  7 ++
 docs/PLUGIN_AUTHORING.md                           | 17 +++++
 docs/mcp.md                                        |  4 ++
 docs/settings-reference.md                         |  4 ++
 packages/core/src/__tests__/mcp-config.test.ts     | 33 +++++++++
 .../__tests__/plugin-contribution-types.test.ts    | 16 +++++
 .../__tests__/plugin-loader-single-load.test.ts    | 23 +++++++
 packages/core/src/index.gate.ts                    |  3 +
 packages/core/src/index.ts                         |  3 +
 packages/core/src/mcp-config.ts                    | 37 ++++++++--
 packages/core/src/plugin-loader.ts                 | 24 +++++++
 packages/core/src/plugin-mcp-servers.ts            | 78 ++++++++++++++++++++++
 packages/core/src/plugin-types.ts                  | 15 ++++-
 packages/core/src/types.ts                         |  2 +-
 .../__tests__/SettingsModal.mcp.test.tsx           | 34 +++++++++-
 .../settings/sections/McpServersCard.tsx           | 52 ++++++++++-----
 .../settings/sections/ProjectMcpSection.tsx        | 31 ++++++++-
 .../register-config-mcp-pi-settings-routes.test.ts | 18 ++++-
 packages/dashboard/src/routes/context.ts           | 71 +++++++++++++++++++-
 .../register-config-mcp-pi-settings-routes.ts      | 30 ++++++++-
 .../engine/src/__tests__/mcp-resolution.test.ts    | 20 ++++++
 packages/engine/src/mcp-resolution.ts              | 15 ++++-
 packages/engine/src/plugin-runner.ts               | 38 +++++++++++
 packages/engine/src/runtimes/in-process-runtime.ts | 23 +++++++
 packages/plugin-sdk/src/index.ts                   |  1 +
 25 files changed, 563 insertions(+), 36 deletions(-)

Fusion-Task-Id: FN-8491

Fusion-Task-Lineage: be7e22fa-5776-4b3d-9fd1-a873799e6427

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-22 15:25:20 -07:00
gsxdsm
242b22dbf4 FN-8488: add branded icons for first-class providers
Ensure every first-class authentication provider renders an intentional branded icon.

- Add custom llama.cpp, Brave Search, and Tavily provider icons.
- Make OpenClaw theme-aware and add stable icon test selectors.
- Export the API-key provider catalog and verify dashboard parity.

Files changed:
 packages/dashboard/app/components/ProviderIcon.tsx | 65 ++++++++++++++++---
 .../app/components/__tests__/ProviderIcon.test.tsx | 73 +++++++++++++++++++++-
 packages/dashboard/app/styles.css                  |  6 ++
 .../__tests__/auth-provider-catalog-parity.test.ts | 11 ++++
 packages/engine/src/index.ts                       |  1 +
 packages/engine/src/provider-auth.ts               |  6 +-
 6 files changed, 148 insertions(+), 14 deletions(-)

Fusion-Task-Id: FN-8488

Fusion-Task-Lineage: e75e823b-4f03-4ad9-892f-100212a6022e

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-22 14:42:04 -07:00
gsxdsm
961edf2145 fix(dashboard): mount plugin routes without engine
Keep plugin-defined APIs reachable in UI-only dashboards by sourcing routes from the plugin loader when no engine runner exists.
2026-07-22 13:47:58 -07:00
flexi767
8e6985aed3 feat(core): reconcile archived mission evidence atomically (#2379)
## Summary

- add an atomic PostgreSQL operation that reconciles a mission feature
with a terminal delivery task
- support retained archived-task evidence without unarchiving or waking
mission automation
- reject missing, active, deleted-without-archive, and duplicate-linked
task evidence without partial mutation
- route the reconciliation endpoint through the transactional store
operation

## Root cause

Mission reconciliation previously relied on ordinary task-link and
lifecycle paths that cannot safely use retained archived task evidence.
That made historical delivery repair either impossible or vulnerable to
partial linkage and unintended mission-loop side effects.

## Scope

This PR contains the reusable product capability recovered from FX-001.
It intentionally does not perform the project-specific 69-row live data
mutation; that operational reconciliation was blocked by ambiguous
evidence and belongs outside the source change.

## Validation

- PostgreSQL mission-store tests: 23 passed
- dashboard reconciliation route tests: 3 passed
- `@fusion/core` typecheck
- `@fusion/dashboard` typecheck
- targeted ESLint
- strict changeset validation


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

## Summary by CodeRabbit

* **New Features**
* Added safer reconciliation for completed mission features using
validated terminal task evidence.
* Supports eligible archived tasks without restoring or relinking them.
* Reconciliation is idempotent and updates related mission progress
consistently.

* **Bug Fixes**
* Prevented conflicting or invalid task evidence from changing mission
state.
  * Added atomic rollback when reconciliation encounters an error.
* Improved API responses for missing resources and reconciliation
conflicts.

* **Documentation**
* Expanded reconciliation safety, error, idempotency, and
duplicate-cleanup guidance.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: fusion-merge-train <merge-train@topkoli.local>
Co-authored-by: Fusion <noreply@runfusion.ai>
2026-07-22 13:46:08 -07:00