feat(fusion): add Global → General settings pane and wire fn --version

Move the Star-on-GitHub toggle, CLI Binary panel, and update-check
controls out of project General into a new Global → General pane (with
an inline Updates subsection), matching their actual scope. Drop the
CLI Binary panel's outlined card background and apply the standard
horizontal indent so it doesn't bleed to the pane edges.

Wire --version / -v in the fn/fusion bin so the dashboard's CLI Binary
probe gets a real version string instead of booting the dashboard and
reporting "unknown".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-05-01 16:02:23 -07:00
parent 1f58786c1a
commit 4a8e40838c
4 changed files with 117 additions and 61 deletions

View File

@@ -13,9 +13,10 @@
*/
import { existsSync, mkdtempSync, readFileSync, symlinkSync, writeFileSync } from "node:fs";
import { createRequire } from "node:module";
import { join, dirname } from "node:path";
import { join, dirname, resolve } from "node:path";
import { tmpdir } from "node:os";
import { performance } from "node:perf_hooks";
import { fileURLToPath } from "node:url";
// @ts-expect-error -- Bun-only global; undefined in Node
const isBunBinary = typeof Bun !== "undefined" && !!Bun.embeddedFiles;
@@ -412,9 +413,53 @@ function getFlagValueNumber(args: string[], flag: string): number | undefined {
return Number.isFinite(parsed) ? parsed : undefined;
}
/**
* Locate `@runfusion/fusion`'s own version by walking up from the running
* `bin.js`. Mirrors `packages/dashboard/src/cli-package-version.ts` but is
* inlined here to avoid pulling the dashboard barrel into the bin's static
* import graph (bin keeps app imports dynamic until env bootstrap is done).
*/
function readOwnCliVersion(): string | undefined {
let currentDir: string;
try {
currentDir = dirname(fileURLToPath(import.meta.url));
} catch {
return undefined;
}
for (let i = 0; i < 8; i += 1) {
const pkgPath = resolve(currentDir, "package.json");
if (existsSync(pkgPath)) {
try {
const parsed = JSON.parse(readFileSync(pkgPath, "utf-8")) as {
name?: string;
version?: string;
};
if (parsed.name === "@runfusion/fusion" && typeof parsed.version === "string") {
return parsed.version;
}
} catch {
// Ignore malformed manifest and keep walking.
}
}
const parentDir = resolve(currentDir, "..");
if (parentDir === currentDir) break;
currentDir = parentDir;
}
return undefined;
}
async function main() {
const { cleanedArgs: args, projectName } = extractGlobalProjectFlag(process.argv.slice(2));
// Print version and exit before any application imports. This is what the
// dashboard's CLI Binary panel probes via `<bin> --version`; without an
// early exit, the flag falls through to the default `dashboard` command and
// boots the full server.
if (args.includes("--version") || args.includes("-v")) {
console.log(readOwnCliVersion() ?? "unknown");
process.exit(0);
}
if (args.includes("--help") || args.includes("-h")) {
console.log(HELP);
process.exit(0);