Files
fusion/scripts/dev-with-memory-lib.mjs
gsxdsm a227b19a22 feat: add Command Center System panel with rebuild/restart controls, Plugins tab, and supervised-by-default dashboard
- 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>
2026-07-12 14:42:09 -07:00

136 lines
4.4 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) {
/*
FNXC:DevWorkflow 2026-07-12-10:20:
`pnpm dev` and `pnpm start` with no command must behave exactly like
`pnpm dev dashboard` (client prebuild + LAN host injection), not fall through
to the CLI's bare default. Normalize empty/flag-only invocations to an
explicit "dashboard" command so every downstream decision (prebuild mode,
host injection) sees the same shape.
*/
const hasCommand = args.length > 0 && !String(args[0]).startsWith("-");
const normalized = hasCommand ? args : ["dashboard", ...args];
const needsDevHostInjection = normalized[0] === "dashboard" && !hasHostOverride(normalized);
return needsDevHostInjection ? [...normalized, "--host", "0.0.0.0"] : normalized;
}
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;
}
}