- pnpm dev / new pnpm start default to the dashboard command
- fn dashboard (and bare fn/fusion/npx, incl. packaged binaries) now runs
supervised by default via an attached foreground child (TUI-safe);
--no-supervise opts out; FUSION_RESTART_EXIT_CODE=86 = intentional restart
- New /api/system routes: info, restart, rebuild jobs with SSE output,
engine restart, agents restart-all, plugins reload-all, log tail
- System tab: rebuild & restart (source checkouts only, hidden elsewhere),
restart server/engine/agents, backup DB, live server logs, copy
diagnostics, report bug; new Plugins tab reusing PluginManager
- Desktop restart via Electron app.relaunch(); DashboardLogSink now keeps a
bounded history + listener feed for the log viewer
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Prototype and land a rebuilt-every-run esbuild bundle of the @fusion/core gate-safe barrel closure, collapsing the engine-core gate's per-fork Vite SSR import-phase cost (18 forks x ~430-file closure re-resolved from scratch) into a single file load per fork.
- Add scripts/build-engine-core-gate-bundle.mjs: esbuild-bundles packages/core/src/index.gate.ts (220 first-party files, packages:"external" so third-party/node: imports stay external, treeShaking:false to preserve side effects) into packages/core/.gate-bundle/core.mjs + core.meta.json
- Wire the builder into packages/engine/vitest.config.ts's engine-core project globalSetup (alongside the existing vitest-teardown hook) so the bundle is rebuilt fresh before every gate invocation, and repoint the @fusion/core resolve.alias at the bundled output instead of index.gate.ts source
- Place the bundle output at packages/core/.gate-bundle/ as a sibling of packages/core/node_modules/ (not nested inside it) to avoid Vite SSR's external-dep heuristic, which would otherwise silently defeat vi.mock interception for imports nested in the bundle
- Gitignore packages/core/.gate-bundle/ and add a matching ESLint ignore entry so the generated bundle text is never linted or committed
- Add esbuild ^0.25.12 as a root devDependency (pnpm-lock.yaml updated accordingly)
- Document the pre-bundling rationale, placement constraints, and measured A/B wall-time results in docs/testing.md
Verified: pnpm test:gate passes (335/335 engine-core tests, 63/63 CLI ci-shape tests), engine package typecheck clean, eslint clean on touched files.
Files changed:
.gitignore | 11 ++
docs/testing.md | 3 +
eslint.config.mjs | 10 ++
package.json | 1 +
packages/engine/vitest.config.ts | 50 ++++++++-
pnpm-lock.yaml | 3 +
scripts/build-engine-core-gate-bundle.mjs | 174 ++++++++++++++++++++++++++++++
7 files changed, 247 insertions(+), 5 deletions(-)
Fusion-Task-Id: FN-7669
Fusion-Task-Lineage: 62b06b2a-4ac6-45ae-ac79-9771132bc303
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
The Windows desktop installer failed to package: electron-builder's production-dependency walk rejected
`@aws-sdk/core@3.974.26` because `@aws-sdk/credential-provider-env` (resolved in the `--legacy` deploy
closure) requires `^3.974.27`. Root cause: an incidental `pnpm.overrides` entry pinning
`@aws-sdk/core` to the exact version `3.974.26` (added without rationale in an unrelated commit) which
force-held core below what its consumers now demand — the classic stale-exact-pin trap.
Fixes / prevention:
- Remove the `@aws-sdk/core` override so the deploy closure resolves core to 3.974.27 (satisfies all
consumers). The main lockfile still resolves core to 3.974.26 for its own consistent graph, so the
published @runfusion/fusion closure is unchanged (no changeset needed). Verified locally: a fresh
`@fusion/desktop build` + `electron-builder --dir` now passes the dependency walk with no manual patch.
- Add an advisory, path-gated `Desktop packaging` job to pr-checks.yml that reproduces electron-builder's
production-dependency walk (`--dir`, no NSIS/signing) plus a `pnpm dedupe --check` early-warning. This
is the only check that validates the packageable closure, which previously ran only in release/manual
workflows — so any future dependency skew now fails at PR time, for ANY dependency, instead of at
release/local-build time. Kept OUT of the required set so the thin merge gate [Lint, Typecheck, Build,
Gate] and branch protection are untouched; promote to blocking by adding it to required checks.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds scripts/verify-fast.mjs + root `pnpm verify:fast`, an opt-in, flake-free
verification path that runs typecheck + build scoped to the changed packages
(reusing test-changed.mjs git-diff / changed-package resolution) plus the
existing boot smoke once, with no test suite. Each step is bounded by the
shared runWithWatchdog (class "changed"); exits nonzero on the first failure.
No default changed: pnpm test, the merge gate, and CI are untouched.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Chain distillation into release:version so both local and CI versioning
flows get distilled notes. Update release.yml to use curated CHANGELOG
notes instead of GitHub's auto-generated release notes.
Add a pretest guard that caps new source files at 2,000 lines to stop
god-files from being born, following the existing check-no-* guard pattern.
Existing oversized files (106 of them) are grandfathered via a ratchet
baseline (scripts/line-count-baseline.json): each is pinned to its current
line count and may shrink but never grow. Files refactored under the cap
drop out of the baseline and cannot regress. Generated, lock, locale, and
.d.ts files are out of scope via the source-extension filter.
Wired into pretest and pretest:full; covered by 11 unit tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a weekly baseline workflow for tracking test feedback-loop speed and flake pressure.
- Add a stdlib-only script to record gate and pnpm test timings alongside slowest test files and quarantine counts.
- Publish generated markdown and JSON baseline artifacts for #leads reporting.
- Document the weekly refresh process and add package scripts plus coverage for the baseline helper.
Files changed:
docs/test-feedback-loop-baseline.md | 48 ++++++
docs/test-feedback-loop-baselines.json | 122 ++++++++++++++
docs/testing.md | 12 ++
package.json | 1 +
scripts/__tests__/test-feedback-baseline.test.mjs | 90 ++++++++++
scripts/test-feedback-baseline.mjs | 192 ++++++++++++++++++++++
6 files changed, 465 insertions(+)
Fusion-Task-Id: FN-6612
Fusion-Task-Lineage: 72bdc070-50e3-4e6b-a07d-3b8aeb9c2e92
- Add scripts/mobile-run-android.sh + pnpm mobile:run:android (auto-detects
Android SDK + JDK 21, writes local.properties, reconnects network ADB
before deploy, supports remote backend via FUSION_SERVER_URL).
- Header.css: reserve env(safe-area-inset-top) so top app chrome no longer
draws under the OS status bar on edge-to-edge native shells (Capacitor
Android API 35+, iOS notch, PWA standalone). No-op on web/desktop.
- .gitignore: ignore generated packages/mobile/{ios,android} (stale paths
pointed at packages/dashboard/).
Add a fast guard that rejects Vitest timeout bumps in tracked test files.
- Add a test-timeout appeasement scanner with a temporary allowlist for legacy exemptions.
- Run the scanner in pretest, pretest:full, and test:gate so merge gates catch timeout bumps.
- Cover the scanner behavior with node:test cases and document the policy/remediation path.
Files changed:
docs/testing.md | 6 ++
package.json | 6 +-
.../check-no-test-timeout-appeasement.test.mjs | 49 +++++++++
scripts/check-no-test-timeout-appeasement.mjs | 119 +++++++++++++++++++++
.../lib/test-timeout-appeasement-allowlist.json | 10 ++
5 files changed, 187 insertions(+), 3 deletions(-)
Fusion-Task-Id: FN-6434
Fusion-Task-Lineage: deb46a27-b0c9-4644-b8bb-34ce98e7acde
Create the @fusion/i18n package as the authored source-of-truth: shared
i18next config (namespace split, script-aware zh-CN/zh-TW fallback, plural
setup), en base catalogs, and a generated CLI static-import map so the
terminal surface is drop-in for new locales. Add the i18next-cli workflow
(extract/sync/types/status/lint) wired as root i18n:* scripts, install the
i18next stack into dashboard + CLI, strip @fusion/i18n from the published CLI
manifest, gitignore the generated dashboard catalog tree, and add a changeset.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Document and enforce pnpm build-script review decisions to prevent ignored-script install warnings.
- add reviewed ignoredBuiltDependencies entries to the root pnpm config and mirror the effective policy in pnpm-workspace.yaml
- add a regression test that verifies reviewed dependencies are categorized exactly once and stay aligned across both config files
- document the pnpm build-script approval policy in contributing docs and link plugin authoring guidance from AGENTS.md and PLUGIN_AUTHORING.md
Files changed:
AGENTS.md | 5 ++
docs/PLUGIN_AUTHORING.md | 3 +-
docs/contributing.md | 14 ++++
package.json | 9 +++
pnpm-workspace.yaml | 14 ++++
scripts/__tests__/pnpm-build-scripts-config.test.mjs | 74 ++++++++++++++++++++++
6 files changed, 118 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-5927
Fusion-Task-Lineage: 192bbed9-c5ed-45cb-b4bd-fb18514e2783
(b) Windows desktop build flakily failed with "Property 'ok'/'status' does
not exist on type 'Response'" because the workspace resolved multiple
@types/node versions (incl. an ancient 12.20.55 from @manypkg/find-root that
predates global fetch types). plugin-sdk compiles with lib:["ES2022"] and no
DOM lib, so Response comes solely from @types/node — nondeterministic across
runners. Pin via pnpm.overrides "@types/node": "^25.5.2"; collapses the
lockfile to one version. Verified: plugin-sdk build + desktop + full
workspace typecheck all pass.
Also: build-exe-cross tests cross-compiled all 5 platforms on every CI run
(auto-enabled via Boolean(process.env.CI)) — a release-build dependency in
the normal lane. Made them opt-in (FUSION_TEST_BUILD_EXE=1) and pointed the
root test:slow-cli at the CLI slow lane instead of test:pre-release, so
everyday CI no longer depends on release builds. test:pre-release and
test-release.yml still validate binaries deliberately.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>