Commit Graph

10772 Commits

Author SHA1 Message Date
gsxdsm
9cbed745f9 feat(dashboard): surface the planning-capacity wait and stop overclaiming Start
Start performs a bare column move, so "Started planning {id}" reported an
outcome the handler cannot observe: the engine still has to admit the card, and
a busy pool (per-project maxConcurrent or cross-project globalMaxConcurrent) can
defer that indefinitely. The wait was only visible in the engine log
("Plan throttled by running-agent cap|global semaphore"), so a throttled card
looked like a bug.

- Add a "Queued to plan" badge: the exact complement of "Ready" (same idle-Todo
  conditions, but no steps yet, so it waits for a PLANNING slot rather than a WIP
  slot). Three Todo states are now distinguishable: planning in flight, queued to
  plan, and ready. Pause suppression matches Ready; the badge reuses the existing
  status-badge primitives with a color-mix tint, no new tokens.
- Retitle the Start toast to "Queued {id} for planning" in both call sites
  (TaskCard Start and QuickEntryBox quick-add Start).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 09:14:11 -07:00
gsxdsm
b5578448fa fix(workflow): start planning immediately when a task is started
Pressing Start on a Coding (Ideas) card only writes a column move — there is no
dispatch call in that path — so planning did not begin until the triage
processor's next timer tick, up to pollIntervalMs (15s default) later. The
"Started planning" toast was optimistic and the card just sat in Todo.

- Wake planning discovery on the store's task:updated/task:created event when a
  task lands in todo/triage. Binding the wake to the store event rather than the
  Start button covers every move surface (board drag, context menu, task detail,
  List view, CLI, agent tools, POST /tasks/:id/move) by construction. The wake is
  advisory: it only advances WHEN the poll runs, so every pause, seed-prompt,
  dependency, and concurrency gate still applies.
- Admit a todo task whose PROMPT.md is missing instead of dropping it through a
  silent `catch {}`. The scheduler KEEPS a candidate whose prompt it cannot read,
  so such a card was invisible to planning while still visible to dispatch, with
  no log line in either lane. Unreadable (non-ENOENT) prompts now log.
- Route the scheduler's dispatch filter through the shared isUnplannedSeedPrompt
  predicate. Its open-coded strict bootstrap compare disagreed with triage on the
  refinement-seed shape, leaving hold-release as the only thing between an
  executor and a prompt containing just the operator's feedback text. The
  predicate also normalizes line endings/trailing whitespace, so a CRLF or
  trailing-newline round-trip no longer reclassifies an unplanned card as planned.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 09:14:11 -07:00
gsxdsm
1c38c6e93b fix(dashboard): make duplicate-warning "Open" actually open the task
The "Open" button on a possible-duplicate warning did nothing — the modal
closed and no task appeared. The app has two task deep-link shapes and only
one had a consumer: `?task=<id>` was handled by useDeepLink, while
`#/tasks/<id>` had no `hashchange` listener anywhere in the dashboard.

Five surfaces write the hash form. InlineCreateCard and NewTaskModal write it
unconditionally, so their Open was always dead. QuickEntryBox, Column, and
ListView try an in-memory board lookup first and fall through to the dead hash,
which is why it looked intermittent: duplicate matches come from a
project-wide searchTasks, so a match that is `done` or outside the loaded
board slice misses the lookup and lands on the no-op.

Handle the hash form inside useDeepLink so the app keeps one deep-link
authority owning both shapes, rather than forking a parallel hook. The id is
resolved by fetch instead of an in-memory lookup (that lookup is the dead end
being removed), the hash is cleared via replaceState so re-Opening the same
task fires again, and an unresolvable id toasts instead of failing silently.

Regression tests assert the invariant shared by all five surfaces rather than
the single reported repro: a written hash always resolves to an open or a
toast, never a no-op. Verified against the pre-fix code — 5 of the 6 new tests
fail without this change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 09:07:09 -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
2ea5ac206d fix(cli-tests,dashboard): align quiet-mode result spies and voiceInput allowlist
CLI JSON/create success lines write via result() (raw stdout) so quiet mode
cannot drop machine-readable output; capture that seam in research/update/task
tests instead of console.log. Allowlist nested voiceInput settings for the
FN-7505 default-description guard and ship locale keys for Voice Input UI.
2026-07-25 09:02:59 -07:00
gsxdsm
927efb1477 fix(workflow): allow Coding (Ideas) cards to move back from Todo to Ideas
A legacy source column (todo/in-progress/...) validated moves only against the
closed VALID_TRANSITIONS map, which cannot know about a workflow-declared
column, so Todo -> Ideas was rejected even though the board drag pre-check and
context menu both offered it. Legacy sources now union VALID_TRANSITIONS with
the task's workflow-resolved adjacency, resolved lazily only when the legacy
table alone would reject. builtin:coding adjacency is unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 08:45:52 -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
2a2b157cb9 FN-8585: fix dashboard composer test source reads
Stabilize dashboard composer tests when Vitest launches from the workspace root.

