Files
fusion/scripts/dev-prebuild-client.mjs
gsxdsm 8f7089ecc9 fix(FN-7779): rebuild changed plugins on pnpm dev + warn on stale plugin dist
The Grok stale-dist bug was possible because the dev/build path never
refreshed plugin dist:

- The `client` prebuild (default `pnpm dev dashboard`) rebuilt only
  @fusion/core + @fusion/engine + @fusion/dashboard, never plugins.
- The FN-6638 stale-dist startup warning only scanned packages/, never
  plugins/, so a source-ahead plugin dist ran phantom-old with no warning.

Changes:
- build-workspace.mjs: add `--plugins-only` to plan/build just the plugins
  that changed, reusing the existing content-hash skip cache (cheap no-op when
  unchanged).
- scripts/dev-prebuild-client.mjs: new orchestrator — fast core/engine/
  dashboard build, then incremental changed-plugin rebuild. The `client`
  prebuild now runs this single cross-platform command.
- dist-freshness.mjs: scan plugin roots (plugins/, plugins/examples/) so a
  stale plugin dist is warned like a stale package dist; the warning names the
  plugin dir.

Verified: --plugins-only plans only plugins, skips unchanged on the second
run, and re-plans exactly the one plugin whose source changed. All script and
CLI lib tests pass.

Fusion-Task-Id: FN-7779
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 13:26:23 -07:00

44 lines
1.9 KiB
JavaScript

#!/usr/bin/env node
/*
FNXC:DevWorkflow 2026-07-10-15:40:
FN-7779 stale-plugin-dist: the `client` prebuild for `pnpm dev dashboard`.
Runs in two ordered steps so a dev restart never runs phantom-old code:
1. The FN-6638 fast path — rebuild @fusion/core + @fusion/engine +
@fusion/dashboard dist (NOT the full workspace) so landed engine/core/UI
fixes take effect.
2. Incrementally rebuild ONLY changed plugins via build-workspace's
content-hash skip cache (`--plugins-only`). Plugins load their built
dist/ at runtime, so a source-only plugin fix (e.g. the Grok CLI-flag fix
that caused "messages aren't sending") was silently stale until this step
existed — the old client prebuild rebuilt the three app packages but never
the plugins.
Unchanged plugins are a cheap content-hash no-op, so step 2 stays fast. Node
(not a shell `&&`) sequences the steps for cross-platform correctness.
*/
import { spawnSync } from "node:child_process";
import path from "node:path";
import { fileURLToPath } from "node:url";
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
// Windows resolves `pnpm` to a `.cmd` shim Node can't spawn without a shell
// (ENOENT since CVE-2024-27980); these args carry no shell metacharacters.
const useShell = process.platform === "win32";
function run(command, args, options = {}) {
const result = spawnSync(command, args, { cwd: repoRoot, stdio: "inherit", ...options });
return result.status ?? 1;
}
// Step 1: fast app-package build (core -> engine -> dashboard, dependency order).
const appStatus = run(
"pnpm",
["--filter", "@fusion/core", "--filter", "@fusion/engine", "--filter", "@fusion/dashboard", "build"],
{ shell: useShell },
);
if (appStatus !== 0) process.exit(appStatus);
// Step 2: incremental changed-plugin rebuild.
process.exit(run("node", ["scripts/build-workspace.mjs", "--plugins-only"]));