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:
gsxdsm
2026-04-08 14:47:30 -07:00
parent 4ac4f92a59
commit b94c7428d3
11 changed files with 58 additions and 53 deletions

View File

@@ -21,7 +21,7 @@ const SUPPORTED_TARGETS = [
function expectedBinaryName(target: string): string {
const suffix = target.replace(/^bun-/, "");
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);
it("produces dist/kb-linux-x64", () => {
const bin = join(distDir, "kb-linux-x64");
it("produces dist/fn-linux-x64", () => {
const bin = join(distDir, "fn-linux-x64");
expect(existsSync(bin)).toBe(true);
expect(statSync(bin).size).toBeGreaterThan(0);
});
@@ -64,8 +64,8 @@ describe("build-exe-cross: windows target has .exe extension", () => {
});
}, 180_000);
it("produces dist/kb-windows-x64.exe", () => {
const bin = join(distDir, "kb-windows-x64.exe");
it("produces dist/fn-windows-x64.exe", () => {
const bin = join(distDir, "fn-windows-x64.exe");
expect(existsSync(bin)).toBe(true);
expect(statSync(bin).size).toBeGreaterThan(0);
});
@@ -143,8 +143,8 @@ describe("build-exe-cross: default (no args) backward compatibility", () => {
});
}, 180_000);
it("produces dist/kb (no platform suffix)", () => {
const defaultName = process.platform === "win32" ? "kb.exe" : "kb";
it("produces dist/fn (no platform suffix)", () => {
const defaultName = process.platform === "win32" ? "fn.exe" : "fn";
const bin = join(distDir, defaultName);
expect(existsSync(bin)).toBe(true);
expect(statSync(bin).size).toBeGreaterThan(0);

View File

@@ -6,8 +6,8 @@ import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
const cliRoot = join(import.meta.dirname!, "..", "..");
const outBinary = join(cliRoot, "dist", process.platform === "win32" ? "kb.exe" : "kb");
const binaryName = process.platform === "win32" ? "kb.exe" : "kb";
const outBinary = join(cliRoot, "dist", process.platform === "win32" ? "fn.exe" : "fn");
const binaryName = process.platform === "win32" ? "fn.exe" : "fn";
const clientDir = join(cliRoot, "dist", "client");
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.
*/
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(clientDir, join(dir, "client"), { recursive: true });
// Copy runtime native assets alongside binary

View File

@@ -51,7 +51,7 @@ describe("CI workflow (.github/workflows/ci.yml)", () => {
});
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", () => {

View File

@@ -37,12 +37,12 @@ describe("CLI package.json publishing config", () => {
it("does not include bare 'dist' entry or globs that would match Bun binaries", () => {
const bunBinaryNames = [
"kb",
"kb-linux-x64",
"kb-linux-arm64",
"kb-darwin-x64",
"kb-darwin-arm64",
"kb-windows-x64.exe",
"fn",
"fn-linux-x64",
"fn-linux-arm64",
"fn-darwin-x64",
"fn-darwin-arm64",
"fn-windows-x64.exe",
];
// No bare "dist" entry that would include everything
expect(pkg.files).not.toContain("dist");
@@ -51,8 +51,8 @@ describe("CLI package.json publishing config", () => {
for (const bin of bunBinaryNames) {
expect(entry).not.toBe(`dist/${bin}`);
}
// No wildcard like "dist/kb*" that would match binaries
expect(entry).not.toMatch(/^dist\/kb/);
// No wildcard like "dist/fn*" that would match binaries
expect(entry).not.toMatch(/^dist\/fn/);
}
});

View File

@@ -24,11 +24,11 @@ if (isBunBinary) {
if (!existsSync(localPkg)) {
// 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(
join(tmp, "package.json"),
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,
2,
) + "\n",

View File

@@ -8,7 +8,7 @@
* where bundled code runs. Node-pty looks for native modules at:
* /$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
* temp directory (on macOS/Linux) so node-pty can find the native assets.
*/
@@ -64,9 +64,9 @@ function cleanupStaleBunfsLinks(): void {
if (stats.isSymbolicLink()) {
const target = readlinkSync(bunfsRoot);
// 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);
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.
*
* Creates:
* /tmp/kb-bunfs-<pid>/kb/prebuilds/<platform>-<arch>/
* /tmp/fn-bunfs-<pid>/fn/prebuilds/<platform>-<arch>/
* ├── pty.node
* └── spawn-helper (Unix only)
*
@@ -89,7 +89,7 @@ function cleanupStaleBunfsLinks(): void {
export function setupNativeResolution(): { success: boolean; nativeDir: string | null } {
const nativeDir = findStagedNativeDir();
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 };
}
@@ -102,9 +102,9 @@ export function setupNativeResolution(): { success: boolean; nativeDir: string |
process.env.FUSION_NATIVE_ASSETS_PATH = nativeDir;
// Create the fake bunfs structure
const tmpRoot = join(tmpdir(), `kb-bunfs-${process.pid}`);
const kbDir = join(tmpRoot, "kb");
const prebuildsDir = join(kbDir, "prebuilds");
const tmpRoot = join(tmpdir(), `fn-bunfs-${process.pid}`);
const fnDir = join(tmpRoot, "fn");
const prebuildsDir = join(fnDir, "prebuilds");
const platformDir = join(prebuildsDir, basename(nativeDir));
try {
@@ -138,23 +138,23 @@ export function setupNativeResolution(): { success: boolean; nativeDir: string |
}
}
// Create new symlink pointing to our temp kb directory
// We want /$bunfs/root -> /tmp/kb-bunfs-<pid>/kb
// Create new symlink pointing to our temp fn directory
// We want /$bunfs/root -> /tmp/fn-bunfs-<pid>/fn
// So that /$bunfs/root/prebuilds/<platform>/pty.node resolves correctly
symlinkSync(kbDir, bunfsRoot);
symlinkSync(fnDir, 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) {
// Symlink creation failed (likely permission denied) - not fatal
// 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 };
} 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 };
}
}