- Resolve dashboard test source fixtures relative to the app directory.
- Migrate affected component tests away from cwd-relative CSS reads.
- Enforce the fixture convention in test hooks and document it.

Files changed:
 docs/testing.md                                    |  4 +++
 package.json                                       |  6 ++--
 .../__tests__/AuthTokenRecoveryDialog.test.tsx     |  3 +-
 .../components/__tests__/ChatView.mobile.test.tsx  |  5 +--
 .../__tests__/EngineControlMenu.test.tsx           | 11 ++----
 .../components/__tests__/FloatingWindow.test.tsx   |  5 +--
 .../app/components/__tests__/ListView.test.tsx     |  5 +--
 .../__tests__/MissionInterviewModal.test.tsx       |  3 +-
 .../app/components/__tests__/MobileNavBar.test.tsx |  3 +-
 .../app/components/__tests__/NewTaskModal.test.tsx |  3 +-
 .../__tests__/PlanningModeModal.initial.test.tsx   |  3 +-
 .../PlanningModeModal.ui-interactions.test.tsx     |  7 ++--
 .../components/__tests__/PrCreateModal.test.tsx    |  3 +-
 .../__tests__/QuickChat.persist.test.tsx           |  3 +-
 .../components/__tests__/QuickEntryBox.test.tsx    |  3 +-
 .../components/__tests__/ReportActionMenu.test.tsx |  9 ++---
 .../app/components/__tests__/ReportModal.test.tsx  |  3 +-
 .../__tests__/ShadcnColorPicker.test.tsx           |  3 +-
 .../components/__tests__/TerminalModal.test.tsx    |  3 +-
 .../components/__tests__/ThemeDropdown.test.tsx    |  9 ++---
 .../__tests__/WorkflowNodeEditor.test.tsx          |  5 +--
 .../WorkflowOptionalStepsDropdown.test.tsx         |  3 +-
 .../components/__tests__/WorkflowSwitcher.test.tsx |  5 +--
 .../app/components/__tests__/board-mobile.test.tsx |  4 +--
 .../__tests__/CommandCenterControls.test.tsx       |  6 ++--
 .../__tests__/SystemControlsArea.test.tsx          |  5 +--
 .../__tests__/SystemStatsArea.test.tsx             |  3 +-
 .../command-center/areas/__tests__/areas.test.tsx  |  3 +-
 .../__tests__/KeyboardShortcutsSection.test.tsx    |  3 +-
 .../app/test/__tests__/cssFixture.test.ts          | 35 +++++++++++++++++++
 packages/dashboard/app/test/cssFixture.ts          | 12 +++++++
 .../check-no-cwd-relative-dashboard-test-reads.mjs | 39 ++++++++++++++++++++++
 32 files changed, 162 insertions(+), 55 deletions(-)

Fusion-Task-Id: FN-8585

Fusion-Task-Lineage: 83a35fb6-a29d-4e97-b282-1054c68b8cc9

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-25 06:22:23 -07:00
gsxdsm
9575e4b493 FN-8580: deduplicate voice availability settings reads
Voice dictation now shares a project-scoped availability request without fetching settings separately.

- Add a deduplicated voice availability hook for status and browser support
- Update voice dictation to consume shared availability state
- Cover composer settings isolation and voice availability behavior
- Add a patch changeset for duplicate settings request fixes

Files changed:
 .changeset/fn-8580-voice-settings-read-dedupe.md   |   7 +
 .../composer-settings-read-isolation.test.tsx      | 200 +++++++++++++++++++++
 .../hooks/__tests__/useVoiceAvailability.test.tsx  |  70 ++++++++
 .../app/hooks/__tests__/useVoiceDictation.test.tsx |  27 ++-
 .../dashboard/app/hooks/useVoiceAvailability.ts    |  69 +++++++
 packages/dashboard/app/hooks/useVoiceDictation.ts  |  31 +---
 6 files changed, 360 insertions(+), 44 deletions(-)

Fusion-Task-Id: FN-8580

Fusion-Task-Lineage: fac6f7f6-dda9-45d8-b501-d3762dca26df

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-25 05:48:35 -07:00
gsxdsm
32adc0a153 FN-8573: add voice dictation controls to composers
Add shared voice dictation support across chat, planning, and task-creation composers.

- Add browser speech-recognition and composer insertion hooks.
- Provide a reusable mic button with accessible recording states.
- Integrate and test dictation across all supported composer surfaces.
- Document the feature and add a package changeset.

Files changed:
 .changeset/fn-8573-voice-dictation-mic.md          |   7 +
 docs/dashboard-guide.md                            |   6 +
 packages/dashboard/app/components/ChatView.tsx     |  44 +++-
 .../dashboard/app/components/ComposeChatPanel.tsx  |   8 +-
 packages/dashboard/app/components/MicButton.css    |   5 +
 packages/dashboard/app/components/MicButton.tsx    |  20 ++
 .../dashboard/app/components/PlanningModeModal.tsx |  82 ++++--
 .../dashboard/app/components/QuickEntryBox.tsx     |   4 +
 .../app/components/StandardChatSurface.tsx         | 108 +++++---
 packages/dashboard/app/components/TaskChatTab.tsx  |   4 +
 packages/dashboard/app/components/TaskComments.tsx |  66 ++---
 packages/dashboard/app/components/TaskForm.tsx     |  18 +-
 .../app/components/TaskPlannerChatTab.tsx          |   7 +
 .../app/components/__tests__/MicButton.test.tsx    |  28 +++
 .../components/__tests__/QuickEntryBox.test.tsx    |   5 +
 .../app/components/__tests__/TaskForm.test.tsx     |   5 +
 .../app/components/__tests__/insertAtCaret.test.ts |  25 ++
 .../__tests__/voice-dictation-composers.test.tsx   | 230 +++++++++++++++++
 packages/dashboard/app/components/insertAtCaret.ts |  20 ++
 .../hooks/__tests__/useComposerDictation.test.tsx  |  58 +++++
 .../app/hooks/__tests__/useVoiceDictation.test.tsx | 158 ++++++++++++
 .../dashboard/app/hooks/useComposerDictation.ts    | 112 +++++++++
 .../dashboard/app/hooks/useVoiceDictation.ts       | 277 +++++++++++++++++++++
 23 files changed, 1204 insertions(+), 93 deletions(-)

Fusion-Task-Id: FN-8573

Fusion-Task-Lineage: 905ae982-3e63-494f-aba8-e3665f00cdda

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-25 05:15:02 -07:00
gsxdsm
11db36187f FN-8572: add voice input settings and model controls
Add project-scoped voice dictation controls with observable local model management.

- Add the Voice Input settings section with opt-in enablement and runtime-safe status handling.
- Add Parakeet v3 model download, removal, progress polling, search, documentation, and regression coverage.
- Add a minor release changeset for Voice Input settings.

Files changed:
 .changeset/fn-8572-voice-input-settings.md         |   7 ++
 docs/dashboard-guide.md                            |   4 +
 docs/settings-reference.md                         |   1 +
 .../dashboard/app/components/SettingsModal.tsx     |   7 +-
 .../VoiceInputSection.modal-visibility.test.tsx    |  19 +++
 .../settings/__tests__/VoiceInputSection.test.tsx  | 137 +++++++++++++++++++++
 .../settings/__tests__/section-keys.test.ts        |   1 +
 .../search/__tests__/settings-search-index.test.ts |   1 +
 .../app/components/settings/search/entries.ts      |   2 +
 .../app/components/settings/section-keys.ts        |   2 +
 .../settings/sections/VoiceInputSection.css        |  48 ++++++++
 .../settings/sections/VoiceInputSection.search.ts  |  14 +++
 .../settings/sections/VoiceInputSection.tsx        | 128 ++++++++++++++++++++
 13 files changed, 370 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-8572
Fusion-Task-Lineage: 2d2ad0df-3765-4d19-a6f3-7c2b5ca5df95
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-25 02:51:28 -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
b31bee03a8 FN-8576: add global quiet flag to CLI
Add a global quiet mode that suppresses informational CLI stdout without hiding requested results.

- Parse --quiet/-q and FUSION_QUIET with command and output exemptions.
- Route result output and interactive prompts around the reversible stdout gate.
- Document the flag and cover quiet output, prompts, and argument parsing.

Files changed:
 .changeset/fn-8576-cli-quiet-flag.md               |   7 ++
 docs/cli-reference.md                              |   8 ++
 packages/cli/src/__tests__/bin.test.ts             |  15 +++
 packages/cli/src/__tests__/cli-quiet-mode.test.ts  |  63 +++++++++++++
 .../__tests__/cli-quiet-prompt-surfaces.test.ts    |  33 +++++++
 packages/cli/src/bin.ts                            |  39 ++++++--
 packages/cli/src/commands/experiment-finalize.ts   |   3 +-
 packages/cli/src/commands/git.ts                   |  17 ++--
 packages/cli/src/commands/goals.ts                 |   4 +-
 packages/cli/src/commands/mission.ts               |   8 +-
 packages/cli/src/commands/node.ts                  |   4 +-
 packages/cli/src/commands/onboard.ts               |   4 +-
 packages/cli/src/commands/org-import.ts            |   5 +-
 packages/cli/src/commands/plugin.ts                |  14 ++-
 packages/cli/src/commands/port-prompt.ts           |   4 +-
 packages/cli/src/commands/project.ts               |   6 +-
 packages/cli/src/commands/research.ts              |   3 +-
 packages/cli/src/commands/task.ts                  | 101 +++++++++++---------
 packages/cli/src/commands/update.ts                |   3 +-
 packages/cli/src/commands/workflow.ts              |  13 +--
 packages/cli/src/output.ts                         | 104 +++++++++++++++++++++
 packages/cli/src/project-resolver.ts               |  20 ++--
 22 files changed, 388 insertions(+), 90 deletions(-)

Fusion-Task-Id: FN-8576

Fusion-Task-Lineage: 2493d6d5-bbd9-4fc2-b903-950457ef30b0

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-25 00:54:46 -07:00
gsxdsm
0056d75314 FN-8569: surface unrecoverable report health
Classify parked direct reports as operator-actionable even when their stored state appears live.

- Add a reusable Reports Health classifier that prioritizes pause markers.
- Clear stale pause markers during live-state resumes without removing diagnostic errors.
- Cover desynchronized report states and document the health invariant.

Files changed:
 .../fn-8569-reports-health-error-unrecoverable.md  |  7 +++
 docs/architecture.md                               |  1 +
 .../agent-store-pause-marker-clear.test.ts         | 65 +++++++++++++++++++
 packages/core/src/agent-store.ts                   | 12 ++++
 .../src/__tests__/heartbeat-executor.test.ts       | 27 ++++++--
 .../engine/src/__tests__/reports-health.test.ts    | 73 ++++++++++++++++++++++
 packages/engine/src/agent-heartbeat.ts             | 36 ++++++-----
 packages/engine/src/index.ts                       |  6 ++
 packages/engine/src/reports-health.ts              | 70 +++++++++++++++++++++
 9 files changed, 278 insertions(+), 19 deletions(-)

Fusion-Task-Id: FN-8569

Fusion-Task-Lineage: 37c798a0-1f2b-4221-a0c6-ccbff8d72696

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-24 23:57:49 -07:00
gsxdsm
38e625a3c2 fix(i18n): add anthropicAuthPreference strings to all locales
English-source keys were added for en only; the i18n parity gate requires
identical key sets across es/fr/ko/zh-CN/zh-TW catalogs.
2026-07-24 23:35:05 -07:00
gsxdsm
cb8d116b2d FN-8568: apply new tags to open chats
Assign context-menu-created tags to their open conversations immediately.

- Return the created chat tag from the chat hook.
- Preserve existing session tags while assigning the new tag through either creation control.
- Cover Enter, Add, existing-tag, and blank-name paths.
- Add a patch changeset for the chat-tag behavior fix.

Files changed:
 .changeset/fn-8568-chat-tag-creation.md            |  7 ++
 packages/dashboard/app/components/ChatView.tsx     | 36 ++++++++-
 .../__tests__/ChatView.core-interactions.test.tsx  | 90 ++++++++++++++++++++++
 packages/dashboard/app/hooks/useChat.ts            |  4 +-
 4 files changed, 133 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-8568

