-
Notifications
You must be signed in to change notification settings - Fork 516
Expand file tree
/
Copy pathbun-runtime.ts
More file actions
90 lines (80 loc) · 3.3 KB
/
Copy pathbun-runtime.ts
File metadata and controls
90 lines (80 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/**
* Bundled Bun runtime resolution.
*
* opencodex ships the Bun runtime via the `bun` npm dependency (esbuild-style:
* a tiny main package + platform-specific `@oven/bun-*` optionalDependencies,
* finalized by the package's own postinstall `node install.js`). The npm `bin`
* launcher (bin/ocx.mjs) and the durable service/shim integrations both need a
* stable path to that binary. This module is the single source of truth.
*
* In a from-source dev checkout the `bun` dependency may be absent; callers fall
* back to `process.execPath` (which is itself Bun when run via `bun src/cli/index.ts`).
*/
import { createRequire } from "node:module";
import { dirname, join, resolve } from "node:path";
import { isRealBunBinary } from "./bun-binary-validator.mjs";
export { isRealBunBinary };
const require = createRequire(import.meta.url);
const BUN_OVERRIDE_ENV = "OPENCODEX_BUN_PATH";
export const BUN_RUNTIME_SOURCE_ENV = "OCX_BUN_RUNTIME_SOURCE";
export type BunRuntimeSource = "override" | "bundled" | "process";
export type DurableBunRuntime = {
path: string;
source: BunRuntimeSource;
overrideEnv: typeof BUN_OVERRIDE_ENV;
};
/**
* Absolute path to the bundled Bun binary, or null if the `bun` dependency is
* not installed/resolvable (or only the un-downloaded placeholder is present).
* The npm `bun` package ships the binary as `bin/bun.exe` on every platform;
* we also probe `bin/bun` for forward compatibility.
*/
export function bundledBunPath(): string | null {
try {
const bunDir = dirname(require.resolve("bun/package.json"));
for (const name of ["bun.exe", "bun"]) {
const p = join(bunDir, "bin", name);
if (isRealBunBinary(p)) return p;
}
return null;
} catch {
return null;
}
}
export function overrideBunPath(): string | null {
const value = process.env[BUN_OVERRIDE_ENV]?.trim();
if (!value) return null;
const resolved = resolve(value);
return isRealBunBinary(resolved) ? resolved : null;
}
export function durableBunRuntime(): DurableBunRuntime {
const override = overrideBunPath();
if (override) return { path: override, source: "override", overrideEnv: BUN_OVERRIDE_ENV };
const bundled = bundledBunPath();
if (bundled) return { path: bundled, source: "bundled", overrideEnv: BUN_OVERRIDE_ENV };
return { path: process.execPath, source: "process", overrideEnv: BUN_OVERRIDE_ENV };
}
/**
* Runtime origin asserted by the launcher that started this process.
*
* This is diagnostic provenance, not a security boundary. Accept only the
* launcher allowlist and leave a missing/invalid marker unknown. In particular,
* never inspect the current shell to guess how an already-running service began.
*/
export function reportedBunRuntimeSource(
env: NodeJS.ProcessEnv = process.env,
): BunRuntimeSource | undefined {
const source = env[BUN_RUNTIME_SOURCE_ENV]?.trim();
return source === "override" || source === "bundled" || source === "process"
? source
: undefined;
}
/**
* Bun path to bake into durable artifacts (launchd/systemd/Task Scheduler and
* the Codex auto-start shim). Prefer the bundled binary — it lives under the
* npm global prefix and survives across `ocx update` — and fall back to the
* current runtime, which is Bun when launched normally.
*/
export function durableBunPath(): string {
return durableBunRuntime().path;
}