Command Center analytics now honor picker presets and open-ended date bounds.\n\n- Serialize All time with an explicit upper bound and preserve one-sided custom/preset query params.\n- Resolve server analytics ranges as open windows for from-only and to-only requests instead of defaulting them away.\n- Cover picker query serialization and range-consuming Command Center endpoints with regression tests.\n- Document the restored picker contract and add a patch changeset.\n\nFiles changed:\n .changeset/fn-7019-command-center-range.md | 7 ++\n docs/dashboard-guide.md | 3 +-\n .../components/command-center/DateRangePicker.tsx | 12 ++-\n .../command-center/areas/__tests__/areas.test.tsx | 54 ++++++++++++-\n .../components/command-center/areas/areaShared.ts | 8 +-\n .../register-command-center-routes.test.ts | 92 +++++++++++++++++++++-\n .../src/routes/register-command-center-routes.ts | 28 ++++---\n 7 files changed, 183 insertions(+), 21 deletions(-)
Fusion-Task-Id: FN-7019
Fusion-Task-Lineage: 327f8f45-8ad8-4103-8cc4-efcf2af6a73a
Keep discovered skill rows within the left pane by truncating long text values.
- Wrap skill names in a truncatable text span while keeping chevrons fixed-size.
- Add ellipsis rules and compact font sizing for skill names, paths, and sources.
- Cover long, short, and empty metadata skill rows with a dashboard test.
- Add a patch changeset for the published CLI package.
Files changed:
.changeset/fn-7027-skill-list-truncation.md | 7 +++
packages/dashboard/app/components/SkillsView.css | 28 ++++++++++
packages/dashboard/app/components/SkillsView.tsx | 2 +-
.../app/components/__tests__/SkillsView.test.tsx | 64 ++++++++++++++++++++++
4 files changed, 100 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-7027
Fusion-Task-Lineage: ae50f1aa-e58b-4374-abae-38ca28e4073a
Make the dashboard AI session needs-input banner less prominent while preserving visibility rules.
- Reduce the session notification banner spacing, text scale, max heights, and mobile density.
- Cover banner visibility on missions, planning, hidden, empty, and board-session states.
- Add a patch changeset for the published CLI package.
Files changed:
.changeset/fn-7020-session-banner-compact.md | 7 +
.../app/components/SessionNotificationBanner.css | 47 +++--
.../dashboard/__tests__/DashboardBanners.test.tsx | 227 +++++++++++++++++++++
3 files changed, 263 insertions(+), 18 deletions(-)
Fusion-Task-Id: FN-7020
Fusion-Task-Lineage: bd48da60-29ef-4871-ae27-8a1a48f744ea
Refinement: Code Review is now a DEFAULT-ON but toggleable `optional-group` in the
built-in coding and stepwise coding workflows (defaultOn:true), not a standard
always-on node. It is part of the existing pre-merge flow (execute →
[browser-verification optional] → code-review → review) and runs for every coding
task by default, yet an operator can toggle it off per task by removing `code-review`
from enabledWorkflowSteps; disabled → byte-inert pass-through. Advisory gateMode keeps
it non-blocking (operators can promote to a gate); toolMode readonly.
- Restore the optional-group builder (builtin-code-review-node.ts → -group.ts) with
config.defaultOn:true; stable group id `code-review`, inner id `code-review-step`.
- Wire the default-on optional-group into both built-in coding IRs.
- Fix store default-workflow seeding: interpreter-deferred built-ins (which carry
optional-group nodes) previously bailed to `undefined` in
materializeDefaultWorkflowSteps, dropping default-on group seeding under a
project-default workflow. Now they seed resolveDefaultOnOptionalGroupIds, mirroring
the explicit-workflow path, so defaultOn:true actually takes effect (the executor
enables a group strictly via enabledWorkflowSteps.includes(node.id)).
- Update tests + changeset; full @fusion/core suite green (356 files).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Design correction: Code Review is now a STANDARD, default-ON step in the
built-in coding and stepwise coding workflows — not a default-off optional-group
toggle. It is a regular advisory `prompt` node on the pre-merge success path
(execute → [browser-verification optional] → code-review → review), so it runs
for every coding task with no enabledWorkflowSteps gating. Advisory gateMode means
it does not change merge outcomes; operators can promote it to a blocking gate.
- Replace the optional-group module with a standard prompt-node builder
(builtin-code-review-group.ts → builtin-code-review-node.ts).
- Keep the `code-review` WORKFLOW_STEP_TEMPLATE in the catalog (editor palette).
- Edges unchanged: code-review → review on success, code-review → end on failure
(mirrors the existing review node, no dead-end).
- Update tests + changeset for the standard always-on (no-toggle) semantics.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a configurable "Code Review" diff-review step to the built-in coding and
stepwise coding workflows as a default-OFF optional-group prompt gate. It reuses
the existing workflow-step machinery and the shared trailing-verdict convention
(REVISE blocks, APPROVE/APPROVE_WITH_NOTES pass) — no engine verification code.
- New `code-review` WORKFLOW_STEP_TEMPLATE (toolMode readonly, gateMode advisory,
phase pre-merge) focused on the correctness value tests miss: logic bugs, edge
cases, intent-vs-implementation drift, regressions, error handling, contracts.
- New builtin-code-review-group.ts mirroring builtin-browser-verification-group.ts
(stable group id `code-review`, distinct inner node id `code-review-step`).
- Wired into builtin-coding-workflow-ir.ts and builtin-stepwise-coding-workflow-ir.ts
on the pre-merge path next to browser-verification, default OFF / opt-in.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Restores mobile access to all task detail tabs by making the tab strip the horizontal scroller.
- Allow the task-detail content, body, modal tabs, tablet tabs, and embedded tabs to shrink within narrow containers.
- Preserve touch horizontal panning and momentum scrolling on tab strips without moving horizontal overflow to the detail body.
- Cover the Board modal, List embedded pane, and complete tab label set with responsive CSS regression tests.
- Add a patch changeset for the published Fusion package.
Files changed:
.../fn-7012-task-detail-mobile-tabs-scroll.md | 7 +++
.../dashboard/app/components/TaskDetailModal.css | 25 +++++++-
...etailModal.responsive-and-dependencies.test.tsx | 67 +++++++++++++++++++++-
3 files changed, 96 insertions(+), 3 deletions(-)
Fusion-Task-Id: FN-7012
Fusion-Task-Lineage: 06b06a81-b9ec-4058-879f-2f5e187a63a4
Make the AI mission planning workspace movable on desktop and safer when streams fail.
- Host the Plan Mission with AI modal in FloatingWindow with desktop drag/resize geometry and mobile full-screen preservation.
- Normalize terminal mission interview stream failures, close SSE/keepalive once, and suppress duplicate late terminal events.
- Cover modal geometry and stream-error behavior with dashboard tests and document the operator-facing behavior.
Files changed:
.changeset/fn-6975-mission-modal-stream.md | 7 ++
docs/dashboard-guide.md | 7 ++
.../api/__tests__/mission-interview-stream.test.ts | 98 ++++++++++++++++++
packages/dashboard/app/api/legacy.ts | 66 ++++++++++---
.../app/components/MissionInterviewModal.css | 51 ++++++++++
.../app/components/MissionInterviewModal.tsx | 37 ++++---
.../__tests__/MissionInterviewModal.test.tsx | 110 ++++++++++++++++++++-
7 files changed, 344 insertions(+), 32 deletions(-)
Fusion-Task-Id: FN-6975
Fusion-Task-Lineage: b2ffa558-8b7e-4a46-8882-f2c4f6189831
Diff-proportional verification (deriveFileScopedPnpmTestCommand) + scope-aware
verification timeout, so merge/step checks finish in seconds. Propagated to this
worktree directly.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Keep mobile New Task dialog controls reachable and tappable under keyboard-constrained viewports.
- Re-enable hit testing on the New Task sheet while preserving desktop overlay click-through behavior.
- Bound GitHub, dependency, and agent picker popups so mobile users can scroll them inside the sheet.
- Add regression coverage for mobile dialog affordances and document the mobile behavior.
- Add a patch changeset for the published Fusion package.
Files changed:
.changeset/fn-7002-mobile-new-task-affordances.md | 7 ++
docs/dashboard-guide.md | 2 +-
packages/dashboard/app/components/NewTaskModal.css | 18 +++++
.../app/components/__tests__/NewTaskModal.test.tsx | 87 +++++++++++++++++++++-
.../__tests__/core-modals-mobile.test.tsx | 32 ++++++++
5 files changed, 144 insertions(+), 2 deletions(-)
Fusion-Task-Id: FN-7002
Fusion-Task-Lineage: 31c2504e-56fd-4395-bbe3-e753aab04e23
## Problem
Fusion's verification gate (the merger, and the executor's per-step
auto-gate) runs the project's configured `testCommand`/`buildCommand`
bounded by a **flat 10-minute** default
(`VERIFICATION_COMMAND_TIMEOUT_MS = 600_000`) when no
`verificationCommandTimeoutMs` override is set. A **workspace-scoped**
command (a full suite that legitimately takes ~10+ min) hits that wall
and is killed as an **infra `timedOut`** — blocking the merge — even
though nothing is actually hung. Meanwhile a **package-scoped** command
got a too-generous bound. The `fn_run_verification` tool already derived
its default from scope (300s/900s); the merger/executor did not.
## Change
Make the shared `runVerificationCommand` (used by both the merger and
the executor auto-gate) **scope-aware**, mirroring the tool:
- **package-scoped** (`pnpm --filter`/`-F …`) → **300s**
- **workspace-scoped** (root command like `pnpm test`) → **900s**
An explicit project `verificationCommandTimeoutMs` still overrides, and
the 30-min hard cap (`VERIFICATION_COMMAND_HARD_CAP_MS`) still clamps.
New `classifyVerificationScope` / `defaultVerificationTimeoutMs` helpers
mirror `run-verification-tool`'s `DEFAULT_TIMEOUT_PACKAGE_SEC` (300) /
`DEFAULT_TIMEOUT_WORKSPACE_SEC` (900).
## Verification
- `verification-utils.test.ts` (new scope-classification + default
cases), `run-verification-command.test.ts`,
`merger-verification.test.ts` — **143 tests pass**.
- Lint clean. `patch` changeset added.
Note: a workspace command needing >900s should be **scoped** (FN-5048 /
the bounded-verification guidance), or set
`verificationCommandTimeoutMs` explicitly.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- stage-review-badge-begin -->
---
<a href="https://stagereview.app/Runfusion/Fusion/pull/1771">
<picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://stagereview.app/assets/gh-open-in-stage-dark.svg">
<img src="https://stagereview.app/assets/gh-open-in-stage-light.svg"
alt="Open in Stage">
</picture>
</a>
<!-- stage-review-badge-end -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Verification (merge/step gate) timeouts are now scope-aware:
package-scoped commands default to 300s and workspace-scoped commands
default to 900s.
* If a custom timeout is provided, it still overrides the default, while
the safety hard cap remains enforced.
* **Bug Fixes**
* Prevents verification jobs from using an overly generic fixed timeout,
reducing unnecessary early timeouts or excessive waits.
* **Tests**
* Expanded coverage to validate scope detection and the new default
timeout behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
The merger and executor verification gate (shared runVerificationCommand) used
a flat 10-min default (VERIFICATION_COMMAND_TIMEOUT_MS) for any configured
test/build command, while the fn_run_verification tool already derived its
default from command scope. A workspace-scoped command (a full suite, ~10+ min)
hit the flat 10-min wall and was killed as an infra timeout; a package-scoped
command got a too-generous bound.
Derive the default from command scope to match the tool: package-scoped
(pnpm --filter/-F ...) → 300s, workspace-scoped (root command like pnpm test)
→ 900s. An explicit project verificationCommandTimeoutMs still overrides, and
the 30-min hard cap still clamps the result. Covers both the merger and the
executor per-step auto-gate, which share runVerificationCommand.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fixes ~19 deterministic dashboard test failures pre-existing on origin/main
(non-blocking full-suite lane). Mix of real product fixes and stale-test
reconciliation; no appeasement (no widened timeouts, skips, or weakened
assertions).
Product CSS fixes (real regressions the guards caught):
- Info toast contrast: shadcn-custom light theme had white-on-#0284c7 (4.10,
below WCAG AA 4.5); enrolled it in the light-mode dark-text correction.
- 27 undefined CSS token references (typos/foreign tokens) renamed to canonical
defined tokens; defined the genuinely-intended --border-strong and
--right-dock-min/max-width.
- Raw rgba() box-shadow fallback tokenized to color-mix; dev-server mobile
header split into its own responsive rule.
Stale tests reconciled with intentional product changes:
- workflowColumns graduated to always-on (board-workflows unit test).
- workflow optional-steps source re-pointed to v2 optional-group nodes.
- command-center pricing docs (one doc gap filled: openai-codex:* keying).
- SetupWizardModal added detectWorkspace + workspaceMode/taskPrefix payload.
- board-mobile listener-count assertion → unmount no-throw behavior.
- CommandCenterControls / ThemeSelector: default theme relabeled "Fusion Legacy".
- ProjectOverview / WorkflowNodeEditor: header divider intentionally removed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The global mobile fullscreen modal rule (`.modal-lg`, `.modal:not(.confirm-dialog)`)
forced the embedded Planning shell to 100dvh, overflowing its bounded `.planning-view`
pane. `overflow:hidden` then clipped the footer action buttons and blocked scrolling.
Qualify the mobile embedded override as `.planning-view.open .planning-modal--embedded`
so it outranks the global rule, and re-pin `max-height:100%` so the inner flex scroll
chain works. Adds a CSS regression test.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Keep Command Center token usage surfaces mounted and updated during live analytics polling.
- Preserve existing analytics data while background polls are in flight so token surfaces revalidate without disappearing.
- Add live refresh intervals for Overview and Tokens token-usage data.
- Cover in-place token stat, chart, and model-row updates with Command Center and area tests.
- Add a patch changeset for the published Fusion package.
Files changed:
.changeset/fn-6970-command-center-token-live.md | 7 ++
.../components/command-center/CommandCenter.tsx | 4 +
.../__tests__/CommandCenter.test.tsx | 81 +++++++++++++--
.../components/command-center/areas/AreaShell.tsx | 3 +
.../components/command-center/areas/TokensArea.tsx | 4 +
.../command-center/areas/__tests__/areas.test.tsx | 111 +++++++++++++++++++--
.../command-center/areas/useAnalyticsArea.ts | 12 ++-
7 files changed, 208 insertions(+), 14 deletions(-)
Fusion-Task-Id: FN-6970
Fusion-Task-Lineage: 670bb5ac-bc7d-47d8-abed-ef6748292cc6
Dashboard Back navigation now dismisses task detail surfaces before leaving the current context.
- Add full-panel task-detail history entries that restore board/list state or the previous nested detail.
- Route modal task-detail Back handling through the same close path as explicit dismissal so deep-link cleanup runs.
- Cover board-opened, nested, and modal popstate flows and document the Back behavior.
- Add a patch changeset for the published Fusion dashboard behavior.
Files changed:
.changeset/fn-6964-dashboard-back-navigation.md | 7 ++
docs/dashboard-guide.md | 3 +-
packages/dashboard/app/App.tsx | 50 ++++++++++--
packages/dashboard/app/components/AppModals.tsx | 31 ++++++--
.../app/components/__tests__/App.test.tsx | 90 ++++++++++++++++++++++
.../app/components/__tests__/AppModals.test.tsx | 5 +-
.../app/components/dashboard/MainContent.tsx | 6 +-
.../dashboard/app/components/dashboard/types.ts | 1 -
8 files changed, 173 insertions(+), 20 deletions(-)
Fusion-Task-Id: FN-6964
Fusion-Task-Lineage: 2308b603-a6ac-4978-9a6a-a6028b9bc38c
Remove the stale branch reattachment affordance from Task Detail while preserving self-healing as the recovery path.
- Remove unused rebind banner styles and mobile action-shell rules.
- Drop stale recoverBranchBinding mocks from TaskDetailModal tests.
- Add rendering coverage proving Task Detail and embedded content do not show reattachment affordances across missing, populated, workspace, and mobile branch states.
- Add a patch changeset for the published Fusion package.
Files changed:
.changeset/fn-6983-task-detail-rebind-warning.md | 7 ++
.../dashboard/app/components/TaskDetailModal.css | 42 +-----------
.../TaskDetailModal.create-pr-e2e.test.tsx | 1 -
.../TaskDetailModal.create-pr-integration.test.tsx | 1 -
.../__tests__/TaskDetailModal.rendering.test.tsx | 80 ++++++++++++++++++++++
.../__tests__/TaskDetailModal.test-helpers.ts | 1 -
6 files changed, 88 insertions(+), 44 deletions(-)
Fusion-Task-Id: FN-6983
Fusion-Task-Lineage: 1a45c38e-f7d0-4df7-94cf-7d1309758e0d
Ensure mobile Missions exits detail tabs back to the mission list before outer navigation.
- Track mobile detail visibility instead of selected mission IDs when adding navigation entries.
- Avoid duplicate history entries for Structure/Activity tab switches and mission refreshes.
- Cover browser back and visible Back button behavior across mobile tabs while desktop stays unchanged.
- Add a patch changeset for the published Fusion package.
Files changed:
.changeset/fn-6998-mobile-mission-back.md | 7 ++
.../dashboard/app/components/MissionManager.tsx | 35 +++++--
.../__tests__/MissionManager.swipe-back.test.tsx | 114 ++++++++++++++++++---
3 files changed, 131 insertions(+), 25 deletions(-)
Fusion-Task-Id: FN-6998
Fusion-Task-Lineage: d3dbf3b7-0195-498f-a57f-ed83c6a422e7
The central DB (~/.fusion/fusion-central.db) is opened concurrently by every
fusion process on a host. In WAL mode those connections coordinate through a
memory-mapped `-shm` wal-index; on macOS/APFS a reader takes a SIGBUS
(walIndexReadHdr / `cluster_pagein past EOF`) when another process resizes it
mid-checkpoint, killing the node process with no JS stack or log. Observed 3x
in 3 days. Switch the central DB to journal_mode=DELETE, which uses no `-shm`
mmap and coordinates cross-process access via POSIX byte-range locks instead;
busy_timeout absorbs the added writer serialization. Per-project DBs keep WAL.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
## Summary
Replaces dense, agent-authored technical changeset paragraphs with a
**structured, concise changeset schema** (end-user summary + category +
optional dev detail), enforced by a linter. Adds a **deterministic
distillation step** at version time that transforms a release's
collected changesets into clean, grouped, end-user-facing release notes.
Unifies both release paths (local `release.mjs` and CI `version.yml` /
`release.yml`) behind a single distilled artifact so the root
`CHANGELOG.md` and GitHub Release both carry the same user-facing notes.
## Changes
### Changeset format (`scripts/lib/changeset-schema.mjs`)
- Each changeset body now uses labeled fields: `summary` (required,
user-facing, max 120 chars), `category` (required:
feature/fix/breaking/security/performance/internal), `dev` (optional
developer detail)
- Legacy freeform changesets are detected and flagged for the transition
period
### Linter (`scripts/check-changeset-format.mjs`)
- Validates structured schema, summary length, category enum, and
frontmatter package scope
- Wired into `test:gate`, `pretest`, `pretest:full`, and `pr-checks.yml`
- Legacy changesets warn (exit 0) during transition; `--strict` flag
fails on them
### Distillation (`scripts/lib/distill-release-notes.mjs`)
- `distillDeterministic` builds grouped, end-user-facing release notes
by category (New, Fixed, Breaking, Security, Performance, Internal)
- `buildDistillationPrompt` and `DISTILLATION_SYSTEM_PROMPT` ready for
AI distillation via `createFnAgent` when model credentials are available
- Graceful fallback: deterministic bullet list when no model is
configured
### Release integration
- **Local path** (`scripts/release.mjs`): captures changeset entries
before `changeset version` deletes them, distills notes post-version,
replaces the version's CHANGELOG section with curated notes
- **CI path** (`scripts/ci-distill-release-notes.mjs`,
`scripts/run-ci-distill.mjs`): chained into `release:version` so both
flows get distilled notes
- **GitHub Release** (`release.yml`): uses curated CHANGELOG notes
instead of `generate_release_notes: true`
### Documentation
- `AGENTS.md`, `RELEASING.md`, `docs/contributing.md` updated with the
structured format guide
- `.changeset/README.md` template for `pnpm changeset` consumers
## Testing
- 54 new unit tests across changeset-schema, check-changeset-format,
distill-release-notes, and extract-version-notes
- `pnpm lint` clean
- `pnpm test:gate` green (371 tests)
- `pnpm check:changesets` passes (13 legacy warnings expected during
transition)
## Plan
Full implementation plan:
`docs/plans/2026-06-24-001-feat-better-changelog-plan.md`
<!-- stage-review-badge-begin -->
---
<a href="https://stagereview.app/Runfusion/Fusion/pull/1750">
<picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://stagereview.app/assets/gh-open-in-stage-dark.svg">
<img src="https://stagereview.app/assets/gh-open-in-stage-light.svg"
alt="Open in Stage">
</picture>
</a>
<!-- stage-review-badge-end -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added structured release-note guidance and validation for changeset
entries.
* Release notes now use curated, grouped changelog content instead of
auto-generated text.
* Added a fallback process to keep release notes consistent when
automated distillation isn’t available.
* **Bug Fixes**
* Improved handling of legacy changesets and malformed entries.
* Ensured version-specific changelog sections are updated without
affecting older releases.
* **Tests**
* Added coverage for changeset validation, note grouping, and changelog
section replacement.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Update AGENTS.md, RELEASING.md, contributing.md with the structured
changeset format guide. Add .changeset/README.md template. Add changeset
for this change. Update distill-release-notes.mjs with final version.
Multiworkspace tasks could not complete due to two independent bugs:
1. task.workspaceWorktrees had no SQLite column / rowToTask mapping, so
fn_acquire_repo_worktree's updateTask write was dropped on every persist
(applyTaskPatch writes the DB-round-tripped task back to task.json). Every
later getTask returned undefined, so fn_task_done's scope verifier read {}
and blocked with "acquired no sub-repo worktrees", and isWorkspaceTask()
consumers misfired. Persist it mirroring mergeDetails (schema column + v129
migration + db-migrate + defineTaskColumn + TaskRow + rowToTask).
2. In workspace mode every task ran rooted at the shared browse-only root, and
setActiveSession registered that path keyed only by path — so a second
concurrent workspace task was rejected by the foreign-task guard
("active-session path ... is held by ..."). Give each task a task-scoped
synthetic session key (sessionRegistryPath), applied at all register and
unregister sites; the in-memory worktree Set still holds the real root.
Regression tests assert the persistence invariant across getTask/listTasks/
store-reopen and concurrent session registration across all three session
surfaces; both verified to fail without the fix.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>