Fusion-Task-Lineage: 38ee0e02-adbb-4b21-9058-486310da2190

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-24 23:31:11 -07:00
gsxdsm
4b0edf65d5 fix(dashboard-tests): index Anthropic auth preference and pause badge contract
- Register AuthenticationSection search entry for anthropicAuthPreference
- Map setting default description + en locale strings for the new control
- Expect executorState paused when enginePaused with zero running tasks
2026-07-24 23:24:28 -07:00
gsxdsm
58d55d6439 chore(release): v0.74.0-beta.0
Version bump via changesets.
2026-07-24 23:12:53 -07:00
gsxdsm
a03eb0b39c fix(dashboard-tests): green Full Suite after chat tags, TaskForm meta, remote lifecycle
- Replace undefined --space-2xs in ChatView tag menu with calc(--space-xs / 2)
- Stub fetchChatTags/create/rename/delete on streaming-thread api mock for useChat mount
- Expect TaskForm model/tracking callbacks with TaskFormValueChangeMeta source
- Drive remote tunnel lifecycle via one stop then error status (no double Stop race)
2026-07-24 23:02:16 -07:00
gsxdsm
1847d2bc2a chore(release): back-merge v0.73.0 from release
Keeps .changeset/project-switch-modal-reset.md: it was re-edited on main after
the v0.73.0 cut (f9f283293) and covers an unreleased fix.
2026-07-24 22:55:17 -07:00
gsxdsm
a727e20843 fix(auth): read the Anthropic credential preference from the resolved global dir
Global settings live in settings.json under the resolved global dir, which
falls back to the pre-rename ~/.pi/fusion and ~/.pi/kb dirs for installs that
never migrated. The reader hardcoded ~/.fusion, so on those installs the
operator's preference was silently ignored and resolution fell back to raw-key
precedence -- the same silent fallback the preference exists to remove.

Mirror the legacy-aware lookup getModelRegistryModelsPath already does for
models.json rather than importing core's resolver, which throws under VITEST
when called without an explicit dir.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 22:38:15 -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
8dc6598aa0 feat(auth): let operators choose which Anthropic credential wins
An operator can hold a raw Anthropic API key and a Claude subscription OAuth
login at once, and the raw key always won silently. A stale or revoked saved
key therefore shadowed a working subscription and failed every direct Anthropic
call with 401 invalid x-api-key, while both Settings cards still read Active.

Add the global anthropicAuthPreference setting ("api-key" default, preserving
the historical precedence, or "subscription"), read in resolveAnthropicRuntimeApiKey
straight from ~/.fusion/settings.json so it applies without a restart and needs
no settings plumbing through createFusionAuthStorage. Neither value removes a
source: with one credential configured, resolution reaches it either way.

Settings -> Authentication now names the credential in use on the two Anthropic
cards and renders the control, but only when both are actually connected.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 22:32:39 -07:00
gsxdsm
8156308695 feat(quick-add): show a visible Start button for waiting-column workflows
Replace the hidden long-press/right-click Start menu on Quick Add's Save with a
visible Start button in the action row, rendered only for workflows whose first
visible lane is a hold column (or Coding (Ideas)). Eligibility, the workflow
snapshot, the create-time column override, and the hold-first follow-up move are
unchanged; ineligible workflows render no Start chip or shell.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 22:32:30 -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
e01dc7d3d3 feat(board): speed up kanban scrolling and drop desktop snapping
Desktop board scrollers no longer snap: the browser's proximity-snap settle
animation was capturing wheel/trackpad pans and reading as a slow, sticky drag
toward a column center. Base `.board`, `.board-workflow-columns`, and
`.lane-columns` declare `scroll-snap-type: none`; proximity snap is re-declared
in phone-tier media blocks only, where the JS column pager owns paging.

On phones, the hook now owns post-lift motion instead of waiting it out. A
directional lift kills native inertia and animates to its target column via rAF
ease-out (~190-300ms), so the page starts moving on lift rather than after a
native fling that can coast for most of a second. Fling reach is preserved by
deriving a page count (1-3) from release velocity sampled off the board's own
scroll ticks, not from however far inertia happens to travel.

Guards: re-touch cancels the animation and hands the axis back to the finger;
reduced motion, missing rAF, and sub-2px distances fall back to the instant hard
jump; unmount mid-animation restores the frozen inline styles; a fast drag that
rests before lifting is not treated as a flick.

Tap-to-stop-during-momentum is gone as an interaction (no long coast remains to
interrupt). Its regression test is reframed around the equivalent seam: a drag
that interrupts the page animation wins over the pending page.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 22:16:11 -07:00
gsxdsm
4b4df1ff30 FN-8565: restore tablet task modal resizing
Restore resizable Task Detail and New Task windows on 768px touch tablets.

- Classify known touch tablets separately from phone sheets
- Restore bounded modal geometry and resize grips with keyboard support
- Add regression coverage, documentation, and a patch changeset

Files changed:
 .changeset/fn-8565-tablet-task-modal-resize.md     |  7 +++
 docs/dashboard-guide.md                            |  5 ++
 .../task-detail-modal-tablet-width.test.ts         | 15 +++++
 packages/dashboard/app/components/NewTaskModal.css | 18 +++++-
 packages/dashboard/app/components/NewTaskModal.tsx | 44 +++++++++++++-
 .../dashboard/app/components/TaskDetailModal.css   | 30 ++++++++++
 .../dashboard/app/components/TaskDetailModal.tsx   | 40 +++++--------
 .../app/components/__tests__/NewTaskModal.test.tsx | 68 +++++++++++++++++++++-
 ...etailModal.responsive-and-dependencies.test.tsx | 51 ++++++++++++++++
 .../hooks/__tests__/useModalResizePersist.test.tsx | 53 ++++++++++++++++-
 .../dashboard/app/hooks/useModalResizePersist.ts   | 58 +++++++++++++++---
 11 files changed, 352 insertions(+), 37 deletions(-)

Fusion-Task-Id: FN-8565

Fusion-Task-Lineage: 7d9bbeb9-0e6a-4ad9-8b4d-e9f3d8aef650

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-24 19:20:16 -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
c50e303a94 fix(viewport): keep large phones in mobile mode so the bottom nav renders
FN-8557 excluded any touch device from mobile mode when its reported physical
screen exceeded the 480px phone threshold, at any CSS width. Large Android
phones report exactly that, so they resolved to tablet: MobileNavBar returns
null off mode "mobile", while MobileNavBar.css still displayed at
(max-width: 768px) — JS and CSS disagreeing about the same device. The board
also fell back to the horizontally-scrollable desktop layout.

No tablet uses a <=600px viewport as its primary layout, so width now
overrides the physical-screen heuristic below that floor; the carve-out
FN-8557 wanted (portrait tablets at the 768 boundary) keeps the 601-768 band.

The floor checks all three width signals the classifier already trusts —
media query, innerWidth, visualViewport — since each can lead on a different
device or update late on rotation. Regression tests cover all three; each
fails against the pre-fix classifier.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 18:54:27 -07:00
gsxdsm
749167cbed fix(engine-controls): surface a paused engine instead of showing it as idle
A paused engine with nothing running derived executorState "idle", so the
footer badge was indistinguishable from a healthy engine waiting for work.
That is exactly the state a pause settles into once in-flight tasks drain:
triage and planning stall while the board keeps moving, with the pause only
visible by opening the Engine Control menu. Pause state now dominates run
state; the adjacent counters still report throughput.

In the CLI TUI, the global `t` (Git view) branch returned before the Utilities
dispatch in the same key handler, so the advertised "[t] Toggle Engine Pause"
was unreachable dead UI. It now yields when Utilities owns input, and because
the shortcut can stop the board, pausing takes a second `t` within 5s while
resuming stays single-press.

Tests assert the invariant across the whole state matrix (both pause flags x
0/1/5 running), not just the zero-running repro, plus the TUI routing, the
two-press pause, single-press resume, and re-arm behavior.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 18:49:19 -07:00
gsxdsm
f3a69497dc FN-8563: preserve new task edits before defaults load
Treat asynchronous New Task defaults as pristine while retaining operator changes for discard confirmation.

- Track initialization versus user writes for workflow steps, models, and GitHub defaults
- Prevent delayed model auto-preset selection from overwriting an operator-selected custom model
- Cover blank-modal close paths and the delayed-settings custom-model regression

Files changed:
 .changeset/fn-8563-pristine-new-task-close.md      |   7 ++
 packages/dashboard/app/components/NewTaskModal.tsx |  68 +++++++++--
 packages/dashboard/app/components/TaskForm.tsx     |  58 ++++++---
 .../app/components/__tests__/NewTaskModal.test.tsx | 134 +++++++++++++++++++++
 4 files changed, 235 insertions(+), 32 deletions(-)

Fusion-Task-Id: FN-8563

Fusion-Task-Lineage: d70c1e41-37b4-4cb6-bcf7-9bd7dd64ac39

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-24 18:43:29 -07:00
gsxdsm
cc053915f3 test(dashboard-tests): drive SettingsModal auto-save retry/trailing tests with fake timers
Two auto-save tests waited out the real 500ms debounce via waitFor (up to two
cycles each), unlike the sibling coalesces test which already uses fake timers.
Switch both to vi.advanceTimersByTimeAsync(500) to remove ~1.7s of wall-clock
dead time from the dashboard's slowest feedback-loop suite with identical
coverage (Standing Rule: prefer fake timers over real time waits).
2026-07-24 18:11:24 -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
03cfc2dfc8 FN-8561: add lifecycle dates to task cards
Show localized creation and completion dates directly on task cards.

- Render compact, locale-aware lifecycle timestamps with accessible full-date titles.
- Persist archive timestamps for completed archived-task fallbacks and add coverage.
- Add translated labels, documentation, and a minor release changeset.

Files changed:
 .changeset/fn-8561-task-card-dates.md              |  7 +++
 docs/dashboard-guide.md                            |  1 +
 .../__tests__/archive-entry-serialization.test.ts  | 35 ++++++++++++++
 packages/core/src/task-store/serialization.ts      |  8 ++++
 packages/core/src/types/task-core.ts               |  5 ++
 packages/dashboard/app/components/TaskCard.css     | 27 +++++++++++
 packages/dashboard/app/components/TaskCard.tsx     | 55 ++++++++++++++++++++++
 .../__tests__/TaskCard.host-inventory.test.tsx     | 21 +++++++++
 .../app/components/__tests__/TaskCard.test.tsx     | 17 +++++++
 .../dashboard/app/i18n/__tests__/format.test.ts    | 19 +++++++-
 packages/dashboard/app/i18n/format.ts              | 38 +++++++++++++++
 packages/i18n/locales/en/app.json                  |  4 ++
 packages/i18n/locales/es/app.json                  |  4 ++
 packages/i18n/locales/fr/app.json                  |  4 ++
 packages/i18n/locales/ko/app.json                  |  4 ++
 packages/i18n/locales/zh-CN/app.json               |  4 ++
 packages/i18n/locales/zh-TW/app.json               |  4 ++
 17 files changed, 256 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-8561

Fusion-Task-Lineage: 474b949b-d8e7-469a-b564-00acae66e58a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-24 11:15:43 -07:00
gsxdsm
ab41554980 fix(cli-tests): load task.js once for lock-retry suite under real timers
Full Suite shard 4 timed out runTaskShow lock-exhaustion at the default 5s
budget (run 30096660913): each case re-imported the heavy task.js graph under
fake timers, so cold CI workers spent the whole budget on transform and left
unhandled store.getTask / process.exit races after the timeout.

Import task.js once per cached-store describe under real timers via a mutable
store holder, and enable fake timers only around the backoff body. Exhaustion
cases now finish in ~1ms locally while keeping the shipped entry path.
2026-07-24 08:27:57 -07:00
gsxdsm
c5a8421533 FN-8560: forward desktop test telemetry flags
Desktop test execution now preserves CI reporter and JSON output flags.

- Forward caller-selected Vitest reporters and output files through the desktop test wrapper.
- Add coverage for reporter syntax and shard timing command forwarding.
- Document desktop timing artifact requirements.

Files changed:
 docs/testing.md                                    |  7 ++++-
 packages/desktop/scripts/__tests__/test-args.test.ts | 36 ++++++++++++++++++++++
 packages/desktop/scripts/test-args.ts              | 13 ++++++++
 packages/desktop/scripts/test.ts                   |  3 +-
 scripts/__tests__/ci-test-shard.test.mjs           |  9 ++++++
 5 files changed, 66 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-8560

Fusion-Task-Lineage: 2a89b28d-39f6-4949-aec2-1123c36126cf

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-24 05:30:45 -07:00
gsxdsm
19f25f9a35 fix(dashboard-tests): align SettingsModal suites with FN-8453 and #2400; de-race worktree copy-files save
- general: FN-8453 removed the duplicate "Max Triage Concurrent" control
  (assert it stays gone); #2400 replaced the per-phase moved-to-workflow note
  with the editable "Project workflow model lanes" section.
- scheduling-merge: await the updateSettings call that carries
  worktreeCopyFiles instead of assuming calls[0] (CI lane-load ordering).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 03:11:22 -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
cdc5b7f901 fix(dashboard-tests): settle canvas hydration before the edge-targeted optional-group pick
Full-suite run 30077108784 hit an additive insert under CI lane load (group
spliced while merge→end survived) because the toolbar pick ran before the
canvas settled its edge-target state; 5/5 green locally. Same
settle-before-interact class as 5a5796bca; recurrence goes to quarantine.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 01:20:43 -07:00
gsxdsm
973c978f91 FN-8557: preserve terminal geometry on tablets
Keep floating terminal controls available on touch tablets across responsive and keyboard viewport changes.

- Classify known tablet screens separately from phone fallbacks.
- Restore tablet floating and docked geometry at the 768px breakpoint with larger touch resize targets.
- Cover keyboard-shrunken and breakpoint tablet interactions, and document the responsive behavior.

