Skip to content

Commit cce46bb

Browse files
fix: use bare identifier references for build-time define constants in bootstrap.ts
Bun's `define` option performs compile-time identifier substitution — it replaces bare identifier tokens in source code with their configured values. Dynamic property lookups like `(globalThis as any)["ALTIMATE_VALIDATE_SKILL_MD"]` are runtime expressions and are NOT substituted by the bundler. The previous `readAsset(globalName: string, ...)` helper passed constant names as strings, so the globalThis lookup always returned `undefined` in the production binary. The fallback `fs.readFile(import.meta.dir + ...)` then failed because the source paths don't exist in a compiled binary. Since `ensureValidationSetup()` is wrapped in a bare `catch {}`, this failed completely silently — skill files were never written to `~/.claude/` on startup. Fix: - Add `declare const` for all three build-time globals - Change `readAsset` signature to accept the resolved value directly - Pass bare identifiers at each call site so the bundler inlines the content This matches the pattern already used correctly in `validate.ts`. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent bb29944 commit cce46bb

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

packages/opencode/src/project/bootstrap.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,14 @@ function getClaudeDir(): string {
2525
return path.join(os.homedir(), ".claude")
2626
}
2727

28-
async function readAsset(globalName: string, fallbackRelPath: string): Promise<string> {
29-
const val = (globalThis as any)[globalName]
30-
if (typeof val === "string" && val) return val
28+
// Injected at build time by build.ts via Bun's define option.
29+
// Must be referenced as bare identifiers — dynamic globalThis lookup does not work with define.
30+
declare const ALTIMATE_VALIDATE_SKILL_MD: string
31+
declare const ALTIMATE_VALIDATE_BATCH_PY: string
32+
declare const ALTIMATE_LOGGER_HOOK_PY: string
33+
34+
async function readAsset(defined: string, fallbackRelPath: string): Promise<string> {
35+
if (typeof defined === "string" && defined) return defined
3136
return fs.readFile(path.join(import.meta.dir, fallbackRelPath), "utf-8")
3237
}
3338

@@ -67,11 +72,11 @@ async function ensureValidationSetup(): Promise<void> {
6772
await fs.mkdir(validateSkillDir, { recursive: true })
6873
await fs.writeFile(
6974
path.join(validateSkillDir, "SKILL.md"),
70-
await readAsset("ALTIMATE_VALIDATE_SKILL_MD", "../skill/validate/SKILL.md"),
75+
await readAsset(ALTIMATE_VALIDATE_SKILL_MD, "../skill/validate/SKILL.md"),
7176
)
7277
await fs.writeFile(
7378
path.join(validateSkillDir, "batch_validate.py"),
74-
await readAsset("ALTIMATE_VALIDATE_BATCH_PY", "../skill/validate/batch_validate.py"),
79+
await readAsset(ALTIMATE_VALIDATE_BATCH_PY, "../skill/validate/batch_validate.py"),
7580
)
7681

7782
// Install hook + register in settings.json only when logging is enabled
@@ -81,7 +86,7 @@ async function ensureValidationSetup(): Promise<void> {
8186
const hookPath = path.join(hooksDir, "altimate_logger_hook.py")
8287
await fs.writeFile(
8388
hookPath,
84-
await readAsset("ALTIMATE_LOGGER_HOOK_PY", "../skill/validate/logger_hook.py"),
89+
await readAsset(ALTIMATE_LOGGER_HOOK_PY, "../skill/validate/logger_hook.py"),
8590
)
8691
await mergeStopHook(
8792
path.join(claudeDir, "settings.json"),

0 commit comments

Comments
 (0)