b85a5d4531df8fa749d77bf85ea4ab9ab960ce86
2646 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b85a5d4531 |
fix(core): bound compound engineering review remediation (#2532)
## Summary - cap Compound Engineering Code Review remediation at two Execute→Review repair passes - enable no-progress detection for the built-in CE workflow - preserve explicit project/workflow overrides while making the authored CE default visible in settings and docs - update stale IR/changeset language that still described Code Review as unbounded when unset ## Why The previous CE default was effectively unbounded. A reviewer that repeatedly returned `REVISE` could consume thousands of remediation cycles without terminally parking the task. The built-in workflow should fail closed after a small, explicit budget while still allowing operators to author a different numeric cap. ## Verification - `FUSION_PG_TEST_SKIP=1 corepack pnpm@10.33.0 --filter @fusion/core exec vitest run src/__tests__/builtin-workflows.test.ts` — 46 passed, 17 skipped - `corepack pnpm@10.33.0 --filter @fusion/core typecheck` - `corepack pnpm@10.33.0 --filter @fusion/dashboard exec vitest run app/components/__tests__/WorkflowSettingsPanel.test.tsx app/components/__tests__/workflow-setting-display.test.ts` — 33 passed - `corepack pnpm@10.33.0 --filter @fusion/dashboard typecheck` - `corepack pnpm@10.33.0 changeset status --since=origin/main` - `git diff --check origin/main...HEAD` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Improvements** - Compound Engineering Code Review now caps remediation attempts at 2; after two unsuccessful attempts, the process parks instead of retrying indefinitely. - Post-restart review recovery now completes in a single maintenance cycle to reduce delays. - Default post-review fix budget increased from 3 to 10. - Review revision limits now consistently honor workflow-authored defaults when settings are left empty, and `0` disables automatic remediation. - **Documentation** - Updated the workflow editor, settings reference, workflow steps, and operator panel text to clarify cap/default/disable semantics (including CE: 2). - **Tests** - Added/updated unit tests to validate the new bounded remediation behavior and messaging. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
99be8e6153 |
docs(U9): correct the safeguard baseline — safeguards 1 and 4 are NOT covered (#2520)
**U9, PR4.** Docs-only correction to a document already on `main` (#2511). No changeset. ## I got #2511 wrong, and it matters #2511's table claimed all six merge safeguards were verified. **Two of them were not**, and the error is the same family this program exists to stamp out: I reported the **absolute** failure count under mutation, with **no baseline**. `merge-error-recovery.test.ts` (10 failures) and `self-healing.test.ts` (1) are **already red on clean `main`**. The "11 failed" I credited to the row 1 mutation *was that pre-existing red*. The mutation added nothing. I even flagged the identical `11 failed` on rows 1 and 3 as "a red flag" in my own notes and then did not chase it. ## Re-measured as deltas Baseline fail-SET vs mutated fail-SET on the identical selection, reporting only NEW failures, each named: | # | Safeguard | Baseline | Mutated | **NEW** | Verdict | |---|---|---|---|---|---| | 1 | user pause | 11 | 11 | **0** | **NOT COVERED** | | 2 | `autoMerge:false` | 0 | 9 | **9** | covered | | 3 | dependency gating | 0 | 5 | **5** | covered | | 4 | capacity single-flight | 10 | 10 | **0** | **NOT COVERED** | | 5a | merge-proof (pre-enqueue) | 0 | 1 | **1** | covered, thin | | 5b | file-scope | 0 | 6 | **6** | covered | | 6 | at-most-once | 0 | 3 | **3** | covered | **Four hold. Two do not.** - **Safeguard 1** is the pause invariant re-ratified in #2486. Removing `task.paused || task.userPaused` from the merge admission provider admits a **user-paused card into the merge pump** — and nothing fails. - **Safeguard 4** is the single-flight guard that serializes merge. Removing it permits concurrent `drainMergeQueue` entry — and nothing fails. Both guards **work correctly today**. What is missing is any test that would notice if they stopped. That is exactly the state U9 must not convert on top of — and #2511 said the opposite. ## Also corrected: nothing here is defended by blocking CI The one gate-admitted file (`merger-merge-lifecycle.test.ts`) is not the file that proves any surviving row. Rows 2/5a/6 rest on `project-engine.test.ts`, row 3 on core's `task-merge.test.ts` — neither is in the gate (core's gate is two PG tests via `test:pg-gate`). ## Three distinct ways the first pass was wrong All recorded in the doc, because each produced a confident wrong answer: 1. **Absolute counts with no baseline** — rows 1 and 4. A mutation run must diff fail-sets and report only new failures. 2. **Too-narrow selection** — an earlier pass measured rows 1 and 3 at zero and I nearly filed two false gaps. Widening fixed row 3 but is also how the pre-existing red crept in. Both directions need the baseline diff. 3. **A harness that silently matched nothing** — the delta harness's regex required a `|project|` segment in vitest's `FAIL` line. `@fusion/core` does not emit one, so it parsed **zero** failures at both baseline and mutation and printed "NOT COVERED" for row 3, which is covered by 5 tests. A verification tool that reports success without checking anything is worse than no tool; it must be tested against a known-failing case first. The harness now aborts on a no-op patch, asserts a clean restore, and I validated its parser against a known-failing run before trusting it. ## Next **PR5 writes the missing tests for safeguards 1 and 4**, then gate admission. Neither should wait for U8 — they guard code that exists today, and the conversion needs them in place first. That is the reversible call I'm making rather than asking. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
aeef592187 |
docs(U9): safeguard baseline — six merge safeguards verified by mutation (#2511)
**U9, PR3.** Docs-only, one new file, zero production changes. No changeset (internal docs). Independent of #2504. This is the six-row safeguard table required as a U9 artifact — delivered **verified**, replacing the partial, unearned version I put in #2494. ## Every row proven by mutation Break the guard in production, run the cited tests, confirm red, restore. A cited test that does not fail is not evidence. | # | Safeguard | Consulted at | Result under mutation | |---|---|---|---| | 1 | user pause | `project-engine.ts:645` (merge admission filter) | **11 failed** / 1865 passed | | 2 | `autoMerge:false` | `project-engine.ts:2797` `allowsAutoMergeProcessing` | **9 failed** / 250 passed | | 3 | dependency gating | `task-merge.ts:402` unresolved-dependency reason | **5 failed** / 94 passed | | 4 | capacity | `project-engine.ts:3178` single-flight `mergeRunning` | **11 failed** / 1445 passed | | 5a | merge-proof (pre-enqueue) | `project-engine.ts:2609` `getTaskMergeBlocker` consult | **1 failed** / 272 passed | | 5b | merge-proof (file scope) | `merger-file-scope.ts:200` `FileScopeViolationError` | **6 failed** / 172 passed | | 6 | at-most-once | `project-engine.ts:2730` `mergeActive` dedupe | **3 failed** / 263 passed | **All six hold. Nothing is currently broken.** Per-row test attribution is in the doc. ## Finding 1 — one of nine safeguard test files runs in blocking CI Only `merger-merge-lifecycle.test.ts` is in the `engine-core` allow-list. The core gate is two PG tests (`test:pg-gate`) and does not include `task-merge.test.ts`. AGENTS.md: CI blocks on Lint/Typecheck/Build/Gate, and "a red non-blocking run is information, not a merge stopper." So a change breaking **user pause on merge admission, dependency gating, capacity single-flight, or the file-scope invariant** does not block a PR today — it goes red in full-suite, after the merge. Acceptable for a lane nobody is rewriting. Wrong for the lane U9 rewrites next. **Recommendation: admit the highest-value safeguard tests to the gate before conversion begins, with the budget cost measured** — engine-core is 5.36s against a ~60s ceiling, so there is room, but I won't assume it. Proposed as PR4. ## Finding 2 — safeguard 5a rests on a single non-gate test Removing the pre-enqueue merge-blocker consult fails exactly one test. Thinnest of the six, on a destructive-risk gate. Its sibling 5b is well covered (6 tests), so the invariant isn't unguarded — but the consult that keeps a blocked task out of the queue very nearly is. ## Methodology note, because it cost an hour **Rows 1 and 3 initially measured ZERO failures and looked like coverage gaps. Both were wrong** — the test selection was too narrow. Widening row 1 from three files to `project-engine|merge|concurrency|self-healing` turned 0 failures into 11. Row 3's real coverage lives in `@fusion/core`'s suite, which `pnpm --filter @fusion/engine` never runs, even though the engine config aliases `@fusion/core` to source so the mutation *was* live. I nearly reported two false gaps. Recorded as two rules: a narrow mutation run cannot prove absence of coverage, and cross-package guards need cross-package runs. ## Scope New file only — deliberately **no** edit to `docs/workflow-policy-ownership-map.md`, because #2504 already edits that file at the same anchor and I want both PRs independently revertable. Cross-link follows once both are on main. Verified: no production diff, all mutations restored, `pnpm lint` clean. ## Not covered, stated rather than implied Reviewer-lane safeguards; FN-7720 operator bypass; FN-8492 orphaned-pending-step rewrite; branch-group promotion sequencing. Each needs its own verified row before the matching conversion. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
6ee20d9817 |
docs(U9): correct merge-stack slice statuses to measured wiring state (#2504)
**U9, PR2.** Docs-only, no changeset (AGENTS.md: internal docs). ## Why All seven slices in `docs/plans/workflow-owned-merge-stack/` were marked `draft-stack-handoff` — accurate when drafted 2026-06-09, wrong now. **A worker picking up this stack cold would have re-implemented S04, which has already landed.** I nearly did. ## Measured, against `main @ 46f35323c` | Slice | Was | Now | Evidence | |---|---|---|---| | S02 projection | draft | `landed-unwired` | `projectMergeRequestToWorkflowWorkItem` implemented, **0 production callers** | | S03 scheduler claim | draft | `landed-unwired` | `claimDueWorkflowWorkItem` implemented; its only caller is S05's processor, itself unwired | | S04 IR regions | draft | **`landed`** | `merge-gate`, `merge-retry`, `manual-merge-hold`, `merge-attempt`, `recovery-router` present in the coding IR | | S05 runtime driver | draft | `landed-unwired` | `runWorkItem` / `processDueWorkflowWorkItem` implemented, exported from `index.ts`, **0 production callers** | | S06/S07/S08 | draft | `not-started` | merge still runs through `merger.ts` + the live `ProjectEngine.mergeQueue` pump | ## The finding that changes U9's sequencing `WorkflowWorkItemKind` is `task | merge | retry | manual-hold | recovery`. The only live pump — `InProcessRuntime.drainWorkflowContinuations` — filters `kinds: ["task"]`. The generic processor that would claim the other four kinds has **no production caller**. So the entire merge-lane work-item vocabulary is dormant: **zero writers, zero readers.** **I checked whether this is a live bug and it is not.** Nothing in production writes a non-`task` kind — the only two writers (`plan-review-continuation.ts`, `workflow-column-boundary-hooks.ts`) both go through `replaceActiveTaskWorkflowContinuation`. Nothing is stranded today. I'd rather say that plainly than let a scary-sounding finding stand unqualified. But it produces a hard ordering constraint, now recorded in S07: > **S07 must not land before S03/S05 are actually driven.** S07 is the slice that starts writing `merge`-kind work items. If it lands first, those items are created and never claimed — a card that reaches the merge boundary and silently stops. This also reframes U9's job on S02/S03/S05: **wire them, don't build them.** ## Scope discipline Docs-only — `git diff --stat` is 9 files, all under `docs/`. No production code, no tests, no behavior. `pnpm lint` clean. I also fixed the three parent-plan lines asserting the slices are "all still `draft-stack-handoff`", and the four landed slices' Stack Role paragraphs that would otherwise contradict their own new Measured State block. Leaving those stale would recreate exactly the defect this PR fixes. Related: #2494 pins the S04 caveat — the IR regions are declared but their config is read by nothing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Documentation** - Updated workflow-owned merge planning documents with current implementation and wiring statuses. - Added measured wiring details showing which workflow capabilities are active, implemented but unused, or not started. - Clarified sequencing requirements to ensure merge processing is not enabled before prerequisite workflow paths are operational. - Corrected slice metadata and references to reflect the latest measured state. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
d873ee8160 |
docs: correct KTD-6 — the "flag-off" move path is live, the hooks path is dead (#2466)
Docs only. Corrects a factual error in the program plan merged in #2463, found during Phase A execution. ## What was wrong KTD-6 listed three deletions as "provably dead." Two are. The third — the flag-off inline move path in `task-store/moves.ts` — is the **live** path: - It is gated on `isWorkflowColumnsCompatibilityFlagEnabled` (`store.ts:38`), which reads the **raw** `experimentalFeatures.workflowColumns` key. - That is a *different* function from the always-true public `isWorkflowColumnsEnabled`, which is what the plan reasoned from. - No production code writes that key, so the flag reads false — the inline branch runs for essentially every project, and `default-workflow-hooks.ts` is the dead one. - `moves.ts:637` already said so: *"this 'flag-OFF' branch is the DEFAULT move path for nearly every project — the strict compat flag reads false because nothing sets it."* Deleting it would have swapped every project onto an untravelled code path and called it a cleanup. ## Changes - **KTD-6** carries the correction inline, with the two consequences that bind the rest of the program. - **U2** rescoped to the two proven-dead deletions; `moves.ts` is out of scope for it. - **New U2b** converges the two implementations with a per-behavior equivalence proof, and **blocks Phase B** — nothing downstream may assume the trait-hook path runs until it lands. - **U3's emit point must attach to the live inline path.** Wired into the dead hooks path, the event seam would never fire — and because subscribers are non-authoritative by design, *nothing would fail a test*. - Risk table gains: *a "dead" branch turns out to be live*. ## How it was caught The Phase A worker escalated instead of following the instruction, because U2 carried a delete-only Execution note: *any behavior change found while removing a branch means the branch was not dead — stop and treat it as a finding*. I verified the claim independently (flag function, absent writers, live `settings.json`, source comment) before accepting it. That note stays on every deletion unit. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Clarified terminology in the workflow lifecycle migration plan, distinguishing the live inline move path from the compat-flag behavior. * Expanded the convergence phase with explicit behavior-equivalence requirements, pinned observable expectations, and removal of compat-flag branching. * Updated the migration diagram and phase ordering to reflect the new gating structure, revised scope boundaries, and refreshed risk mitigations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
3c5d07ab01 |
docs: workflow-owned lifecycle program plan + column-placement contract (#2463)
Docs only — no code. Companion to #2462. ## `docs/solutions/architecture-patterns/workflow-node-column-placement-and-graph-entry-contract.md` Why a workflow node's `column` is a lifecycle contract rather than a display choice: it decides **who can drive the node**, **whether the card holds a WIP slot**, and **whether anything can move it onward**. Contents: - The graph **entry contract** (`resolveColumnResumeNode`, shipped in #2462) with the resume table. - The **plan-in-place chain** — triage → finalize → continuation seed → drain → resume → capacity suspend → release — annotated with the check each link performs. Notably `todo`, not `triage`: an intake column has no releaser, so a card parked there waits for a human. - Why the pre-release gate must be narrow (column match **and** enablement). - The measured failure table from three reverted placement attempts. - Why removing a column is a lifecycle-vocabulary refactor, not a workflow edit: **82 guards** that silently stop matching, **43 writes** to a column that no longer exists, **59 dashboard literals**. A guard that never fires doesn't fail a test — it disables a recovery path. ## `docs/plans/2026-07-26-001-refactor-workflow-owned-lifecycle-plan.md` The program that finishes the job, in four movements: 1. Resolve lifecycle columns from the workflow instead of ~207 string literals. 2. Move every lane — planning, execution, review, merge — behind graph nodes; lane services keep substrate only (storage, leases, timers, supervision, capacity, recovery, audit). 3. A **post-commit event seam**: transitions commit transactionally, *then* emit; subscribers react and may enqueue durable work items, but no subscriber performs a transition. Enforced by test — dropping every subscriber must change no lifecycle outcome. 4. Only then merge Todo into a single Planning column. Phased so each phase lands green independently, with the IR change deliberately **last** (KTD-7). Changing the workflow first makes the suite green over dead guards — that's how the earlier attempts hid their own breakage. The merge lane **adopts** the existing design in `docs/plans/2026-06-09-003-refactor-workflow-owned-merge-full-migration-slices-plan.md` (slices S02–S08, still `draft-stack-handoff`) rather than authoring a competing one, with a note to re-validate against current `main` since it was drafted seven weeks ago. Scale is stated honestly: ~48k lines across the four lane services, with the executor unit explicitly landing across several commits rather than one sweep. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
0e3d2a2265 |
refactor: delete meta-task auto-archive and automated recovery follow-ups (#2461)
Deletes two pieces of automated "meta" machinery that filed and garbage-collected cards restating state already on the task that failed. Net **-1015 lines**. ## Why **Automated recovery follow-ups.** `createAutomatedFollowup` and its dedup engine (289 lines of signature matching, 1h recurrence rate-limiting, 24h supersedes windows) existed to file recovery cards for verification-cap and merge-conflict give-ups. In both cases the parent is *already* parked `failed` with a descriptive `error` and a log entry carrying the failing command, branch, and output — the card was a second copy of that. **Meta-task auto-archive.** The sweeps that garbage-collected those cards were worse than redundant: the regex classifier matched ordinary feature work, and its positional fallback bound cards to unrelated tasks, so **live work could be archived**. They are removed together, because the auto-archive sweeps only existed to clean up after the follow-up engine. ## What changed ### Deleted - `packages/engine/src/verification-followup-dedup.ts` in full — `createAutomatedFollowup`, `decideAutomatedFollowup`, `AutomatedFollowupKind`, `computeVerificationFailureSignature`, `extractFailingTestFiles`. - `findActiveRecoveryFollowUp` — dead code, defined and never called (`tsc` independently flagged it `6133 declared but its value is never read`). - The meta-task auto-archive sweeps `autoArchiveResolvedMetaTasks` / `autoArchiveStalledMetaTasks` and helpers `classifyMetaTask` / `resolveMetaTargetTaskId` / `computeMetaChainDepth` / `archiveMetaTask` / `evaluateMetaAutoArchiveGuards`, plus settings `metaTaskStallAutoCloseMs` and `metaTaskActiveExecutionGraceMs`. - Run-audit types `task:auto-archived-meta-resolved`, `task:auto-archived-meta-stalled`, `task:auto-archive-meta-resolved-skipped`, `task:auto-archive-meta-stalled-skipped`, `verification:followup-created`, `verification:followup-deduped`. The two signature helpers were **deleted rather than relocated** — once the three call sites went they were provably unreachable: `buildVerificationFailureSignature` had exactly one caller, and it was the only caller of `extractFailingTestFiles`. ### Call sites 1 and 2 — park kept, card dropped Verification-cap and merge-conflict give-ups keep their park, audit event, operator comment, and log entry. Site 1's `error` string was reworded off `"See follow-up task for investigation."` (no follow-up will exist) to carry the guidance itself. `autoResolveDisabled` was **kept** — it still drives the outer park guard and the `reason` string; only the inner branch that guarded card creation is gone. ### Call site 3 — autostash orphan, replaced not deleted This one is a genuine data-loss guard, so it keeps a durable trail. A `live`-classified orphan is a merger stash holding **real uncommitted work**, and unlike sites 1–2 there is no parked parent — the parent may already be `done` and merged, so nothing else on the board would ever mention the stash. The card is replaced by a `logEntry` **and** an `addTaskComment` on the parent, preserving every fact the old description carried: the sha, `record.label` (the handle `git stash` recovery needs), `record.detectedByTaskId`, and `sourcePhase`. New truthful run-audit event `task:autostash-orphan-live-detected` replaces the borrowed `verification:followup-*` name, with ids/outcomes-only metadata per AGENTS.md. ### Kept unchanged: the two real product features Eval follow-ups (`eval-followups.ts`) and PR-comment follow-ups (`pr-comment-handler.ts`) only borrowed the shared engine for its dedup pass. Both keep their exact behavior, column, priority, `sourceType`, and log lines, with dedup inlined as a `listTasks` scan on `suggestionId` / `prNumber` respectively. Both fail open (create) if the listing throws, matching the old engine. ## Test changes — read this one Two tests asserted the *deleted* engine's rate-limited `"[verification recurrence]"` logEntry. Those assertions were removed, **not loosened**: both tests still assert no duplicate card is created, and the eval test still asserts the existing id is reported back. No coverage of surviving behavior was weakened. The three `meta-*` test files were deleted along with the sweeps they covered. ## Verification ``` $ pnpm test:gate Test Files 2 passed (2) Tests 10 passed (10) # core Test Files 16 passed (16) Tests 299 passed (299) # engine-core Test Files 1 passed (1) Tests 70 passed (70) # ci-shape GATE_EXIT=0 $ pnpm --filter @fusion/engine --filter @fusion/core exec tsc --noEmit -p tsconfig.json TSC_EXIT=0 (no output) ``` Plus a file-scoped run over the touched surfaces (`eval-followups`, `pr-comment-handler`, `merger-autostash-orphan-surface`, `merger-autostash-cleanup`, `run-audit`, `run-audit-secret-taxonomy`, `project-engine`, `project-engine-manager`): **213/213 passed**. A repo-wide grep confirms no surviving references to any deleted symbol, module, or audit event. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Failed tasks now retain recovery and verification details directly on the original task instead of generating separate follow-up cards. * Live autostash issues now preserve stash information in task comments and activity logs. * Existing evaluation and pull-request follow-ups continue to be reused when appropriate. * **Changes** * Removed automatic archival of meta-tasks. * Removed obsolete meta-task timing settings. * **Documentation** * Updated architecture and settings documentation to reflect these workflow changes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
d6c917d726 |
feat(dashboard): add view and settings-section enumeration API (#2453)
## Summary Gives external integrations (command palettes, plugin launchers, alternate dashboard shells) a supported way to **discover the host UI** — instead of hardcoding the dashboard's view ids, labels and settings search terms and hand-syncing them on every release. This is the read-only metadata slice of the "constrained by a stable host context and API client" idea in `docs/proposals/2026-07-01-dashboard-theme-plugin-system.md`, and the follow-on to #2415 (theme tokens + overlay layering). Two additions, both inert unless called: | Endpoint | Returns | |---|---| | `GET /api/views` | Every registered built-in view id, in dashboard order — `id`, English `label`, plus optional i18n `labelKey`, legacy `aliases` and `internal` flag. | | `GET /api/settings/sections` | Selectable Settings sections — `id`, `label`, `labelKey`, `scope`, `group`, `keywords`, `searchableKeys`, `advanced`. | Both are read-only, return static project-independent metadata, take no project id, and are mounted inside `createApiRoutes` so they sit behind exactly the same `/api` authentication as every other dashboard route — no more, no less. ## What actually changed — one source of truth The endpoints are the small part. The core of the diff is **collapsing duplicated UI metadata into two shared registries that now drive both the dashboard UI and the API**: - `packages/dashboard/src/shared/dashboard-views.ts` — canonical view ids + English labels + i18n keys + legacy aliases. - `packages/dashboard/src/shared/settings-sections.ts` — canonical settings sections + scope/group/search metadata, with `group` and `advanced` derived from the list's own structure. `LeftSidebarNav`, `SettingsModal` and `useViewState` were rewritten to consume those registries instead of carrying their own copies (net **−230 lines** in `SettingsModal` alone). Edit the registry and the rendered UI and the API move together. ## Drift protection Being precise about what each test can and cannot catch, because "no-drift" claims are easy to overstate: - `left-sidebar-nav-registry-parity.test.tsx` — the one test that catches drift the registry does not already determine. It **renders** the sidebar with a recording `t()` spy and pins each entry's translation key and English fallback to the registry (the sidebar still hardcodes its keys). It also asserts the rendered destination count equals the enrolled id list, so a newly added sidebar view fails until it is enrolled. - `ui-metadata-sync.test.ts` — pins the Settings navigation list, advanced-visibility set, persisted view list, reset-key registry and both endpoint payloads to the registries. Since those consumers are now *derived* from the registries, these assertions mainly guard against a future consumer **re-hardcoding** its own copy. Two of them do stand on their own: each section's served `group` is pinned to the group header it actually renders under, and no published `labelKey` may resolve to a non-leaf i18n node. - `register-ui-metadata-routes.test.ts` — drives the real Express router and asserts each endpoint serves the registry payload verbatim, with no filtering or reshaping. - Exactly two **existing** tests are updated, both for the same reason: they asserted that `SettingsModal.tsx`'s *source text* contains a section literal that now lives in the registry. `VoiceInputSection.modal-visibility.test.tsx` now asserts Voice Input's Basic-mode contract against `SETTINGS_SECTION_METADATA`, and `mcp-documentation.test.ts` reads the registry for the two MCP section ids. No other existing test in the package changes. ## Design notes / decisions for review - **`GET /api/views` returns the full registry, not the live menu.** It includes flag-gated / experimental ids and `internal` (non-navigable) destinations; reachability depends on flags and plugins this endpoint does not evaluate. Documented as "known view ids", not "visible nav entries". - **`labelKey` is optional and best-effort; `label` is the guarantee.** A `labelKey` is published only where the dashboard itself renders that view's title through it. `graph` (labelled from a plugin manifest) and the internal `task-detail` carry none rather than advertise a key that resolves to nothing — and `task-detail` in particular must not point at `taskDetail.title`, which is an occupied i18n *namespace* whose lookup returns an object rather than falling through to a default. A guard test now enforces that. Separately, a few published keys (`nav.ideation`, `nav.importTasks`, `nav.automations`, `pr.view.title`) are the dashboard's real keys but aren't in the shipped catalogs yet because the host supplies their English inline; the docs say plainly that consumers must fall back to `label`. - **`keywords` / `searchableKeys` are explicitly non-contractual.** `searchableKeys` exposes the raw i18n translation-key strings backing a section's searchable copy; values, ordering and presence may change between releases. Documented as best-effort search hints, never stable identifiers. - **Migration is deliberately partial.** The desktop sidebar, Settings navigation and persisted view list now come from the registries; `Header.tsx` and the mobile More sheet still hardcode a few of the same labels. They can still drift from what `GET /api/views` reports; converting them is left to a follow-up so this diff stays reviewable. - **No project scoping, deliberately.** The proposal doc rightly pushes plugin traffic through a project-scoped client — these two endpoints are the exception that proves the rule: they return static registry metadata that is identical for every project, so threading a `projectId` would imply a scoping guarantee that does not exist here. They never touch `getScopedStore` / `TaskStore`. - **Two endpoints rather than one `/api/ui-metadata` envelope.** Views and Settings sections are independent registries with different consumers, and `/settings/sections` sits naturally beside the existing `/settings/*` routes. A consumer that only needs navigation doesn't pay for settings metadata. - **The registry extraction ships with the endpoints rather than as a separate PR.** The registries *are* the mechanism that keeps the API honest — split apart, the first half is a refactor with no observable effect and the second can't land without it. - **Placement:** `packages/dashboard/src/shared/` is a new directory, and these are the first *production* `app/ → src/` imports in the package (today the only one is in `ProviderIcon.test.tsx`). They sit under `src/` because `src/`'s tsconfig cannot import `app/`, so a module both sides consume has nowhere else to go; both registries are dependency-free data leaves, and `vite build` plus `check-no-node-only-core-imports-in-dashboard` confirm the client bundle is unaffected. The considered alternative was `packages/core/src` behind the `dashboard-browser-safe-core-modules.json` allowlist, where `mobile-nav-primary-items.ts` keeps a destination→labelKey table — these stayed out of `core` because they are dashboard-owned UI ids, and because the two tables describe different surfaces (core mirrors the mobile nav's `nav.skills`/`nav.settings`; this registry mirrors the desktop sidebar's `header.skillsView`/`header.settings`). - Ships a `@runfusion/fusion` **minor** changeset (`category: feature`). Happy to adjust any of the above — shape, placement, or dropping `searchableKeys` — if you'd rather it landed differently. ## Verification - Rebased onto `main@26dcccb7c`. Two conflicts, both resolved by absorbing upstream's work rather than reverting it: - `SettingsModal.tsx` — upstream's `voice-input` section (and the `FNXC:VoiceInput` decision comment explaining it stays out of the advanced-only set) moved into the registry. The registry's section list is byte-identical to `main`'s `SETTINGS_SECTIONS` (45/45 entries, all fields), and the registry-derived `ADVANCED_SETTINGS_SECTION_IDS` is identical to `main`'s hardcoded set (19/19, same order) — both verified mechanically, not by eye. Upstream's `RUNTIME_*` hide-uninstalled-runtimes sets are untouched. - `routes/README.md` — the `mount-sequence` list regenerated from `CREATE_API_ROUTES_REGISTRAR_MOUNT_SEQUENCE`, so `registerVoiceRoutes` and `registerUiMetadataRoutes` are both in place and the contract test passes. - `DASHBOARD_VIEWS` covers exactly `main`'s `BuiltInTaskView` union, aliases included, and `BUILT_IN_TASK_VIEWS` reproduces `main`'s 27-entry array in order (`devserver` still preceding `dev-server` for the migration path). - Every one of the 20 sidebar labels the refactor rewrote was checked to be byte-identical to `main`'s hardcoded fallback, and every `FNXC:` decision comment displaced by the move was accounted for — all 75 in `SettingsModal.tsx` and all 11 in `useViewState.ts` survive, relocated onto the registry entries they document. - The full `dashboard-app` + `dashboard-api` suites were run at this commit (**20,706 passing**) and again on unmodified `main@26dcccb7c`, and the failing-file sets compared: **every file that fails here also fails on `main`** — nothing regresses. The overlap is environment-driven (Postgres-backed `*.pg.test.ts`, tests needing built `dist` artifacts, and `SettingsModalNodeRouting.test.tsx`'s `No "fetchSystemInfo" export is defined on the "../../api" mock`), none of it touched by this change. - `tsc --noEmit` clean for both dashboard projects, `eslint` clean on every changed file, and `vite build` of the client bundle succeeds (the two pre-existing `@fusion-plugin-examples/claude-runtime` / `playwright-core` module-resolution errors reproduce on unmodified `main`). - Repo gate scripts pass: `check-changeset-format`, `check-routes-modular`, `check-no-node-only-core-imports-in-dashboard`, `check-no-cwd-relative-dashboard-test-reads`, `check-mock-completeness`. - The three new assertions were mutation-tested rather than assumed load-bearing: breaking the registry's `group` derivation, dropping an enrolled sidebar id, and re-pointing `task-detail` at the `taskDetail.title` namespace each make their test fail. - Local CodeRabbit review over two passes: 3 minor findings, all addressed (parity projection missing `group`; route tests asserting partial instead of exact payloads; the `labelKey` guard not covering the settings registry). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added authenticated, read-only APIs for discovering dashboard views and selectable Settings sections. * Added dashboard view metadata, including labels, aliases, internal status, and translation keys. * Added Settings metadata with grouping, scope, advanced status, and search-related information. * Updated navigation and Settings UI labels to use shared metadata. * **Documentation** * Documented the new metadata endpoints and integration guidance. * **Bug Fixes** * Added safeguards and automated checks to keep UI navigation and API metadata synchronized. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
e4cb957b57 |
FN-8619: migrate modal geometry to FloatingWindow
Unify migrated modal geometry and responsive behavior under FloatingWindow. - Cover Agent Detail and GitHub Import floating-window interaction and persistence contracts. - Preserve unique Agent Detail labels, mouse-only backdrop dismissal, and tablet touch layouts. - Update the dashboard modal migration inventory. Files changed: docs/dashboard-modal-inventory.md | 6 +- .../dashboard/app/components/AgentDetailView.css | 49 +++++----- .../dashboard/app/components/AgentDetailView.tsx | 6 +- .../dashboard/app/components/FloatingWindow.css | 10 +- .../dashboard/app/components/TaskDetailModal.css | 15 +++ .../AgentDetailView.floating-window.test.tsx | 102 +++++++++++++++++++++ .../__tests__/GitHubImportModal.test.tsx | 58 ++++++++++++ ...etailModal.responsive-and-dependencies.test.tsx | 24 +++++ 8 files changed, 241 insertions(+), 29 deletions(-) Fusion-Task-Id: FN-8619 Fusion-Task-Lineage: efa95e41-b12e-4e5d-aeb2-65b43c2dd8e0 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
43160a7aae |
FN-8621: migrate complex modals to FloatingWindow
Unify complex dashboard modal presentation under persisted FloatingWindow geometry. - Migrate Create Room, Task Detail, Agent Detail, and GitHub Import modal presentations. - Preserve documented embedded and docked exceptions, dismissal behavior, and nested scrolling. - Add presentation-contract coverage and publish dashboard guidance and changesets. Files changed: ...n-8619-resize-persist-modals-floating-window.md | 7 ++ .changeset/fn-8621-create-room-floating-window.md | 7 ++ docs/dashboard-guide.md | 16 +++- docs/dashboard-modal-inventory.md | 12 +-- .../dashboard/app/components/AgentDetailView.css | 16 +--- .../dashboard/app/components/AgentDetailView.tsx | 102 ++++++++++++++++----- .../dashboard/app/components/CreateRoomModal.css | 19 +++- .../dashboard/app/components/CreateRoomModal.tsx | 57 ++++++++---- .../dashboard/app/components/FloatingWindow.css | 13 ++- .../dashboard/app/components/FloatingWindow.tsx | 15 +++ .../dashboard/app/components/GitHubImportModal.css | 11 +-- .../dashboard/app/components/GitHubImportModal.tsx | 40 ++++++-- .../dashboard/app/components/TaskDetailModal.css | 52 +---------- .../dashboard/app/components/TaskDetailModal.tsx | 58 ++++++------ .../__tests__/AgentDetailView.core.test.tsx | 2 +- .../AgentDetailView.mobile-scroll.test.tsx | 6 +- .../components/__tests__/CreateRoomModal.test.tsx | 62 +++++++++++-- .../components/__tests__/FloatingWindow.test.tsx | 1 + .../__tests__/GitHubImportModal.test.tsx | 8 +- ...etailModal.responsive-and-dependencies.test.tsx | 77 +++++++--------- .../__tests__/modal-presentation-contract.test.tsx | 74 +++++++++++++++ .../dashboard/app/hooks/useEmbeddedPresentation.ts | 2 +- .../dashboard/app/hooks/useModalResizePersist.ts | 5 + 23 files changed, 441 insertions(+), 221 deletions(-) Fusion-Task-Id: FN-8621 Fusion-Task-Lineage: 04b6f3fe-d527-4a21-a0cb-489eb20f5e91 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
89b4621a93 |
FN-8607: migrate shared modals to FloatingWindow
Standardize agent, onboarding, and utility modal behavior on the shared FloatingWindow contract. - Migrate modal hosts to shared geometry, sheet, dismissal, and focus behavior. - Make FloatingWindow the sole owner of modal ARIA semantics and protect portal-safe dismissal surfaces. - Cover migrated modal contracts and document the responsive sheet requirements. Files changed: docs/dashboard-guide.md | 6 +- packages/dashboard/app/components/AgentGenerationModal.tsx | 8 +- packages/dashboard/app/components/AgentImportModal.tsx | 4 +- packages/dashboard/app/components/AgentListModal.tsx | 4 +- packages/dashboard/app/components/AgentOnboardingModal.tsx | 4 +- packages/dashboard/app/components/DockerNodeOnboardingModal.tsx | 4 +- packages/dashboard/app/components/ExperimentalAgentOnboardingModal.tsx | 4 +- packages/dashboard/app/components/FloatingWindow.css | 36 ++++-- packages/dashboard/app/components/FloatingWindow.tsx | 12 ++ packages/dashboard/app/components/MilestoneSliceInterviewModal.tsx | 2 +- packages/dashboard/app/components/NativeShellOnboardingModal.tsx | 2 +- packages/dashboard/app/components/SetupWizardModal.tsx | 3 +- packages/dashboard/app/components/SubtaskBreakdownModal.tsx | 2 +- packages/dashboard/app/components/__tests__/AgentModals.floatingWindow.test.tsx | 134 ++++++++++++++++++--- packages/dashboard/app/components/__tests__/OnboardingModals.floatingWindow.test.tsx | 128 +++++++++++++++++--- packages/dashboard/app/components/__tests__/UtilityModals.floatingWindow.test.tsx | 124 +++++++++++++++++-- packages/dashboard/app/components/__tests__/migratedModalFixtures.tsx | 59 ++++++--- packages/dashboard/app/components/__tests__/modalFloatingWindowContract.test.tsx | 20 ++- 18 files changed, 458 insertions(+), 98 deletions(-) Fusion-Task-Id: FN-8607 Fusion-Task-Lineage: 11ba6a9c-ce89-4358-83c4-a15ef15b6128 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
ba24a530ef |
FN-8620: migrate dashboard modals to FloatingWindow
Standardize dashboard modal geometry and interaction behavior through the shared FloatingWindow contract. - Migrate New Task, right-dock expansion, terminal, onboarding, and utility modals to FloatingWindow. - Expand shared window resizing, positioning, accessibility, and contract coverage. - Document the modal migration inventory and publish changesets. Files changed: .changeset/fn-8607-floating-modal-contract.md | 7 + .changeset/fn-8620-bespoke-geometry-modals.md | 7 + docs/dashboard-guide.md | 47 ++ docs/dashboard-modal-inventory.md | 6 +- .../app/components/AgentGenerationModal.tsx | 14 +- .../dashboard/app/components/AgentImportModal.tsx | 7 +- .../dashboard/app/components/AgentListModal.tsx | 8 +- .../app/components/AgentOnboardingModal.tsx | 6 +- .../app/components/DockerNodeOnboardingModal.tsx | 14 +- .../ExperimentalAgentOnboardingModal.tsx | 6 +- .../dashboard/app/components/FloatingWindow.css | 21 + .../dashboard/app/components/FloatingWindow.tsx | 62 ++- packages/dashboard/app/components/MailboxModal.tsx | 14 +- .../components/MilestoneSliceInterviewModal.tsx | 12 +- .../app/components/NativeShellOnboardingModal.tsx | 6 +- packages/dashboard/app/components/NewTaskModal.css | 196 +------ packages/dashboard/app/components/NewTaskModal.tsx | 593 +++++++-------------- packages/dashboard/app/components/RightDock.css | 84 +-- .../app/components/RightDockExpandModal.tsx | 333 ++---------- .../dashboard/app/components/SetupWizardModal.tsx | 20 +- .../app/components/SubtaskBreakdownModal.tsx | 6 +- .../dashboard/app/components/TerminalModal.css | 120 +---- .../dashboard/app/components/TerminalModal.tsx | 321 ++--------- .../__tests__/AgentModals.floatingWindow.test.tsx | 26 + .../components/__tests__/FloatingWindow.test.tsx | 27 +- .../app/components/__tests__/NewTaskModal.test.tsx | 66 +-- .../OnboardingModals.floatingWindow.test.tsx | 20 + .../app/components/__tests__/RightDock.test.tsx | 18 +- .../components/__tests__/TerminalModal.test.tsx | 61 +-- .../UtilityModals.floatingWindow.test.tsx | 18 + .../components/__tests__/migratedModalFixtures.tsx | 25 + .../__tests__/modalFloatingWindowContract.test.tsx | 30 ++ 32 files changed, 726 insertions(+), 1475 deletions(-) Fusion-Task-Id: FN-8620 Fusion-Task-Lineage: 2a912260-3292-4b13-bcf0-9de5a3df8ccd Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
034827f251 |
FN-8623: restore CDP touch geometry test lane
Restore a dedicated Chromium CDP lane for dashboard touch-geometry coverage. - Add an opt-in touch-geometry test command and isolated Vitest project. - Keep the browser-dependent spec out of deep and quality backfill collection. - Document browser discovery, port, and single-collection requirements. Files changed: docs/testing.md | 10 ++- packages/dashboard/package.json | 1 + .../__tests__/dashboard-test-config-guard.test.ts | 71 +++++++++++++++++++++- .../task-modal-touch-resize-browser.test.ts | 5 ++ packages/dashboard/vitest.config.ts | 28 ++++++++- scripts/lib/test-inventory-spec.json | 3 +- 6 files changed, 114 insertions(+), 4 deletions(-) Fusion-Task-Id: FN-8623 Fusion-Task-Lineage: eafd7497-9302-49a4-8e9e-aa93c9f56a6f Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
62e13f484b |
docs: index dashboard-modal-inventory.md in Audit Reports
FN-8617 committed docs/dashboard-modal-inventory.md as the canonical classification of all 45 dashboard modal surfaces (classes A-D) with file:line evidence and FloatingWindow migration targets, but the docs index was not updated. Add the Audit Reports entry so the doc is discoverable from the docs hub. Verified: orphan scan clean (only known intentional orphans remain); pnpm --filter @runfusion/fusion test:docs-index passes (2/2). |
||
|
|
2bb8537352 |
FN-8616: make agent tool-output limits configurable
Expose the shared agent tool-output budget as a scoped operator setting with an explicit no-limit option. - Resolve global and project output caps with a safe finite default and zero sentinel. - Propagate configured budgets through PI and plugin runtime tool wrappers. - Add settings controls, localized labels, documentation, and regression coverage. Files changed: .changeset/fn-8616-tool-output-budget-setting.md | 7 ++++ docs/agents.md | 4 +- docs/settings-reference.md | 1 + .../core/src/__tests__/tool-output-budget.test.ts | 23 ++++++++--- packages/core/src/index.gate.ts | 2 + packages/core/src/index.ts | 2 + packages/core/src/settings-schema.ts | 12 ++++++ packages/core/src/tool-output-budget.ts | 31 +++++++++++++-- packages/core/src/types/settings-scope.ts | 8 ++++ .../app/components/settings/save-split.ts | 1 + .../sections/GlobalGeneralSection.search.ts | 20 ++++++++++ .../settings/sections/GlobalGeneralSection.tsx | 26 ++++++++++++ ...lobalGeneralSection.tool-output-budget.test.tsx | 46 ++++++++++++++++++++++ .../settings-default-descriptions.test.tsx | 1 + .../src/__tests__/agent-session-helpers.test.ts | 20 ++++++++++ .../src/__tests__/runtime-resolution.test.ts | 15 +++++++ .../__tests__/tool-output-budget-wrapper.test.ts | 45 ++++++++++++++++----- packages/engine/src/agent-runtime.ts | 2 + packages/engine/src/agent-session-helpers.ts | 18 +++++++-- packages/engine/src/pi.ts | 29 ++++++++++---- packages/engine/src/runtime-resolution.ts | 10 ++++- packages/i18n/locales/en/app.json | 4 ++ packages/i18n/locales/es/app.json | 6 ++- packages/i18n/locales/fr/app.json | 6 ++- packages/i18n/locales/ko/app.json | 6 ++- packages/i18n/locales/zh-CN/app.json | 6 ++- packages/i18n/locales/zh-TW/app.json | 6 ++- packages/i18n/src/resources.d.ts | 4 ++ 28 files changed, 323 insertions(+), 38 deletions(-) Fusion-Task-Id: FN-8616 Fusion-Task-Lineage: 3ca99a61-d6ae-48ff-98d2-f14a153aa2b7 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
d3002d1453 |
FN-8617: restore authoritative dashboard modal inventory
Restore the committed source of truth for dashboard modal migration coverage. - Add the evidence-backed inventory of dashboard modal classifications and migration ownership. - Link the dashboard guide to the canonical modal inventory. Files changed: docs/dashboard-guide.md | 4 ++ docs/dashboard-modal-inventory.md | 103 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) Fusion-Task-Id: FN-8617 Fusion-Task-Lineage: 87159726-d574-4f71-bd6f-66cf9f2f9a9e Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
743dc5f46e |
FN-8612: remove tablet task modal padding
Keep task modals dense on tablets without reducing their touch resize targets. - Move the Task Detail drag target out of layout flow while preserving its 44px hit area. - Restore desktop-density New Task header and body padding on tablet resize surfaces. - Add CSS, unit, and browser coverage for tablet geometry and generic floating windows. Files changed: .changeset/fn-8612-tablet-modal-padding.md | 7 + docs/dashboard-guide.md | 8 +- .../task-detail-modal-tablet-width.test.ts | 8 + .../dashboard/app/components/FloatingWindow.css | 40 ++++- packages/dashboard/app/components/NewTaskModal.css | 14 ++ .../FloatingWindow.touch-geometry.test.tsx | 14 ++ .../app/components/__tests__/NewTaskModal.test.tsx | 8 + .../app/task-modal-touch-resize-e2e-fixture.tsx | 54 ++++++- .../task-modal-touch-resize-browser.test.ts | 177 ++++++++++++++++++++- packages/dashboard/vitest.config.ts | 6 + 10 files changed, 322 insertions(+), 14 deletions(-) Fusion-Task-Id: FN-8612 Fusion-Task-Lineage: fecd7c48-7b6c-434e-9002-f8f21241120c Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
07c8c95b10 |
FN-8614: cap agent tool output
Bound every engine-injected tool result to preserve agent context capacity. - Add shared 16,000-character total text budgets with deterministic truncation markers and validated overrides. - Apply outermost output clamps to Pi and non-Pi plugin tool paths, with semantic caps for high-volume reads. - Cover budget behavior and document the operator-facing configuration contract. Files changed: .changeset/fn-8614-tool-output-budget.md | 7 ++ docs/agents.md | 8 ++ .../core/src/__tests__/tool-output-budget.test.ts | 58 +++++++++++++ packages/core/src/index.gate.ts | 7 ++ packages/core/src/index.ts | 7 ++ packages/core/src/tool-output-budget.ts | 97 ++++++++++++++++++++++ .../src/__tests__/agent-artifact-tools.test.ts | 10 +++ .../src/__tests__/agent-document-tools.test.ts | 10 +++ .../__tests__/agent-task-logs-read-tools.test.ts | 8 ++ .../__tests__/tool-output-budget-wrapper.test.ts | 67 +++++++++++++++ packages/engine/src/agent-session-helpers.ts | 7 +- packages/engine/src/agent-tools.ts | 43 ++++++++-- packages/engine/src/pi.ts | 54 +++++++++++- 13 files changed, 374 insertions(+), 9 deletions(-) Fusion-Task-Id: FN-8614 Fusion-Task-Lineage: b6a76ccd-d7b4-4b43-af7e-cfd16ffb7fc8 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
a6885b73f2 |
FN-8606: migrate core workflow modals to shared floating windows
Migrate dashboard dialogs to the shared movable and resizable FloatingWindow contract. - Move core, workflow, Git, planning, and automation modal surfaces to stable floating-window identities with persisted geometry. - Suspend geometry and floating controls for phone and short-viewport sheets, including Quick Chat. - Add accessibility wiring, tablet touch targets, migration tests, and operator documentation. Files changed: .changeset/fn-8606-floating-window-core-modals.md | 7 + docs/dashboard-guide.md | 4 + packages/dashboard/app/App.tsx | 8 +- .../dashboard/app/components/ActivityLogModal.tsx | 30 ++-- packages/dashboard/app/components/AddNodeModal.tsx | 8 +- .../dashboard/app/components/ChangesDiffModal.tsx | 35 +++-- .../dashboard/app/components/ConnectNodeModal.tsx | 9 +- .../dashboard/app/components/FloatingWindow.css | 71 ++++++++- .../dashboard/app/components/FloatingWindow.tsx | 27 +++- .../dashboard/app/components/GitManagerModal.tsx | 30 +++- .../dashboard/app/components/GroupTaskModal.tsx | 8 +- .../app/components/ModelOnboardingModal.tsx | 28 ++-- .../dashboard/app/components/NodeDetailModal.tsx | 9 +- .../dashboard/app/components/PlanningModeModal.css | 1 - .../dashboard/app/components/PlanningModeModal.tsx | 57 +++---- .../app/components/ScheduledTasksModal.tsx | 9 +- packages/dashboard/app/components/ScriptsModal.css | 1 - packages/dashboard/app/components/ScriptsModal.tsx | 32 ++-- .../dashboard/app/components/SettingsModal.css | 1 - .../dashboard/app/components/SettingsModal.tsx | 58 ++++--- .../app/components/WorkflowAddStepModal.css | 15 -- .../app/components/WorkflowAddStepModal.tsx | 46 +++--- .../components/__tests__/ActivityLogModal.test.tsx | 33 ++-- .../app/components/__tests__/AddNodeModal.test.tsx | 12 +- .../components/__tests__/ChangesDiffModal.test.tsx | 78 +++++----- .../components/__tests__/ConnectNodeModal.test.tsx | 7 + .../components/__tests__/FloatingWindow.test.tsx | 173 ++++++++++++++++++++- .../components/__tests__/GitManagerModal.test.tsx | 30 ++-- .../components/__tests__/GroupTaskModal.test.tsx | 9 ++ .../__tests__/ModelOnboardingModal.test.tsx | 18 ++- .../components/__tests__/NodeDetailModal.test.tsx | 9 ++ .../__tests__/PlanningModeModal.autosize.test.tsx | 30 ++-- .../__tests__/ScheduledTasksModal.test.tsx | 21 ++- .../app/components/__tests__/ScriptsModal.test.tsx | 15 +- .../__tests__/SettingsModal.mobileClose.test.tsx | 25 ++- .../__tests__/WorkflowAddStepModal.test.tsx | 7 + .../floatingWindowMigration.test-helpers.ts | 126 +++++++++++++++ 37 files changed, 828 insertions(+), 259 deletions(-) Fusion-Task-Id: FN-8606 Fusion-Task-Lineage: dab0df2d-73f4-4b0f-bec3-a45016310c91 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
827b145fa1 |
FN-8611: persist manual import translations
Persist manual GitHub and GitLab import translations across preview sessions. - Add durable translation cache reads and identity-aware translation requests. - Route manual translations through the translation budget with actionable API errors. - Restore cached previews automatically and cover API/UI behavior with tests. Files changed: .changeset/fn-8611-manual-import-translations.md | 7 ++ docs/dashboard-guide.md | 2 +- packages/dashboard/app/api/ai-text.ts | 52 ++++++-- packages/dashboard/app/api/legacy.ts | 2 + .../dashboard/app/components/GitHubImportModal.tsx | 14 ++- .../components/GitHubImportTranslateControls.tsx | 39 +++++- .../__tests__/GitHubImportModal.test.tsx | 42 +++++++ packages/dashboard/src/ai-translate.ts | 23 ++++ .../register-ai-text-assistant-routes.test.ts | 135 +++++++++++++++++---- .../routes/register-ai-text-assistant-routes.ts | 131 ++++++++++++++------ 10 files changed, 370 insertions(+), 77 deletions(-) Fusion-Task-Id: FN-8611 Fusion-Task-Lineage: 00a84f43-4469-4bc5-bbb6-8245d8d79781 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
47087342fc |
FN-8605: harden tablet touch window controls
Make shared floating dashboard windows reliably movable and resizable on tablet touch viewports. - Apply a tablet-aware 44px drag and resize hit-target contract to FloatingWindow. - Preserve phone full-screen sheets below 768px while retaining desktop-hybrid geometry. - Add geometry, browser touch, and viewport boundary coverage with captured visual evidence. - Document the shared modal touch contract and release the dashboard fix. Files changed: .changeset/fn-8605-floating-window-touch.md | 7 ++ docs/dashboard-guide.md | 5 + docs/testing.md | 2 +- .../dashboard/app/components/FloatingWindow.css | 116 ++++++++++++++---- .../dashboard/app/components/FloatingWindow.tsx | 56 ++++++++- .../components/__tests__/FloatingWindow.test.tsx | 80 +++--------- .../FloatingWindow.touch-geometry.test.tsx | 136 +++++++++++++++++++++ .../FloatingWindowStack.cross-type.test.tsx | 2 +- .../app/hooks/__tests__/useViewportMode.test.ts | 18 ++- packages/dashboard/app/hooks/useViewportMode.ts | 7 +- .../app/task-modal-touch-resize-e2e-fixture.tsx | 39 +++++- .../__screenshots__/fn-8605/phone-fullscreen.png | Bin 0 -> 11393 bytes .../e2e/__screenshots__/fn-8605/tablet-after.png | Bin 0 -> 14275 bytes .../e2e/__screenshots__/fn-8605/tablet-before.png | Bin 0 -> 14308 bytes .../task-modal-touch-resize-browser.test.ts | 83 +++++++++++++ 15 files changed, 453 insertions(+), 98 deletions(-) Fusion-Task-Id: FN-8605 Fusion-Task-Lineage: 993c7ed8-c3e9-4673-b0b7-5c50746991a7 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
fde3b76a8c |
FN-8602: enable tablet touch resizing for task modals
Enable touch-driven resizing for task modals on tablet viewports. - Add tablet touch resize handles and pointer interactions for task and new-task modals. - Preserve responsive modal sizing while keeping phone layouts fullscreen. - Add unit, browser, and visual regression coverage with updated documentation. Files changed: .changeset/fn-8602-tablet-touch-resize.md | 7 + docs/dashboard-guide.md | 6 +- docs/testing.md | 4 + packages/dashboard/app/components/NewTaskModal.css | 70 ++++++++++ packages/dashboard/app/components/NewTaskModal.tsx | 19 ++- .../dashboard/app/components/TaskDetailModal.css | 12 ++ .../dashboard/app/components/TaskDetailModal.tsx | 7 +- .../app/components/__tests__/NewTaskModal.test.tsx | 4 + ...etailModal.responsive-and-dependencies.test.tsx | 1 + .../hooks/__tests__/useModalResizePersist.test.tsx | 10 +- .../app/hooks/__tests__/useViewportMode.test.ts | 26 +++- .../dashboard/app/hooks/useModalResizePersist.ts | 26 +++- packages/dashboard/app/hooks/useViewportMode.ts | 13 ++ packages/dashboard/app/styles.css | 16 +++ .../app/task-modal-touch-resize-e2e-fixture.html | 5 + .../app/task-modal-touch-resize-e2e-fixture.tsx | 60 ++++++++ .../__screenshots__/fn-8602/phone-fullscreen.png | Bin 0 -> 43987 bytes .../e2e/__screenshots__/fn-8602/tablet-after.png | Bin 0 -> 52549 bytes .../e2e/__screenshots__/fn-8602/tablet-before.png | Bin 0 -> 11500 bytes .../task-modal-touch-resize-browser.test.ts | 154 +++++++++++++++++++++ 20 files changed, 424 insertions(+), 16 deletions(-) Fusion-Task-Id: FN-8602 Fusion-Task-Lineage: f07ce22f-f529-4be3-ba1b-04063154a1b0 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
cca13737b6 |
FN-8603: reduce steady-state diagnostic log noise
Route routine core, engine, and dashboard diagnostics through debug-gated shared loggers. - Demote steady-state diagnostic sites while preserving warnings and errors for actionable failures. - Add cross-package severity contracts and manifest coverage for demoted log sites. - Document logging severity guidance and add a patch changeset. Files changed: .changeset/fn-8603-log-severity.md | 7 ++ docs/diagnostics.md | 20 ++++-- .../__tests__/log-severity-spam-contract.test.ts | 71 ++++++++++++++++++ packages/core/src/activity-analytics.ts | 5 +- packages/core/src/ai-summarize.ts | 61 +++++++--------- packages/core/src/async-mission-store.ts | 5 +- packages/core/src/async-secrets-store.ts | 7 +- packages/core/src/central-core.ts | 17 ++--- packages/core/src/docker-provisioning.ts | 13 ++-- packages/core/src/index.ts | 1 + packages/core/src/master-key.ts | 9 ++- packages/core/src/memory-compaction.ts | 29 ++++---- packages/core/src/memory-insights.ts | 7 +- packages/core/src/migration-orchestrator.ts | 7 +- packages/core/src/mission-store.ts | 5 +- packages/core/src/node-discovery.ts | 7 +- packages/core/src/notification/dispatcher.ts | 9 ++- .../core/src/plugins/bundled-plugin-install.ts | 11 +-- packages/core/src/reflection-store.ts | 5 +- packages/core/src/secrets-store.ts | 7 +- packages/core/src/task-store/agent-logs.ts | 21 +++--- packages/core/src/task-store/async-events.ts | 5 +- packages/core/src/task-store/async-maintenance.ts | 7 +- packages/core/src/task-store/comments-ops.ts | 7 +- packages/core/src/task-store/task-mutation-ops.ts | 11 +-- packages/core/src/task-store/workflow-integrity.ts | 9 ++- packages/core/src/types/merge-policy.ts | 5 +- packages/core/src/usage-events.ts | 5 +- .../__tests__/log-severity-spam-contract.test.ts | 48 +++++++++++++ packages/dashboard/src/ai-refine.ts | 5 +- packages/dashboard/src/ai-session-diagnostics.ts | 10 +-- packages/dashboard/src/chat.ts | 8 ++- packages/dashboard/src/devserver-manager.ts | 9 ++- packages/dashboard/src/file-service.ts | 5 +- packages/dashboard/src/github-tracking-comments.ts | 7 +- .../dashboard/src/github-tracking-reconciler.ts | 5 +- packages/dashboard/src/github-tracking-state.ts | 5 +- packages/dashboard/src/gitlab-lifecycle.ts | 5 +- packages/dashboard/src/insights-routes.ts | 9 ++- packages/dashboard/src/issue-image-attachments.ts | 5 +- packages/dashboard/src/knowledge-index.ts | 5 +- packages/dashboard/src/plugin-routes.ts | 7 +- packages/dashboard/src/routes/board-workflows.ts | 5 +- packages/dashboard/src/routes/context.ts | 5 +- .../dashboard/src/routes/register-auth-routes.ts | 13 ++-- .../routes/register-docker-provisioning-routes.ts | 7 +- .../dashboard/src/routes/register-git-github.ts | 21 +++--- packages/dashboard/src/routes/register-gitlab.ts | 7 +- .../src/routes/register-session-diff-routes.ts | 9 ++- .../src/routes/register-settings-memory-routes.ts | 7 +- .../src/routes/register-setup-activity-routes.ts | 7 +- .../dashboard/src/routes/register-signal-routes.ts | 5 +- .../src/routes/register-task-workflow-routes.ts | 11 +-- packages/dashboard/src/runtime-logger.ts | 11 +-- packages/dashboard/src/server.ts | 7 +- packages/dashboard/src/sse.ts | 8 ++- packages/dashboard/src/terminal-service.ts | 34 ++++----- packages/dashboard/src/view-chunk-manifest.ts | 5 +- .../engine/src/__tests__/log-severity-manifest.ts | 83 ++++++++++++++++++++++ .../__tests__/log-severity-spam-contract.test.ts | 40 ++++++++++- .../src/__tests__/logger-debug-gating.test.ts | 7 +- packages/engine/src/goal-anchoring-audit.ts | 5 +- packages/engine/src/plugin-runner.ts | 44 ++++++------ packages/engine/src/pty-native.ts | 9 ++- .../engine/src/runtimes/child-process-worker.ts | 4 +- packages/engine/src/self-healing.ts | 12 ++-- packages/engine/src/worktree-hooks.ts | 10 ++- 67 files changed, 632 insertions(+), 250 deletions(-) Fusion-Task-Id: FN-8603 Fusion-Task-Lineage: 53901db6-1af2-4bd7-b5ea-49507e048ef2 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
a516c8b409 |
docs(FN-8600): capture the live-planning-worktree reclaim incident
Documents why self-healing force-removed a worktree a planning session was using and parked the card branch-conflict-unrecoverable: planning gained a task worktree but never took an active-session lease, so the reclaim sweep's liveness guard had nothing to see, and a zero-commit branch classifies as tip-already-merged by construction. Captures the investigation's dead ends too — including reading maxConcurrent from a multi-tenant config table without filtering by project_id, which produced a confidently wrong root cause — and the three ways the first version of the fix was itself wrong. CONCEPTS.md: adds planning to the Active-session lease kinds (the entry had gone stale), states the converse invariant that an unheld path reads as proof nothing is running, and defines Top-level agent slot — the capacity concept whose conflation with the worktree limit derailed the first hour of diagnosis. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
47d030215c |
feat(workflow): run pre-merge review gates in the In review column
Code Review and Browser Verification now run with the card in `in-review` instead of `in-progress`, so the board shows the card under review with the running step as a badge (matching the Coding (Ideas) preset). Their paired remediation nodes stay in `in-progress`, so a changes-requested verdict visibly sends the card back to implementation. The column move IS the badge switch: the dashboard badge was already lane-gated on `column === "in-review"`. Applied to the shared stepwise coding IR, so it is inherited by builtin:coding (the default), builtin:stepwise-coding, builtin:brainstorming and builtin:coding-ideas; builtin:legacy-coding keeps its historical placement. Two consequences handled: - Capacity: `in-review` has no `wip` trait, so the slot is released during review and the remediation crossing back into `in-progress` can hit the non-bypassable in-transaction capacity check. The column boundary now PARKS the run on a `capacity-exhausted` rejection instead of failing it, preserving the failed gate result and worktree so the next graph run retries once a slot frees. Non-capacity rejections still propagate. - Reopen clears: `applyReopenFieldClears` wiped `workflowStepResults` on every in-review -> in-progress move, which the remediation crossing now performs routinely. That destroyed the remediation input, made `routeRetryableRemediationGraphFailureToPreMergeFix` and `recoverFailedPreMergeWorkflowStep` silently no-op, and — worse — made both `getTaskMergeBlocker` branches vacuously false, so a card could return to `in-review` and be mergeable with its gate never re-run. Now exempted for graph-owned in-review -> in-progress crossings only; operator reopens, merge bounces and every -> todo/triage rebound still clear, so the executor's documented bounce invariant is unchanged. Adds regression coverage for both (there was previously none for the reopen clear in either direction), and annotates the unreachable legacy scheduler dispatch block rather than mirroring the fix into dead code. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
fd073e287f |
FN-8592: self-heal stranded hold continuations
Restore graph-owned plan-review continuations for eligible hold-column cards stranded after planning cancellation. - Detect real-spec hold cards with no active workflow continuation and re-seed Plan Review safely. - Serialize workflow continuation seeding, review-result writes, and lease claims to prevent duplicate recovery. - Add recovery diagnostics, release warnings, regression coverage, and a patch changeset. Files changed: .changeset/fn-8592-stranded-hold-continuation.md | 7 + AGENTS.md | 1 + docs/architecture.md | 4 + .../workflow-task-serialization-protocol.test.ts | 119 +++++++++++++ .../workflow-work-items-conditional-seed.test.ts | 191 +++++++++++++++++++++ packages/core/src/store.ts | 5 +- .../src/task-store/async-workflow-workitems.ts | 123 +++++++++---- packages/core/src/task-store/project-store-ops.ts | 14 ++ .../src/task-store/workflow-task-create-ops.ts | 16 +- .../src/task-store/workflow-workitems-ops-2.ts | 91 ++++++---- .../src/__tests__/pre-release-plan-review.test.ts | 17 ++ ...self-healing-stranded-hold-continuation.test.ts | 171 ++++++++++++++++++ packages/engine/src/hold-release.ts | 57 +++++- packages/engine/src/plan-review-continuation.ts | 94 ++++++++++ packages/engine/src/runtimes/in-process-runtime.ts | 30 +--- packages/engine/src/self-healing.ts | 100 ++++++++++- 16 files changed, 945 insertions(+), 95 deletions(-) Fusion-Task-Id: FN-8592 Fusion-Task-Lineage: fe7ffd34-96e4-4418-a879-7418e6293d30 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
106c61e6ee |
fix(agent-tools): close the fn_delegate_task Deny bypass and the store's window clamp
Follow-up to
|
||
|
|
0c85613313 |
fix(engine): address code-review findings on the planner/worktree recovery fixes
Review of |
||
|
|
351fba1d33 |
FN-8594: improve project overview mobile reflow
Make the project overview usable at small viewport widths while hiding its non-functional mobile task navigation. - Reflow overview filters, stats, cards, and skeletons for 480px and 380px breakpoints. - Hide the mobile navigation bar and clear its reserved height outside an active project task view. - Add regression coverage and document responsive dashboard behavior. Files changed: docs/dashboard-guide.md | 5 +- packages/dashboard/app/App.tsx | 8 +- .../mobile-feature-access-regression.test.tsx | 22 ++++- .../project-overview-small-screen.test.ts | 91 ++++++++++++++++++++ packages/dashboard/app/components/MobileNavBar.tsx | 19 ++++- packages/dashboard/app/components/ProjectCard.css | 58 +++++++++++++ .../dashboard/app/components/ProjectOverview.css | 99 ++++++++++++++++++++++ 7 files changed, 294 insertions(+), 8 deletions(-) Fusion-Task-Id: FN-8594 Fusion-Task-Lineage: 0999f6e4-ffe9-4ed6-a471-8e5ba3413029 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
99b80ad748 |
feat(dashboard): add opt-in auto-update and harden restart supervision
Add the `autoUpdateAndRestart` global setting (default off, Settings -> General next to Release channel). When enabled, the dashboard host installs available updates on the selected channel by itself and requests the supervised in-place restart. Supervised hosts only: without a parent to respawn, installing would leave a running process whose code no longer matches its own install. Fix two ways the restart affordance could silently do nothing: - The supervisor now stamps FUSION_SUPERVISOR_PID and supervision is only counted when that pid is the real parent. FUSION_RESTART_SUPERVISED is inherited by every process Fusion spawns, so `fn dashboard` launched from an agent terminal skipped its own supervisor while still advertising restart support -- a restart request then killed it for good. - Settings and the update banner probe /system/info on mount and treat capability as advisory: the button always issues the request and shows the server's actual refusal instead of sitting disabled after a failed probe. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
3597d06380 |
FN-8578: pin verified Parakeet v3 model asset
Enable secure downloads of the upstream Parakeet v3 voice model. - Pin the archive URL, filename, SHA-256, expected files, and nested extraction layout. - Accept the archive's BSD tar timestamp format while preserving safe extraction checks. - Cover download gates and installation behavior, and document the verified model asset. Files changed: .changeset/fn-8578-parakeet-v3-asset-pin.md | 7 ++++ docs/dashboard-guide.md | 2 +- docs/settings-reference.md | 8 ++-- .../src/stt/__tests__/model-manager.test.ts | 46 ++++++++++++++++++++++ .../dashboard/src/stt/__tests__/voice-stt.test.ts | 33 +++++++++++++++- packages/dashboard/src/stt/model-manager.ts | 13 +++--- packages/dashboard/src/stt/types.ts | 18 +++++++-- 7 files changed, 114 insertions(+), 13 deletions(-) Fusion-Task-Id: FN-8578 Fusion-Task-Lineage: ab397190-fa0c-491e-b0f8-0ab6641be95a Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
2a2b157cb9 |
FN-8585: fix dashboard composer test source reads
Stabilize dashboard composer tests when Vitest launches from the workspace root. - Resolve dashboard test source fixtures relative to the app directory. - Migrate affected component tests away from cwd-relative CSS reads. - Enforce the fixture convention in test hooks and document it. Files changed: docs/testing.md | 4 +++ package.json | 6 ++-- .../__tests__/AuthTokenRecoveryDialog.test.tsx | 3 +- .../components/__tests__/ChatView.mobile.test.tsx | 5 +-- .../__tests__/EngineControlMenu.test.tsx | 11 ++---- .../components/__tests__/FloatingWindow.test.tsx | 5 +-- .../app/components/__tests__/ListView.test.tsx | 5 +-- .../__tests__/MissionInterviewModal.test.tsx | 3 +- .../app/components/__tests__/MobileNavBar.test.tsx | 3 +- .../app/components/__tests__/NewTaskModal.test.tsx | 3 +- .../__tests__/PlanningModeModal.initial.test.tsx | 3 +- .../PlanningModeModal.ui-interactions.test.tsx | 7 ++-- .../components/__tests__/PrCreateModal.test.tsx | 3 +- .../__tests__/QuickChat.persist.test.tsx | 3 +- .../components/__tests__/QuickEntryBox.test.tsx | 3 +- .../components/__tests__/ReportActionMenu.test.tsx | 9 ++--- .../app/components/__tests__/ReportModal.test.tsx | 3 +- .../__tests__/ShadcnColorPicker.test.tsx | 3 +- .../components/__tests__/TerminalModal.test.tsx | 3 +- .../components/__tests__/ThemeDropdown.test.tsx | 9 ++--- .../__tests__/WorkflowNodeEditor.test.tsx | 5 +-- .../WorkflowOptionalStepsDropdown.test.tsx | 3 +- .../components/__tests__/WorkflowSwitcher.test.tsx | 5 +-- .../app/components/__tests__/board-mobile.test.tsx | 4 +-- .../__tests__/CommandCenterControls.test.tsx | 6 ++-- .../__tests__/SystemControlsArea.test.tsx | 5 +-- .../__tests__/SystemStatsArea.test.tsx | 3 +- .../command-center/areas/__tests__/areas.test.tsx | 3 +- .../__tests__/KeyboardShortcutsSection.test.tsx | 3 +- .../app/test/__tests__/cssFixture.test.ts | 35 +++++++++++++++++++ packages/dashboard/app/test/cssFixture.ts | 12 +++++++ .../check-no-cwd-relative-dashboard-test-reads.mjs | 39 ++++++++++++++++++++++ 32 files changed, 162 insertions(+), 55 deletions(-) Fusion-Task-Id: FN-8585 Fusion-Task-Lineage: 83a35fb6-a29d-4e97-b282-1054c68b8cc9 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
32adc0a153 |
FN-8573: add voice dictation controls to composers
Add shared voice dictation support across chat, planning, and task-creation composers. - Add browser speech-recognition and composer insertion hooks. - Provide a reusable mic button with accessible recording states. - Integrate and test dictation across all supported composer surfaces. - Document the feature and add a package changeset. Files changed: .changeset/fn-8573-voice-dictation-mic.md | 7 + docs/dashboard-guide.md | 6 + packages/dashboard/app/components/ChatView.tsx | 44 +++- .../dashboard/app/components/ComposeChatPanel.tsx | 8 +- packages/dashboard/app/components/MicButton.css | 5 + packages/dashboard/app/components/MicButton.tsx | 20 ++ .../dashboard/app/components/PlanningModeModal.tsx | 82 ++++-- .../dashboard/app/components/QuickEntryBox.tsx | 4 + .../app/components/StandardChatSurface.tsx | 108 +++++--- packages/dashboard/app/components/TaskChatTab.tsx | 4 + packages/dashboard/app/components/TaskComments.tsx | 66 ++--- packages/dashboard/app/components/TaskForm.tsx | 18 +- .../app/components/TaskPlannerChatTab.tsx | 7 + .../app/components/__tests__/MicButton.test.tsx | 28 +++ .../components/__tests__/QuickEntryBox.test.tsx | 5 + .../app/components/__tests__/TaskForm.test.tsx | 5 + .../app/components/__tests__/insertAtCaret.test.ts | 25 ++ .../__tests__/voice-dictation-composers.test.tsx | 230 +++++++++++++++++ packages/dashboard/app/components/insertAtCaret.ts | 20 ++ .../hooks/__tests__/useComposerDictation.test.tsx | 58 +++++ .../app/hooks/__tests__/useVoiceDictation.test.tsx | 158 ++++++++++++ .../dashboard/app/hooks/useComposerDictation.ts | 112 +++++++++ .../dashboard/app/hooks/useVoiceDictation.ts | 277 +++++++++++++++++++++ 23 files changed, 1204 insertions(+), 93 deletions(-) Fusion-Task-Id: FN-8573 Fusion-Task-Lineage: 905ae982-3e63-494f-aba8-e3665f00cdda Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
11db36187f |
FN-8572: add voice input settings and model controls
Add project-scoped voice dictation controls with observable local model management. - Add the Voice Input settings section with opt-in enablement and runtime-safe status handling. - Add Parakeet v3 model download, removal, progress polling, search, documentation, and regression coverage. - Add a minor release changeset for Voice Input settings. Files changed: .changeset/fn-8572-voice-input-settings.md | 7 ++ docs/dashboard-guide.md | 4 + docs/settings-reference.md | 1 + .../dashboard/app/components/SettingsModal.tsx | 7 +- .../VoiceInputSection.modal-visibility.test.tsx | 19 +++ .../settings/__tests__/VoiceInputSection.test.tsx | 137 +++++++++++++++++++++ .../settings/__tests__/section-keys.test.ts | 1 + .../search/__tests__/settings-search-index.test.ts | 1 + .../app/components/settings/search/entries.ts | 2 + .../app/components/settings/section-keys.ts | 2 + .../settings/sections/VoiceInputSection.css | 48 ++++++++ .../settings/sections/VoiceInputSection.search.ts | 14 +++ .../settings/sections/VoiceInputSection.tsx | 128 ++++++++++++++++++++ 13 files changed, 370 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-8572 Fusion-Task-Lineage: 2d2ad0df-3765-4d19-a6f3-7c2b5ca5df95 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
9a2aea6120 |
FN-8571: add Parakeet STT transcription backend
Add a configurable sherpa-onnx Parakeet v3 speech-to-text service and dashboard API. - Add model download, validation, caching, and lifecycle management for the bundled STT runtime. - Register multipart-safe voice transcription routes with request-size handling and service-backed responses. - Expose STT settings, documentation, release metadata, and focused integration coverage. Files changed: .changeset/fn-8571-voice-stt-backend.md | 7 + docs/settings-reference.md | 12 + .../core/src/__tests__/settings-parity.test.ts | 10 + packages/core/src/index.ts | 2 +- packages/core/src/settings-schema.ts | 2 + packages/core/src/types.ts | 2 + packages/core/src/types/settings-scope.ts | 19 ++ packages/dashboard/package.json | 3 + .../voice-body-parser-integration.test.ts | 67 ++++++ packages/dashboard/src/routes.ts | 2 + packages/dashboard/src/routes/README.md | 74 +++--- .../routes/__tests__/register-voice-routes.test.ts | 159 ++++++++++++ .../src/routes/create-api-routes-mount-sequence.ts | 2 +- .../dashboard/src/routes/register-voice-routes.ts | 92 +++++++ packages/dashboard/src/server.ts | 21 +- .../src/stt/__tests__/model-manager.test.ts | 171 +++++++++++++ .../dashboard/src/stt/__tests__/voice-stt.test.ts | 48 ++++ packages/dashboard/src/stt/model-manager.ts | 268 +++++++++++++++++++++ packages/dashboard/src/stt/parakeet-service.ts | 77 ++++++ packages/dashboard/src/stt/types.ts | 14 ++ pnpm-lock.yaml | 65 +++++ 21 files changed, 1086 insertions(+), 31 deletions(-) Fusion-Task-Id: FN-8571 Fusion-Task-Lineage: b11e0cea-9c9c-41d4-a141-c47e5ed56dba Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
b31bee03a8 |
FN-8576: add global quiet flag to CLI
Add a global quiet mode that suppresses informational CLI stdout without hiding requested results. - Parse --quiet/-q and FUSION_QUIET with command and output exemptions. - Route result output and interactive prompts around the reversible stdout gate. - Document the flag and cover quiet output, prompts, and argument parsing. Files changed: .changeset/fn-8576-cli-quiet-flag.md | 7 ++ docs/cli-reference.md | 8 ++ packages/cli/src/__tests__/bin.test.ts | 15 +++ packages/cli/src/__tests__/cli-quiet-mode.test.ts | 63 +++++++++++++ .../__tests__/cli-quiet-prompt-surfaces.test.ts | 33 +++++++ packages/cli/src/bin.ts | 39 ++++++-- packages/cli/src/commands/experiment-finalize.ts | 3 +- packages/cli/src/commands/git.ts | 17 ++-- packages/cli/src/commands/goals.ts | 4 +- packages/cli/src/commands/mission.ts | 8 +- packages/cli/src/commands/node.ts | 4 +- packages/cli/src/commands/onboard.ts | 4 +- packages/cli/src/commands/org-import.ts | 5 +- packages/cli/src/commands/plugin.ts | 14 ++- packages/cli/src/commands/port-prompt.ts | 4 +- packages/cli/src/commands/project.ts | 6 +- packages/cli/src/commands/research.ts | 3 +- packages/cli/src/commands/task.ts | 101 +++++++++++--------- packages/cli/src/commands/update.ts | 3 +- packages/cli/src/commands/workflow.ts | 13 +-- packages/cli/src/output.ts | 104 +++++++++++++++++++++ packages/cli/src/project-resolver.ts | 20 ++-- 22 files changed, 388 insertions(+), 90 deletions(-) Fusion-Task-Id: FN-8576 Fusion-Task-Lineage: 2493d6d5-bbd9-4fc2-b903-950457ef30b0 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
0056d75314 |
FN-8569: surface unrecoverable report health
Classify parked direct reports as operator-actionable even when their stored state appears live. - Add a reusable Reports Health classifier that prioritizes pause markers. - Clear stale pause markers during live-state resumes without removing diagnostic errors. - Cover desynchronized report states and document the health invariant. Files changed: .../fn-8569-reports-health-error-unrecoverable.md | 7 +++ docs/architecture.md | 1 + .../agent-store-pause-marker-clear.test.ts | 65 +++++++++++++++++++ packages/core/src/agent-store.ts | 12 ++++ .../src/__tests__/heartbeat-executor.test.ts | 27 ++++++-- .../engine/src/__tests__/reports-health.test.ts | 73 ++++++++++++++++++++++ packages/engine/src/agent-heartbeat.ts | 36 ++++++----- packages/engine/src/index.ts | 6 ++ packages/engine/src/reports-health.ts | 70 +++++++++++++++++++++ 9 files changed, 278 insertions(+), 19 deletions(-) Fusion-Task-Id: FN-8569 Fusion-Task-Lineage: 37c798a0-1f2b-4221-a0c6-ccbff8d72696 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
3c3acbf769 |
docs(settings): record why global settings are not all in postgres
Global settings are already split three ways -- values in settings.json, the revision journal in postgres, and globalMaxConcurrent/defaultProjectId in central tables -- so the recurring "finish the cutover" proposal keeps getting re-litigated from scratch. Write down the two hard constraints (startup-factory reads embeddedPostgresMaxConnections to start postgres; createFusionAuthStorage is synchronous and host-agnostic), the recovery argument, and the one real motivation for a partial move (multi-node policy consistency), plus the machine-tier vs operator-policy-tier rule for placing new keys. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
8dc6598aa0 |
feat(auth): let operators choose which Anthropic credential wins
An operator can hold a raw Anthropic API key and a Claude subscription OAuth
login at once, and the raw key always won silently. A stale or revoked saved
key therefore shadowed a working subscription and failed every direct Anthropic
call with 401 invalid x-api-key, while both Settings cards still read Active.
Add the global anthropicAuthPreference setting ("api-key" default, preserving
the historical precedence, or "subscription"), read in resolveAnthropicRuntimeApiKey
straight from ~/.fusion/settings.json so it applies without a restart and needs
no settings plumbing through createFusionAuthStorage. Neither value removes a
source: with one credential configured, resolution reaches it either way.
Settings -> Authentication now names the credential in use on the two Anthropic
cards and renders the control, but only when both are actually connected.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
8156308695 |
feat(quick-add): show a visible Start button for waiting-column workflows
Replace the hidden long-press/right-click Start menu on Quick Add's Save with a visible Start button in the action row, rendered only for workflows whose first visible lane is a hold column (or Coding (Ideas)). Eligibility, the workflow snapshot, the create-time column override, and the hold-first follow-up move are unchanged; ineligible workflows render no Start chip or shell. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
4b4df1ff30 |
FN-8565: restore tablet task modal resizing
Restore resizable Task Detail and New Task windows on 768px touch tablets. - Classify known touch tablets separately from phone sheets - Restore bounded modal geometry and resize grips with keyboard support - Add regression coverage, documentation, and a patch changeset Files changed: .changeset/fn-8565-tablet-task-modal-resize.md | 7 +++ docs/dashboard-guide.md | 5 ++ .../task-detail-modal-tablet-width.test.ts | 15 +++++ packages/dashboard/app/components/NewTaskModal.css | 18 +++++- packages/dashboard/app/components/NewTaskModal.tsx | 44 +++++++++++++- .../dashboard/app/components/TaskDetailModal.css | 30 ++++++++++ .../dashboard/app/components/TaskDetailModal.tsx | 40 +++++-------- .../app/components/__tests__/NewTaskModal.test.tsx | 68 +++++++++++++++++++++- ...etailModal.responsive-and-dependencies.test.tsx | 51 ++++++++++++++++ .../hooks/__tests__/useModalResizePersist.test.tsx | 53 ++++++++++++++++- .../dashboard/app/hooks/useModalResizePersist.ts | 58 +++++++++++++++--- 11 files changed, 352 insertions(+), 37 deletions(-) Fusion-Task-Id: FN-8565 Fusion-Task-Lineage: 7d9bbeb9-0e6a-4ad9-8b4d-e9f3d8aef650 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
a9d5b06013 |
FN-8562: add tags to chat conversations
Enable project-scoped reusable tags for Direct chat sessions. - Add tag storage, migrations, and scoped assignment APIs. - Add chat sidebar tag creation, assignment, and filtering controls. - Document tag behavior and cover schema and chat interactions. - Establish the session project/id candidate key before creating scoped tag foreign keys. Files changed: .changeset/fn-8562-chat-conversation-tags.md | 7 ++ docs/dashboard-guide.md | 4 + docs/storage.md | 2 + .../src/__tests__/postgres/schema-applier.test.ts | 8 +- packages/core/src/async-chat-store.ts | 117 ++++++++++++++++++++- packages/core/src/chat-store.ts | 32 ++++++ packages/core/src/chat-types.ts | 14 +++ packages/core/src/index.gate.ts | 3 + packages/core/src/index.ts | 3 + .../postgres/migrations/0036_chat_session_tags.sql | 64 +++++++++++ packages/core/src/postgres/schema-applier.ts | 16 ++- packages/core/src/postgres/schema/project.ts | 34 ++++++ packages/dashboard/app/api.ts | 1 + packages/dashboard/app/api/chat.ts | 18 ++++ packages/dashboard/app/components/ChatView.css | 17 +++ packages/dashboard/app/components/ChatView.tsx | 70 +++++++++++- .../__tests__/ChatView.core-interactions.test.tsx | 27 +++++ .../dashboard/app/hooks/__tests__/useChat.test.ts | 1 + packages/dashboard/app/hooks/useChat.ts | 52 ++++++++- .../dashboard/src/routes/register-chat-routes.ts | 70 ++++++++++++ 20 files changed, 550 insertions(+), 10 deletions(-) Fusion-Task-Id: FN-8562 Fusion-Task-Lineage: 4efe798c-0865-451a-adbd-6b85f9f8b149 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
03cfc2dfc8 |
FN-8561: add lifecycle dates to task cards
Show localized creation and completion dates directly on task cards. - Render compact, locale-aware lifecycle timestamps with accessible full-date titles. - Persist archive timestamps for completed archived-task fallbacks and add coverage. - Add translated labels, documentation, and a minor release changeset. Files changed: .changeset/fn-8561-task-card-dates.md | 7 +++ docs/dashboard-guide.md | 1 + .../__tests__/archive-entry-serialization.test.ts | 35 ++++++++++++++ packages/core/src/task-store/serialization.ts | 8 ++++ packages/core/src/types/task-core.ts | 5 ++ packages/dashboard/app/components/TaskCard.css | 27 +++++++++++ packages/dashboard/app/components/TaskCard.tsx | 55 ++++++++++++++++++++++ .../__tests__/TaskCard.host-inventory.test.tsx | 21 +++++++++ .../app/components/__tests__/TaskCard.test.tsx | 17 +++++++ .../dashboard/app/i18n/__tests__/format.test.ts | 19 +++++++- packages/dashboard/app/i18n/format.ts | 38 +++++++++++++++ packages/i18n/locales/en/app.json | 4 ++ packages/i18n/locales/es/app.json | 4 ++ packages/i18n/locales/fr/app.json | 4 ++ packages/i18n/locales/ko/app.json | 4 ++ packages/i18n/locales/zh-CN/app.json | 4 ++ packages/i18n/locales/zh-TW/app.json | 4 ++ 17 files changed, 256 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-8561 Fusion-Task-Lineage: 474b949b-d8e7-469a-b564-00acae66e58a Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
c5a8421533 |
FN-8560: forward desktop test telemetry flags
Desktop test execution now preserves CI reporter and JSON output flags. - Forward caller-selected Vitest reporters and output files through the desktop test wrapper. - Add coverage for reporter syntax and shard timing command forwarding. - Document desktop timing artifact requirements. Files changed: docs/testing.md | 7 ++++- packages/desktop/scripts/__tests__/test-args.test.ts | 36 ++++++++++++++++++++++ packages/desktop/scripts/test-args.ts | 13 ++++++++ packages/desktop/scripts/test.ts | 3 +- scripts/__tests__/ci-test-shard.test.mjs | 9 ++++++ 5 files changed, 66 insertions(+), 2 deletions(-) Fusion-Task-Id: FN-8560 Fusion-Task-Lineage: 2a89b28d-39f6-4949-aec2-1123c36126cf Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
973c978f91 |
FN-8557: preserve terminal geometry on tablets
Keep floating terminal controls available on touch tablets across responsive and keyboard viewport changes. - Classify known tablet screens separately from phone fallbacks. - Restore tablet floating and docked geometry at the 768px breakpoint with larger touch resize targets. - Cover keyboard-shrunken and breakpoint tablet interactions, and document the responsive behavior. Files changed: docs/dashboard-guide.md | 2 +- .../dashboard/app/components/TerminalModal.css | 76 +++++++++-- .../dashboard/app/components/TerminalModal.tsx | 33 ++--- .../components/__tests__/TerminalModal.test.tsx | 150 +++++++++++++++++++++ .../app/hooks/__tests__/useViewportMode.test.ts | 14 ++ packages/dashboard/app/hooks/useViewportMode.ts | 33 ++++- 6 files changed, 277 insertions(+), 31 deletions(-) Fusion-Task-Id: FN-8557 Fusion-Task-Lineage: cd334682-e70a-4531-ab53-c5c0898f0bf1 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
faeb491ea4 |
fix(dashboard): harden terminal paste contract and manual-start button per review
Review follow-up to
|
||
|
|
dfb9ca6630 |
FN-8543: enforce bounded generated-fix remediation
Keep generated fix chains within their root retry budget and preserve intervention stops. - Track retry counts and stop reasons on the canonical root feature. - Persist project-isolated lineage stops across generated-fix removal and archive paths. - Serialize stop recording with generated-fix admission and expose conflict-safe mission resume behavior. Files changed: .changeset/fn-8543-bounded-fix-lineage.md | 7 + docs/missions.md | 6 +- .../__tests__/postgres/mission-store.pg.test.ts | 72 +++++++ packages/core/src/async-mission-store-queries.ts | 91 ++++++++- packages/core/src/async-mission-store.ts | 206 ++++++++++++++++++--- packages/core/src/index.ts | 2 +- packages/core/src/mission-store.ts | 10 + packages/core/src/mission-types.ts | 7 + .../0035_fn_8543_mission_lineage_stop.sql | 31 ++++ packages/core/src/postgres/schema-applier.ts | 18 +- packages/core/src/postgres/schema/project.ts | 21 +++ .../core/src/task-store/archive-lifecycle-2.ts | 15 +- .../core/src/task-store/async-archive-lineage.ts | 10 +- packages/dashboard/src/mission-routes.ts | 14 +- packages/engine/src/mission-execution-loop.ts | 30 ++- 15 files changed, 495 insertions(+), 45 deletions(-) Fusion-Task-Id: FN-8543 Fusion-Task-Lineage: 24c03d63-5914-4072-aa17-16862432fc78 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
0c085bf444 |
fix(engine): pushAfterMerge no longer strands approved merges when the remote diverges (#2407)
## Problem
With `pushAfterMerge` enabled (and `mergeStrategy` other than
`pull-request`), if `origin/<integration-branch>` advances externally
between the local squash-merge and the push, the divergence path opens a
clean-room `git pull --rebase` and an AI agent resolves and stages the
conflicts — but the flow could end there: no `git rebase --continue`, no
push, and no surfaced error.
Because finalize runs *before* the push, the task is already `done`, so
a reviewed, approved merge is silently left container-only, and every
subsequent merge on the project stalls the same way. Separately, an
abort mid-push (`MergeAbortedError`) was swallowed with only a
process-log warning — no task-log entry, no run-audit event.
## Change
- **Deterministic regression coverage** for the conflicting-divergence
path (real-git fixture) proving the rebase runs to completion and the
push lands (refs converge), plus abort/termination scenarios.
- **Recovery-branch safety net:** before the clean-room rebase starts,
the pre-rebase local squash is force-pushed to a per-task remote branch
`fusion/<task-id>-stranded`, so approved content is never container-only
— even across process death or abort. Deleted after a successful target
push; retained on failure/abort as the recovery source.
- **Never-silent outcomes:** every non-pushed outcome (failure or abort)
writes a durable task-log entry and a `push:origin` run-audit event. The
audit contract now documents `push:origin` as polymorphic (dashboard
Smart Push vs. automated post-merge push) and enumerates the automated
path's outcomes, including the new `"aborted"` shutdown case.
- **Cleanup hardening:** `isRebaseInProgress` now probes Git's
worktree-specific `rebase-merge`/`rebase-apply` state directories
(async, timeout-guarded) so a completed rebase can't receive a spurious
second `--continue`; unfinished rebases are cleaned up.
Out of scope by design: withholding the "merge confirmed" state until
the push succeeds — the `FNXC:MergePush` invariant ("a push problem can
never park or roll back a landed merge") is deliberate; the recovery
branch + surfacing satisfy the data-preservation intent without breaking
it.
## Files
`packages/engine/src/merger-ai.ts`, `packages/engine/src/merger.ts`,
`packages/engine/src/run-audit.ts`, new/updated tests under
`packages/engine/src/__tests__/`, `docs/settings-reference.md`,
`docs/dashboard-guide.md`, `AGENTS.md`, and a labeled changeset.
## Validation
`tsc --noEmit` clean; engine divergence + merger suites pass (41 tests);
rebased onto current `main` with no conflicts.
---
_Developed with Claude Code, under human supervision and review._
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Prevented approved post-merge pushes from becoming stranded when the
remote diverges by using a recovery-branch workflow and safer cleanup.
* Improved behavior and reporting when pushes are aborted or fail after
merge, including clearer non-fatal status and audit outcomes.
* **Documentation**
* Expanded push-after-merge and dashboard Smart Push documentation with
recovery-branch and `push:origin`/`push:recovery-branch` outcome
semantics.
* **Tests**
* Added end-to-end regression tests for divergent/conflicting AI
push-after-merge flows, including abort and worktree cleanup
verification.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Victor Cano <victortroz@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
|
||
|
|
e5caea542a |
FN-8544: gate mission remediation behind autopilot
Keep mission validation report-only until an operator explicitly enables autopilot. - Gate validator-created remediation features and task dispatch behind mission autopilot. - Audit attributed status and autopilot transitions atomically across mission stores. - Expose mission autonomy controls and document the opt-in lifecycle. Files changed: .changeset/fn-8544-mission-autonomy-audit.md | 7 ++ docs/missions.md | 10 +- packages/cli/src/extension.ts | 26 ++++- .../__tests__/postgres/mission-store.pg.test.ts | 27 +++++ packages/core/src/async-mission-store.ts | 70 +++++++++++-- packages/core/src/index.gate.ts | 3 + packages/core/src/index.ts | 3 + packages/core/src/mission-store.ts | 113 +++++++++++++-------- packages/core/src/mission-types.ts | 22 ++++ .../dashboard/app/components/MissionManager.tsx | 1 + packages/dashboard/src/mission-routes.ts | 25 +++-- .../src/__tests__/agent-mission-tools.test.ts | 17 +++- .../src/__tests__/mission-execution-loop.test.ts | 21 ++++ packages/engine/src/agent-heartbeat.ts | 4 +- packages/engine/src/agent-tools.ts | 30 +++++- packages/engine/src/executor.ts | 5 +- packages/engine/src/mission-autopilot.ts | 51 +++++----- packages/engine/src/mission-execution-loop.ts | 49 ++++++--- packages/engine/src/triage.ts | 5 +- 19 files changed, 377 insertions(+), 112 deletions(-) Fusion-Task-Id: FN-8544 Fusion-Task-Lineage: 23a69923-5a19-407e-9fe2-8973c166ee9a Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |
||
|
|
e7c9b2ac80 |
FN-8542: separate milestone acceptance from feature validation
Keep feature validation scoped to linked feature assertions while evaluating milestone acceptance at rollup. - Add assertion scope and origin provenance with database migration support - Synchronize milestone acceptance prose to a canonical milestone assertion - Prevent milestone assertions from affecting feature verdicts and document the completion contract - Cover scoped validation and milestone rollup behavior with core and engine tests Files changed: .changeset/fn-8542-feature-validation-scope.md | 7 + docs/missions-completion-contract.md | 25 +- docs/missions.md | 6 +- .../mission-store.sync-loop-transition.test.ts | 53 +++++ packages/core/src/async-mission-store-queries.ts | 17 +- packages/core/src/async-mission-store.ts | 58 ++++- packages/core/src/mission-store.ts | 118 +++++++++- packages/core/src/mission-types.ts | 25 ++ .../core/src/postgres/migrations/0000_initial.sql | 2 + .../0034_milestone_assertion_provenance.sql | 30 +++ packages/core/src/postgres/schema-applier.ts | 24 +- packages/core/src/postgres/schema/project.ts | 1 + .../src/__tests__/mission-execution-loop.test.ts | 161 ++++++++++++- packages/engine/src/mission-execution-loop.ts | 262 ++++++++++++++++----- 14 files changed, 700 insertions(+), 89 deletions(-) Fusion-Task-Id: FN-8542 Fusion-Task-Lineage: cf112d31-376a-456e-be08-225eab5de393 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai> |