Files changed:
 docs/dashboard-guide.md                            |   2 +-
 .../dashboard/app/components/TerminalModal.css     |  76 +++++++++--
 .../dashboard/app/components/TerminalModal.tsx     |  33 ++---
 .../components/__tests__/TerminalModal.test.tsx    | 150 +++++++++++++++++++++
 .../app/hooks/__tests__/useViewportMode.test.ts    |  14 ++
 packages/dashboard/app/hooks/useViewportMode.ts    |  33 ++++-
 6 files changed, 277 insertions(+), 31 deletions(-)

Fusion-Task-Id: FN-8557

Fusion-Task-Lineage: cd334682-e70a-4531-ab53-c5c0898f0bf1

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-24 00:59:42 -07:00
gsxdsm
e4fc3d2acb FN-8558: enlarge Quick Chat tablet drag target
Make the floating Quick Chat header easier to drag on tablet viewports.

- Increase only the floating Chat header touch target in the tablet viewport band.
- Cover floating header controls for empty and populated chats and scope the CSS contract.
- Add a patch changeset for the Quick Chat usability fix.

Files changed:
 .changeset/quick-chat-tablet-drag-header.md        |  7 ++++
 packages/dashboard/app/components/ChatView.css     | 13 +++++++
 packages/dashboard/app/components/__tests__/ChatView.mobile.test.tsx  | 41 ++++++++++++++++++++++
 packages/dashboard/app/components/__tests__/FloatingWindow.test.tsx   | 20 +++++++++++
 4 files changed, 81 insertions(+)

Fusion-Task-Id: FN-8558

Fusion-Task-Lineage: 2d2f788b-b417-4fa3-b066-8790858b393a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-24 00:46:44 -07:00
gsxdsm
c3cebcd56b FN-8556: fix Windows agent target selection
Make direct-chat Agent selection reliable when Windows Electron suppresses the click after pointer activation.

- Switch target mode on primary pointerdown while retaining keyboard activation.
- Expose selected Model and Agent modes with aria-pressed semantics.
- Cover pointer activation and persistence across direct-chat layouts.
- Add a patch changeset for the Windows selection fix.

Files changed:
 .changeset/fn-8556-windows-agent-selection.md      |  7 ++++
 .../app/components/ChatThinkingLevelControl.tsx    | 28 ++++++++++++-
 .../__tests__/ChatThinkingLevelControl.test.tsx    | 27 +++++++++++--
 .../__tests__/ChatView.thinking-level.test.tsx     | 46 +++++++++++++++++-----
 4 files changed, 93 insertions(+), 15 deletions(-)

Fusion-Task-Id: FN-8556

Fusion-Task-Lineage: 25b06177-3b59-4d2d-8440-e92fe7172259

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-24 00:35:34 -07:00
gsxdsm
f6795317a8 fix(dashboard-tests): useTasks column normalization asserts the post-cutover contract
b2a7425c7 replaced the six-legacy-id whitelist with normalizeColumnId: custom
workflow column ids pass through untouched, only structurally unusable values
(non-string/empty) fall back to triage. The two normalization tests now assert
both halves of that invariant instead of the deleted whitelist behavior.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 00:28:55 -07:00
gsxdsm
94f1bd9527 fix(dashboard-tests): align remaining ChatView send assertions with FN-8502 delivery callbacks
Same drift as chat-commands/mobile: sendMessage gained the {onDelivered,onFailed}
third argument; autosize and draft suites now expect it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 00:09:44 -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
74236211ea fix(dashboard): repaint stalled terminal renderer so first shell prompt shows without a keypress
On some systems the terminal opened blank — buffered prompt present but
never painted (renderer stalled at init: WebGL activation on a zero-sized
canvas or context-loss fallback). Every automatic recovery path fit() but
never refreshed, and fit() with unchanged cols/rows triggers no internal
xterm repaint, so only user input, a font-size change, or a new tab
repaired it. Observer/geometry-driven fits in TerminalModal and
SessionTerminal now always follow fit() with an explicit full-viewport
terminal.refresh(0, rows-1).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 23:51:12 -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
da0d73c853 fix(release): give desktop closure staging 30min in bun binary builds
The CLI full-package build's nested @fusion/desktop build stages the
production closure via pnpm deploy (~1300+ packages); on cold-store macOS
release runners that exceeded runWorkspaceCommand's default 10-minute
timeout and killed every v0.73.0-beta.* bun-darwin-arm64 release leg with
exit 143. Raise the desktop sub-build budget to 30 minutes and widen the
build-binaries job timeout to 45 minutes to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 22:56:52 -07:00