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>
126 lines
3.9 KiB
JavaScript
126 lines
3.9 KiB
JavaScript
export function buildDevNodeArgs({
|
|
inspectFlags = [],
|
|
preload,
|
|
loader,
|
|
entry,
|
|
args = [],
|
|
}) {
|
|
return [
|
|
...inspectFlags,
|
|
"--conditions=source",
|
|
"--require",
|
|
preload,
|
|
"--import",
|
|
`file://${loader}`,
|
|
entry,
|
|
...args,
|
|
];
|
|
}
|
|
|
|
const VALID_PREBUILD_MODES = new Set(["auto", "none", "client", "full"]);
|
|
|
|
export function normalizePrebuildMode(value) {
|
|
const mode = value === undefined || value === null ? "auto" : String(value).toLowerCase();
|
|
if (mode === "" || !VALID_PREBUILD_MODES.has(mode)) {
|
|
throw new Error(`Invalid prebuild mode "${value}". Expected one of: auto, none, client, full.`);
|
|
}
|
|
return mode;
|
|
}
|
|
|
|
export function hasHostOverride(args) {
|
|
return args.includes("--host") || args.some((arg) => arg.startsWith("--host="));
|
|
}
|
|
|
|
export function buildForwardedDevArgs(args) {
|
|
const needsDevHostInjection = args[0] === "dashboard" && !hasHostOverride(args);
|
|
return needsDevHostInjection ? [...args, "--host", "0.0.0.0"] : args;
|
|
}
|
|
|
|
export function parseDevWrapperArgs(rawArgs, env = process.env) {
|
|
const inspectFlags = [];
|
|
const args = [];
|
|
let requestedPrebuild = env.FUSION_DEV_PREBUILD ?? "auto";
|
|
|
|
for (let i = 0; i < rawArgs.length; i += 1) {
|
|
const arg = rawArgs[i];
|
|
if (arg === "--inspect" || arg === "--inspect-brk" || arg.startsWith("--inspect=") || arg.startsWith("--inspect-brk=")) {
|
|
inspectFlags.push(arg);
|
|
continue;
|
|
}
|
|
|
|
if (arg === "--prebuild") {
|
|
const value = rawArgs[i + 1];
|
|
if (!value) {
|
|
throw new Error("Missing value for --prebuild. Expected one of: auto, none, client, full.");
|
|
}
|
|
requestedPrebuild = value;
|
|
i += 1;
|
|
continue;
|
|
}
|
|
|
|
if (arg.startsWith("--prebuild=")) {
|
|
requestedPrebuild = arg.slice("--prebuild=".length);
|
|
continue;
|
|
}
|
|
|
|
if (arg === "--skip-build") {
|
|
requestedPrebuild = "none";
|
|
continue;
|
|
}
|
|
|
|
args.push(arg);
|
|
}
|
|
|
|
return {
|
|
inspectFlags,
|
|
args,
|
|
requestedPrebuild: normalizePrebuildMode(requestedPrebuild),
|
|
};
|
|
}
|
|
|
|
export function resolvePrebuildMode(requestedPrebuild, forwardedArgs) {
|
|
const mode = normalizePrebuildMode(requestedPrebuild);
|
|
if (mode !== "auto") {
|
|
return mode;
|
|
}
|
|
|
|
const command = forwardedArgs[0] ?? "dashboard";
|
|
return command === "dashboard" ? "client" : "none";
|
|
}
|
|
|
|
export function getPrebuildCommand(mode) {
|
|
switch (normalizePrebuildMode(mode)) {
|
|
case "full":
|
|
return { command: "pnpm", args: ["build"], label: "workspace build" };
|
|
case "client":
|
|
/*
|
|
FNXC:DevWorkflow 2026-06-18-16:40:
|
|
FN-6638/stale-dist: `pnpm dev dashboard` must rebuild @fusion/core and
|
|
@fusion/engine alongside the dashboard UI, not only the client bundle.
|
|
Although the CLI runs under `--conditions=source` (engine/core resolve to
|
|
src), the running process and any dist-resolving consumer (plugins,
|
|
sub-imports, a later non-dev `fn`/`pnpm local`) load built dist. Leaving
|
|
engine/core dist stale is exactly how landed fixes (FN-6644/6647/6648,
|
|
etc.) silently failed to run for ~2 days.
|
|
|
|
FNXC:DevWorkflow 2026-07-10-15:40:
|
|
FN-7779/stale-plugin-dist: the app-package build alone left plugin dist/
|
|
stale — a source-only plugin fix (the Grok CLI-flag fix behind "messages
|
|
aren't sending") never took effect until a manual rebuild. The client
|
|
prebuild is now an orchestrator (scripts/dev-prebuild-client.mjs) that
|
|
first runs the fast core → engine → dashboard build (dependency order;
|
|
dashboard `build` also runs the vite client bundle + server tsc) and then
|
|
incrementally rebuilds ONLY changed plugins via the content-hash skip
|
|
cache. A single node command keeps the spawn contract cross-platform.
|
|
*/
|
|
return {
|
|
command: "node",
|
|
args: ["scripts/dev-prebuild-client.mjs"],
|
|
label: "core + engine + dashboard + changed plugins build",
|
|
};
|
|
case "none":
|
|
case "auto":
|
|
return null;
|
|
}
|
|
}
|