feat(FN-1318): rename CLI binary artifacts from kb to fn
- Update CLI build and runtime paths to emit and reference fn-named binaries across default and cross-target builds - Adjust Bun binary bootstrap stubs and native patch temp/symlink prefixes to use fn naming consistently - Update CI, release, and test-release workflows to validate and collect fn-prefixed artifacts - Align CLI build and package config tests with fn binary expectations and add a patch changeset for @gsxdsm/fusion
This commit is contained in:
5
.changeset/rename-cli-binary-kb-to-fn.md
Normal file
5
.changeset/rename-cli-binary-kb-to-fn.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@gsxdsm/fusion": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Rename standalone binary output from `kb` to `fn` to match the product rename.
|
||||||
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -40,4 +40,4 @@ jobs:
|
|||||||
run: pnpm --filter @gsxdsm/fusion build:exe
|
run: pnpm --filter @gsxdsm/fusion build:exe
|
||||||
|
|
||||||
- name: Verify binary exists
|
- name: Verify binary exists
|
||||||
run: test -f packages/cli/dist/kb
|
run: test -f packages/cli/dist/fn
|
||||||
|
|||||||
10
.github/workflows/release.yml
vendored
10
.github/workflows/release.yml
vendored
@@ -29,16 +29,16 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
target: bun-linux-x64
|
target: bun-linux-x64
|
||||||
binary: kb-linux-x64
|
binary: fn-linux-x64
|
||||||
- os: macos-latest
|
- os: macos-latest
|
||||||
target: bun-darwin-arm64
|
target: bun-darwin-arm64
|
||||||
binary: kb-darwin-arm64
|
binary: fn-darwin-arm64
|
||||||
- os: macos-13
|
- os: macos-13
|
||||||
target: bun-darwin-x64
|
target: bun-darwin-x64
|
||||||
binary: kb-darwin-x64
|
binary: fn-darwin-x64
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
target: bun-windows-x64
|
target: bun-windows-x64
|
||||||
binary: kb-windows-x64.exe
|
binary: fn-windows-x64.exe
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -133,7 +133,7 @@ jobs:
|
|||||||
- name: Collect release files
|
- name: Collect release files
|
||||||
run: |
|
run: |
|
||||||
mkdir release-files
|
mkdir release-files
|
||||||
find artifacts -type f \( -name "kb-*" -o -name "*.sha256" \) -exec cp {} release-files/ \;
|
find artifacts -type f \( -name "fn-*" -o -name "*.sha256" \) -exec cp {} release-files/ \;
|
||||||
ls -la release-files/
|
ls -la release-files/
|
||||||
|
|
||||||
- name: Create GitHub Release
|
- name: Create GitHub Release
|
||||||
|
|||||||
10
.github/workflows/test-release.yml
vendored
10
.github/workflows/test-release.yml
vendored
@@ -19,16 +19,16 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
target: bun-linux-x64
|
target: bun-linux-x64
|
||||||
binary: kb-linux-x64
|
binary: fn-linux-x64
|
||||||
- os: macos-latest
|
- os: macos-latest
|
||||||
target: bun-darwin-arm64
|
target: bun-darwin-arm64
|
||||||
binary: kb-darwin-arm64
|
binary: fn-darwin-arm64
|
||||||
- os: macos-13
|
- os: macos-13
|
||||||
target: bun-darwin-x64
|
target: bun-darwin-x64
|
||||||
binary: kb-darwin-x64
|
binary: fn-darwin-x64
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
target: bun-windows-x64
|
target: bun-windows-x64
|
||||||
binary: kb-windows-x64.exe
|
binary: fn-windows-x64.exe
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -133,7 +133,7 @@ jobs:
|
|||||||
- name: Combine artifacts
|
- name: Combine artifacts
|
||||||
run: |
|
run: |
|
||||||
mkdir combined
|
mkdir combined
|
||||||
find artifacts -type f \( -name "kb-*" -o -name "*.sha256" \) -exec cp {} combined/ \;
|
find artifacts -type f \( -name "fn-*" -o -name "*.sha256" \) -exec cp {} combined/ \;
|
||||||
ls -la combined/
|
ls -la combined/
|
||||||
|
|
||||||
- name: Upload combined archive
|
- name: Upload combined archive
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#!/usr/bin/env bun
|
#!/usr/bin/env bun
|
||||||
/**
|
/**
|
||||||
* Bun compile build script for the `kb` CLI.
|
* Bun compile build script for the `fn` CLI.
|
||||||
*
|
*
|
||||||
* Produces a single self-contained executable at packages/cli/dist/kb
|
* Produces a single self-contained executable at packages/cli/dist/fn
|
||||||
* with the dashboard client assets co-located at packages/cli/dist/client/.
|
* with the dashboard client assets co-located at packages/cli/dist/client/.
|
||||||
*
|
*
|
||||||
* Usage:
|
* Usage:
|
||||||
@@ -55,20 +55,20 @@ function targetToPrebuildName(target: BunTarget): string {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Map a Bun target identifier to the output binary name.
|
* Map a Bun target identifier to the output binary name.
|
||||||
* e.g. "bun-linux-x64" → "kb-linux-x64", "bun-windows-x64" → "kb-windows-x64.exe"
|
* e.g. "bun-linux-x64" → "fn-linux-x64", "bun-windows-x64" → "fn-windows-x64.exe"
|
||||||
*/
|
*/
|
||||||
function binaryNameForTarget(target: BunTarget): string {
|
function binaryNameForTarget(target: BunTarget): string {
|
||||||
// "bun-linux-x64" → "linux-x64"
|
// "bun-linux-x64" → "linux-x64"
|
||||||
const suffix = target.replace(/^bun-/, "");
|
const suffix = target.replace(/^bun-/, "");
|
||||||
const isWindows = target.includes("windows");
|
const isWindows = target.includes("windows");
|
||||||
return `kb-${suffix}${isWindows ? ".exe" : ""}`;
|
return `fn-${suffix}${isWindows ? ".exe" : ""}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine the default binary name for the current platform (no cross-compile).
|
* Determine the default binary name for the current platform (no cross-compile).
|
||||||
*/
|
*/
|
||||||
function defaultBinaryName(): string {
|
function defaultBinaryName(): string {
|
||||||
return process.platform === "win32" ? "kb.exe" : "kb";
|
return process.platform === "win32" ? "fn.exe" : "fn";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -272,7 +272,7 @@ const { targets } = parseArgs();
|
|||||||
const clientAssetMode = ensureClientAssets();
|
const clientAssetMode = ensureClientAssets();
|
||||||
|
|
||||||
if (targets === null) {
|
if (targets === null) {
|
||||||
// Default: build for current platform → dist/kb
|
// Default: build for current platform → dist/fn
|
||||||
const outBinary = join(outDir, defaultBinaryName());
|
const outBinary = join(outDir, defaultBinaryName());
|
||||||
const ok = compileBinary(outBinary, "bun", false);
|
const ok = compileBinary(outBinary, "bun", false);
|
||||||
if (!ok) process.exit(1);
|
if (!ok) process.exit(1);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const SUPPORTED_TARGETS = [
|
|||||||
function expectedBinaryName(target: string): string {
|
function expectedBinaryName(target: string): string {
|
||||||
const suffix = target.replace(/^bun-/, "");
|
const suffix = target.replace(/^bun-/, "");
|
||||||
const isWindows = target.includes("windows");
|
const isWindows = target.includes("windows");
|
||||||
return `kb-${suffix}${isWindows ? ".exe" : ""}`;
|
return `fn-${suffix}${isWindows ? ".exe" : ""}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,8 +44,8 @@ describe("build-exe-cross: single target", () => {
|
|||||||
});
|
});
|
||||||
}, 180_000);
|
}, 180_000);
|
||||||
|
|
||||||
it("produces dist/kb-linux-x64", () => {
|
it("produces dist/fn-linux-x64", () => {
|
||||||
const bin = join(distDir, "kb-linux-x64");
|
const bin = join(distDir, "fn-linux-x64");
|
||||||
expect(existsSync(bin)).toBe(true);
|
expect(existsSync(bin)).toBe(true);
|
||||||
expect(statSync(bin).size).toBeGreaterThan(0);
|
expect(statSync(bin).size).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
@@ -64,8 +64,8 @@ describe("build-exe-cross: windows target has .exe extension", () => {
|
|||||||
});
|
});
|
||||||
}, 180_000);
|
}, 180_000);
|
||||||
|
|
||||||
it("produces dist/kb-windows-x64.exe", () => {
|
it("produces dist/fn-windows-x64.exe", () => {
|
||||||
const bin = join(distDir, "kb-windows-x64.exe");
|
const bin = join(distDir, "fn-windows-x64.exe");
|
||||||
expect(existsSync(bin)).toBe(true);
|
expect(existsSync(bin)).toBe(true);
|
||||||
expect(statSync(bin).size).toBeGreaterThan(0);
|
expect(statSync(bin).size).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
@@ -143,8 +143,8 @@ describe("build-exe-cross: default (no args) backward compatibility", () => {
|
|||||||
});
|
});
|
||||||
}, 180_000);
|
}, 180_000);
|
||||||
|
|
||||||
it("produces dist/kb (no platform suffix)", () => {
|
it("produces dist/fn (no platform suffix)", () => {
|
||||||
const defaultName = process.platform === "win32" ? "kb.exe" : "kb";
|
const defaultName = process.platform === "win32" ? "fn.exe" : "fn";
|
||||||
const bin = join(distDir, defaultName);
|
const bin = join(distDir, defaultName);
|
||||||
expect(existsSync(bin)).toBe(true);
|
expect(existsSync(bin)).toBe(true);
|
||||||
expect(statSync(bin).size).toBeGreaterThan(0);
|
expect(statSync(bin).size).toBeGreaterThan(0);
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import { mkdtempSync, rmSync } from "node:fs";
|
|||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
|
|
||||||
const cliRoot = join(import.meta.dirname!, "..", "..");
|
const cliRoot = join(import.meta.dirname!, "..", "..");
|
||||||
const outBinary = join(cliRoot, "dist", process.platform === "win32" ? "kb.exe" : "kb");
|
const outBinary = join(cliRoot, "dist", process.platform === "win32" ? "fn.exe" : "fn");
|
||||||
const binaryName = process.platform === "win32" ? "kb.exe" : "kb";
|
const binaryName = process.platform === "win32" ? "fn.exe" : "fn";
|
||||||
const clientDir = join(cliRoot, "dist", "client");
|
const clientDir = join(cliRoot, "dist", "client");
|
||||||
const runtimeDir = join(cliRoot, "dist", "runtime");
|
const runtimeDir = join(cliRoot, "dist", "runtime");
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ const runtimeDir = join(cliRoot, "dist", "runtime");
|
|||||||
* and runtime/ assets — no package.json. Returns the dir path and a cleanup function.
|
* and runtime/ assets — no package.json. Returns the dir path and a cleanup function.
|
||||||
*/
|
*/
|
||||||
function createIsolatedDir(): { dir: string; binary: string; cleanup: () => void } {
|
function createIsolatedDir(): { dir: string; binary: string; cleanup: () => void } {
|
||||||
const dir = mkdtempSync(join(tmpdir(), "kb-iso-"));
|
const dir = mkdtempSync(join(tmpdir(), "fn-iso-"));
|
||||||
cpSync(outBinary, join(dir, binaryName), { recursive: true });
|
cpSync(outBinary, join(dir, binaryName), { recursive: true });
|
||||||
cpSync(clientDir, join(dir, "client"), { recursive: true });
|
cpSync(clientDir, join(dir, "client"), { recursive: true });
|
||||||
// Copy runtime native assets alongside binary
|
// Copy runtime native assets alongside binary
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ describe("CI workflow (.github/workflows/ci.yml)", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("verifies binary exists after build", () => {
|
it("verifies binary exists after build", () => {
|
||||||
expect(content).toContain("test -f packages/cli/dist/kb");
|
expect(content).toContain("test -f packages/cli/dist/fn");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("includes pnpm test step", () => {
|
it("includes pnpm test step", () => {
|
||||||
|
|||||||
@@ -37,12 +37,12 @@ describe("CLI package.json publishing config", () => {
|
|||||||
|
|
||||||
it("does not include bare 'dist' entry or globs that would match Bun binaries", () => {
|
it("does not include bare 'dist' entry or globs that would match Bun binaries", () => {
|
||||||
const bunBinaryNames = [
|
const bunBinaryNames = [
|
||||||
"kb",
|
"fn",
|
||||||
"kb-linux-x64",
|
"fn-linux-x64",
|
||||||
"kb-linux-arm64",
|
"fn-linux-arm64",
|
||||||
"kb-darwin-x64",
|
"fn-darwin-x64",
|
||||||
"kb-darwin-arm64",
|
"fn-darwin-arm64",
|
||||||
"kb-windows-x64.exe",
|
"fn-windows-x64.exe",
|
||||||
];
|
];
|
||||||
// No bare "dist" entry that would include everything
|
// No bare "dist" entry that would include everything
|
||||||
expect(pkg.files).not.toContain("dist");
|
expect(pkg.files).not.toContain("dist");
|
||||||
@@ -51,8 +51,8 @@ describe("CLI package.json publishing config", () => {
|
|||||||
for (const bin of bunBinaryNames) {
|
for (const bin of bunBinaryNames) {
|
||||||
expect(entry).not.toBe(`dist/${bin}`);
|
expect(entry).not.toBe(`dist/${bin}`);
|
||||||
}
|
}
|
||||||
// No wildcard like "dist/kb*" that would match binaries
|
// No wildcard like "dist/fn*" that would match binaries
|
||||||
expect(entry).not.toMatch(/^dist\/kb/);
|
expect(entry).not.toMatch(/^dist\/fn/);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ if (isBunBinary) {
|
|||||||
|
|
||||||
if (!existsSync(localPkg)) {
|
if (!existsSync(localPkg)) {
|
||||||
// Write a minimal package.json to a temp dir and redirect PI_PACKAGE_DIR
|
// Write a minimal package.json to a temp dir and redirect PI_PACKAGE_DIR
|
||||||
const tmp = mkdtempSync(join(tmpdir(), "kb-pkg-"));
|
const tmp = mkdtempSync(join(tmpdir(), "fn-pkg-"));
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
join(tmp, "package.json"),
|
join(tmp, "package.json"),
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
{ name: "kb", version: "0.1.0", type: "module", piConfig: { name: "kb", configDir: ".fusion" } },
|
{ name: "fn", version: "0.1.0", type: "module", piConfig: { name: "fn", configDir: ".fusion" } },
|
||||||
null,
|
null,
|
||||||
2,
|
2,
|
||||||
) + "\n",
|
) + "\n",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
* where bundled code runs. Node-pty looks for native modules at:
|
* where bundled code runs. Node-pty looks for native modules at:
|
||||||
* /$bunfs/root/prebuilds/<platform>-<arch>/pty.node
|
* /$bunfs/root/prebuilds/<platform>-<arch>/pty.node
|
||||||
*
|
*
|
||||||
* This module creates a real directory structure at /tmp/kb-bunfs-<pid>/ that mirrors
|
* This module creates a real directory structure at /tmp/fn-bunfs-<pid>/ that mirrors
|
||||||
* the expected structure, then attempts to create a symlink from /$bunfs/root to that
|
* the expected structure, then attempts to create a symlink from /$bunfs/root to that
|
||||||
* temp directory (on macOS/Linux) so node-pty can find the native assets.
|
* temp directory (on macOS/Linux) so node-pty can find the native assets.
|
||||||
*/
|
*/
|
||||||
@@ -64,9 +64,9 @@ function cleanupStaleBunfsLinks(): void {
|
|||||||
if (stats.isSymbolicLink()) {
|
if (stats.isSymbolicLink()) {
|
||||||
const target = readlinkSync(bunfsRoot);
|
const target = readlinkSync(bunfsRoot);
|
||||||
// If the target is a temp dir that no longer exists, remove the stale link
|
// If the target is a temp dir that no longer exists, remove the stale link
|
||||||
if (target.includes("kb-bunfs-") && !existsSync(target)) {
|
if (target.includes("fn-bunfs-") && !existsSync(target)) {
|
||||||
rmSync(bunfsRoot);
|
rmSync(bunfsRoot);
|
||||||
console.log("[kb-native-patch] Cleaned up stale /$bunfs/root symlink");
|
console.log("[fn-native-patch] Cleaned up stale /$bunfs/root symlink");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,7 +79,7 @@ function cleanupStaleBunfsLinks(): void {
|
|||||||
* Set up the native module resolution structure.
|
* Set up the native module resolution structure.
|
||||||
*
|
*
|
||||||
* Creates:
|
* Creates:
|
||||||
* /tmp/kb-bunfs-<pid>/kb/prebuilds/<platform>-<arch>/
|
* /tmp/fn-bunfs-<pid>/fn/prebuilds/<platform>-<arch>/
|
||||||
* ├── pty.node
|
* ├── pty.node
|
||||||
* └── spawn-helper (Unix only)
|
* └── spawn-helper (Unix only)
|
||||||
*
|
*
|
||||||
@@ -89,7 +89,7 @@ function cleanupStaleBunfsLinks(): void {
|
|||||||
export function setupNativeResolution(): { success: boolean; nativeDir: string | null } {
|
export function setupNativeResolution(): { success: boolean; nativeDir: string | null } {
|
||||||
const nativeDir = findStagedNativeDir();
|
const nativeDir = findStagedNativeDir();
|
||||||
if (!nativeDir) {
|
if (!nativeDir) {
|
||||||
console.warn("[kb-native-patch] No native assets found, terminal will be unavailable");
|
console.warn("[fn-native-patch] No native assets found, terminal will be unavailable");
|
||||||
return { success: false, nativeDir: null };
|
return { success: false, nativeDir: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,9 +102,9 @@ export function setupNativeResolution(): { success: boolean; nativeDir: string |
|
|||||||
process.env.FUSION_NATIVE_ASSETS_PATH = nativeDir;
|
process.env.FUSION_NATIVE_ASSETS_PATH = nativeDir;
|
||||||
|
|
||||||
// Create the fake bunfs structure
|
// Create the fake bunfs structure
|
||||||
const tmpRoot = join(tmpdir(), `kb-bunfs-${process.pid}`);
|
const tmpRoot = join(tmpdir(), `fn-bunfs-${process.pid}`);
|
||||||
const kbDir = join(tmpRoot, "kb");
|
const fnDir = join(tmpRoot, "fn");
|
||||||
const prebuildsDir = join(kbDir, "prebuilds");
|
const prebuildsDir = join(fnDir, "prebuilds");
|
||||||
const platformDir = join(prebuildsDir, basename(nativeDir));
|
const platformDir = join(prebuildsDir, basename(nativeDir));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -138,23 +138,23 @@ export function setupNativeResolution(): { success: boolean; nativeDir: string |
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new symlink pointing to our temp kb directory
|
// Create new symlink pointing to our temp fn directory
|
||||||
// We want /$bunfs/root -> /tmp/kb-bunfs-<pid>/kb
|
// We want /$bunfs/root -> /tmp/fn-bunfs-<pid>/fn
|
||||||
// So that /$bunfs/root/prebuilds/<platform>/pty.node resolves correctly
|
// So that /$bunfs/root/prebuilds/<platform>/pty.node resolves correctly
|
||||||
symlinkSync(kbDir, bunfsRoot);
|
symlinkSync(fnDir, bunfsRoot);
|
||||||
bunfsSymlinkPath = bunfsRoot;
|
bunfsSymlinkPath = bunfsRoot;
|
||||||
console.log("[kb-native-patch] Created /$bunfs/root symlink for native module resolution");
|
console.log("[fn-native-patch] Created /$bunfs/root symlink for native module resolution");
|
||||||
} catch (symlinkErr) {
|
} catch (symlinkErr) {
|
||||||
// Symlink creation failed (likely permission denied) - not fatal
|
// Symlink creation failed (likely permission denied) - not fatal
|
||||||
// The terminal service will try alternative loading methods
|
// The terminal service will try alternative loading methods
|
||||||
console.log("[kb-native-patch] Could not create /$bunfs/root symlink (permissions), using fallback");
|
console.log("[fn-native-patch] Could not create /$bunfs/root symlink (permissions), using fallback");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("[kb-native-patch] Native assets staged at:", tmpRoot);
|
console.log("[fn-native-patch] Native assets staged at:", tmpRoot);
|
||||||
return { success: true, nativeDir };
|
return { success: true, nativeDir };
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("[kb-native-patch] Failed to setup native resolution:", err);
|
console.error("[fn-native-patch] Failed to setup native resolution:", err);
|
||||||
return { success: false, nativeDir: null };
|
return { success: false, nativeDir: null };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user