Keep Compound Engineering navigation surfaces on the Boxes glyph even when stale plugin metadata is served.
- Route desktop and mobile plugin nav entries through a dashboard-view icon resolver.
- Pin Compound Engineering plugin nav icons to Boxes by plugin id while preserving normal icon fallback behavior for other plugins.
- Align manifest/header icon invariants and add regression coverage for stale Sparkles/Grid3X3 metadata.
- Add a patch changeset for the published Fusion package.
Files changed:
.changeset/FN-7198-compound-engineering-icon-match.md | 7 +++++++
packages/dashboard/app/components/LeftSidebarNav.tsx | 4 ++--
packages/dashboard/app/components/MobileNavBar.tsx | 6 +++---
.../app/components/__tests__/LeftSidebarNav.test.tsx | 6 +++++-
.../app/components/__tests__/MobileNavBar.test.tsx | 10 +++++++---
.../app/components/__tests__/pluginNavIcon.test.ts | 10 +++++++++-
packages/dashboard/app/components/pluginNavIcon.tsx | 12 ++++++++++++
.../src/__tests__/manifest.test.ts | 14 ++++++++++++++
.../src/dashboard/CompoundEngineeringView.tsx | 3 ++-
9 files changed, 61 insertions(+), 11 deletions(-)
Fusion-Task-Id: FN-7198
Fusion-Task-Lineage: e910bb82-55a7-4c81-a4fe-947a07b3e308
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Give Compound Engineering its own Boxes glyph across plugin navigation and headers.
- Register the Boxes lucide icon for plugin navigation so desktop and mobile sidebars can resolve it.
- Switch the Compound Engineering manifest, plugin definition, and view header from Sparkles to Boxes.
- Update navigation and manifest tests plus the release changeset for the published CLI bundle.
Files changed:
.changeset/FN-7197-compound-engineering-icon.md | 7 +++++++
.../app/components/__tests__/MobileNavBar.test.tsx | 2 +-
.../app/components/__tests__/pluginNavIcon.test.ts | 14 ++++++++++++++
packages/dashboard/app/components/pluginNavIcon.tsx | 7 ++++++-
plugins/fusion-plugin-compound-engineering/manifest.json | 2 +-
.../src/__tests__/manifest.test.ts | 2 +-
.../src/dashboard/CompoundEngineeringView.tsx | 12 +++++++++---
plugins/fusion-plugin-compound-engineering/src/index.ts | 2 +-
8 files changed, 40 insertions(+), 8 deletions(-)
Fusion-Task-Id: FN-7197
Fusion-Task-Lineage: 03c67bfa-3e28-4a2a-b15e-b2c3576588c1
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Keep bundled ce-brainstorm guidance aligned with docs/plans as the durable planning artifact.
- Update the visual probe reference to name docs/plans as the durable artifact.
- Add a recursive skill-content guard that prevents docs/brainstorms from being described as new or durable output.
- Assert legacy docs/brainstorms wording remains limited to ce-plan inputs.
Files changed:
.../__tests__/skill-content-alias-guard.test.ts | 85 ++++++++++++++++++++++
.../ce-brainstorm/references/visual-probes.md | 2 +-
2 files changed, 86 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-7104
Fusion-Task-Lineage: dd26a511-816d-479c-99ac-7cfec2b96bd4
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Root cause: fitToGraph's clampPan clamped against graphBoundsRef, which a separate effect populated from NORMALIZED bounds — on first paint the ref was still {0,0,0,0}, so pan clamped to +/-viewport (off-center) and only a manual drag re-ran clampPan against the committed bounds. Fit now runs on normalizedPositions (fit-space == render-space == clamp-space), after the setGraphBounds effect, deferred a double-rAF so the committed bounds are live before clampPan; ResizeObserver still drives the hidden->visible 0->N fit. Manual-layout opt-out preserved.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- List view: remove the 'X of Y tasks' count from the desktop sidebar toolbar and the border between the controls row and the quick-add box (mobile count kept). Count-display tests now verify the filter via rendered rows.
- Command Center Overview: View Board / View Agents are btn btn-secondary (taller, centered) matching the Stop AI Engine button.
- Dependency graph: fit/center on load — the initial fit ran before the viewport was measured + before nodes were positioned (async), and never re-fit. Now fits only when fittable (nodes + measured viewport) and re-fits when the node set changes (covers async load + re-entering the view).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Code review (8 reviewers) fixes:
- P1: embedded board task-detail now passes onRequestClose so delete/merge/retry dismiss the panel (no ghost task).
- P1: RightDock + TerminalModal drag handlers add pointercancel + unmount teardown (no leaked document listeners / rAF / stuck userSelect); remove dead onOpenChange prop.
- Planning slot DOM-poll interval now caps (self-cancels on mobile); heartbeat slider persist debounced + mounted-guarded.
- Cleanup: remove dead ViewHeader-migration CSS (Skills/Insights), extract shared GithubIcon, move Activity Log embedded CSS to ActivityLogModal.css, FNXC date-format fixes, AGENTS lazy-view note.
- Update stale RightDock roster tests + LeftSidebarNav 'Compound Eng' test to current behavior.
Live UI tweaks:
- Default load lands on board, never the Command Center Dashboard.
- View Board/View Agents moved to the Command Center Overview tab (under the live-activity strip).
- Heartbeat card full-width with spaced, wrapping controls.
- Dev Server panel scrolls in the dock; ChatView right-pane title takes the full line.
- Files pop-out renders deterministic left-right two-pane.
- Mailbox list pane narrower + narrow by default; Add Goal button height matches the Compound stage button; Memory Working-Memory tab no longer overlaps; Skills view fills full width.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Compound Engineering plugin view now renders the dashboard's shared ViewHeader (Sparkles icon + title) so it matches the other main-content views. Expose ViewHeader via the dashboard exports map; resolve it in the plugin via an ambient interop declaration (no host runtime dependency). Tests updated (plugin suite green).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rescue the ci-status plugin test suite by making CI polling deterministic and network-free.
- Stub global fetch for the full suite so refresh handlers and interval polls cannot reach ci.example.com.
- Share the mock task fixture across refresh and task-move tests.
- Cover tracked-branch and empty-branch refresh paths plus interval polling behavior.
Files changed:
.../src/__tests__/index.test.ts | 145 ++++++++++++++++-----
1 file changed, 115 insertions(+), 30 deletions(-)
Fusion-Task-Id: FN-6898
Fusion-Task-Lineage: 3758d995-bda9-4ab9-add7-e6a3f710dc6f
Roadmap dashboard styling now uses defined Fusion theme tokens and has regression coverage for undefined CSS custom properties.
- Retoken roadmap surfaces, form controls, and text from retired aliases to defined dashboard tokens.
- Document the roadmap styling requirement with an FNXC comment in the plugin CSS.
- Add a CSS-token validity test that rejects retired aliases and undefined roadmap custom-property references.
Files changed:
.../src/dashboard/RoadmapsView.css | 63 ++++-----
.../RoadmapsView.css-token-validity.test.ts | 147 +++++++++++++++++++++
2 files changed, 179 insertions(+), 31 deletions(-)
Fusion-Task-Id: FN-6867
Fusion-Task-Lineage: 0d5c71dc-b6ad-4b70-a792-2d8a05fe81f1
discoverDroidModels ran `droid models`/`droid model list`, which aren't real
droid commands — they parse as a prompt and launch a persistent
`droid exec --stream-jsonrpc` agent session that never exits, leaking a process
per call. The dashboard reloads the droid extension on every chat-send, so these
piled into dozens of orphaned `droid` processes.
Switch discovery to parse `droid exec --help` (lists Available + Custom models,
exits cleanly) via new parseDroidModelsFromHelp, and add a SIGKILL-on-timeout
guard so a wedged spawn can never leak. Verified against the real binary: 46
models, 0 leaked processes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolve conflicts from main's analytics schema additions (plugin
activations, per-model token buckets) against the PR's contract-assertion
type column:
- db.ts: renumber behavioral-verification migration 124 -> 126, bump
SCHEMA_VERSION to 126 so it follows main's migrations 124/125
- core/roadmap tests: adopt main's SCHEMA_VERSION-constant assertions
instead of stale literal 124
- test-quarantine.json: keep all four quarantine entries from both sides
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dist-freshness.test.ts reads the plugin's compiled dist/settings.js and
dist/session/orchestrator.js to guard against stale dist (FN-6596), but the
plugin had no pretest build and was missing from ensure-test-artifacts.mjs.
On a fresh CI checkout dist/ does not exist, so the guard threw "dist/ is
missing" — failing the non-blocking Full Suite on every main commit.
Register the plugin's required artifacts in ensure-test-artifacts.mjs and add
a `pretest` hook that builds them, matching the dependency-graph / hermes /
openclaw plugins. Verified locally: with dist/ absent, `pnpm --filter
@fusion-plugin-examples/compound-engineering test` now builds dist via the
pretest and all 192 plugin tests pass (incl. the two dist-freshness cases).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rescue the Paperclip CLI spawn coverage by making fake child events deterministic and re-enabling the suite.
- Route mintAgentApiKeyViaCli cases through the shared fake spawn helper so close and error events are emitted after listener registration.
- Document the async import/listener-order requirement that caused the quarantine.
- Remove paperclip-client.test.ts from the quarantine ledger and Vitest exclude list so the rescued tests run.
Files changed:
.../src/__tests__/paperclip-client.test.ts | 134 +++++++--------------
.../vitest.config.ts | 2 -
scripts/lib/test-quarantine.json | 5 -
3 files changed, 44 insertions(+), 97 deletions(-)
Fusion-Task-Id: FN-6636
Fusion-Task-Lineage: 79038ab3-0aa6-465e-9c6e-f6bc83fcd407
Restore the compound-engineering broad lane tests after the timeout could not be reproduced on the stabilized shared test infrastructure.
- Re-enable the compound-engineering sync and work-bridge tests by clearing their Vitest quarantine excludes.
- Remove the stale quarantine ledger entries now that the broad package lane stayed stable under verification.
Files changed:
plugins/fusion-plugin-compound-engineering/vitest.config.ts | 10 ++++------
scripts/lib/test-quarantine.json | 13 +------------
2 files changed, 5 insertions(+), 18 deletions(-)
Fusion-Task-Id: FN-6606
Fusion-Task-Lineage: f357c626-c181-44a7-a463-c53644566ca1
Normalize spawned Vitest processes to NODE_ENV=test so React/jsdom lanes do not inherit release-shell production mode. Split the compound-engineering plugin Vitest projects so Node-only setup and teardown only run in Node lanes, and quarantine the remaining broad-lane CE timeout flakes under the deletion ratchet.
Quarantine compound-engineering timeout flakes from the broad test workflow.
- Add the compound-engineering orchestrator and skill-wiring tests to the quarantine ledger.
- Exclude the quarantined tests from the compound-engineering node Vitest project without changing timeouts or retries.
- Document the quarantine requirement next to the Vitest excludes.
Files changed:
.../fusion-plugin-compound-engineering/vitest.config.ts | 15 ++++++++++++++-
scripts/lib/test-quarantine.json | 10 ++++++++++
2 files changed, 24 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-6587
Fusion-Task-Lineage: 5aeb0202-8330-4a93-bdab-675c81b9cb54
Make the WhatsApp chat test double constructable under Vitest 4.
- Replace the arrow-backed WhatsAppConnection vi.fn mock with a named function implementation usable with new.
- Document the Vitest constructor-mock requirement near the test double.
Files changed:
plugins/fusion-plugin-whatsapp-chat/src/__tests__/index.test.ts | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-6586
Fusion-Task-Lineage: 54ed6d1a-c42a-430b-846e-251f8a27e188