0e7b0e75da34de0bd64a5d3755ed1d97b8dcdc42
10887 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0e7b0e75da |
fix(demo): trim leading loading-skeleton frames from README GIFs
The 17 dashboard-capture GIFs opened on the app page-load sequence (skeleton placeholder boxes + "Loading files…" spinner) before real content. Trim those leading frames per-GIF so each starts on fully populated content. Re-encoded with gifsicle --unoptimize/--lossy=60; total 40.0MB -> 38.1MB. Edited reels (fusion-reel/company-reel/mesh) left untouched — they open on designed title cards, not skeletons. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
be94f630ea |
Surface runtime-resolution fallback in dashboard; thread real FallbackReason (#1957)
Closes/relates to Runfusion/Fusion#1956. ## Summary Surfaces silent runtime-resolution fallback in the dashboard, and threads the real `FallbackReason` ("not_found" vs "factory_error") through instead of hardcoding `"not_found"` for every fallback. ## Changes - `packages/engine/src/runtime-resolution.ts`: `resolvePluginRuntime()` now returns a tagged miss result (`{ ok: false, reason }`) distinguishing "not found" from "factory/instantiation error" instead of collapsing both to `null`. `resolveRuntime()` threads the real reason through to `logRuntimeFallback(...)` and returns it via `ResolvedRuntime.fallbackReason`. - `packages/engine/src/agent-session-helpers.ts`: `createResolvedAgentSession()` includes `fallbackReason` in the `session:runtime-resolved` audit event metadata when present. - `packages/dashboard/src/routes/register-task-workflow-routes.ts`: new `GET /api/tasks/:id/runtime-fallback` endpoint, returning the most recent `session:runtime-resolved` event normalized for UI consumption (`wasConfigured`, `runtimeHint`, `reason`, `showFallbackBadge`). - `packages/dashboard/app/hooks/useRuntimeFallbackStatus.ts` (new): polls the endpoint, dedupes toast firing per audit-event-id. - `packages/dashboard/app/components/RuntimeFallbackBadge.tsx` (new): renders the badge + fires the toast; wired into `TaskCard.tsx`, `ActiveAgentsPanel.tsx`, and `AgentsView.tsx` (board and list variants). ## Test plan - `pnpm --filter @fusion/engine exec vitest run src/__tests__/runtime-resolution.test.ts` — 24/24 pass (21 pre-existing + 3 new, none weakened) - `pnpm --filter @fusion/dashboard exec vitest run src/routes/__tests__/register-task-workflow-routes.runtime-fallback.test.ts` — 5/5 pass (empty/configured-ok/fallback-with-hint/fallback-blank-hint/stale-superseded states) - `pnpm --filter @fusion/dashboard exec vitest run app/components/__tests__/RuntimeFallbackBadge.test.tsx` — 8/8 pass (all data states + mobile breakpoint + toast-fires-once) - `pnpm --filter @fusion/dashboard run typecheck` and `pnpm --filter @fusion/engine run typecheck` — both clean <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added runtime-fallback warning badges across task and agent views (including board and “working on” sections) with automatic toast notifications. * Introduced a new backend API to surface the latest runtime-fallback state for a task. * Added runtime-fallback status polling and UI messaging to reflect the most recent state. * **Bug Fixes** * Prevented repeated toasts by deduplicating notifications across polling updates. * Improved fallback reporting so the UI reflects the latest runtime-resolved audit event. * Enhanced diagnostics by distinguishing fallback reasons (e.g., missing runtime vs factory failure) for clearer user guidance. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ec2aeed2bf |
fix(dashboard): drop unknown-rule eslint-disable in RuntimeFallbackBadge
The repo eslint config omits react-hooks/exhaustive-deps, so a disable directive for it is itself a lint error (rule-not-found). Replace with a plain comment documenting the intentional dep omission. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
fd11280ce3 |
FN-7673: document closure of single combined-entry engine-graph gate bundle experiment
Narrative: FN-7673 re-attempted the engine-core gate bundle lever with a single combined-entry engine-graph design (all 14 mock-safe roots redirected through a resolveId plugin to one synthetic packages/engine/.gate-bundle/engine.mjs) after FN-7670's 14-separate-root attempt was inconclusive. This update records the negative A/B result and closes the lever. - Documented that the combined-entry design achieved its structural goal (149 first-party inputs -> 1 output file) and full 335/335 coverage parity - Recorded a true interleaved A/B (5 warm + 1 cold pair) showing the combined-entry bundle is consistently slower than the @fusion/core-only baseline (warm median +29.1%, import-phase aggregate +74.0%) - Captured the working theory: funnelling 14 relative-import sites through a resolveId-plugin redirect to one large synthetic export-* file adds more transform/resolution overhead than it saves, unlike @fusion/core's plain resolve.alias - Noted the experiment was NOT landed; wiring (engine-graph scans, combined-entry builder, resolveId plugin) was fully reverted - Marked this lever (bundling the @fusion/engine relative-import graph for the engine-core gate, in either 14-file or single-combined-entry shape) as CLOSED absent new evidence Files changed: packages/engine/vitest.config.ts | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) Fusion-Task-Id: FN-7673 Fusion-Task-Lineage: 46951e5f-e7dc-4f7c-9601-0cfa0b082d70 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
b1b4735111 |
FN-7671: remove stale merger-post-merge entry from engine-core gate include
Removes a dead test-file reference from the engine-core vitest gate include list, with a code comment documenting why. - Remove the nonexistent `src/__tests__/merger-post-merge.test.ts` entry from packages/engine/vitest.config.ts's engine-core include list (retired by FN-7039; graph is now sole post-merge owner) - Add FNXC comment noting the entry matched zero files and that graph post-merge coverage lives in workflow-graph-post-merge.test.ts (engine-default) Files changed: packages/engine/vitest.config.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-7671 Fusion-Task-Lineage: 73447412-7b8a-4578-a2b8-07f83e381548 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
aa534c19af |
FN-7672: recover durable agents stuck in error state despite active manager
Root-causes 4 correlated CTO-report agent failures where durable non-ephemeral agents got stuck in `error` state indefinitely because the heartbeat scheduler stops ticking error-state agents entirely, and self-healing's recovery sweep previously only considered them when their manager row was missing. - SelfHealingManager: scope the `managerMissing` gate to the "running" orphan-detection path only, so "error"-state durable agents with a present/active manager now fall through to the existing transient/operator-actionable/active-execution/cooldown/retry-budget recovery guards instead of being skipped outright - Add FNXC:AgentHeartbeat comment documenting the FN-7672 incident and rationale for the scoping change - Extend self-healing.test.ts with coverage for manager-present durable agents in error state - Add changeset (patch) describing the fix for release notes - Update docs/agents.md accordingly Files changed: .changeset/fn-7672-durable-agent-recovery.md | 7 ++ docs/agents.md | 2 + packages/engine/src/__tests__/self-healing.test.ts | 129 ++++++++++++++++++++- packages/engine/src/self-healing.ts | 24 +++- 4 files changed, 160 insertions(+), 2 deletions(-) Fusion-Task-Id: FN-7672 Fusion-Task-Lineage: 6676dc9e-66e7-4f70-804a-cccf77e8d337 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
b8fa2a6652 |
FN-7670: document negative result of extending engine-core pre-bundle to @fusion/engine relative-import graph
Prototyped extending the @fusion/core pre-bundle alias lever to @fusion/engine's relative-import production graph reached by the 18 gate files, but an A/B showed no clear win over the @fusion/core-only bundle, so the change was not landed and only the rationale is recorded. - Added an FNXC:EngineTests comment block in packages/engine/vitest.config.ts documenting the FN-7670 prototype (171 first-party files → 35 output files via esbuild multi-entry splitting) - Recorded the negative A/B result: byte-size growth of 14 separate large root bundles offset per-file-dispatch savings, with no clear win beyond host run-to-run noise - Left the vitest alias wiring unchanged at the @fusion/core-only bundle state, pointing future attempts to FN-7670's task docs for full analysis and to consider a single combined engine-graph entry instead of 14 separate root entries Files changed: packages/engine/vitest.config.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) Fusion-Task-Id: FN-7670 Fusion-Task-Lineage: efd27f94-a6c4-49c7-a78e-50213fd42a24 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
ad9a72176c |
FN-7669: pre-bundle @fusion/core gate-safe barrel to cut engine-core gate import-phase cost
Prototype and land a rebuilt-every-run esbuild bundle of the @fusion/core gate-safe barrel closure, collapsing the engine-core gate's per-fork Vite SSR import-phase cost (18 forks x ~430-file closure re-resolved from scratch) into a single file load per fork. - Add scripts/build-engine-core-gate-bundle.mjs: esbuild-bundles packages/core/src/index.gate.ts (220 first-party files, packages:"external" so third-party/node: imports stay external, treeShaking:false to preserve side effects) into packages/core/.gate-bundle/core.mjs + core.meta.json - Wire the builder into packages/engine/vitest.config.ts's engine-core project globalSetup (alongside the existing vitest-teardown hook) so the bundle is rebuilt fresh before every gate invocation, and repoint the @fusion/core resolve.alias at the bundled output instead of index.gate.ts source - Place the bundle output at packages/core/.gate-bundle/ as a sibling of packages/core/node_modules/ (not nested inside it) to avoid Vite SSR's external-dep heuristic, which would otherwise silently defeat vi.mock interception for imports nested in the bundle - Gitignore packages/core/.gate-bundle/ and add a matching ESLint ignore entry so the generated bundle text is never linted or committed - Add esbuild ^0.25.12 as a root devDependency (pnpm-lock.yaml updated accordingly) - Document the pre-bundling rationale, placement constraints, and measured A/B wall-time results in docs/testing.md Verified: pnpm test:gate passes (335/335 engine-core tests, 63/63 CLI ci-shape tests), engine package typecheck clean, eslint clean on touched files. Files changed: .gitignore | 11 ++ docs/testing.md | 3 + eslint.config.mjs | 10 ++ package.json | 1 + packages/engine/vitest.config.ts | 50 ++++++++- pnpm-lock.yaml | 3 + scripts/build-engine-core-gate-bundle.mjs | 174 ++++++++++++++++++++++++++++++ 7 files changed, 247 insertions(+), 5 deletions(-) Fusion-Task-Id: FN-7669 Fusion-Task-Lineage: 62b06b2a-4ac6-45ae-ac79-9771132bc303 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
6902077972 |
FN-7667: add gate-scoped @fusion/core barrel to decouple engine-core gate from full barrel growth
Introduces a project-scoped @fusion/core barrel used only by the engine-core gate project, so new feature modules added to the full barrel don't silently inflate the gate's transform/import cost. - Add packages/core/src/index.gate.ts, a copy of the full @fusion/core barrel minus export statements for modules added since the last re-audit baseline (i.e. it still re-exports everything the full barrel does except newly added, gate-irrelevant feature modules). - Update packages/engine/vitest.config.ts to add a project-scoped resolve.alias mapping @fusion/core -> packages/core/src/index.gate.ts for the engine-core project only; engine-default/engine-reliability/engine-slow and @fusion/engine continue to resolve the full barrel. - Document the gate-safe barrel and its audit procedure in docs/testing.md. Files changed: docs/testing.md | 3 + packages/core/src/index.gate.ts | 2102 ++++++++++++++++++++++++++++++++++++++ packages/engine/vitest.config.ts | 17 + 3 files changed, 2122 insertions(+) Fusion-Task-Id: FN-7667 Fusion-Task-Lineage: 054ec89a-d973-44dd-b9ac-ad266f553f01 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
845fad2aa4 |
FN-7666: record weekly test-velocity regression finding (gate 7.7s -> 36.3s)
Narrative: update the 2026-W28 test-velocity baseline report with the newly measured merge-gate/changed-test wall-time regression and document root-cause attribution. - Bump baseline cycle to 2026-W28 (captured 2026-07-08T09:30:50.606Z) - Update headline metrics table: gate 7.7s -> 36.3s (+28.6s), boot smoke 17.4s -> 25.3s (+7.9s), pnpm test 9.3s -> 43.4s (+34.0s), quarantine count unchanged at 1 - Add FN-7666 finding note attributing the regression to ~4,305 new re-exported source lines across 14 modules pulled through the @fusion/core / @fusion/engine barrels, inflating per-fork import/transform cost across the 18 curated engine-core gate files; confirms it is a genuine regression (not cache/env noise) via cold-vs-warm reruns; files follow-up FN-7667 for the barrel-decoupling fix - Update weekly history table (previous/latest/delta rows) and the #leads post text block - Append new row capturing this week's measurements to scripts/test-velocity-history.json Files changed: docs/test-velocity-baseline.md | 23 ++++---- scripts/test-velocity-history.json | 112 +++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 12 deletions(-) Fusion-Task-Id: FN-7666 Fusion-Task-Lineage: 73ec627c-2fc6-4289-8e6e-3e839ed5c675 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
03161adfb9 |
FN-7659: paginate and sort the Archived column newest-first
Adds server-side pagination for the Archived task column, sorted by most-recently-archived first, with a Show more control on the dashboard.
- Add ArchiveDatabase.listPage and TaskStore.listArchivedTasks for a bounded SQL LIMIT/OFFSET read ordered by archivedAt DESC
- Add GET /tasks/archived route for paged archive fetches, leaving the legacy merged listTasks({includeArchived}) path unchanged
- Wire useTasks.loadArchivedTasks to fetch page 1 on first Archived-column expand and loadMoreArchivedTasks for subsequent pages
- Add a "Show more" affordance in Column.tsx/Board.tsx/MainContent.tsx to trigger loading additional archived pages
- Extend taskSorting.ts to keep archived task ordering stable with the new paged data
- Add core and dashboard tests covering archive pagination and store/route behavior
- Add changeset for @runfusion/fusion (minor) and update docs/storage.md and docs/dashboard-guide.md
Files changed:
.changeset/FN-7659-archived-pagination.md | 7 +
docs/dashboard-guide.md | 4 +-
docs/storage.md | 7 +
packages/core/src/__tests__/archive-db-pagination.test.ts | 94 ++++++++
packages/core/src/__tests__/store-archive-search.test.ts | 63 ++++++
packages/core/src/archive-db.ts | 18 ++
packages/core/src/store.ts | 32 +++
packages/dashboard/app/App.tsx | 5 +-
packages/dashboard/app/api/legacy.ts | 19 ++
packages/dashboard/app/components/Board.tsx | 19 +-
packages/dashboard/app/components/Column.tsx | 48 ++++-
packages/dashboard/app/components/__tests__/Column.test.tsx | 41 ++++
packages/dashboard/app/components/__tests__/taskSorting.test.ts | 27 +++
packages/dashboard/app/components/dashboard/MainContent.tsx | 9 +
packages/dashboard/app/components/dashboard/types.ts | 6 +
packages/dashboard/app/components/taskSorting.ts | 16 ++
packages/dashboard/app/hooks/__tests__/useTasks.test.ts | 236 ++++++++++++++++++++-
packages/dashboard/app/hooks/useTasks.ts | 173 ++++++++++++++-
packages/dashboard/app/test/mockApi.ts | 3 +
packages/dashboard/src/routes/__tests__/tasks-archived-pagination.test.ts | 94 ++++++++
packages/dashboard/src/routes/register-task-workflow-routes.ts | 32 +++
21 files changed, 930 insertions(+), 23 deletions(-)
Fusion-Task-Id: FN-7659
Fusion-Task-Lineage: 7a5a1f62-277c-4f29-883c-62e75b269bc5
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
|
||
|
|
7cf70b3c59 |
FN-7665: rename Command Center SDLC funnel intake stage label to Planning
Rename the Command Center SDLC funnel's intake stage display text from "Triage" to "Planning" to match the renamed board column, updating English locale copy and tests; the underlying aggregator/i18n key names stay "triage". - SdlcFunnel.tsx: stage label fallback, enteredInRange, and completionRateAria copy changed to Planning/Entered planning/in-range planning entrants; added FNXC comment explaining the key-vs-label distinction - packages/i18n/locales/en/app.json: synced English strings for the same three keys - SdlcFunnel.test.tsx: updated assertions to match new Planning copy - Added changeset (patch) documenting the label rename Files changed: .changeset/fn-7665-funnel-planning-label.md | 7 +++++++ .../app/components/command-center/SdlcFunnel.tsx | 16 ++++++++++++---- .../command-center/__tests__/SdlcFunnel.test.tsx | 6 +++--- packages/i18n/locales/en/app.json | 6 +++--- 4 files changed, 25 insertions(+), 10 deletions(-) Fusion-Task-Id: FN-7665 Fusion-Task-Lineage: d8aec609-6b8b-4f36-bb43-61d7c7c421f9 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
d2e38ba920 |
FN-7663: consolidate /automations and /routines run-stream SSE handlers into a shared factory
Removes duplicated SSE streaming logic between the /automations/:id/run/stream and /routines/:id/run/stream endpoints by extracting a single generic makeRunStreamHandler factory. - Add makeRunStreamHandler<TStore, TEntity> factory in routes.ts, parameterized by store resolver, entity getter, and not-found message - Replace the two near-identical inline SSE handlers (connect headers, buffered replay, run subscription, auto-attach, teardown, error handling) with calls to the shared factory - Import ScopeValue type from ./routes/types.js to type the factory's scope parameter - Add regression tests in routes-automation.test.ts covering the consolidated handler behavior for both routes Files changed: .../src/__tests__/routes-automation.test.ts | 35 +++ packages/dashboard/src/routes.ts | 246 +++++++++------------ 2 files changed, 137 insertions(+), 144 deletions(-) Fusion-Task-Id: FN-7663 Fusion-Task-Lineage: 55ede468-c4ed-4a72-a428-7d19686e8ea5 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
aae6a6eca2 |
FN-7662: harden boot-smoke temp dir cleanup against macOS ENOTEMPTY races
Boot-smoke's post-verdict temp-dir cleanup could throw ENOTEMPTY on macOS when async writers (fsevents/Spotlight, the just-killed child) still touched the throwaway HOME/project dirs, turning an already-decided PASS into a pnpm verify:fast failure. - Add removeTempDir() helper in scripts/boot-smoke.mjs: wraps rmSync with maxRetries/retryDelay and swallows any residual error (never throws) since cleanup always runs after the smoke verdict is decided/printed - Replace both isolatedHome/isolatedProject rmSync call sites (exit handler and EADDRINUSE retry-port branch) with removeTempDir() - Guard main() behind an import.meta.url === pathToFileURL(process.argv[1]) check so requiring boot-smoke.mjs from tests doesn't spawn a real server - Add scripts/__tests__/boot-smoke.test.mjs covering ENOTEMPTY tolerance, always-failing rm, retry/backoff params, and the no-boot-on-import guard Files changed: scripts/__tests__/boot-smoke.test.mjs | 77 +++++++++++++++++++++++++++++++++++ scripts/boot-smoke.mjs | 44 +++++++++++++++++--- 2 files changed, 115 insertions(+), 6 deletions(-) Fusion-Task-Id: FN-7662 Fusion-Task-Lineage: 3288d055-4f70-4487-8462-933563214ce5 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
dd9fa2d3cb |
FN-7661: expose removeLineageReferences on fn_task_archive/fn_task_delete
Fixes fn_task_archive and fn_task_delete rejecting tasks still referenced as a lineage parent, with no tool-exposed way to clear that reference. - Add optional removeLineageReferences boolean param to fn_task_archive and fn_task_delete tool schemas, forwarded to store.archiveTask/store.deleteTask - Update tool descriptions and prompt guidelines to advertise the recovery path (removeLineageReferences:true) when a lineage-parent block occurs - Add task-lineage-unlink.test.ts covering the new parameter behavior - Document the change in docs/storage.md - Add changeset (@runfusion/fusion minor, category: fix) Files changed: .changeset/fn-7661-lineage-unlink-tools.md | 7 + docs/storage.md | 1 + packages/cli/src/__tests__/task-lineage-unlink.test.ts | 199 +++++++++++++++++++++ packages/cli/src/extension.ts | 28 ++- 4 files changed, 232 insertions(+), 3 deletions(-) Fusion-Task-Id: FN-7661 Fusion-Task-Lineage: 414c046c-43df-4995-85a5-ff00b345de50 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
97e46674f4 |
FN-7660: rename remaining board-column "Triage" labels to "Planning"
Rename remaining "Triage" board-column label references to "Planning" across dashboard editors, locale strings, and docs. - Fixed BUILTIN_WORKFLOW_COLUMN_LABELS.triage in board-workflows.ts (was still "Triage", clobbering FN-7599's IR rename); column id "triage" stays unchanged - Updated dashboard components (AgentDetailView, RoutineEditor, ScheduleForm, ScheduleStepsEditor) to use the "Planning" label - Updated en/app.json locale strings (board.triage, schedule.columnTriage/taskColumnTriage/triageColumn) to "Planning" - Updated board-workflows tests to assert the new label - Updated docs/dashboard-guide.md Triage/Planning column references to "Planning", preserving the FN-7653 intake-only gating correction - Added a patch changeset documenting the label-consistency fix Files changed: .changeset/fn-7660-planning-label-consistency.md | 7 +++++++ docs/dashboard-guide.md | 9 +++++---- packages/dashboard/app/components/AgentDetailView.tsx | 2 +- packages/dashboard/app/components/RoutineEditor.tsx | 2 +- packages/dashboard/app/components/ScheduleForm.tsx | 2 +- packages/dashboard/app/components/ScheduleStepsEditor.tsx | 2 +- .../dashboard/src/routes/__tests__/board-workflows.test.ts | 7 ++++++- packages/dashboard/src/routes/board-workflows.ts | 10 +++++++++- packages/i18n/locales/en/app.json | 8 ++++---- 9 files changed, 35 insertions(+), 14 deletions(-) Fusion-Task-Id: FN-7660 Fusion-Task-Lineage: fc6c94d6-9876-4c0e-80b1-a5518903952e Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
f7d9509294 |
FN-7658: gate same-agent duplicate auto-archiving behind opt-in setting
Duplicate tasks created by the same agent are no longer auto-archived by default; they are flagged for review instead, controlled by a new opt-in project setting. - Add project setting `autoArchiveDuplicateTasksEnabled` (default false) gating the FN-4892 same-agent duplicate intake path - Add `flagSameAgentDuplicate` path and `nearDuplicateOf` metadata used when auto-archive is disabled; tombstone-resurrection blocking is unchanged - Wire the setting through core settings schema/types/store, dashboard SchedulingSection UI, and i18n strings - Update docs (settings-reference.md, task-management.md) to describe the new default-off behavior - Add a changeset for the @runfusion/fusion minor release - Extend duplicate-intake, tombstone-window, store-parent-task-dedup, and reliability-interaction tests to cover both flag states Files changed: $(cat /tmp/fn7658_stat.txt) Fusion-Task-Id: FN-7658 Fusion-Task-Lineage: 7d0d1074-1020-48a8-b96f-186154c2c408 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
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> |
||
|
|
0bed997af8 |
feat: surface runtime-resolution fallback in dashboard, thread real FallbackReason
Fixes silent runtime fallback visibility (dashboard never read wasConfigured or session:runtime-resolved) and threads the real FallbackReason (not_found vs factory_error) through resolveRuntime()/logRuntimeFallback instead of hardcoding "not_found" for every fallback. - packages/engine/src/runtime-resolution.ts: resolvePluginRuntime() now returns a tagged miss result distinguishing not_found from factory_error; resolveRuntime() threads the real reason through and returns it as ResolvedRuntime.fallbackReason - packages/engine/src/agent-session-helpers.ts: includes fallbackReason in the session:runtime-resolved audit event metadata - packages/dashboard/src/routes/register-task-workflow-routes.ts: new GET /api/tasks/:id/runtime-fallback endpoint - packages/dashboard/app/hooks/useRuntimeFallbackStatus.ts + packages/dashboard/app/components/RuntimeFallbackBadge.tsx: new polling hook + badge/toast component wired into TaskCard, ActiveAgentsPanel, and AgentsView Ref: Fusion task FUX-022, investigations/FUX-017-hermes-runtime-fallback.md recommendation #1 |
||
|
|
e29fea38e0 |
FN-7656: restore chat working indicator when reattaching to an active generation
Fixes chat sessions not showing the working/"Thinking…" indicator when returning to a session whose generation was already in flight but hadn't emitted its first delta yet.
- useChat.ts: selectSession's authoritative fetchChatSession refresh now reattaches whenever refreshedSession.isGenerating===true, instead of also requiring a populated inFlightGeneration snapshot (which is null pre-first-delta)
- Added a guard so the reattach only proceeds if the user hasn't navigated away from the session while the refresh was in flight (activeSessionRef.current?.id === id)
- Calls attachIfGenerating(id, refreshedSession.inFlightGeneration, { silent: true }) when no stream is already attached, reusing existing double-attach guarding
- Added regression tests in useChat.test.ts covering the reattach-on-isGenerating-alone behavior and the stale-session navigation guard
- Added a patch changeset documenting the fix
Files changed:
.changeset/fn-7656-chat-reattach-working-state.md | 7 ++
.../dashboard/app/hooks/__tests__/useChat.test.ts | 113 +++++++++++++++++++++
packages/dashboard/app/hooks/useChat.ts | 22 +++-
3 files changed, 141 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-7656
Fusion-Task-Lineage: c923c16a-391f-4475-aab8-6194bbc675f7
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
|
||
|
|
ebe9b9fa67 |
FN-7653: restrict plan auto-approve toggle to the intake/planning column
Fix the Board Auto-approve plan shortcut leaking onto hold (Todo-like) columns; it must render only on the intake/planning column. - Board.tsx: gate the planAutoApproveEnabled/onTogglePlanAutoApprove prop pair on columnDef.flags.intake only (dropped the || columnDef.flags.hold clause) for both the aggregate and single-workflow column renders - Column.tsx: update the FNXC comment to document that Board.tsx is the single source of truth for this intake-only gating; Column.tsx just renders whatever prop it receives - docs/dashboard-guide.md: correct the Board guide to describe the toggle as intake/planning-column-only, not hold columns - Board.test.tsx: fix the existing intake/hold test expectation to assert the hold column does NOT get the toggle, and add a regression test reproducing the built-in Coding workflow's Todo (hold) column symptom - add a patch changeset documenting the fix Files changed: .changeset/FN-7653-plan-auto-approve-intake-only.md | 7 +++++++ docs/dashboard-guide.md | 5 +++-- packages/dashboard/app/components/Board.tsx | 6 ++++-- packages/dashboard/app/components/Column.tsx | 5 ++++- .../app/components/__tests__/Board.test.tsx | 20 +++++++++++++++++--- 5 files changed, 35 insertions(+), 8 deletions(-) Fusion-Task-Id: FN-7653 Fusion-Task-Lineage: 10c5f01a-b00c-4039-9b83-a8a8965fc56c Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
7c7b22e511 |
FN-7652: fix live-run status falsely showing Run failed for successful automations
Reconcile the automation live-run panel's terminal status with the authoritative run result so successful runs no longer flash "Run failed". - ScheduledTasksModal/RoutineCard now reconcile SSE terminal status against the POST/registry result instead of trusting raw stream teardown. - Gate benign SSE teardown (post-terminal close, reconnect exhaustion) from being surfaced as a failure state. - Apply the same reconciliation to both /routines/:id/run/stream and /automations/:id/run/stream routes in routes.ts. - Add regression coverage in RoutineCard, ScheduledTasksModal, and routes-automation tests. - Add a patch changeset documenting the fix. Files changed: .changeset/fn-7652-automation-live-run-false-failure.md | 7 ++ packages/dashboard/app/components/ScheduledTasksModal.tsx | 66 ++++++++++++++-- packages/dashboard/app/components/__tests__/RoutineCard.test.tsx | 37 +++++++++ packages/dashboard/app/components/__tests__/ScheduledTasksModal.test.tsx | 78 +++++++++++++++++++ packages/dashboard/src/__tests__/routes-automation.test.ts | 87 ++++++++++++++++++++++ packages/dashboard/src/routes.ts | 52 ++++++++++++- 6 files changed, 319 insertions(+), 8 deletions(-) Fusion-Task-Id: FN-7652 Fusion-Task-Lineage: 61fc89f5-d25d-44de-9699-bc8ad2a0dea6 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
dfb084c59e |
FN-7655: make planner chat stop button icon-only
Removes the visible "Stop generation" text label from the planner chat's stop button while keeping it accessible via aria-label.
- Add showStopText prop to StandardChatActionButton (defaults to showSendText) to independently control Send vs Stop visible text
- Set showStopText={false} in TaskPlannerChatTab so the streaming stop button renders icon-only
- Update TaskPlannerChatTab test to assert no visible text span on the stop button while aria-label is retained
- Add changeset for @runfusion/fusion (patch)
Files changed:
.changeset/fn-7655-planner-stop-icon-only.md | 7 +++++++
.../dashboard/app/components/StandardChatSurface.tsx | 16 ++++++++++++++--
packages/dashboard/app/components/TaskPlannerChatTab.tsx | 3 +++
.../app/components/__tests__/TaskPlannerChatTab.test.tsx | 4 +++-
4 files changed, 27 insertions(+), 3 deletions(-)
Fusion-Task-Id: FN-7655
Fusion-Task-Lineage: f68a8bfa-30ba-439e-97d0-28654a614c54
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
|
||
|
|
efabdd6f04 |
FN-7651: remove chat "Search in title only" toggle
Simplifies chat search UX by always matching both title and message content, removing the now-unneeded title-only toggle button and state. - Removed the "Search in title only" toggle button and its CSS from ChatView - Dropped searchInTitleOnly/setSearchInTitleOnly state and logic from useChat; content-search query params are now always-on - Updated ChatView tests to drop title-only toggle interactions and assertions - Removed the title-only-search i18n string across all locales - Updated dashboard-guide.md docs to reflect the simplified search behavior - Added a patch changeset documenting the removal Files changed: .../fn-7651-remove-chat-title-only-toggle.md | 7 +++ docs/dashboard-guide.md | 4 +- packages/dashboard/app/components/ChatView.css | 18 -------- packages/dashboard/app/components/ChatView.tsx | 26 +++-------- .../__tests__/ChatView.autosize.test.tsx | 2 - .../__tests__/ChatView.content-search.test.tsx | 51 ++++++---------------- .../components/__tests__/ChatView.draft.test.tsx | 2 - .../__tests__/ChatView.hash-mention.test.tsx | 2 - .../__tests__/ChatView.mobile-render.test.tsx | 2 - .../components/__tests__/ChatView.rooms.test.tsx | 2 - .../__tests__/ChatView.scroll-to-top.test.tsx | 2 - .../components/__tests__/ChatView.test-harness.tsx | 2 - packages/dashboard/app/hooks/useChat.ts | 39 ++++++++--------- packages/i18n/locales/en/app.json | 1 - packages/i18n/locales/es/app.json | 1 - packages/i18n/locales/zh-CN/app.json | 1 - packages/i18n/locales/zh-TW/app.json | 1 - packages/i18n/locales/ko/app.json | 1 - packages/i18n/locales/fr/app.json | 1 - 19 files changed, 47 insertions(+), 118 deletions(-) Fusion-Task-Id: FN-7651 Fusion-Task-Lineage: 5a31825c-8e6e-441f-800d-6053f5f844ba Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
ac719d1203 |
fix: add usage_events to operational-log retention
usage_events was absent from Database.pruneOperationalLogs, so the per-tool telemetry log grew unbounded (~187k rows / ~28MB observed) and became a dominant driver of .fusion DB bloat once runAuditEvents was already 30-day capped. Prune it on the same operationalLogRetentionDays cadence, keyed off its `ts` column (not `timestamp`), alongside the other column-name exceptions. Adds a regression test and changeset. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
ce4f173d8f |
FN-7649: resolve settings landing view to board on project switch
Fixes project-switch hydration so a persisted "settings" view resolves to the Board instead of re-opening Settings. - Extend resolveLandingTaskView() in useViewState.ts to treat "settings" the same as "command-center", resolving both to "board" for the auto-restored/hydrated landing view only - Add regression tests covering the settings->board landing resolution in useViewState.test.ts - Add changeset documenting the patch-level fix Files changed: .changeset/fn-7649-project-switch-board-landing.md | 7 ++ .../app/hooks/__tests__/useViewState.test.ts | 74 ++++++++++++++++++++++ packages/dashboard/app/hooks/useViewState.ts | 5 +- 3 files changed, 85 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-7649 Fusion-Task-Lineage: 7179efd6-bb1b-4ea4-a062-479b9b1fffa3 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
60bfb66c8c |
test(FN-5048): replace fixed WS badge subscription sleeps with deterministic event waits
Follow-through on FN-5048: the four residual fixed 100ms sleeps in the websocket badge integration tests (3 subscription-establishment waits + 1 cross-instance pub/sub propagation wait) are replaced with deterministic awaits on the server-side WebSocketManager subscription:changed event and the shared pub/sub message event. Removes ~400ms of unconditional real-time waiting and closes the ordering races the sleeps papered over. Fusion-Task-Id: FN-5048 |
||
|
|
563a8c6b7c |
FN-7647: route dashboard sync/mesh AuthStorage writes through createFusionAuthStorage
Route node settings-sync and mesh credential writes through the coordinated @fusion/engine auth store to prevent concurrent clobbers of ~/.fusion/agent/auth.json. - register-settings-sync-routes.ts, register-settings-sync-inbound-routes.ts, and register-mesh-routes.ts now persist received credentials via createFusionAuthStorage() instead of raw AuthStorage.create(getFusionAuthPath()) - Shares FN-7646's reload-before-persist + per-provider locked-merge path, avoiding lost writes from concurrent Fusion processes - Uses a static top-level import of @fusion/engine (not dynamic import) per FN-3049's bundler-safety rule - Adds route-level regression coverage in mesh-routes.test.ts, routes-nodes-sync-contract.test.ts, and routes-nodes-sync.test.ts - Adds a patch changeset for @runfusion/fusion Files changed: .../fn-7647-auth-storage-routes-coordination.md | 7 ++ .../dashboard/src/__tests__/mesh-routes.test.ts | 118 +++++++++++++++++++++ .../__tests__/routes-nodes-sync-contract.test.ts | 27 ++++- .../src/__tests__/routes-nodes-sync.test.ts | 110 ++++++++++++++++++- .../dashboard/src/routes/register-mesh-routes.ts | 14 ++- .../register-settings-sync-inbound-routes.ts | 15 ++- .../src/routes/register-settings-sync-routes.ts | 15 ++- 7 files changed, 290 insertions(+), 16 deletions(-) Fusion-Task-Id: FN-7647 Fusion-Task-Lineage: cfab9679-0baa-4eca-8c7a-23db017aa54f Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
bec8987ce9 |
FN-7648: gate hold-release on trait-based unplanned-card check, not literal todo column
Blocks planning/intake column cards from entering processing columns regardless of literal column id, so renamed custom intake/planning columns are covered by the same guard as the legacy todo column. - Add isUnplannedForExecution() in hold-release.ts: true when task.status==="planning", or when the card sits in the legacy todo column or a column carrying the intake trait AND its PROMPT.md still equals the bootstrap stub. - Route issueRelease() (used by the sweep, promoteHeldTask, and releaseHeldTaskByEvent) through this guard before releasing into any countsTowardWip processing column. - Update scheduler.ts's reserveSlot guard to use the same trait-based predicate instead of a hardcoded "todo" column id check. - Add regression tests in hold-release.test.ts and scheduler-workflow-cutover.test.ts covering renamed intake/planning columns. - Document the invariant in docs/architecture.md and docs/workflow-steps.md. - Add changeset (patch) describing the fix. Files changed: .changeset/fn-7648-unplanned-intake-cards-never-execute.md | 7 + docs/architecture.md | 2 + docs/workflow-steps.md | 2 + packages/engine/src/__tests__/hold-release.test.ts | 238 +++++++++++++++++++++ packages/engine/src/__tests__/scheduler-workflow-cutover.test.ts | 60 +++++- packages/engine/src/hold-release.ts | 60 ++++++ packages/engine/src/scheduler.ts | 26 +-- 7 files changed, 378 insertions(+), 17 deletions(-) Fusion-Task-Id: FN-7648 Fusion-Task-Lineage: a4b54d30-f86d-4eb9-9cf2-6ac55b6dbe58 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
009ce26fd0 |
FN-7646: prevent OAuth credential clobbering across concurrent Fusion processes
Fix API keys/OAuth credentials in ~/.fusion/agent/auth.json being clobbered when the desktop app and CLI-served web app run concurrently on one machine. - Reload primary auth storage from disk (primary.reload()) before persisting a refreshed OAuth credential, so a concurrent process's newer login/refresh for the same provider isn't overwritten by this process's stale in-flight refresh. - Re-check credential identity against the freshly reloaded disk state before writing the refreshed token back. - Add cross-process regression coverage exercising concurrent auth.json read-modify-write scenarios. - Add changeset documenting the fix and its dependency on the pi-coding-agent locked per-provider merge (>=0.80.x). Files changed: .changeset/fn-7646-auth-storage-coordination.md | 7 + .../src/__tests__/auth-storage-concurrency.test.ts | 234 +++++++++++++++++++++ packages/engine/src/auth-storage.ts | 27 +++ 3 files changed, 268 insertions(+) Fusion-Task-Id: FN-7646 Fusion-Task-Lineage: de39f08d-2d9f-46ff-b293-c603e3268ecf Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
4e8c621e9c |
FN-7641: fix cards stranded after out-of-band/workspace merges by allowing proven-merge rehome
Fixes a state-machine bug family where cards got stranded after out-of-band or workspace merges landed: store.moveTask now allows a proven-merge recoveryRehome to cross legacy columns (e.g. todo→done), and nodeId='end' finalize no longer silently no-ops — it finalizes on durable merge proof or returns an explicit error, consistently across the dashboard route, the CLI task-update tool, and store.updateTask. - packages/core/src/store.ts: allow proven-merge recoveryRehome moves across legacy columns (e.g. todo→done) instead of rejecting them - packages/core/src/node-override-guard.ts: nodeId='end' finalize now checks for durable merge proof and returns an explicit error instead of silently no-op'ing - packages/dashboard/src/routes/register-task-workflow-routes.ts: dashboard workflow route surfaces the new explicit finalize error/behavior - packages/cli/src/extension.ts: CLI task-update tool surfaces the same explicit finalize error/behavior - docs/task-management.md: documented the updated finalize/rehome behavior - Added regression tests across core (node-override-guard, store-movement, task-node-override), dashboard (register-task-workflow-routes.nodeid-finalize), engine (merger-merge-lifecycle), and CLI (extension) covering the stranded-card invariant - Added changeset for @runfusion/fusion (patch) Files changed: .changeset/fn-7641-stranded-cards-after-merge.md | 7 ++ docs/task-management.md | 2 + packages/cli/src/__tests__/extension.test.ts | 59 ++++++++++++++ packages/cli/src/extension.ts | 10 +++ .../core/src/__tests__/node-override-guard.test.ts | 93 +++++++++++++++++++++ packages/core/src/__tests__/store-movement.test.ts | 94 ++++++++++++++++++++++ .../core/src/__tests__/task-node-override.test.ts | 73 +++++++++++++++++ packages/core/src/node-override-guard.ts | 69 +++++++++++++++- packages/core/src/store.ts | 69 +++++++++++++++- ...er-task-workflow-routes.nodeid-finalize.test.ts | 90 +++++++++++++++++++++ .../src/routes/register-task-workflow-routes.ts | 10 +++ .../src/__tests__/merger-merge-lifecycle.test.ts | 58 +++++++++++++ 12 files changed, 631 insertions(+), 3 deletions(-) Fusion-Task-Id: FN-7641 Fusion-Task-Lineage: 48ea7851-ee68-48f1-92f9-302d0da5acff Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
923bba7082 |
FN-7645: force re-arm zombie heartbeat timers detected as stale during audit
Fixes the heartbeat timer audit so it repairs not just missing timer registrations but also 'zombie' ones — timer entries that remain present in memory after their underlying interval silently stopped firing. Long-interval (~1h) agents were most affected since a single lost tick compounded into hours of staleness before self-healing noticed. - HeartbeatTriggerScheduler audit now computes staleness (elapsed vs repair-stale threshold) up front for every timer-eligible agent, not only for agents missing a timer entry - Present-but-stale timer entries are now treated as non-advancing and force cleared/re-registered via registerAgent() (which already clears any existing timer before re-arming) - Fresh (non-stale) present timers are left alone so healthy short-interval agents are never force-re-armed or double-ticked - Repair reason/log messages now distinguish zombie-timer-rearmed repairs from missing-registration repairs, and the summary log reports counts for each - Added heartbeat-scheduler tests covering the zombie-timer repair path - Added changeset and a docs/architecture.md note Files changed: .changeset/fn-7645-heartbeat-rearm.md | 7 + docs/architecture.md | 1 + .../src/__tests__/heartbeat-scheduler.test.ts | 223 +++++++++++++++++++++ packages/engine/src/agent-heartbeat.ts | 42 +++- 4 files changed, 266 insertions(+), 7 deletions(-) Fusion-Task-Id: FN-7645 Fusion-Task-Lineage: 652bc2eb-a660-4306-9f85-d2d5f9ca7e38 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
f1db31374a |
FN-7642: emit diagnostic output for dispatch/infra failures in optional-group and CE gate nodes
Fixes the code-review/plan-review/CE gate workflow node failing with a blank "(no feedback captured)" message when a dispatch or infra exception (not a reviewer verdict) causes the step to fail. - WorkflowGraphExecutor now synthesizes a non-blank WorkflowStepResult.output when an enabled optional-group (code-review, plan-review, browser-verification) or CE source:"node" skill-gate template node fails via dispatch/infra exception - Diagnostic output is derived from the node:<id>:error context-patch key, falling back to the failure value, then a stable sentinel - status, verdict extraction, edge routing, and self-healing's latestFailedPreMergeStep selection are unchanged - Added regression test coverage: workflow-graph-optional-group-no-feedback.test.ts - Added changeset (patch) documenting the fix for Runfusion/Fusion#1946 Files changed: .changeset/fn-7642-code-review-no-feedback-diagnostic.md | 7 + packages/engine/src/__tests__/workflow-graph-optional-group-no-feedback.test.ts | 246 +++++++++++++++++++++ packages/engine/src/workflow-graph-executor.ts | 104 ++++++++- 3 files changed, 355 insertions(+), 2 deletions(-) Fusion-Task-Id: FN-7642 Fusion-Task-Lineage: 1329e907-652f-4230-a945-5a9d7040ae69 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
6777eea5d2 |
FN-7631: add content search to Chat sidebar with title-only toggle
Chat sidebar search now matches message content by default, not just the conversation title/agent, with an opt-out toggle to restore title-only filtering. - Add ChatStore.searchSessionsByMessageContent (parameterized LIKE ... ESCAPE) for server-side content search across sessions - GET /chat/sessions route (register-chat-routes.ts, legacy.ts) gains q/titleOnly query params, debounced server-side content lookup merged with local title/agent matches - useChat hook exposes searchInTitleOnly state and wires debounced content search into session list results - ChatView renders a "Search in title only" toggle beside the search box (desktop + mobile) and shows a "Matched: ..." preview snippet on content-matched rows - Task-planner sessions remain excluded from content matches via the same common-feed visibility guard used for the normal session list - Add unit/integration tests: chat-store content-search, chat-routes API test, ChatView content-search test - Update docs/dashboard-guide.md to document the new content search behavior and toggle - Add changeset fn-7631-chat-content-search.md (@runfusion/fusion minor) Files changed: .changeset/fn-7631-chat-content-search.md | 7 + docs/dashboard-guide.md | 2 + .../__tests__/chat-store.content-search.test.ts | 157 +++++++++++++++++++++ packages/core/src/chat-store.ts | 64 +++++++++ packages/core/src/chat-types.ts | 8 ++ packages/dashboard/app/api/legacy.ts | 23 ++- packages/dashboard/app/components/ChatView.css | 30 ++++ packages/dashboard/app/components/ChatView.tsx | 26 ++++ .../__tests__/ChatView.autosize.test.tsx | 2 + .../__tests__/ChatView.content-search.test.tsx | 114 +++++++++++++++ .../components/__tests__/ChatView.draft.test.tsx | 2 + .../__tests__/ChatView.hash-mention.test.tsx | 2 + .../__tests__/ChatView.mobile-render.test.tsx | 2 + .../components/__tests__/ChatView.rooms.test.tsx | 2 + .../__tests__/ChatView.scroll-to-top.test.tsx | 2 + .../components/__tests__/ChatView.test-harness.tsx | 2 + packages/dashboard/app/hooks/useChat.ts | 105 ++++++++++++-- .../dashboard/src/__tests__/chat-routes.test.ts | 78 ++++++++++ .../dashboard/src/routes/register-chat-routes.ts | 39 ++++- 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 + 25 files changed, 667 insertions(+), 12 deletions(-) Fusion-Task-Id: FN-7631 Fusion-Task-Lineage: bc68b489-26a7-453e-901b-bda816af364e Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
1b7bb1fe18 |
FN-7639: wire message editing into Planner Chat
Adds the ability to edit and resend a prior user message in task-detail Planner Chat, discarding subsequent turns without reverting already-applied steering/refinement side effects. - Wire FN-7628's editChatMessage + rewindSessionForEdit into TaskPlannerChatTab for synthetic task-planner:<id> sessions - Add edit affordance/UI flow and message resend handling in TaskPlannerChatTab - Ensure already-applied steering comments and refinement tasks are not reverted when a turn is discarded - Expand TaskPlannerChatTab test coverage for edit/resend flows - Update dashboard guide docs to describe the new Planner Chat edit behavior - Add changeset for @runfusion/fusion (minor) Files changed: .changeset/fn-7639-planner-chat-edit.md | 7 + docs/dashboard-guide.md | 4 +- .../app/components/TaskPlannerChatTab.tsx | 90 +++++++- .../__tests__/TaskPlannerChatTab.test.tsx | 242 ++++++++++++++++++++- 4 files changed, 328 insertions(+), 15 deletions(-) Fusion-Task-Id: FN-7639 Fusion-Task-Lineage: ed568a81-12fa-42a8-9ecf-29e6c9a2a884 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
26f22861fa |
FN-7637: port bundled-plugin auto-install into @fusion/core for the desktop runtime
Move the host-agnostic bundled-plugin auto-install logic (manifest loading, entry-path resolution, install/update/enable flow) out of the CLI package into @fusion/core so the desktop embedded runtime can auto-install bundled runtime plugins without depending on the CLI package; the CLI module becomes a thin adapter that supplies its own bundle-dir resolution to the shared helper. - Add packages/core/src/plugins/bundled-plugin-install.ts with the shared, host-agnostic ensureBundledPluginInstalled / ensureBundledDependencyGraphPluginInstalled / ensureBundledCursorRuntimePluginInstalled implementation and BUNDLED_PLUGIN_IDS/ isBundledPluginId/resolvePluginEntryPath, exported from @fusion/core's index. - Slim packages/cli/src/plugins/bundled-plugin-install.ts to a CLI-specific candidate-bundle-dir resolver that delegates to @fusion/core and re-exports the same public surface dashboard.ts/serve.ts/daemon.ts already depend on. - Remove the now-redundant packages/cli/src/plugins/__tests__/resolve-plugin-entry-path-sync.test.ts (coverage moved with the implementation to @fusion/core). - Add packages/desktop/src/bundled-plugin-dirs.ts to resolve each bundled plugin's staged package directory via import.meta.resolve, mirroring the CLI's dist/plugins/<id> resolver. - Wire local-runtime.ts and local-server.ts to call ensureBundledPluginInstalled before loadAllPlugins() and expose a lazy-install callback for PUT /api/plugins/:id/settings, mirroring the CLI dashboard command's startup auto-install pass. - Update docs/PLUGIN_AUTHORING.md to describe the shared bundled-plugin-install location. Files changed: docs/PLUGIN_AUTHORING.md | 11 + .../__tests__/bundled-plugin-install.test.ts | 619 ++------------------- .../resolve-plugin-entry-path-sync.test.ts | 97 ---- packages/cli/src/plugins/bundled-plugin-install.ts | 250 +-------- packages/core/src/index.ts | 8 + .../__tests__/bundled-plugin-install.test.ts | 391 +++++++++++++ .../core/src/plugins/bundled-plugin-install.ts | 186 +++++++ .../src/__tests__/bundled-plugin-dirs.test.ts | 59 ++ .../desktop/src/__tests__/local-runtime.test.ts | 183 +++++- .../desktop/src/__tests__/local-server.test.ts | 96 +++- packages/desktop/src/bundled-plugin-dirs.ts | 61 ++ packages/desktop/src/local-runtime.ts | 66 ++- packages/desktop/src/local-server.ts | 36 +- 13 files changed, 1171 insertions(+), 892 deletions(-) Fusion-Task-Id: FN-7637 Fusion-Task-Lineage: 953c5b82-a079-4600-b3af-45c974cd5014 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
42009cfdb9 |
FN-7628: allow editing sent chat messages and rewinding agent responses
Adds the ability to edit a previously sent message in an agent chat, which rewinds the session/task room and regenerates the response from the edited message. - Add chat-store support for locating/replacing a message and truncating subsequent history for a rewind - Add a chat-manager rewind-session flow and a new register-chat-routes endpoint to rewind a room to an edited message - Add legacy API route wiring and useChat hook support for issuing an edit request - Add ChatView/StandardChatSurface/TaskPlannerChatTab UI affordances (edit control, styling) to trigger message edits - Add a changeset documenting the new chat message-edit capability - Add unit/integration tests covering chat-store rewind logic, chat-manager rewind-session behavior, chat routes, useChat, and ChatView edit UI Files changed: .changeset/fn-7628-chat-message-edit.md | 7 + docs/dashboard-guide.md | 4 + packages/core/src/__tests__/chat-store.test.ts | 171 ++++++++++++++ packages/core/src/chat-store.ts | 95 ++++++++ packages/dashboard/app/api/legacy.ts | 22 ++ packages/dashboard/app/components/ChatView.css | 78 ++++++ packages/dashboard/app/components/ChatView.tsx | 14 ++ .../app/components/StandardChatSurface.tsx | 87 ++++++- .../app/components/TaskPlannerChatTab.tsx | 8 + .../__tests__/ChatView.autosize.test.tsx | 1 + .../__tests__/ChatView.default-model-icon.test.tsx | 1 + .../components/__tests__/ChatView.draft.test.tsx | 1 + .../__tests__/ChatView.hash-mention.test.tsx | 1 + .../__tests__/ChatView.message-edit.test.tsx | 262 +++++++++++++++++++++ .../__tests__/ChatView.mobile-render.test.tsx | 1 + .../components/__tests__/ChatView.rooms.test.tsx | 1 + .../__tests__/ChatView.scroll-to-top.test.tsx | 1 + .../components/__tests__/ChatView.test-harness.tsx | 1 + .../dashboard/app/hooks/__tests__/useChat.test.ts | 98 ++++++++ packages/dashboard/app/hooks/useChat.ts | 60 +++++ .../__tests__/chat-manager-rewind-session.test.ts | 185 +++++++++++++++ .../dashboard/src/__tests__/chat-manager.test.ts | 12 + .../dashboard/src/__tests__/chat-routes.test.ts | 124 ++++++++++ packages/dashboard/src/chat.ts | 147 +++++++++++- .../dashboard/src/routes/register-chat-routes.ts | 52 ++++ 25 files changed, 1429 insertions(+), 5 deletions(-) Fusion-Task-Id: FN-7628 Fusion-Task-Lineage: 36d98989-1b75-428c-baf1-b2c7e8e78013 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
5b243f1223 |
FN-7636: surface Hermes runtime models in /api/models picker
Adds a short-TTL, single-flight Hermes model cache and merges Hermes profile-list models additively into the dashboard's /api/models endpoint under the hermes provider, without displacing existing entries. - Add packages/dashboard/src/hermes-model-cache.ts: single-flight, short-TTL cache wrapping `hermes profile list` CLI output (no per-request spawn) - Merge Hermes-provided models into register-model-routes.ts's /api/models response, deduped by provider/id, additive-only - Add unit tests for the Hermes model cache and the /api/models route's Hermes merge behavior - Document the new behavior in docs/settings-reference.md - Add changeset (@runfusion/fusion: minor) describing the feature for release notes Files changed: .changeset/fn-7636-hermes-picker-models.md | 7 + docs/settings-reference.md | 2 + packages/dashboard/src/__tests__/hermes-model-cache.test.ts | 158 +++++++++++++++++ packages/dashboard/src/__tests__/register-model-routes-hermes.test.ts | 186 +++++++++++++++++++++ packages/dashboard/src/hermes-model-cache.ts | 168 +++++++++++++++++++ packages/dashboard/src/routes/register-model-routes.ts | 33 ++++ 6 files changed, 554 insertions(+) Fusion-Task-Id: FN-7636 Fusion-Task-Lineage: c5ab3bba-37e4-416b-9325-667a8ef321dc Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
51e389199a |
FN-7634: widen Planner Chat stop button to match send button
Fix the Planner Chat composer's streaming Stop button rendering narrower than the idle Send button by giving both variants a shared width floor. - Declare a locally-scoped --chat-input-control-size on .task-planner-chat-composer (same formula as ChatView.css's .chat-input-row so the shared .chat-input-send/.chat-input-stop classes no longer read an undefined custom property and fall back to width: auto. - Add a min-inline-size floor bound to that property on .task-planner-chat-send (present on both send and stop variants) so neither button renders narrower than the other on desktop. - Add a regression test asserting the desktop control-size floor, the pre-existing mobile square sizing, and the FN-7594 stop-icon visibility contract. - Add a changeset documenting the fix as a patch release. Files changed: .changeset/fn-7634-planner-stop-button-width.md | 7 +++++ .../app/components/TaskPlannerChatTab.css | 8 ++++++ .../__tests__/TaskPlannerChatTab.test.tsx | 33 ++++++++++++++++++++++ 3 files changed, 48 insertions(+) EOF ) Fusion-Task-Id: FN-7634 Fusion-Task-Lineage: e73c836f-3c2d-4871-ac93-fdf5e52de5f6 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
413ef1dfa2 |
FN-7633: pin equal explicit heights for Priority, Execution-mode, and Oversight controls
Align the Priority chip, Execution-mode toggle, and Oversight dropdown trigger to the exact same box height in the task detail metadata cluster, closing a gap where a shared min-height floor still let controls diverge. - Add explicit `height: var(--detail-priority-control-min-height)` to `.detail-priority-chip`, `.detail-execution-mode-toggle`, and `.detail-oversight-menu-trigger` alongside the existing `min-height`, so none can outgrow or undershoot the others regardless of flex stretch/content differences - Keep `min-height` as a safety-net floor for edge cases like font scaling - Add regression test asserting all three controls share the same fixed height token on desktop and mobile, and that the Oversight popover itself remains unaffected - Add changeset documenting the fix as a patch-level bug fix Files changed: .../fn-7633-priority-execution-oversight-height.md | 7 ++++ .../dashboard/app/components/TaskDetailModal.css | 44 ++++++++++++++++--- ...etailModal.responsive-and-dependencies.test.tsx | 49 ++++++++++++++++++++++ 3 files changed, 95 insertions(+), 5 deletions(-) Fusion-Task-Id: FN-7633 Fusion-Task-Lineage: 7a89743e-117f-4032-9614-a9a15f2a9b08 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
d54ab80395 |
FN-7623: wire pluginStore/pluginLoader into desktop embedded dashboard server
Fixes the desktop app's plugin subsystem, which was never wired into createServer(), breaking Settings > Plugins Browse registry and plugin install. - local-runtime.ts: construct a PluginStore + PluginLoader (mirroring the CLI dashboard command), load enabled plugins, run plugin schema-init hooks, and pass pluginStore/pluginLoader/pluginRunner into createServer() - local-server.ts: apply the same wiring to the legacy desktop local server path for consistency - Both paths fail soft: a broken plugin subsystem (e.g. corrupt manifest) is logged/traced but no longer blocks embedded dashboard startup - Extend local-runtime.test.ts and local-server.test.ts to cover plugin wiring and the fail-soft path - Add changeset (patch) documenting the fix Files changed: .changeset/fn-7623-desktop-plugin-wiring.md | 7 ++ .../desktop/src/__tests__/local-runtime.test.ts | 123 ++++++++++++++++++++- .../desktop/src/__tests__/local-server.test.ts | 69 +++++++++++- packages/desktop/src/local-runtime.ts | 50 ++++++++- packages/desktop/src/local-server.ts | 41 ++++++- 5 files changed, 286 insertions(+), 4 deletions(-) Fusion-Task-Id: FN-7623 Fusion-Task-Lineage: c6f291fb-e6aa-4ac1-a3f3-4189fc831c60 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
0f2bfa546c |
FN-7629: add enable/disable control for built-in runtime plugins
Adds a durable Plugin Manager toggle to enable/disable built-in runtime plugins (Hermes, Paperclip, OpenClaw, Droid) that persists across restarts, replacing the dead-end "Built-in metadata only" CTA. - renderBuiltinPluginSection now renders an enable/disable toggle for runtime built-ins regardless of installed status - Disabling a not-yet-installed built-in first installs it (mirroring CLI's ensureBundledPluginInstalled) then immediately disables it, so a plugin_installs row + disabled project state exists with no new persistence primitive needed - HermesRuntimeCard/OpenClawRuntimeCard/PaperclipRuntimeCard now show "Disabled in Plugin Manager" instead of a stale detected/connected status when disabled - Added i18n strings across all locales and updated docs - Added changeset for @runfusion/fusion (minor) - Expanded plugin-loader and PluginManager test coverage for the new disable/enable flows Files changed: .changeset/fn-7629-builtin-runtime-disable.md | 7 + docs/dashboard-guide.md | 1 + docs/plugin-management.md | 4 + packages/core/src/__tests__/plugin-loader.test.ts | 46 ++++++ .../dashboard/app/components/HermesRuntimeCard.tsx | 40 ++++- .../app/components/OpenClawRuntimeCard.tsx | 32 +++- .../app/components/PaperclipRuntimeCard.tsx | 32 +++- .../dashboard/app/components/PluginManager.css | 34 +++++ .../dashboard/app/components/PluginManager.tsx | 167 +++++++++++++++------ .../components/__tests__/PluginManager.test.tsx | 12 +- .../__tests__/PluginManager.toggle.test.tsx | 104 ++++++++++++- packages/i18n/locales/en/app.json | 4 + packages/i18n/locales/es/app.json | 4 + packages/i18n/locales/fr/app.json | 4 + packages/i18n/locales/ko/app.json | 4 + packages/i18n/locales/zh-CN/app.json | 4 + packages/i18n/locales/zh-TW/app.json | 4 + packages/i18n/src/resources.d.ts | 4 + 18 files changed, 440 insertions(+), 67 deletions(-) Fusion-Task-Id: FN-7629 Fusion-Task-Lineage: 2a25bb1f-3f73-4273-8769-af05c61778f9 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
a6c60e1592 |
FN-7625: make auth provider list a static catalog, not runtime-derived
Authentication settings previously enumerated providers straight from pi AuthStorage's live runtime registry, so connecting a runtime plugin (e.g. Hermes Runtime) could narrow/collapse the visible provider list. This adds a static, hand-maintained supported-provider catalog and unions it with storage-reported providers so presence in the list is deterministic while status stays live. - Add packages/dashboard/src/routes/auth-provider-catalog.ts with STATIC_OAUTH_PROVIDER_CATALOG, STATIC_API_KEY_PROVIDER_CATALOG, and unionProviderCatalog() (catalog always wins on presence; runtime-only extras still surface; runtime name wins on name conflicts). - Update register-auth-routes.ts's GET /api/auth/status to union the static catalogs with storage.getOAuthProviders()/getApiKeyProviders() instead of relying solely on runtime-reported providers. - Extend routes-auth.test.ts coverage for the new catalog-union behavior (provider presence stable across narrowed runtime registries, extras preserved, name precedence). - Add changeset fn-7625-static-auth-provider-catalog.md (patch, fix). Files changed: .changeset/fn-7625-static-auth-provider-catalog.md | 7 + .../dashboard/src/__tests__/routes-auth.test.ts | 180 +++++++++++++++++++-- .../dashboard/src/routes/auth-provider-catalog.ts | 93 +++++++++++ .../dashboard/src/routes/register-auth-routes.ts | 25 ++- 4 files changed, 291 insertions(+), 14 deletions(-) Fusion-Task-Id: FN-7625 Fusion-Task-Lineage: be984497-b881-4a8f-9860-544617e2b5f7 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
6bf0090a47 |
FN-7630: harden Hermes Runtime as additive-only to provider/model/auth catalogs
Confirms and locks in that the Hermes Runtime plugin cannot suppress independently-configured custom providers, models, or auth options, closing out GitHub #1931's remaining audit items. - Add FNXC documentation comments to register-model-routes.ts and the Hermes Runtime plugin explaining why the plugin structurally cannot mutate AuthStorage/ModelRegistry (no reference in PluginContext) and why configuredProviders only ever grows. - Add regression coverage proving a connected Hermes runtime never narrows the model picker (/api/models), custom-provider CRUD routes, or auth-status surfaces. - Add changeset documenting the fix and remaining follow-up items (FN-7625, FN-7636). Files changed: .changeset/fn-7630-hermes-runtime-additive.md | 7 + .../register-auth-routes-hermes-additive.test.ts | 108 ++++++++++ .../register-model-routes-hermes-additive.test.ts | 152 +++++++++++++ .../custom-provider-routes-hermes-additive.test.ts | 236 +++++++++++++++++++++ .../dashboard/src/routes/register-model-routes.ts | 12 ++ plugins/fusion-plugin-hermes-runtime/src/index.ts | 12 ++ 6 files changed, 527 insertions(+) Fusion-Task-Id: FN-7630 Fusion-Task-Lineage: 651cb242-cabf-487b-bf19-21c51b2e91d3 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
fe5a595984 |
FN-7622: unify desktop and CLI provider seeding to fix truncated provider list
The Electron desktop app's in-process dashboard server skipped the CLI's provider seeding sequence, so /api/providers and /api/models returned a truncated catalog (missing built-in API-key providers and user customProviders[]) compared to the identical config on the web build. - Move provider-auth.ts and custom-provider-registry.ts from @fusion/cli into @fusion/engine as the single shared implementation - Add engine/src/provider-registration.ts exposing seedDashboardProviders(), mirroring the CLI's exact startup order (built-in Zai provider registration -> wrapAuthStorageWithApiKeyProviders -> model merge/refresh -> registerCustomProviders -> settings:updated resubscription) - Update desktop/src/local-runtime.ts and local-server.ts to call the shared seedDashboardProviders() helper instead of constructing a raw authStorage/modelRegistry - Convert packages/cli/src/commands/provider-auth.ts and custom-provider-registry.ts into re-export shims preserving unchanged observable behavior - Add engine/src/__tests__/provider-registration.test.ts and expand desktop local-runtime/local-server tests to cover the shared seeding path - Add changeset for @runfusion/fusion (patch) Files changed: .changeset/fn-7622-desktop-provider-parity.md | 7 + .../cli/src/commands/custom-provider-registry.ts | 122 +---- packages/cli/src/commands/provider-auth.ts | 517 +-------------------- .../desktop/src/__tests__/local-runtime.test.ts | 93 ++++ .../desktop/src/__tests__/local-server.test.ts | 62 ++- packages/desktop/src/local-runtime.ts | 33 +- packages/desktop/src/local-server.ts | 21 +- .../src/__tests__/provider-registration.test.ts | 192 ++++++++ packages/engine/src/custom-provider-registry.ts | 117 +++++ packages/engine/src/index.ts | 18 + packages/engine/src/provider-auth.ts | 513 ++++++++++++++++++++ packages/engine/src/provider-registration.ts | 105 +++++ 12 files changed, 1172 insertions(+), 628 deletions(-) Fusion-Task-Id: FN-7622 Fusion-Task-Lineage: fb6fbbf3-745e-4623-b7af-11471e13f138 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
a4f5fbc0e9 |
FN-7624: fix onboarding GitHub sign-in erroring with model-not-found
Fixes the onboarding/settings GitHub step so it never offers a dashboard OAuth login for github (no github OAuth provider is ever registered; pi only ships anthropic/github-copilot/openai-codex), replacing the broken Connect OAuth button with gh CLI guidance and a clearer server-side error.
- Remove the "Connect OAuth (optional)" button and its login-instructions panel from the onboarding branch that runs when hasGithubProvider is false (ModelOnboardingModal.tsx), since it always called handleLogin("github") against a non-existent provider
- Update ModelOnboardingModal tests to cover the new gh-CLI-only flow
- Make POST /api/auth/login return a clear, actionable 400 naming the requested provider, the registered dashboard OAuth providers, and that GitHub integration uses gh CLI/token auth instead of a generic "Unknown provider" / model-not-found error
- Add routes-auth.test.ts coverage for the improved unknown-provider error message
- Add a patch changeset documenting the fix
Files changed:
.changeset/fn-7624-github-onboarding-auth.md | 7 +++++
packages/dashboard/app/components/ModelOnboardingModal.tsx | 32 +++++++---------------
packages/dashboard/app/components/__tests__/ModelOnboardingModal.test.tsx | 32 +++++++++++++++++++++-
packages/dashboard/src/__tests__/routes-auth.test.ts | 22 +++++++++++++++
packages/dashboard/src/routes/register-auth-routes.ts | 14 +++++++++-
5 files changed, 83 insertions(+), 24 deletions(-)
Fusion-Task-Id: FN-7624
Fusion-Task-Lineage: e7be1b0a-6e50-479d-b56e-1284e8a94b7f
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
|
||
|
|
ebf8f87fdb |
FN-7627: add mobile close button to embedded Settings screen
Adds a close affordance to the embedded Settings header on mobile, since only a bottom nav bar (no sidebar) is available to exit there. - Render a mobile-only `modal-close` button in the embedded Settings header when `isEmbedded && viewportMode === "mobile"`, wired to the existing `onClose` prop. - Leave desktop/tablet embedded and the standalone modal presentation unchanged. - Add regression tests covering the new mobile close button. - Add a patch changeset documenting the fix. Files changed: .changeset/fn-7627-mobile-settings-close.md | 7 ++ .../dashboard/app/components/SettingsModal.css | 16 +++ .../dashboard/app/components/SettingsModal.tsx | 17 +++ .../__tests__/SettingsModal.mobileClose.test.tsx | 125 +++++++++++++++++++++ 4 files changed, 165 insertions(+) Fusion-Task-Id: FN-7627 Fusion-Task-Lineage: b39c7172-bce3-4fb2-9095-58ae376c43ef Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
ca7c987ab5 |
FN-7621: fix mobile terminal shortcut bar horizontal scroll defeated by ancestor touch-action lock
Root-caused and fixed the third recurrence of the mobile terminal shortcut bar not scrolling horizontally: styles.css's mobile lockdown resets touch-action to pan-y across ancestors, and touch-action's used value is the intersection of the touched element's and every ancestor's value, so the leaf .terminal-shortcut-panel's pan-x was silently defeated even though it was already correct. - Opt the terminal overlay and modal ancestors (.modal-overlay.terminal-modal-overlay, .modal.terminal-modal--mobile, plain-media-query mobile modal, and the shortcut/status footer) into touch-action: pan-x pan-y so descendant leaf touch-action values can take effect - Add FNXC:Terminal comments documenting the ancestor-intersection root cause and recurrence history (FN-7550/FN-7560) - Add a documented solution note under docs/solutions/ui-bugs/ for the ancestor-intersection touch-action pattern - Add regression tests asserting the modal/overlay/footer ancestors carry the pan-x pan-y opt-in - Add a changeset for the fix Files changed: .../fn-7621-mobile-terminal-shortcut-scroll.md | 7 ++ ...on-ancestor-intersection-defeats-leaf-scroll.md | 57 +++++++++++ .../dashboard/app/components/TerminalModal.css | 38 ++++++++ .../components/__tests__/TerminalModal.test.tsx | 106 +++++++++++++++++++++ 4 files changed, 208 insertions(+) Fusion-Task-Id: FN-7621 Fusion-Task-Lineage: 771fd79e-e193-43b0-908b-0e8fe2fc2c70 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
8d73b18c35 |
FN-7620: fix mobile terminal rendering blank via ResizeObserver recovery
Fixes the mobile dashboard terminal sometimes rendering completely blank on open by having TerminalModal recover from a zero/collapsed container box. - TerminalModal now attaches a persistent ResizeObserver directly on the xterm container, mirroring SessionTerminal's existing pattern - When the container reports a zero/collapsed box on the first post-open fit, it now re-fits once the real box settles instead of staying stuck at FitAddon's degenerate 2x1-cell floor - Added regression tests covering TerminalModal and SessionTerminal zero-geometry recovery - Documented the root cause and fix in docs/solutions/ui-bugs/mobile-terminal-blank-render-zero-geometry-container.md - Added a patch changeset for @runfusion/fusion Files changed: .changeset/fn-7620-mobile-terminal-blank-render.md | 7 + docs/solutions/ui-bugs/mobile-terminal-blank-render-zero-geometry-container.md | 112 +++++++ packages/dashboard/app/components/TerminalModal.tsx | 49 +++ packages/dashboard/app/components/__tests__/SessionTerminal.test.tsx | 66 ++++ packages/dashboard/app/components/__tests__/TerminalModal.test.tsx | 358 +++++++++++++++++++++ 5 files changed, 592 insertions(+) Fusion-Task-Id: FN-7620 Fusion-Task-Lineage: 103f5b17-9a6e-4e9a-ab61-65ccb2203a8d Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
1add12d703 |
fix: resolve full-suite CI failures across engine + dashboard (shards 1-4) (#1947)
## Summary Fixes the failing **full-suite** CI run on `main` ([run 28874651861](https://github.com/Runfusion/Fusion/actions/runs/28874651861)) — all 4 test shards were red. ~32 test files failing across engine + dashboard (src + app), rooted in ~13 distinct causes from recent main commits. All resolved; the merge gate and full engine/dashboard suites are green locally. ## Root causes & fixes ### Engine (shards 1 & 2) - **`appendAgentLog` 6th timing arg (FN-7503, `2797803c0`)** — `agent-logger.ts` now passes an optional `{durationMs,timeToFirstTokenMs}` 6th arg; many executor/heartbeat/merger tests asserted the old 5-arg form. Added a shared timing-tolerant helper `agent-log-assertions.ts` (asserts `taskId/text/type`, tolerant of the timing object) and applied it across affected files — so future timing fields won't re-break every executor test. - **`reconcileSupersededGeneratedFixFeatures` (mission)** — `mission-execution-loop.ts` calls a method the test's missionStore mock lacked; added a no-op stub (the real `MissionStore` already implements it). - **`ModelFallbackExhaustedError` / `proseSignalsClearApproval` / `extractJsonObjectCandidates` missing from `vi.mock`** — converted stale hand-written mocks (`../pi.js`, `../reviewer.js` in `executor-test-helpers.ts`) to `importOriginal`-spread so real exports carry through. - **Workspace product fixes (2):** - `merger-ai.ts` — `landWorkspaceTask` now recovers the integration-tip sha as `landedSha` when the A1 trailer-fallback proved a sub-repo landed but its sha was never persisted, so `finalizeWorkspaceTask` can build merge proof (was stranding partial-land retries in-review). - `worktree-acquisition.ts` — `acquireWorkspaceRepoWorktree` strips the shared project `integrationBranch/baseBranch` overrides before forwarding to `acquireTaskWorktree` (FN-7360's `freshStartPoint` was resolving an absent shared branch). - **FN-7360 extra `git symbolic-ref` exec** — updated worktree exec-count assertions for the new `resolveIntegrationBranch` call. - **Planner-overseer / stepwise-workflow / workflow-graph / workflow-prompt / executor-step-session / liveness-gate / checkout / ce-workflow / triage-split** — test-alignments for intentional behavior changes (FN-7229 retry-cap, FN-7265 review-node removal, FN-7335 pause-abort logging, FN-7577 recovery-budget, FN-7577 overseer denial loop, specifyTask single promptWithFallback call, FN-4944 already-on-main noop log, FN-7486 ownership short-circuit). ### Dashboard API (shard 3) - **`store.on('task:moved')` (FN-7337)** — `createServer` now registers the listener; backed the 4 affected MockStores with EventEmitter (shared root cause across chat-routes.rooms, register-git-github, routes-run-cited-goals, routes-sandbox-audit). - **`routes-agent-import`** — core mock converted to `importOriginal`-spread (was missing FN-7444 planning-deepening constants). - **`session-resume-history`** — engine mock missing `resolveMcpServersForStore`. - **`task-create-workflow-route`** — `builtin:legacy-coding` defaultSteps now include `plan-review` (FN-7224/7226). - **GitLab parity** — added the missing `[GitLab Parity Inventory]` cross-link in `docs/signals-connectors.md`. ### Dashboard app (shard 4) - Test-alignments for intentional product changes: FN-7057 (workflow selection preservation), FN-7340 (footer concurrency geometry), FN-7156 (Missions overview default), FN-7342/FN-6825 (board scroll + workflow switcher), FN-7352 (openDetailTask 3rd arg), FN-7261 (backdrop dismiss default-off), FN-7234 (non-authoritative fetch failures), plus a missing `fetchWorkflowOptionalSteps` mock. ### MCP coverage - `mcp-surface-coverage` forwarding needle updated for FN-7446's `resolvePlanningMcpServers` helper. ## Approach notes - Each fix is the **minimal** change at the correct source (test-update where a recent commit intentionally changed behavior; product-fix for the 2 real regressions). No assertion was loosened/deleted to force a pass; no timeout appeasement. - Coordination: work was partitioned by package across parallel subagents (engine / dashboard-src / dashboard-app) with Main as the sole git committer (path-scoped commits) after an early shared-index reset wiped in-progress edits — process was tightened mid-flight. ## Verification - **Full engine suite**: green (9231 passed; the lone local-only `custom-providers-openai-completions` import error is stale local `pi-ai@0.79.9` vs the lockfile's `0.80.3` — CI's fresh install resolves `/compat`; it passed in the original CI run). - **Dashboard API** (`dashboard-api-quality-backfill`): 242 files / 3185 tests / 0 failures. - **Dashboard app** (`dashboard-app-quality-backfill`): all targeted files green (37 + 95 tests). - **Merge gate** (`pnpm test:gate`): engine-core 326 + ci-shape 63, plus nohup/4040/appeasement/changeset-format checks — all pass. - 2 changesets added for the published-`@runfusion/fusion` behavior fixes (workspace landedSha, sub-repo worktree branch-strip). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved reliability for partial workspace land retries by recovering the exact proven landed commit so durable merge proofs can complete. * Fixed per-sub-repo worktree creation by removing invalid branch override settings, preventing worktree-add failures. * Dashboard stability updates: preserve mobile board scroll during stabilization/restore, correct task filtering when workflows are missing, ensure the Chat tab appears for done tasks, and refine modal-dismiss and responsive popover behavior. * **Documentation** * Expanded the GitLab connector section with GitLab parity context and a GitLab Parity Inventory reference. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |