3962222863cb36c07a2c19ec48854367cdbffef0
229 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c279b8cefc |
FN-8347: add report capture regression coverage
Expand dashboard report tests across screenshot capture and activity-trace egress. - Cover screenshot capture pending, failure, opt-out, and mobile modal behavior - Verify bounded activity traces and recursive privacy scrubbing across report routes - Exercise screenshot artifact references through draft, duplicate, and filing paths Files changed: .../app/components/__tests__/ReportModal.test.tsx | 46 ++++++++++++ .../app/utils/__tests__/activity-trace.test.ts | 32 +++++++++ .../src/__tests__/report-pipeline.test.ts | 83 +++++++++++++++++++++- .../dashboard/src/__tests__/report-routes.test.ts | 35 ++++++++- .../dashboard/src/__tests__/report-scrub.test.ts | 19 ++++- 5 files changed, 208 insertions(+), 7 deletions(-) Fusion-Task-Id: FN-8347 Fusion-Task-Lineage: 5323fdcb-01c3-48aa-beb9-ecd4651e981a Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
a9c7a6bcc0 |
FN-8371: store report screenshot artifacts
Store opted-in report screenshots as validated local artifacts rather than GitHub attachments. - Add multipart report attachment upload with PNG/JPEG validation and provenance metadata. - Carry validated artifact references through report drafts and filing flows without binary egress. - Update report UI, tests, documentation, and release metadata. Files changed: .changeset/report-screenshot-artifacts.md | 7 + docs/dashboard-guide.md | 2 +- packages/core/src/index.gate.ts | 2 +- packages/core/src/index.ts | 2 +- packages/core/src/types.ts | 7 + packages/dashboard/app/api/report.ts | 14 +- packages/dashboard/app/components/ReportModal.css | 3 +- packages/dashboard/app/components/ReportModal.tsx | 41 ++--- .../app/components/__tests__/ReportModal.test.tsx | 58 +++++-- packages/dashboard/app/utils/report-capture.ts | 47 ++---- .../src/__tests__/report-pipeline.test.ts | 94 ------------ .../dashboard/src/__tests__/report-routes.test.ts | 123 +++++++++++---- packages/dashboard/src/report-pipeline.ts | 128 +++------------- .../dashboard/src/routes/register-report-routes.ts | 169 +++++++-------------- 14 files changed, 279 insertions(+), 418 deletions(-) Fusion-Task-Id: FN-8371 Fusion-Task-Lineage: 48d0e94d-602f-43e2-a63f-cb497221ac29 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
bea51f7bdb |
FN-8348: relocate report actions to settings and command center
Relocate guided reporting from the header into durable project and overview surfaces. - Add Report entry points to Project General settings and Command Center Overview. - Preserve guided report modal context through a shared route helper. - Cover relocated controls and update dashboard guidance. Files changed: docs/dashboard-guide.md | 2 +- packages/dashboard/app/components/Header.tsx | 33 ++++------------------ .../dashboard/app/components/SettingsModal.tsx | 2 +- .../app/components/__tests__/Header.test.tsx | 7 +++++ .../components/command-center/CommandCenter.css | 32 +++++++++++++++++++++ .../components/command-center/CommandCenter.tsx | 30 +++++++++++++++++++- .../__tests__/CommandCenter.test.tsx | 11 ++++++++ .../settings/sections/GeneralSection.tsx | 21 ++++++++++++++ .../GeneralSection.aiUndoWorkflow.test.tsx | 20 +++++++++++-- packages/dashboard/app/utils/reportContextRefs.ts | 13 +++++++++ 10 files changed, 139 insertions(+), 32 deletions(-) Fusion-Task-Id: FN-8348 Fusion-Task-Lineage: add1b302-deab-4e17-be2f-832971c1c83d Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
b2a7425c76 |
refactor(cutover 3/3): dashboard + changesets — IR-driven lifecycle cutover (#2335)
Completes the IR-driven lifecycle cutover: **the workflow IR becomes the
single source of truth for task lifecycle.** Node column assignments
move cards at runtime, every lifecycle predicate re-keys on column
traits instead of literal column ids, and the graph exclusively owns
review gates.
Plan (the spec for this work):
[`docs/plans/2026-07-18-001-refactor-ir-driven-lifecycle-cutover-plan.md`](docs/plans/2026-07-18-001-refactor-ir-driven-lifecycle-cutover-plan.md)
## What changed
**IR as runtime authority (R1, R2).** Graph traversal crossing a node
column boundary moves the card through the store's trait-hook `moveTask`
path, attributed `workflowMoveSource: "workflow-graph"` and emitting
`task:column-transition`. This replaces the executor's hardcoded
`moveTask(id, "in-review")` merge boundary and its handoff-invariant
allowlist. Scheduler, hold/release, self-healing, merger and
finalization now key on column traits
(`intake`/`hold`/`wip`/`merge-blocker`/`human-review`/`merge`/`complete`/`archived`/`timing`/`abort-on-exit`/`reset-on-entry`/`stall-detection`),
with rebound targets resolved per KTD-10.
**Single ownership of review gates (R4, R5).** Triage's out-of-graph
Plan Review gate is deleted; the graph is the sole author. `pending`
step results are CAS-claimed leases with owner and staleness floor
(KTD-4), so a crash/restart re-entry can no longer dispatch a second
reviewer and silently discard the losing verdict.
**Graph ownership is unconditional (R9).** The legacy execute fallback
is gone: `maybeExecuteWorkflowGraph` is now `executeWorkflowGraph`
returning `void`, `graphCompletion` is a required parameter, and a store
that cannot resolve a workflow fails closed rather than silently running
nothing. Also deleted, with a tombstone ratchet: `fn_review_step` and
its RETHINK/session-rewind machinery, `workflow-cutover.ts`,
`workflow-authoritative-driver.ts`, `workflow-parity-observer.ts`, and
the `graphCompletionInterceptors` map.
**`reviewLevel` becomes a creation-time preset (R6)** writing
`enabledWorkflowSteps`, with zero runtime reads.
**Upgrade path (R10).** Migration 0026 adds the durable per-node-entry
IR pin (KTD-3) and the one-time adoption stamp (KTD-8);
`planLegacyAdoption` is the single shared decision run by both the
startup sweep and the store-open reconcile, so pre-cutover rows are
adopted instead of freezing. A stale-binary guard refuses to open a
database migrated by a newer binary.
**Operator surfaces (R2, R11).** Four places still closed the column
set: the dashboard coerced every ingested task's column through the
legacy six-id enum (a card in a custom `Merging` column rendered in
**Triage**), `POST /tasks/:id/move` answered 400 for any
workflow-defined column, retry/reset/re-engage/unassign/spec-revise used
hardcoded move targets, and GitHub issue open/closed mapping
literal-compared `done`/`archived`. All now resolve from the task's
workflow by trait, each with a legacy fallback so `builtin:coding` is
byte-identical.
## Evidence
`builtin:coding` keeps its column ids and observable behavior
byte-compatible (R8, KTD-7), pinned by a characterization oracle. A new
**6-column benchmark acceptance suite** drives a user-authored workflow
— `Ideas → Todo → In-progress → In-review → Merging → Done` — asserting
the ordered transition trail, single-mover at the hold→wip seam (KTD-2),
column-role purity (R12), bounded review cycles from workflow config,
and park-in-place on failure (R3). The same fixture is proven
**editor-buildable** through the real save-validation path, plus
negative cases.
Verified locally on this branch, post-rebase:
- `pnpm test:gate` — green (engine-core 294/294, pg-gate 126/126,
ci-workflow 63/63)
- characterization oracle 59/59, tombstones 5/5, 6-column benchmark
11/11
- `tsc --noEmit` clean for `@fusion/core`, `@fusion/engine`,
`@fusion/dashboard` (both `tsconfig.json` and `tsconfig.app.json`)
## Known reds
- **`executor-task-done-invariant` → "moves a cleanly completed task to
in-review via the merge-node boundary"** — red on this branch. A
real-Postgres test whose graph re-entry rebounds the card to
`in-progress` after `execute()` returns. Not in the merge gate, so it
does not gate CI. Honest status: I could **not** verify it green on
pristine `main` — running main's tests in this worktree reuses built
artifacts and produced obviously polluted results, so I am not claiming
"pre-existing". It needs its own look.
- **`html2canvas` / FN-8309 — fixed here by deleting dead code.**
`packages/dashboard/app/utils/capture-screenshot.ts` imported
`html2canvas`, which is not a dependency of `@fusion/dashboard` and is
**not in `pnpm-lock.yaml` at all**, so it had never compiled in CI. The
file had **zero importers**. Main never caught it because PR Checks runs
only on pull requests (main's last PR Checks run was in June) while
main's own pushes run just the non-blocking Full Suite — so the required
**Typecheck** check was failing on *every* PR against main, including
this one. Inherited from `88b0db0f4` (FN-8309). **To restore when the
feature lands its dependency properly:** `git checkout
|
||
|
|
e30f6d851f |
FN-8293: add native structure drag-and-draft mail composition
Mail composers can attach native structures by drag-and-drop and generate report narratives with AI. - Add a shared native-structure drag protocol and attachable previews across Mail source views. - Add a disposable compose-chat panel that drafts narratives around attached embeds. - Cover drag behavior and compose-chat session lifecycle, and document the Mail interaction. Files changed: .changeset/fn-8293-mail-drag-compose-chat.md | 7 ++ docs/dashboard-guide.md | 3 + .../dashboard/app/components/ComposeChatPanel.css | 33 ++++++ .../dashboard/app/components/ComposeChatPanel.tsx | 117 +++++++++++++++++++++ packages/dashboard/app/components/EvalsView.tsx | 3 +- packages/dashboard/app/components/GoalsView.tsx | 6 ++ packages/dashboard/app/components/InsightsView.tsx | 8 +- .../dashboard/app/components/MessageComposer.css | 22 ++++ .../dashboard/app/components/MessageComposer.tsx | 92 ++++++++++++++-- .../dashboard/app/components/MissionManager.tsx | 11 +- .../components/__tests__/ComposeChatPanel.test.tsx | 102 ++++++++++++++++++ .../components/__tests__/MessageComposer.test.tsx | 25 +++++ .../utils/__tests__/nativeStructureDrag.test.ts | 56 ++++++++++ .../dashboard/app/utils/nativeStructureDrag.ts | 54 ++++++++++ 14 files changed, 525 insertions(+), 14 deletions(-) Fusion-Task-Id: FN-8293 Fusion-Task-Lineage: 9864e76c-2a0d-41f6-b7f2-de8dd63710b5 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
927f2baf7d |
FN-8354: add Oh My Pi provider logo
Render the official Oh My Pi mark throughout provider selection and analytics surfaces. - Add a tokenized OMP SVG icon and provider aliases. - Infer OMP-tagged model identifiers without misattributing bare models. - Cover OMP icon rendering and inference with dashboard tests. Files changed: packages/dashboard/app/components/ProviderIcon.tsx | 26 +++++++++++++++++++++- .../app/components/__tests__/ProviderIcon.test.tsx | 23 +++++++++++++++++++ packages/dashboard/app/styles.css | 1 + .../app/utils/__tests__/providerIconKey.test.ts | 8 +++++++ packages/dashboard/app/utils/providerIconKey.ts | 9 ++++++++ 5 files changed, 66 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-8354 Fusion-Task-Lineage: 71d5638c-b41e-4960-9391-c7a441d04f51 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
7e7c3c999b |
FN-8317: add reviewed report screenshots and activity traces
Capture optional report context while preserving scrubbed text-first filing.\n\n- Add browser screenshot capture, review, validation, and compensating upload cleanup.\n- Include bounded activity traces in report drafts and filing flows.\n- Preserve roadmap deduplication and document report privacy behavior.\n\nFiles changed:\n .changeset/fn-8317-report-context.md | 7 + docs/dashboard-guide.md | 4 +- packages/dashboard/app/api/report.ts | 15 +- packages/dashboard/app/components/ReportModal.css | 5 +- packages/dashboard/app/components/ReportModal.tsx | 52 +++---- .../app/components/__tests__/ReportModal.test.tsx | 14 ++ packages/dashboard/app/hooks/useViewState.ts | 7 + .../app/utils/__tests__/report-capture.test.ts | 17 +++ packages/dashboard/app/utils/report-capture.ts | 47 +++++++ packages/dashboard/package.json | 1 - .../src/__tests__/report-pipeline.test.ts | 100 +++++++++++++- .../dashboard/src/__tests__/report-routes.test.ts | 17 +++ .../dashboard/src/__tests__/report-scrub.test.ts | 8 ++ packages/dashboard/src/github.ts | 107 +++++++++++++++ packages/dashboard/src/report-pipeline.ts | 152 ++++++++++++++++----- packages/dashboard/src/report-scrub.ts | 8 ++ .../dashboard/src/routes/register-report-routes.ts | 103 ++++++-------- pnpm-lock.yaml | 129 +++++++++-------- 18 files changed, 590 insertions(+), 203 deletions(-) Fusion-Task-Id: FN-8317 Fusion-Task-Lineage: 9d200cee-cf69-4827-9e1e-f7789adf09e0 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
02ee8a4fd5 |
fix: hide stale task-card oversight icons (#2318)
## Summary Task cards now remove the overseer eye as soon as their workflow's effective oversight becomes `off`, instead of reusing an active value cached before the setting changed. The invalidation covers card remounts as well as mounted cards, and authoritative writes from the dashboard, agents, and configuration rollback reach the board through the existing project-scoped SSE stream. Older in-flight responses cannot restore the eye after a newer `off` value wins, while unrelated workflow-setting saves leave active indicators undisturbed. ## Validation - 99 focused dashboard regression tests passed across selected and aggregate cards, desktop and mobile, SSE delivery, and out-of-order responses - Core and dashboard typechecks passed - `pnpm lint` and `pnpm check:changesets` passed - `pnpm verify:fast` passed production builds and the CLI/server boot smoke <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Planner-overseer eye badges now disappear immediately when workflow oversight is turned off. - Prevented stale or out-of-order updates from displaying incorrect oversight status. - Oversight indicators now remain hidden when the effective setting cannot be confirmed. - Live workflow setting changes now update task cards without requiring a page refresh. - **Documentation** - Clarified eye badge visibility rules, tooltip meaning, and active oversight states in the dashboard guide. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
88b0db0f4d |
FN-8309: add report screenshot and activity capture
Add opt-in local screenshot attachments and scrubbed activity traces to reports. - Capture, preview, confirm, and locally retain report screenshots without GitHub egress. - Include bounded activity traces in draft and filing context with server-side validation. - Add report pipeline coverage, documentation, and release metadata. Files changed: .changeset/fn-8309-report-capture.md | 7 ++ docs/dashboard-guide.md | 2 + packages/dashboard/app/App.tsx | 10 ++ packages/dashboard/app/api/report.ts | 16 ++- packages/dashboard/app/components/ReportModal.css | 3 + packages/dashboard/app/components/ReportModal.tsx | 45 ++++++- .../app/utils/__tests__/activity-trace.test.ts | 19 +++ packages/dashboard/app/utils/activity-trace.ts | 37 ++++++ packages/dashboard/app/utils/capture-screenshot.ts | 22 ++++ packages/dashboard/package.json | 5 +- .../src/__tests__/report-pipeline.test.ts | 13 +++ packages/dashboard/src/report-pipeline.ts | 29 ++++- packages/dashboard/src/routes.ts | 2 +- .../dashboard/src/routes/register-report-routes.ts | 85 +++++++++++++- packages/dashboard/src/routes/types.ts | 4 +- pnpm-lock.yaml | 129 ++++++++++----------- 16 files changed, 341 insertions(+), 87 deletions(-) Fusion-Task-Id: FN-8309 Fusion-Task-Lineage: db9c14a6-1721-4e81-8891-cfd301473cd0 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
d5db5fd58d |
FN-8304: detect foreign issue-form content for translation
Recognize foreign GitHub and GitLab issue-form prose so import translation remains available. - Remove issue-form scaffolding before content-language scoring. - Identify Czech as unsupported foreign Latin content and offer translation. - Cover automatic and manual translation paths with issue-form fixtures. - Document the expanded import translation behavior and add a patch changeset. Files changed: .changeset/fn-8304-issue-form-translation.md | 7 ++ docs/dashboard-guide.md | 2 +- docs/settings-reference.md | 2 +- packages/core/src/detect-content-language.ts | 66 ++++++++++-- .../__tests__/GitHubImportAutoTranslate.test.tsx | 42 +++++++- .../utils/__tests__/detectContentLanguage.test.ts | 120 +++++++++++++++++++++ .../src/__tests__/import-translate-service.test.ts | 56 ++++++++++ 7 files changed, 284 insertions(+), 11 deletions(-) Fusion-Task-Id: FN-8304 Fusion-Task-Lineage: ef6ca70c-aa67-40ff-a23a-077940b5a5f0 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
9debeaa951 |
FN-8300: show planner activity on status-null cards
Keep planning cards visibly active while fresh planner logs precede authoritative task status updates. - Track bounded client-only planner activity from fresh triage log events - Render matching pulsing Planning badges in board and list card views - Cover transient activity, authoritative clearing, and inactive edge cases Files changed: docs/dashboard-guide.md | 2 + packages/core/src/types.ts | 6 +++ packages/dashboard/app/components/ListView.tsx | 26 ++++++++--- packages/dashboard/app/components/TaskCard.tsx | 20 +++++--- .../app/components/__tests__/ListView.test.tsx | 38 +++++++++++++++ .../app/components/__tests__/TaskCard.test.tsx | 19 +++++++- .../dashboard/app/hooks/__tests__/useTasks.test.ts | 54 ++++++++++++++++++++++ packages/dashboard/app/hooks/useTasks.ts | 44 +++++++++++++----- .../app/utils/__tests__/taskActivity.test.ts | 22 ++++++++- packages/dashboard/app/utils/taskActivity.ts | 15 +++++- 10 files changed, 219 insertions(+), 27 deletions(-) Fusion-Task-Id: FN-8300 Fusion-Task-Lineage: e12f1277-5628-45a1-b731-54310027540e Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
68ce5c31da |
fix: harden onboarding/git/desktop batch per multi-agent review findings
- uninstaller: taskkill only the first, digits-only postmaster.pid line (the for /f loop ran taskkill on the port/epoch lines — potential unrelated-process kill) - git-missing dialogs use new ConfirmOptions.alwaysAsk so global skip-confirmations cannot silently pick an unseen choice - Windows quit prompt: embedded-local runtimes only, skipped during OS session end (sync dialog blocked Windows shutdown) - 'leave it running' detaches the embedded lifecycle (disarms its process shutdown hook) so Electron exit cannot kill the postmaster the operator chose to keep (new detachKeepingEmbedded) - wizard: ref-based double-submit guard around the async git preflight - clone route: ENOENT invalidate-and-retry matching runGitCommand - openExternalUrl: drop the async window.open fallback (always popup-blocked); log bridge failures instead - DirectoryPicker: close the panel when listing the created folder fails so Select cannot re-commit the parent - git status probe bounded to two spawns (PATH + first candidate) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
7bf83bb458 |
fix(desktop,dashboard): open OAuth URLs via activation-free IPC on desktop
window.open after awaiting /auth/login can outlive Chromium's transient user activation and get silently popup-blocked in the desktop app — the OpenAI Codex flow (method select + localhost callback server) crossed that threshold while Anthropic's faster flow usually didn't, so Codex login never opened the browser. Add a shell:openExternal IPC bridge (http/https only), expose it in preload, and route every dashboard auth-URL open through an openExternalUrl helper that falls back to window.open on the web. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
9152d8fa61 |
FN-8229: remove background AI tasks pill
Replace the redundant footer AI session control with progress and action visibility in the session notification banner. - Delete the BackgroundTasksIndicator component, styles, footer wiring, and obsolete translations. - Surface non-planning generating and retained error sessions through the notification banner while leaving Planning in its dedicated view. - Update session lifecycle, localization, documentation, and regression coverage. Files changed: .../fn-8229-remove-ai-background-tasks-pill.md | 7 + docs/dashboard-guide.md | 4 +- packages/dashboard/README.md | 1 - packages/dashboard/app/App.tsx | 28 +-- .../app/__tests__/css-hygiene-scan.test.ts | 2 - .../dashboard-component-color-tokenization.test.ts | 1 - packages/dashboard/app/api/legacy.ts | 2 +- .../app/components/BackgroundTasksIndicator.css | 130 ------------- .../app/components/BackgroundTasksIndicator.tsx | 210 --------------------- .../dashboard/app/components/ExecutorStatusBar.css | 3 - .../dashboard/app/components/ExecutorStatusBar.tsx | 30 +-- .../app/components/SessionNotificationBanner.css | 10 + .../app/components/SessionNotificationBanner.tsx | 52 ++++- .../app/components/SubtaskBreakdownModal.tsx | 7 +- .../app/components/__tests__/App.test.tsx | 11 +- .../__tests__/ExecutorStatusBar.test.tsx | 1 - .../__tests__/SessionNotificationBanner.test.tsx | 88 ++++----- .../components/__tests__/utility-mobile.test.tsx | 191 +------------------ .../app/components/dashboard/DashboardBanners.tsx | 8 +- .../dashboard/__tests__/DashboardBanners.test.tsx | 30 ++- .../hooks/__tests__/useBackgroundSessions.test.ts | 21 ++- .../dashboard/app/hooks/useBackgroundSessions.ts | 21 ++- .../app/utils/__tests__/appLifecycle.test.ts | 61 ++---- packages/dashboard/app/utils/appLifecycle.ts | 16 +- packages/dashboard/src/routes.ts | 2 +- packages/i18n/locales/en/app.json | 33 +--- packages/i18n/locales/es/app.json | 44 ++--- packages/i18n/locales/fr/app.json | 44 ++--- packages/i18n/locales/ko/app.json | 44 ++--- packages/i18n/locales/zh-CN/app.json | 44 ++--- packages/i18n/locales/zh-TW/app.json | 44 ++--- packages/i18n/src/resources.d.ts | 48 ++--- 32 files changed, 316 insertions(+), 922 deletions(-) Fusion-Task-Id: FN-8229 Fusion-Task-Lineage: a232fb04-08ff-4f0a-a440-e94545243e61 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
7f175b036b |
FN-8195: label replan task status
Display the needs-replan task state with a clear localized operator-facing label. - Map needs-replan status badges to Replan centrally. - Add English i18n resources and generated resource typings. - Cover the status-label mapping and add a patch changeset. Files changed: .changeset/fn-8195-replan-badge.md | 7 +++++++ .../dashboard/app/utils/__tests__/taskStatusBadgeLabel.test.ts | 4 ++++ packages/dashboard/app/utils/taskStatusBadgeLabel.ts | 8 ++++++++ packages/i18n/locales/en/app.json | 2 ++ packages/i18n/src/resources.d.ts | 2 ++ 5 files changed, 23 insertions(+) Fusion-Task-Id: FN-8195 Fusion-Task-Lineage: 7ad115b8-6405-426e-9201-bfa1258fff5e Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
79b05c62ea |
FN-8190: apply heartbeat multipliers to agent health
Align dashboard health labels with project-resolved heartbeat cadence. - Load the project heartbeat multiplier in agent list and detail views. - Apply the effective cadence once when determining stale agents. - Cover long-cadence and multiplier boundary health states. Files changed: .../dashboard/app/components/AgentDetailView.tsx | 19 ++++++++++++-- .../dashboard/app/components/AgentListModal.tsx | 19 ++++++++++++-- packages/dashboard/app/components/AgentsView.tsx | 2 +- .../__tests__/AgentDetailView.test-helpers.ts | 3 +++ .../components/__tests__/AgentListModal.test.tsx | 27 ++++++++++++++++++++ .../app/utils/__tests__/agentHealth.test.tsx | 29 ++++++++++++++++++++++ packages/dashboard/app/utils/agentHealth.tsx | 25 ++++++++++++++++--- 7 files changed, 115 insertions(+), 9 deletions(-) Fusion-Task-Id: FN-8190 Fusion-Task-Lineage: 1efcdc19-503a-4893-b277-f65e900a399b Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
30aaab209c |
FN-8170: suppress stale planning status badges
Hide stale planning badges from Todo and In Progress task surfaces. - Centralize the planning badge suppression predicate. - Apply it to board cards and desktop/mobile list views. - Cover suppressed and preserved status badge behavior. Files changed: packages/dashboard/app/components/ListView.tsx | 11 +++-- packages/dashboard/app/components/TaskCard.tsx | 16 +++++-- .../app/components/__tests__/ListView.test.tsx | 53 ++++++++++++++++++++++ .../app/components/__tests__/TaskCard.test.tsx | 40 ++++++++++++++++ .../utils/__tests__/taskStatusBadgeLabel.test.ts | 21 ++++++++- .../dashboard/app/utils/taskStatusBadgeLabel.ts | 14 ++++++ 6 files changed, 147 insertions(+), 8 deletions(-) Fusion-Task-Id: FN-8170 Fusion-Task-Lineage: e2a00154-8537-4eb3-aadb-45b42f13f15b Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
50179ed5eb |
FN-8167: suppress failed UI during automatic recovery
Prevent transient automatic-retry tasks from appearing as terminal failures. - Centralize pending-recovery and manual-retry presentation rules. - Suppress failed styling, failure alerts, and Retry actions across list, card, and detail views. - Cover recovery timing and desktop/mobile task surfaces with regression tests. Files changed: .changeset/fn-8167-transient-retry-affordance.md | 7 ++ packages/dashboard/app/components/ListView.tsx | 16 ++--- packages/dashboard/app/components/TaskCard.tsx | 13 ++-- .../dashboard/app/components/TaskDetailModal.tsx | 13 ++-- .../app/components/__tests__/ListView.test.tsx | 38 +++++++++++ .../app/components/__tests__/TaskCard.test.tsx | 22 +++++++ .../__tests__/TaskDetailModal.rendering.test.tsx | 26 ++++++++ .../app/utils/__tests__/taskRecovery.test.ts | 77 ++++++++++++++++++++++ packages/dashboard/app/utils/taskRecovery.ts | 32 +++++++++ 9 files changed, 215 insertions(+), 29 deletions(-) Fusion-Task-Id: FN-8167 Fusion-Task-Lineage: 60d599e2-2e0e-46e7-ad16-cc6a836b5ac7 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
478f226a54 |
test: green full-suite CI after main drift (#2229)
## Summary Restores green **Full Suite (non-blocking)** runs on `main`. Recent main merges left i18n key parity, schema baseline bookkeeping (0011→0012), heartbeat tool inventory (FN-8058 `fn_task_logs_read`), and merger whitespace-classification mocks (execFile `git diff -p -w :2: :3:`) out of date, so all four test shards failed. ## Root causes observed on main - **Shard 4 / `@fusion/i18n`**: missing `skipConfirmationDialogs*` + `reviewBudgetExhausted` in non-en locales; orphan `awaitingApprovalPlanReviewReplanCap` - **Shard 3 / `@fusion/core`**: `SCHEMA_BASELINE_VERSION` advanced to `0012` while tests still equated it with `OWNER_PROJECT_ID_SPLIT_VERSION` (`0011`) and omitted `0012` from applied-migration lists - **Shards 1–2 / `@fusion/engine`**: tool count/snapshot drift for `fn_task_logs_read`; merger tests still mocked `git diff-tree` for trivial classification after the execFile `:2:`/`:3:` cutover; mock provider `updateTask` arity drift ## Changes - Locale catalogs: add missing keys, drop orphan key - Schema applier tests: immutable 0011 identity + baseline 0012 lists - Heartbeat + gating snapshots: include `fn_task_logs_read` - Merger unit mocks: recognize `git diff -p -w :2:path :3:path` - Mock provider: accept optional third `updateTask` arg ## Test plan - [x] `pnpm --filter @fusion/i18n exec vitest run` — 23/23 - [x] `pnpm --filter @fusion/core exec vitest run src/__tests__/postgres/schema-applier.test.ts` (immutable + automation upgrade) — pass - [x] `pnpm --filter @fusion/core exec vitest run` project-identity + satellite-fusiondir — pass - [x] Engine suites from failed CI shards (file-scoped, hermes/openclaw/paperclip/grok, reliability post-finalize/mission, heartbeat, gating, merger recovery/prompt, mock-provider, etc.) — pass - [ ] Full Suite workflow green on merge to main <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Improved project data isolation across backend operations. - Added safer optional toast handling when UI components render outside the full application shell. - Added support for reading task logs during agent heartbeat sessions. - **Bug Fixes** - Prevented runtime probes from hanging and avoided scanning large binary files. - Improved path handling for workspaces with missing descendants. - Corrected task retry state resets and GitHub import/issue-close behavior. - **Style** - Improved chat, terminal, and settings spacing. - Added clearer accessibility labeling for the auto-merge control. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
4df5c62854 |
FN-8133: add local codebase context metrics
Expose local codebase token estimates and apparent disk size in the project dashboard. - Add a bounded, cached, symlink-safe codebase metrics service and project API. - Display token and disk indicators across Command Center overview states. - Add formatting, route, UI, and metric calibration coverage with a minor changeset. Files changed: .changeset/fn-8133-codebase-metrics.md | 7 + docs/dashboard-guide.md | 2 +- .../dashboard/app/__tests__/api-projects.test.ts | 12 ++ packages/dashboard/app/api/legacy.ts | 14 ++ .../components/command-center/CommandCenter.css | 5 + .../components/command-center/CommandCenter.tsx | 65 +++++++-- .../CommandCenter.mobile-chart-layout.test.ts | 4 + .../__tests__/CommandCenter.test.tsx | 10 ++ .../__tests__/SystemStatsArea.test.tsx | 8 + .../command-center/areas/SystemStatsArea.tsx | 8 +- .../app/utils/__tests__/formatBytes.test.ts | 18 +++ packages/dashboard/app/utils/formatBytes.ts | 11 ++ .../src/lib/__tests__/codebase-metrics.test.ts | 62 ++++++++ .../lib/__tests__/fixtures/token-corpus/README.md | 17 +++ .../fixtures/token-corpus/calibration/component.ts | 1 + .../fixtures/token-corpus/calibration/config.json | 1 + .../lib/__tests__/fixtures/token-corpus/example.ts | 1 + .../lib/__tests__/fixtures/token-corpus/notes.md | 3 + .../fixtures/token-corpus/reference-counts.json | 9 ++ .../__tests__/fixtures/token-corpus/settings.json | 1 + .../lib/__tests__/fixtures/token-corpus/view.tsx | 1 + packages/dashboard/src/lib/codebase-metrics.ts | 161 +++++++++++++++++++++ .../__tests__/codebase-metrics-route.test.ts | 34 +++++ .../src/routes/register-project-routes.ts | 19 +++ 24 files changed, 456 insertions(+), 18 deletions(-) Fusion-Task-Id: FN-8133 Fusion-Task-Lineage: d591636b-d4b8-469e-8788-c4516eeb8405 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
566158232b |
FN-8069: toggle dashboard keyboard shortcuts
Dashboard keyboard shortcuts now toggle their associated dashboard interfaces. - Dispatch toggle callbacks for every configurable dashboard shortcut. - Restore retained prior views and preserve repeated Settings/Command Center history entries. - Add regression coverage, documentation, and a dashboard feature changeset. Files changed: .changeset/fn-8069-shortcut-toggle.md | 7 + docs/dashboard-guide.md | 3 + packages/dashboard/app/App.tsx | 48 ++++-- .../app/__tests__/App.keyboard-shortcuts.test.tsx | 172 +++++++++++++++++---- .../useDashboardKeyboardShortcuts.test.tsx | 82 +++++----- .../app/hooks/useDashboardKeyboardShortcuts.ts | 40 ++--- .../app/utils/dashboardShortcutToggles.ts | 41 +++++ 7 files changed, 290 insertions(+), 103 deletions(-) Fusion-Task-Id: FN-8069 Fusion-Task-Lineage: c2e6d67a-d215-46dd-9803-78ffb49fbbda Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
99b79e456b |
FN-8066: show reverted badges for completed tasks
Persist git-revert provenance and display it on completed task cards. - Stamp source tasks after clean or already-reverted git outcomes. - Render localized Reverted badges in completed and archived task views. - Cover metadata, route, and card behavior with regression tests. Files changed: .changeset/fn-8066-reverted-badge.md | 7 +++ docs/dashboard-guide.md | 2 + packages/dashboard/app/components/TaskCard.css | 14 ++++- packages/dashboard/app/components/TaskCard.tsx | 20 ++++++- .../app/components/__tests__/TaskCard.test.tsx | 67 ++++++++++++++++++++++ .../app/utils/__tests__/taskRevert.test.ts | 17 ++++++ packages/dashboard/app/utils/taskRevert.ts | 11 ++++ .../src/__tests__/task-revert-route.test.ts | 35 +++++++++++ .../src/routes/register-task-workflow-routes.ts | 30 ++++++++++ packages/i18n/locales/en/app.json | 2 + packages/i18n/locales/es/app.json | 2 + packages/i18n/locales/fr/app.json | 2 + packages/i18n/locales/ko/app.json | 2 + packages/i18n/locales/zh-CN/app.json | 2 + packages/i18n/locales/zh-TW/app.json | 2 + packages/i18n/src/resources.d.ts | 2 + 16 files changed, 213 insertions(+), 4 deletions(-) Fusion-Task-Id: FN-8066 Fusion-Task-Lineage: 2a071c14-7e5d-4161-ab0c-158f47ad9c22 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
39d76fdabe |
FN-8062: normalize room message ordering
Normalize room chat snapshots to chronological display order. - Reverse newest-first API snapshots before cache hydration and rendering. - Version the room message cache and cover initial, refresh, recovery, SSE, and host layouts. - Add a patch changeset for the chat transcript ordering fix. Files changed: .changeset/fn-8062-room-message-order.md | 7 +++ .../components/__tests__/ChatView.rooms.test.tsx | 26 ++++++++ .../app/hooks/__tests__/useChatRooms.cache.test.ts | 8 +-- .../app/hooks/__tests__/useChatRooms.test.ts | 73 +++++++++++++++++++++- packages/dashboard/app/hooks/useChatRooms.ts | 45 ++++++++----- packages/dashboard/app/utils/swrCache.ts | 3 +- 6 files changed, 140 insertions(+), 22 deletions(-) Fusion-Task-Id: FN-8062 Fusion-Task-Lineage: 99bb313c-fb24-40e2-b33b-4811bde6d6cb Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
8f176e3b89 |
FN-8055: align active-agent indicators with task activity
Keep board and list activity styling synchronized with actual agent work. - Centralize task activity detection across cards, lists, routing, and model-resolution surfaces. - Show running workflow activity while suppressing stale, paused, stuck-killed, and terminal task states. - Cover status-null workflow activity and terminal-state regressions. Files changed: packages/dashboard/app/components/ListView.tsx | 34 ++--------- packages/dashboard/app/components/RoutingTab.tsx | 17 +----- packages/dashboard/app/components/TaskCard.tsx | 28 +++------ .../app/components/__tests__/ListView.test.tsx | 66 +++++++++++--------- .../app/components/__tests__/TaskCard.test.tsx | 44 ++++++++++++++ .../app/components/effective-model-resolution.ts | 18 +----- .../app/utils/__tests__/taskActivity.test.ts | 71 ++++++++++++++++++++++ packages/dashboard/app/utils/taskActivity.ts | 59 ++++++++++++++++++ 8 files changed, 228 insertions(+), 109 deletions(-) Fusion-Task-Id: FN-8055 Fusion-Task-Lineage: 9ce38d60-06c8-4050-83f4-263e2f765c86 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
e46ffebde1 |
FN-7985: surface review budget exhaustion and configure replan cap
Expose exhausted Plan Review replan budgets for operator approval and allow workflows to configure the cap. - Add validated numeric workflow setting support and a Plan Review replan-cap setting. - Route configured cap exhaustion with a distinct approval reason and preserve fallback behavior. - Display the budget-exhaustion state across task cards, lists, and details. - Add tests, localized copy, documentation, and a minor changeset. Files changed: .changeset/fn-7985-review-budget-approval.md | 7 ++++ docs/settings-reference.md | 9 +++-- docs/workflow-steps.md | 2 +- .../builtin-workflow-settings-triage.test.ts | 27 +++++++++++++-- packages/core/src/builtin-workflow-settings.ts | 17 ++++++++++ packages/core/src/index.gate.ts | 1 + packages/core/src/index.ts | 1 + packages/core/src/workflow-ir-types.ts | 4 +++ packages/core/src/workflow-ir.ts | 27 +++++++++++++++ packages/core/src/workflow-settings-resolver.ts | 1 + packages/core/src/workflow-settings.ts | 6 ++++ packages/dashboard/app/components/ListView.css | 19 +++++++++++ packages/dashboard/app/components/ListView.tsx | 22 +++++++++--- packages/dashboard/app/components/TaskCard.css | 18 ++++++++++ packages/dashboard/app/components/TaskCard.tsx | 6 ++-- .../dashboard/app/components/TaskDetailModal.tsx | 4 +-- .../app/components/__tests__/ListView.test.tsx | 30 +++++++++++++++++ .../app/components/__tests__/TaskCard.test.tsx | 17 ++++++++-- .../app/components/workflow-setting-display.ts | 11 ++++++ .../dashboard/app/utils/reviewBudgetApproval.ts | 11 ++++++ .../triage-plan-review-replan-cap.test.ts | 39 +++++++++++++++++++--- packages/engine/src/triage.ts | 21 ++++++++---- packages/i18n/locales/en/app.json | 2 +- packages/i18n/src/resources.d.ts | 19 ++++++++--- 24 files changed, 288 insertions(+), 33 deletions(-) Fusion-Task-Id: FN-7985 Fusion-Task-Lineage: 125f101c-caca-45c2-8b40-996b2a31c019 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
959a7877c8 |
FN-8020: harden agent heartbeat health classification
Validate the four-interval heartbeat grace window and classify invalid persisted heartbeats safely. - Cover reported field heartbeat ages in dashboard and engine health checks. - Mark unparseable heartbeat timestamps as unresponsive and clamp future timestamps to fresh. - Align dashboard health documentation with the existing four-interval grace window. Files changed: .../app/utils/__tests__/agentHealth.test.tsx | 48 +++++++++++++++++++++- packages/dashboard/app/utils/agentHealth.tsx | 26 ++++++++++-- .../src/__tests__/heartbeat-executor.test.ts | 31 ++++++++++++++ 3 files changed, 100 insertions(+), 5 deletions(-) Fusion-Task-Id: FN-8020 Fusion-Task-Lineage: 2bc0df78-d68c-489b-8bfb-9b09da10cdfa Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
0863c0fb58 |
feat(dashboard): auto-translate foreign-language GitHub issues on import (#2141)
## Why The Import Tasks panel routinely lists issues in languages the operator cannot read. Translation already shipped in #2128, but deliberately **opt-in and preview-only** — its header comment read *"Translation is opt-in (never automatic) so import provenance stays faithful until the operator asks."* This reverses that decision **behind a default-off setting**, so operators who never opt in keep byte-faithful import provenance. The superseded comment is kept and annotated rather than deleted, so the reason the rule changed stays in the code. ### The structural gap #2128 left `POST /github/issues/import` accepts only `{owner, repo, issueNumber}` and **re-fetches the issue server-side**. A translation held in React state could never reach the created task, and the in-memory cache died with the modal. That is why the cache here is server-side rather than in the hook — it's what makes "imported issues carry the translated version" actually true. ## What operators get Auto-translate is **off by default**. When enabled: - The **50 most recent OPEN** foreign-language issues translate on panel load — **list titles**, not just the preview, so the list reads in your language before you click anything. - Translations show **by default**, with a toggle back to the original (hover a translated list title to see the original). - Translations **persist until the issue closes**, so re-opening the panel neither waits nor re-bills. - **Both single and batch import** carry the translation, so the created task reads like the preview you approved. - A **target language** setting (unset = follow the dashboard language) and a dedicated **model lane**, so you can pin a cheap/fast model without dragging the summarization lane onto it. ## Notable decisions | Decision | Why | |---|---| | Detect **before** the model | An issue already in the target language is never sent. Without this, an English repo with the setting on would bill every issue to return its input unchanged. | | Detection moved to `@fusion/core` | The panel and the server must not disagree about which issues are foreign; two copies of a heuristic drift. | | Own rate-limit budget | Translation shared a 10/hour budget with refine/goal-draft. Fanning out per-issue would fail partway **and** starve refine for the hour. | | Cache keyed on a **source hash** | An edited issue misses the cache and re-translates instead of serving stale prose. | | Import is **cache-read only** | A miss imports the original. Import must never block on, or fail because of, translation. | | `project_id` leads the cache PK + full RLS contract | All projects share one flat `project` schema. `verification_cache`'s PK predates that discipline; this table does not copy that mistake. | ## Verification - ✅ `pnpm lint`, `@fusion/core` + `@fusion/dashboard` typecheck - ✅ `pnpm verify:fast` — build + scoped typecheck + real boot smoke (`/api/health`) - ✅ `pnpm test:gate` — 479 tests - ✅ 19 new tests covering the billing invariants (off/closed/same-language ⇒ **no model call**), cache hit/miss-on-edit, the 50 cap, and per-item fail-soft - ✅ `schema-applier` real-Postgres suite (46 tests) exercises migration `0010` and its isolation invariant **Pre-existing failures NOT touched** (confirmed red on `HEAD` before this branch): `AppearanceSection`'s task-popup test, and two PG-cutover keys (`sqliteMigrationNotice`, `postgresMigrationInboxMessageSentAt`) missing description mappings. I left the latter rather than guess an allowlist entry that could mask a real coverage gap. ## Reviewer notes - Short Latin-script prose (a one-line Spanish title) rates only *medium* confidence and won't auto-translate — the existing heuristic is deliberately conservative so English issues are never billed. CJK detects regardless of length. The threshold is the knob if you'd rather bias toward translating. - The RLS/isolation contract in migration `0010` is the part most worth a careful look. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
e172b13612 |
fix(dashboard): never show raw landing/reviewing on task status badges
Share one badge label mapper for board and list so AI-merge pipeline statuses always display as Merging… instead of engine strings. |
||
|
|
49114a27ad |
fix(dashboard): show Merging badge during AI-merge reviewing/landing
AI merge spends most of its time in reviewing and landing, not merging. Treat the full merge pipeline as active so cards, workflow switcher, and stall suppression show Merging… while the pump owns a task. |
||
|
|
bc2d22df6e |
feat(dashboard): offer AI translation in Import Tasks preview (#2128)
## Summary Import Tasks can now offer on-demand AI translation when a selected GitHub or GitLab issue/PR title and body appear to be in a different language than the active dashboard locale. - Detect foreign-language content with a conservative client heuristic (Unicode scripts + Latin stopwords) - Show an opt-in banner: **Translate**, then **Show original / Show translation**, plus **Dismiss** - Call new `POST /api/ai/translate-text` (shared AI-helper rate limit with refine/draft) - Translation is **display-only** in the preview; imported task text stays the original source language ## Why Operators working in a non-English dashboard (or reading non-dashboard-language issues) needed a way to understand import candidates without leaving the preview or changing what gets imported. ## Test plan - [x] Unit tests for language detection (`detectContentLanguage`) - [x] Unit tests for translate request validation, response parsing, and AI agent path - [x] GitHub import modal: French content shows translate controls; English content does not - [x] Dashboard typecheck clean for app + server packages - [ ] Manual: open Import Tasks with dashboard language English, select a French/Korean issue, translate and toggle original - [ ] Manual: confirm Import still creates the task with original title/body - [ ] Manual: dismiss banner for a selection and confirm it stays dismissed for that item ## Notes - Comments are not translated (title + body only) - zh-CN / zh-TW share a CJK family so Chinese content does not prompt translation when the UI is either Chinese locale - Secondary locale catalogs have empty placeholders for the new `git.translate*` keys (runtime falls back to English) |
||
|
|
cdf67c1d98 |
fix(dashboard): stop Planning Mode retry loop, make AI sessions multi-tab (#2101)
## Problem Reported: planning gets stuck in a cycle of retrying and regenerating after a response was already supplied. After the user answers a planning question, `submitResponse` pushed the answer to history but left `session.currentQuestion` pointing at the just-answered question for the whole next generation. The planning SSE route's catch-up path re-emits `currentQuestion` to every fresh connection — and each FN-7946 auto-retry (#2073) opens a fresh connection. So after any generation error: 1. Auto-retry connects a fresh stream → the server re-emits the **already-answered** question. 2. The client treats any question event as progress: it **resets the 3-attempt auto-retry budget** and re-shows the answered question. 3. The retry regenerates; if it errors again the cycle repeats with a fresh budget — an unbounded retry/regenerate loop. Re-answering the stale question also 409-collided with the in-flight generation, feeding the same loop. ## Fix Invariant: `currentQuestion` is only set while the session is genuinely awaiting user input. - `submitResponse` clears it the moment an answer is accepted (normal turns and the deepening checkpoint), while preserving the legacy 200 respond contract on generation failure (the modal ignores the body and lets the SSE error drive recovery). - `retrySession` scrubs stale questions persisted by pre-fix builds before regenerating. - `buildSessionFromRow` only restores a question when the persisted row is `awaiting_input`. - `didSubmitSameAnswer` now compares against the last history entry so the duplicate-submit 409 message survives. - Agent onboarding gets the same fix (its SSE route also re-emits `currentQuestion` on connect); retry now asks the next question instead of re-asking the answered one. Surface enumeration: mission and milestone interviews keep questions the same way but their SSE routes never re-emit on connect, and the auto-retry budget machinery is Planning-Mode-only — planning + onboarding were the two affected surfaces. ## Symptom Verification - **Original symptom:** after answering a question, Planning Mode loops between "Retrying…" and regenerating, re-showing the already-answered question, with the auto-retry budget never exhausting. - **Exact reproduction:** answer a question, have the next generation fail (stuck watchdog/provider error), let the client auto-retry open a fresh SSE connection. - **Assertion it is gone:** new regression suite `planning-answered-question-reemit.test.ts` asserts `currentQuestion` is cleared mid-generation, on generation failure, on retry, and on restore from non-`awaiting_input` rows — so the SSE catch-up path has nothing stale to re-emit. All 5 tests fail against pre-fix code and pass with the fix; an onboarding regression test covers the sibling surface. ## Verification - New regression tests: 5/5 fail on pre-fix code, pass with the fix (plus 1 onboarding test). - Existing suites: 137 planning server tests pass (3 failures in `routes-planning.test.ts` fail identically without this change — pre-existing on the branch); all 69 `PlanningModeModal.planning-flow` client tests pass; `tsc --noEmit` clean; `pnpm check:changesets` passes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Made Planning Mode (and related planning controls) lock-free and multi-tab—no more take-over/active-in-another-tab lock overlays. * **Bug Fixes** * Fixed Planning Mode retry/generation flows where already-answered questions could reappear. * Ensured answered questions clear immediately and aren’t re-emitted during session recovery/SSE catch-up. * Improved session restoration and preserved legacy recovery behavior when generation fails after an answer. * **Tests** * Added regression coverage for the answered-question invariant and updated existing tests to reflect lock-free behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --- ## Follow-up: Planning Mode is now multi-tab via DB state (lock-free) Second commit removes all cross-tab coordination from planning — the persisted session row is the single source of truth and multiple tabs can read and interact with the same session: - **Server:** `/planning/*` routes no longer run `checkSessionLock` or parse `tabId`; a stale `tabId` from an older client is ignored instead of 409'd. Subtask/mission interview routes keep their existing lock behavior. - **Client:** `PlanningModeModal` drops `useSessionLock`, the `useAiSessionSync` BroadcastChannel broadcasts, `sessionTabId`/`lockSessionId` state, and the "Take Control" overlay. Tabs stay current via the per-session SSE stream plus the global `ai_session:updated` events `useBackgroundSessions` already consumes; concurrent writes resolve via the server's generation-in-progress guard (409). - **API client:** planning functions lose their `tabId` params. - **Fix uncovered by the refactor:** the 8s stuck-poll now resolves the session id inside each tick — the removed lock state was what previously re-armed the poll after Start Planning resolved the session id. - Also fixes a pre-existing PG-cutover break in `planning-generation-cancellation.test.ts` (`getSession` is async). Verification: 144 client planning tests and 137 server planning tests pass (the 3 remaining `routes-planning.test.ts` failures are pre-existing on the branch and fail identically without these changes); `tsc --noEmit` and eslint clean on changed files; `pnpm check:changesets` passes. Lock-conflict route tests were rewritten to assert lock-free semantics, plus a new modal test proving a session stays fully interactive with no lock acquisition even when another tab is active. --- ## Follow-up 2: the per-tab session lock is gone entirely Third commit extends the multi-tab model from planning to **every** AI interview surface (planning, subtask breakdown, mission interview, milestone/slice interview) and deletes the lock machinery root and branch. **Server** - Deleted the `/ai-sessions/:id/lock`, `/lock/force`, and `/lock/beacon` routes. - Dropped `checkSessionLock` from every planning/subtask/mission/milestone route (both copies — `routes.ts` and `mission-routes.ts`). A `tabId` from an older client is ignored, never 409'd; all `tabId` body parsing is gone. - Dropped `acquireLock` / `releaseLock` / `forceAcquireLock` / `getLockHolder` / `releaseStaleLocks` from `AiSessionStore`, plus the `@fusion/core` async helpers (`acquireAiSessionLock` et al) and core's re-exports. - Removed `lockedByTab`/`lockedAt` from `AiSessionRow`/`AiSessionSummary`, the upsert SQL, and all four session producers. **Client** - Deleted `useSessionLock` and the now-orphaned `getSessionTabId` util. - Removed the Take Control overlay, the "active in another tab" banners, and `BackgroundTasksIndicator`'s active-elsewhere gate (the confirm prompt and lock badge — sessions now just open). - Reduced `useAiSessionSync` to what its own comments already called it — a low-latency *status* supplement to SSE: no `activeTabMap`, `broadcastLock/Unlock/Heartbeat`, `owningTabId`, `tab:*` messages, or stale-heartbeat sweep. - Dropped `tabId` from every session API client function; removed the lock CSS. **Deliberately kept: the two DB columns.** `ai_sessions.locked_by_tab` / `locked_at` remain as dead, always-NULL columns with a deprecation note. Dropping them is an irreversible migration, and released binaries still name those columns explicitly in their upsert — an older install pointed at the same database would fail every session write. They can be dropped once no such binary can reach it. No code reads or writes them. **Verification**: 397 client tests and 137 server planning tests pass (the same 3 `routes-planning.test.ts` failures are pre-existing — verified identical on a clean stash); `tsc --noEmit` clean for `@fusion/core` and `@fusion/dashboard`; eslint clean on all changed files; the 30 PG `schema-applier` tests pass (they exercise the retained columns); `pnpm check:changesets` passes. The lock-conflict route tests and both modal lock tests were rewritten to assert the inverse: routes and modals stay fully interactive while another tab "holds" a lock, and the lock API is never called. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
b77e12351e |
FN-7872: add custom terminal shortcut buttons to the Preferences panel
Lets users define, edit, and remove custom terminal shortcut buttons (label + injected key sequence) from the terminal Preferences panel, persisted client-side. - Add a customShortcuts list to terminalPreferences (kb-terminal-preferences localStorage) with add/edit/remove management - Add decodeTerminalShortcutSequence to decode \n, \t, \r, \e/\x1b, and \\ escapes for injected sequences - Render custom shortcut buttons in TerminalModal's shortcut panel, injecting via the focus-preserving sendLiteralShortcut path - Add management UI (add/edit/remove) for custom shortcuts in the terminal Preferences panel, styled in TerminalModal.css - Extend TerminalModal and terminalPreferences test coverage for the new custom shortcut behavior - Document custom terminal shortcuts in docs/dashboard-guide.md - Add a minor changeset for @runfusion/fusion Files changed: .changeset/fn-7872-terminal-custom-shortcuts.md | 7 + docs/dashboard-guide.md | 7 +- .../dashboard/app/components/TerminalModal.css | 106 +++++++++++ .../dashboard/app/components/TerminalModal.tsx | 202 ++++++++++++++++++++- .../components/__tests__/TerminalModal.test.tsx | 183 +++++++++++++++++++ .../utils/__tests__/terminalPreferences.test.ts | 68 +++++++ .../dashboard/app/utils/terminalPreferences.ts | 140 +++++++++++++- 7 files changed, 708 insertions(+), 5 deletions(-) Fusion-Task-Id: FN-7872 Fusion-Task-Lineage: 9b2df0da-0eb7-4cec-a42b-767e23ff4c2c Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
bb86844f8d |
FN-7869: add hide done toggle to Todo list view
Adds a per-project Hide done / Show done toggle to the Todo list items header so operators can declutter long selected lists while completion counts still reflect all items. - Add hideDone state persisted per project via localStorage (kb-dashboard-todo-hide-done key registered in projectStorage) - Filter rendered todo items to hide completed ones when the toggle is active, while keeping list stats/progress counts based on all items - Adjust up/down item reordering to operate correctly against the visible (filtered) list while still reordering the underlying full item list - Add an empty-state message when all items are hidden by the toggle, with Eye/EyeOff icon + i18n strings (todo.hideDone, todo.showDone, todo.allDoneHidden) - Add regression tests covering the toggle, persistence, filtering, and empty state - Document the Hide done / Show done control in the dashboard guide Files changed: docs/dashboard-guide.md | 3 + packages/dashboard/app/components/TodoView.css | 45 ++++++++++ packages/dashboard/app/components/TodoView.tsx | 66 +++++++++++++-- .../app/components/__tests__/TodoView.test.tsx | 99 ++++++++++++++++++++++ packages/dashboard/app/utils/projectStorage.ts | 1 + packages/i18n/locales/en/app.json | 3 + 6 files changed, 210 insertions(+), 7 deletions(-) Fusion-Task-Id: FN-7869 Fusion-Task-Lineage: 9c334aba-e802-43b8-963c-0f2daf727583 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
c7c6c5a8c4 |
FN-7842: color-code priority icons by urgency across quick add, task form, and task cards
Adds a shared urgency color source to priorityIndicator and wires it into every priority-glyph surface so low/normal/high/urgent read consistently by color, not just icon shape. - priorityIndicator.tsx: add colorVar (low=info/blue, normal=muted, high=warning/amber, urgent=error/red) and new getPriorityColorVar() export as the single source of truth - QuickEntryBox: tint the icon-only priority trigger and each option row in the priority picker with the matching urgency color - TaskForm: tint the New Task inline priority glyph using the same color source - TaskCard: render a colored priority glyph alongside the existing text label in the card-priority-badge (kept the non-normal visibility gate and badge geometry via a small CSS gap addition) - Updated/added tests for QuickEntryBox, TaskCard (badge, badge-height, badge-wrap), and priorityIndicator to assert the new colors; added a patch changeset and a dashboard-guide.md doc update Files changed: .changeset/fn-7842-priority-color-coding.md | 7 +++++ docs/dashboard-guide.md | 7 +++-- .../dashboard/app/components/QuickEntryBox.tsx | 7 +++-- packages/dashboard/app/components/TaskCard.css | 2 ++ packages/dashboard/app/components/TaskCard.tsx | 6 +++- packages/dashboard/app/components/TaskForm.tsx | 7 +++-- .../components/__tests__/QuickEntryBox.test.tsx | 17 +++++++++-- .../__tests__/TaskCard.badge-height.test.tsx | 5 ++++ .../__tests__/TaskCard.badge-wrap.test.tsx | 5 ++++ .../app/components/__tests__/TaskCard.test.tsx | 33 +++++++++++++++++++++- .../app/utils/__tests__/priorityIndicator.test.tsx | 13 +++++---- packages/dashboard/app/utils/priorityIndicator.tsx | 16 ++++++++--- 12 files changed, 103 insertions(+), 22 deletions(-) Fusion-Task-Id: FN-7842 Fusion-Task-Lineage: 0b2d0d15-6e61-45fc-9378-bc09002bef55 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
fc07bdfc7e |
FN-7831: add Reviewing badge for active Plan Review on task cards and list rows
Adds a distinct "Reviewing" status badge that surfaces on TaskCard and ListView rows while a task's optional plan-review workflow step is actively running, reusing the unified progress predicate so board and list surfaces stay in sync. - Add isPlanReviewRunning(task) helper in taskProgress.ts, derived from getUnifiedTaskProgress's workflow-plan-review item status - Render a pulsing "Reviewing" badge on TaskCard header (additive to existing status badges, with title/data-testid) while plan-review is running - Render the matching "Reviewing" badge on both grouped and ungrouped ListView row layouts for parity with TaskCard - Add supporting CSS for .card-status-badge--reviewing and .list-status-badge--reviewing - Add unit tests for isPlanReviewRunning and component tests for the new badge across TaskCard and ListView - Add minor changeset documenting the new operator-facing badge Files changed: .changeset/tidy-reviewing-badges.md | 7 ++ packages/dashboard/app/components/ListView.css | 10 +++ packages/dashboard/app/components/ListView.tsx | 22 +++++- packages/dashboard/app/components/TaskCard.css | 10 +++ packages/dashboard/app/components/TaskCard.tsx | 25 ++++++- .../app/components/__tests__/ListView.test.tsx | 78 ++++++++++++++++++++++ .../app/components/__tests__/TaskCard.test.tsx | 31 +++++++++ .../app/utils/__tests__/taskProgress.test.ts | 16 ++++- packages/dashboard/app/utils/taskProgress.ts | 10 +++ 9 files changed, 205 insertions(+), 4 deletions(-) Fusion-Task-Id: FN-7831 Fusion-Task-Lineage: d36f8c63-9b84-400a-8b10-3b9f3b04212b Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
937650472a |
FN-7820: add Cost tab to task detail and optional card cost badge
Adds a shared cost-derivation utility and surfaces token/cost info in a new Cost tab on the task detail modal, plus an opt-in per-card cost badge on the board. - Extract token-cost calculation into a shared taskTokenCost helper (read-time costFor derivation) reused by the Summary tab, new Cost tab, and card badge - Add TaskDetailModal Cost tab (TaskCostTab.tsx/.css) showing cost breakdown for a task - Simplify TaskSummaryTab by delegating cost math to the shared helper - Add default-off project setting showCostBadgeOnCards (settings-schema.ts, types.ts) with a SettingsModal/AppearanceSection toggle - Add CostBadgeContext to thread the setting into TaskCard without prop drilling - Show an optional cost badge on TaskCard when the setting is enabled - Update i18n strings across en/es/fr/ko/zh-CN/zh-TW locales - Update docs (dashboard-guide.md, settings-reference.md) and add changeset fn-7820-cost-tab-and-card-badge.md Files changed: .changeset/fn-7820-cost-tab-and-card-badge.md | 7 ++ docs/dashboard-guide.md | 4 + docs/settings-reference.md | 1 + .../core/src/__tests__/settings-defaults.test.ts | 13 ++ packages/core/src/settings-schema.ts | 5 + packages/core/src/types.ts | 5 + packages/dashboard/app/App.tsx | 5 + .../dashboard/app/components/SettingsModal.tsx | 6 + packages/dashboard/app/components/TaskCard.css | 7 +- packages/dashboard/app/components/TaskCard.tsx | 27 +++- packages/dashboard/app/components/TaskCostTab.css | 51 ++++++++ packages/dashboard/app/components/TaskCostTab.tsx | 91 ++++++++++++++ .../dashboard/app/components/TaskDetailModal.tsx | 14 ++- .../dashboard/app/components/TaskSummaryTab.tsx | 123 +----------------- .../app/components/__tests__/TaskCard.test.tsx | 81 +++++++++++- .../app/components/__tests__/TaskCostTab.test.tsx | 55 ++++++++ .../TaskDetailModal.attachments-and-tabs.test.tsx | 11 +- .../settings/sections/AppearanceSection.tsx | 8 ++ .../sections/__tests__/AppearanceSection.test.tsx | 20 +++ .../settings-default-descriptions.test.tsx | 1 + .../dashboard/app/context/CostBadgeContext.tsx | 19 +++ packages/dashboard/app/hooks/useAppSettings.ts | 15 +++ .../app/utils/__tests__/taskTokenCost.test.ts | 62 +++++++++ packages/dashboard/app/utils/taskTokenCost.ts | 139 +++++++++++++++++++++ packages/i18n/locales/en/app.json | 29 ++++- packages/i18n/locales/es/app.json | 30 ++++- packages/i18n/locales/fr/app.json | 27 +++- packages/i18n/locales/ko/app.json | 30 ++++- packages/i18n/locales/zh-CN/app.json | 30 ++++- packages/i18n/locales/zh-TW/app.json | 30 ++++- 30 files changed, 789 insertions(+), 157 deletions(-) Fusion-Task-Id: FN-7820 Fusion-Task-Lineage: d33c5678-a68c-4b29-9db1-8ff0369dfd72 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
3da9da28f3 |
FN-7818: replace placeholder Cursor icon with official brand mark
Swap the hand-drawn Cursor CLI placeholder SVG for Cursor's official cube/arrow brand mark and ensure model-id-shaped provider strings resolve to it. - Replace CursorCliIcon's placeholder rounded-square+badge SVG with Cursor's official cube/arrow brand mark path data - Add cursor -> cursor-cli mapping in inferProviderIconKey so cursor, cursor-agent, and cursor/<model> strings resolve to the branded icon instead of falling through to the generic CPU icon - Update ProviderIcon and providerIconKey tests to cover the new brand mark paths and provider-string inference - Add a patch changeset documenting the fix Files changed: .changeset/fn-7818-cursor-logo.md | 7 +++++ packages/dashboard/app/components/ProviderIcon.tsx | 33 +++++++++++----------- .../app/components/__tests__/ProviderIcon.test.tsx | 12 ++++++-- .../app/utils/__tests__/providerIconKey.test.ts | 4 +++ packages/dashboard/app/utils/providerIconKey.ts | 8 ++++++ 5 files changed, 44 insertions(+), 20 deletions(-) Fusion-Task-Id: FN-7818 Fusion-Task-Lineage: 73e85e18-e98a-4dc3-b89d-f831525620de Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
60b8b4e4c5 |
FN-7805: redesign quick-add priority indicators as icon-only controls
Redesigns the Quick Add composer's priority selector to icon-only glyph buttons and relocates GitHub tracking beside attach, backed by a new shared priorityIndicator helper. - Add packages/dashboard/app/utils/priorityIndicator.tsx as the single source of ArrowUp/ArrowDown/Flag/TriangleAlert priority glyphs, shared by QuickEntryBox and TaskForm - Rework QuickEntryBox.tsx to render icon-only priority/Fast controls and move GitHub tracking + Priority into the .quick-entry-primary-group, with matching QuickEntryBox.css layout updates - Update TaskForm.tsx to reuse the new priorityIndicator helper instead of duplicating icon/label logic - Update quick-entry height-parity/trigger-height tests and QuickEntryBox/TaskForm/NewTaskModal tests for the new icon-only layout - Add priorityIndicator.test.tsx covering the shared helper - Update docs/dashboard-guide.md and add changeset fn-7805-quick-add-priority-indicators.md (patch, feature) Files changed: .../fn-7805-quick-add-priority-indicators.md | 7 + docs/dashboard-guide.md | 3 +- .../quick-entry-action-row-height-parity.test.tsx | 13 +- .../quick-entry-workflow-trigger-height.test.tsx | 10 +- .../dashboard/app/components/QuickEntryBox.css | 19 +- .../dashboard/app/components/QuickEntryBox.tsx | 197 +++++++++++---------- packages/dashboard/app/components/TaskForm.tsx | 33 ++-- .../app/components/__tests__/NewTaskModal.test.tsx | 3 + .../components/__tests__/QuickEntryBox.test.tsx | 113 ++++++++---- .../app/components/__tests__/TaskForm.test.tsx | 3 + .../app/utils/__tests__/priorityIndicator.test.tsx | 21 +++ packages/dashboard/app/utils/priorityIndicator.tsx | 30 ++++ 12 files changed, 300 insertions(+), 152 deletions(-) Fusion-Task-Id: FN-7805 Fusion-Task-Lineage: 404fe8d6-0851-44cb-b31d-f47896aaaaba Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
0755fc5747 |
fix(FN-7693): mobile terminal blank — exempt xterm measurement from * { max-width: 100% }
Real root cause of the blank mobile terminal (the FN-7692 remeasure guard did not
fix it and is reverted here). styles.css has a mobile-only reset
`@media (max-width: 768px) { * { max-width: 100% } }` to prevent horizontal
overflow. That universal selector also matches xterm's hidden character-measurement
subtree (`.xterm-helpers` / `.xterm-char-measure-element`). That subtree's containing
block (`.xterm-helpers`) is a 0x0 absolutely-positioned box, so `max-width: 100%`
resolves to `max-width: 0` and hard-caps xterm's character-cell measurement at 0.
FitAddon.fit() then proposes 0 columns/rows and `.xterm-screen` (plus the WebGL
canvas) collapses to 0x0 — the prompt streams in and is written into xterm's row DOM
but paints into a zero-size box, so the terminal is blank. Mobile-only, which is why
desktop always rendered fine.
Reproduced live via mobile emulation: `.xterm-char-measure-element` measured 0 while
an identical monospace span in the same container measured ~295px; `max-width: none`
on the measure element restored ~295px, and reopening the terminal with the exemption
active rendered the prompt with `.xterm-screen` sized 369x760. No amount of
remeasure/refit can fix this — the CSS re-caps the measurement to 0 every time — so
the FN-7692 CharSizeService guard is removed.
- Exempt `.xterm-helpers` / `.xterm-char-measure-element` from the mobile max-width
reset in styles.css (covers both TerminalModal and SessionTerminal)
- Revert the ineffective FN-7692 remeasure guard and its tests
- Update changeset (patch) and the docs/solutions write-up to the real root cause
Note: root cause + fix validated in the automation browser via mobile emulation
(393px, iPhone UA, forced touch), not a physical device.
Fusion-Task-Id: FN-7693
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|
|
b7b1b71cae |
fix(FN-7692): recover blank mobile terminal when xterm screen collapses to 0x0
The mobile terminal rendered blank even though the WebSocket was Connected and the shell prompt had already streamed in. Root cause (reproduced live): on the mobile fullscreen layout xterm's CharSizeService can measure a 0-width character cell, so FitAddon.fit() proposes 0 columns/rows and .xterm-screen (plus the WebGL canvas) collapses to 0x0 — prompt bytes arrive and are written into xterm's row DOM but paint into a zero-size box. Renderer-independent and mobile-layout- specific; not fixed by resize/font-size re-fits because prior guards only validate the container width and font load, never the resulting measured screen/cell width. Add guardAgainstCollapsedTerminalScreen (app/utils/terminalPreferences.ts) and arm it from both terminal surfaces (TerminalModal + SessionTerminal) right after their initial fit. While the container has a width but .xterm-screen does not, it forces a genuine DOM-strategy remeasure (forceTerminalFontRemeasure) + fit, re-driven by a ResizeObserver until the screen has a real width. It waits (does not give up) while the container is not yet measurable, is bounded so it never spins, and is disposed on every re-init/close path. Recurrence of FN-7620/FN-7686. - Add isTerminalScreenCollapsed + guardAgainstCollapsedTerminalScreen with tests - Wire + dispose the guard across all xterm (re)init/close paths in both surfaces - Add changeset (patch) and a docs/solutions write-up Note: reproduced via mobile emulation (393px, iPhone UA, forced touch), not a physical device; the guard is the structural fix — confirm on a real device. Fusion-Task-Id: FN-7692 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
511bcaf56d |
FN-7657: persist GitHub issue import modal state across close/reopen
Retains the GitHub Import Tasks modal's provider/tab/filter/selection state so returning to Import Tasks doesn't reset the user's in-progress import setup. - GitHubImportModal now persists provider, active tab, label filter, remote, and issue selection per project via a new modalPersistence hook, restoring them on remount instead of always defaulting. - Added packages/dashboard/app/hooks/modalPersistence.ts to encapsulate the persisted-state read/write logic backed by projectStorage. - projectStorage.ts gains the `kb-dashboard-github-import-state` storage key. - Falls back to the existing default-remote auto-detect behavior when no persisted state exists. - Added extensive test coverage in GitHubImportModal.test.tsx for the new persistence behavior. - Updated docs/dashboard-guide.md to describe the retained state. - Added a patch changeset for @runfusion/fusion. Files changed: .changeset/fn-7657-github-import-state-retained.md | 7 + docs/dashboard-guide.md | 2 + .../dashboard/app/components/GitHubImportModal.tsx | 204 +++++++++++++-- .../__tests__/GitHubImportModal.test.tsx | 282 +++++++++++++++++++++ packages/dashboard/app/hooks/modalPersistence.ts | 72 ++++++ packages/dashboard/app/utils/projectStorage.ts | 1 + 6 files changed, 547 insertions(+), 21 deletions(-) Fusion-Task-Id: FN-7657 Fusion-Task-Lineage: c8086340-368c-4efd-a12a-4cddeeb0aa26 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
5631c88d54 |
FN-7614: replace planning-mode banner with yellow nav badge for needs-input state
Planning Mode's "waiting for input" indicator moves from a top banner (whose button did not redirect correctly) to a yellow status-dot badge on the Planning nav destination, matching the existing chat unread-badge pattern. - Add a `planningNeedsInput` flag in app lifecycle utils to detect awaiting_input planning sessions - Exclude planning awaiting_input sessions from SessionNotificationBanner so the banner no longer shows for this case - Add a status-dot--pending badge to the Planning entry in LeftSidebarNav and to the Planning item/tab in MobileNavBar - Add/extend tests covering appLifecycle, LeftSidebarNav, MobileNavBar, and SessionNotificationBanner behavior - Add changeset (patch) documenting the fix - Update dashboard-guide.md docs Files changed: .changeset/fn-7614-planning-badge.md | 7 +++ docs/dashboard-guide.md | 4 ++ packages/dashboard/app/App.tsx | 13 +++- .../dashboard/app/components/LeftSidebarNav.tsx | 10 +++ packages/dashboard/app/components/MobileNavBar.css | 20 ++++++ packages/dashboard/app/components/MobileNavBar.tsx | 19 +++++- .../components/__tests__/LeftSidebarNav.test.tsx | 28 +++++++++ .../app/components/__tests__/MobileNavBar.test.tsx | 41 ++++++++++++ .../__tests__/SessionNotificationBanner.test.tsx | 44 +++++++++++++ .../app/utils/__tests__/appLifecycle.test.ts | 73 +++++++++++++++++++++- packages/dashboard/app/utils/appLifecycle.ts | 12 ++++ packages/i18n/locales/en/app.json | 1 + packages/i18n/locales/es/app.json | 1 + packages/i18n/locales/fr/app.json | 1 + packages/i18n/locales/ko/app.json | 1 + packages/i18n/locales/zh-CN/app.json | 1 + packages/i18n/locales/zh-TW/app.json | 1 + packages/i18n/src/resources.d.ts | 1 + 18 files changed, 275 insertions(+), 3 deletions(-) Fusion-Task-Id: FN-7614 Fusion-Task-Lineage: 249e6ee8-149c-4d51-85b6-561dfc30c769 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
e347062e1f |
FN-7603: force xterm DOM-based char measurement to fix mobile terminal spacing
Fixes recurrence #5 of mobile terminal inter-character spacing by unifying xterm's cell-width measurement pipeline with WidthCache's DOM-based glyph measurement, validated against real xterm instead of the jsdom mock. - Add withDomBasedTerminalCharacterMeasurement() in terminalPreferences.ts: transiently hides window.OffscreenCanvas during terminal.open() so CharSizeService's constructor throws and self-selects its own DOM-based fallback strategy, unifying dimensions.css.cell.width with WidthCache.get('W') measurement - Wire withDomBasedTerminalCharacterMeasurement() around terminal.open() calls in SessionTerminal.tsx and TerminalModal.tsx - Add FNXC:Terminal comments documenting the Canvas-vs-DOM measurement divergence root cause, grounded in the installed @xterm/xterm@5.5.0 source - Add docs/solutions/ui-bugs/xterm-options-noop-remeasure-after-font-settle.md recurrence #5 section - Expand TerminalModal.test.tsx coverage for the new measurement-forcing behavior - Add changeset fn-7603-mobile-terminal-spacing.md (patch, fix) Files changed: .changeset/fn-7603-mobile-terminal-spacing.md | 7 + docs/solutions/ui-bugs/xterm-options-noop-remeasure-after-font-settle.md | 101 ++++++ packages/dashboard/app/components/SessionTerminal.tsx | 16 +- packages/dashboard/app/components/TerminalModal.tsx | 16 +- packages/dashboard/app/components/__tests__/TerminalModal.test.tsx | 363 ++++++++++++++++++++- packages/dashboard/app/utils/terminalPreferences.ts | 63 ++++ 6 files changed, 554 insertions(+), 12 deletions(-) Fusion-Task-Id: FN-7603 Fusion-Task-Lineage: 6c7d980f-953e-4fa9-908e-b24125904cbe Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
986e249bc1 |
FN-7555: surface bidirectional undo/source task links in dashboard UI
Adds a client-side helper and UI affordances so AI-undo tasks and their source tasks link to each other in the dashboard, without any new API or backend changes. - Add packages/dashboard/app/utils/taskRevert.ts with getRevertOfId() (resolves the revertOf marker written by createAiUndoTask, with a defensive sourceType==="recovery" fallback to sourceParentTaskId) and findOpenUndoTaskForSource() (reverse lookup for the most recent open undo task pointing at a source task) - TaskCard and TaskDetailModal now render "Undo of <id>" / "Undo task: <id>" provenance links using the shared helper, keeping forward and reverse affordances consistent - Add TaskCard.css styling for the new undo-link affordance - Add/extend tests: TaskCard.test.tsx and TaskDetailModal.rendering.test.tsx cover the new undo/source link rendering - Update docs/task-management.md and packages/i18n/locales/en/app.json for the new UI copy Files changed: docs/task-management.md | 2 +- packages/dashboard/app/components/TaskCard.css | 37 +++++ packages/dashboard/app/components/TaskCard.tsx | 29 +++- .../dashboard/app/components/TaskDetailModal.tsx | 46 ++++++ .../app/components/__tests__/TaskCard.test.tsx | 46 ++++++ .../__tests__/TaskDetailModal.rendering.test.tsx | 160 +++++++++++++++++++++ packages/dashboard/app/utils/taskRevert.ts | 80 +++++++++++ packages/i18n/locales/en/app.json | 7 +- 8 files changed, 403 insertions(+), 4 deletions(-) Fusion-Task-Id: FN-7555 Fusion-Task-Lineage: c3d2dbd2-4d86-40b5-afce-0ca7a6dfc73d Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
9d4a45b0f9 |
FN-7561: fix mobile terminal excess inter-character spacing after font settle
Root-cause fix for xterm text rendering with wide inter-character gaps on mobile after fonts settle post-load. - Added forceTerminalFontRemeasure() in terminalPreferences.ts to work around xterm's OptionsService setter being a no-op when reassigning an already-current fontFamily/fontSize - Applied the remeasure helper at every post-waitForTerminalFontMetrics() settle site in TerminalModal.tsx and SessionTerminal.tsx - Added regression tests covering the remeasure invariant across SessionTerminal, TerminalModal, and terminalPreferences - Documented root cause and fix in docs/solutions/ui-bugs/xterm-options-noop-remeasure-after-font-settle.md - Added changeset for @runfusion/fusion (patch) Files changed: .changeset/fn-7561-mobile-terminal-spacing.md | 7 + docs/solutions/ui-bugs/xterm-options-noop-remeasure-after-font-settle.md | 120 ++++++++++ packages/dashboard/app/components/SessionTerminal.tsx | 11 +- packages/dashboard/app/components/TerminalModal.tsx | 11 +- packages/dashboard/app/components/__tests__/SessionTerminal.test.tsx | 108 ++++++++- packages/dashboard/app/components/__tests__/TerminalModal.test.tsx | 257 ++++++++++++++++++++- packages/dashboard/app/utils/__tests__/terminalPreferences.test.ts | 55 +++++ packages/dashboard/app/utils/terminalPreferences.ts | 38 +++ 8 files changed, 601 insertions(+), 6 deletions(-) Fusion-Task-Id: FN-7561 Fusion-Task-Lineage: ad9da396-abf4-46ea-8c60-f2ed40fa4b01 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
f992e6aefa |
FN-7553: add dedicated keyboard shortcuts settings section
Adds a standalone Keyboard Shortcuts settings section with an easier-to-use capture input and support for more shortcut actions. - Introduce a new KeyboardShortcutsSection with a dedicated ShortcutCaptureInput component for recording key combos - Split keyboard-shortcut settings out of the general settings section into their own settings tab - Extend the shortcut schema/types and useDashboardKeyboardShortcuts hook to support additional actions - Update settings save-split, section-keys, and defaults/parity tests to cover the new section - Update dashboard docs and add a changeset for the new settings section Files changed: .changeset/fn-7553-keyboard-shortcuts-section.md | 7 + docs/dashboard-guide.md | 22 ++- packages/core/src/__tests__/global-settings.test.ts | 9 +- packages/core/src/__tests__/settings-defaults.test.ts | 4 + packages/core/src/__tests__/settings-parity.test.ts | 2 +- packages/core/src/settings-schema.ts | 6 +- packages/core/src/types.ts | 12 ++ packages/dashboard/app/App.tsx | 26 +++- packages/dashboard/app/__tests__/App.keyboard-shortcuts.test.tsx | 47 ++++++- packages/dashboard/app/components/SettingsModal.css | 56 ++++++-- packages/dashboard/app/components/SettingsModal.tsx | 30 +++- packages/dashboard/app/components/__tests__/SettingsModal.general.test.tsx | 63 --------- packages/dashboard/app/components/__tests__/SettingsModal.keyboardShortcuts.test.tsx | 156 +++++++++++++++++++++ packages/dashboard/app/components/settings/__tests__/section-keys.test.ts | 1 + packages/dashboard/app/components/settings/save-split.ts | 6 +- packages/dashboard/app/components/settings/sections/GlobalGeneralSection.tsx | 38 ----- packages/dashboard/app/components/settings/sections/KeyboardShortcutsSection.tsx | 78 +++++++++++ packages/dashboard/app/components/settings/sections/ShortcutCaptureInput.tsx | 118 ++++++++++++++++ packages/dashboard/app/components/settings/sections/__tests__/KeyboardShortcutsSection.test.tsx | 113 +++++++++++++++ packages/dashboard/app/hooks/__tests__/useDashboardKeyboardShortcuts.test.tsx | 73 +++++++++- packages/dashboard/app/hooks/useDashboardKeyboardShortcuts.ts | 38 ++++- packages/dashboard/app/utils/__tests__/keyboardShortcuts.test.ts | 37 ++++- packages/dashboard/app/utils/keyboardShortcuts.ts | 54 ++++++- 23 files changed, 854 insertions(+), 142 deletions(-) Fusion-Task-Id: FN-7553 Fusion-Task-Lineage: 51c1ad69-fbd3-45ce-8d2d-45d9962d7b76 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
3b52a4d2d9 |
FN-7527: fix desktop server switching redirects
Route desktop shell server switches through the live runtime/profile state. - Replace separate local/remote redirect effects with a shared resolver that uses localRuntime/baseUrl and active remote profiles. - Remove the dead localServer shell state field and document the local/remote switch navigation behavior. - Add regression coverage for desktop shell redirect targets and include a patch changeset. Files changed: .changeset/fn-7527-desktop-switch-server-navigation.md | 7 + docs/native-shell.md | 2 +- packages/dashboard/app/App.tsx | 44 ++--- packages/dashboard/app/components/__tests__/App.test.tsx | 1 - packages/dashboard/app/types/native-shell.d.ts | 13 +- packages/dashboard/app/utils/__tests__/appLifecycle.test.ts | 180 +++++++++++++++++++++ packages/dashboard/app/utils/appLifecycle.ts | 70 ++++++++ 7 files changed, 280 insertions(+), 37 deletions(-) Fusion-Task-Id: FN-7527 Fusion-Task-Lineage: a0fe5cbc-120b-4a56-b791-48306223a636 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
9f24b507fc |
FN-7507: prioritize topmost dashboard shortcut dismissal
Refine dashboard keyboard shortcut behavior and coverage for configurable popup handling. - Factor App Escape dismissal into a pure helper that closes one topmost surface at a time. - Prioritize popped-out tasks ahead of Quick Chat, Terminal, and fixed dashboard modals. - Add regression coverage for configurable shortcut bindings, editable focus guards, default-prevented events, and Escape ordering. - Update dashboard shortcut documentation and release-note wording. Files changed: .changeset/fn-7494-keyboard-shortcuts.md | 4 +- docs/dashboard-guide.md | 2 +- packages/dashboard/app/App.tsx | 110 +++++++++----- .../app/__tests__/App.keyboard-shortcuts.test.tsx | 158 +++++++++++++++++++++ .../app/utils/__tests__/keyboardShortcuts.test.ts | 1 + 5 files changed, 236 insertions(+), 39 deletions(-) Fusion-Task-Id: FN-7507 Fusion-Task-Lineage: 804986ef-ec6c-4404-a168-6d154f75b118 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
2f23d2260d |
FN-7494: add configurable dashboard shortcuts
Add configurable dashboard keyboard shortcuts for opening Quick Chat and Terminal. - Add global settings defaults, schemas, persistence, and Settings UI controls for dashboard shortcuts. - Register safe document-level shortcut handling with editable-target guards and Escape popup dismissal. - Normalize shortcut strings, detect disabled/conflicting bindings, and document operator behavior. - Cover shortcut parsing, dashboard listener behavior, and settings persistence with tests. Files changed: .changeset/fn-7494-keyboard-shortcuts.md | 7 + docs/dashboard-guide.md | 14 ++ .../core/src/__tests__/global-settings.test.ts | 20 +++ .../core/src/__tests__/settings-defaults.test.ts | 10 ++ .../core/src/__tests__/settings-parity.test.ts | 10 ++ packages/core/src/__tests__/store-settings.test.ts | 10 ++ packages/core/src/settings-schema.ts | 8 + packages/core/src/types.ts | 12 ++ packages/dashboard/app/App.tsx | 52 ++++++ .../dashboard/app/components/SettingsModal.css | 21 +++ .../dashboard/app/components/SettingsModal.tsx | 11 ++ .../__tests__/SettingsModal.general.test.tsx | 63 ++++++++ .../app/components/settings/save-split.ts | 1 + .../settings/sections/GlobalGeneralSection.tsx | 38 +++++ .../useDashboardKeyboardShortcuts.test.tsx | 101 ++++++++++++ packages/dashboard/app/hooks/useAppSettings.ts | 8 +- .../app/hooks/useDashboardKeyboardShortcuts.ts | 66 ++++++++ .../app/utils/__tests__/keyboardShortcuts.test.ts | 76 +++++++++ packages/dashboard/app/utils/keyboardShortcuts.ts | 175 +++++++++++++++++++++ 19 files changed, 702 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-7494 Fusion-Task-Lineage: 30445f4d-c0c5-4657-bd79-fc2acaf3c37d Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
50786f29d4 |
FN-7475: delay GitHub setup warnings
Delay dashboard GitHub setup warnings until the project grace period expires while keeping AI setup warnings immediate. - Add per-project GitHub warning delay state and persistence. - Route dashboard GitHub warnings to Settings → Authentication with a Connect GitHub action. - Hide non-actionable GitHub-only warnings in the New Task modal and update localized copy, docs, and tests. Files changed: .changeset/fn-7475-github-setup-warning.md | 7 ++ docs/dashboard-guide.md | 6 + packages/dashboard/app/App.tsx | 11 +- packages/dashboard/app/components/NewTaskModal.tsx | 8 +- .../app/components/SetupWarningBanner.css | 10 ++ .../app/components/SetupWarningBanner.tsx | 18 ++- .../app/components/__tests__/NewTaskModal.test.tsx | 46 ++++++- .../__tests__/SetupWarningBanner.test.tsx | 40 ++++++ .../app/components/dashboard/DashboardBanners.tsx | 3 + .../dashboard/__tests__/DashboardBanners.test.tsx | 125 ++++++++++++++++++- .../dashboard/app/components/dashboard/types.ts | 1 + .../__tests__/useGithubSetupWarningDelay.test.ts | 134 +++++++++++++++++++++ .../app/hooks/useGithubSetupWarningDelay.ts | 96 +++++++++++++++ packages/dashboard/app/utils/projectStorage.ts | 1 + packages/i18n/locales/en/app.json | 5 +- packages/i18n/locales/es/app.json | 5 +- packages/i18n/locales/fr/app.json | 5 +- packages/i18n/locales/ko/app.json | 5 +- packages/i18n/locales/zh-CN/app.json | 5 +- packages/i18n/locales/zh-TW/app.json | 5 +- packages/i18n/src/resources.d.ts | 127 +++++++++++++------ 21 files changed, 606 insertions(+), 57 deletions(-) Fusion-Task-Id: FN-7475 Fusion-Task-Lineage: 5bf1fffa-b58c-42a1-b170-367a4c20eaaf Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |