Parent: #10107 (OpenCode v1.18.30). This single bug blocks every real OpenCode command (run, models, serve, TUI): the shared bootstrap in packages/opencode/src/cli/effect-cmd.ts:84-88 does
const { InstanceStore } = await import("@/project/instance-store")
InstanceStore.Service.use(...) // TypeError: Cannot read properties of undefined (reading 'Service')
and packages/opencode/src/project/instance-store.ts:213 exports the module's own namespace: export * as InstanceStore from "./instance-store". OpenCode uses this self-namespace re-export pattern in 265 modules (export * as Foo from "./foo"), and reads them through dynamic imports in effect-cmd.ts, cli/cmd/tui.ts, cli/cmd/attach.ts, cli/cmd/run.ts, …
Minimal repro (2 modules)
// store.ts
export class Service { static use(f: (s: string) => string) { return f("store-ok") } }
export const node = "node-layer"
export * as InstanceStore from "./store"
// main.ts
import { InstanceStore as Static } from "./store"
console.log("static:", typeof Static, Static && typeof Static.Service, Static && Static.Service.use((s) => s))
const mod = await import("./store")
console.log("dyn keys:", Object.keys(mod).sort().join(","))
const { InstanceStore } = mod
console.log("dyn destructured:", typeof InstanceStore, InstanceStore && typeof InstanceStore.Service)
try { console.log("dyn use:", InstanceStore.Service.use((s) => s + "!")) } catch (e: any) { console.log("dyn use FAILED:", e.message) }
perry 0.5.1543 (origin/main 5603d63), perry compile main.ts --no-auto-optimize:
static: object function store-ok
dyn keys: InstanceStore,Service,node
dyn destructured: undefined undefined
dyn use FAILED: Cannot read properties of undefined (reading 'Service')
bun 1.3.14 (and node):
static: object function store-ok
dyn keys: InstanceStore,Service,node
dyn destructured: object function
dyn use: store-ok!
So the dynamic-import namespace object has the InstanceStore key but its value is undefined: the export * as X from "./self" entry is not materialized for the dynamic namespace (only the static-import binding path resolves it). Worth checking the non-self case too (export * as Y from "./other" read through import()), and import * as ns + ns.InstanceStore on the dynamic namespace.
Acceptance
Parent: #10107 (OpenCode v1.18.30). This single bug blocks every real OpenCode command (
run,models,serve, TUI): the shared bootstrap inpackages/opencode/src/cli/effect-cmd.ts:84-88doesand
packages/opencode/src/project/instance-store.ts:213exports the module's own namespace:export * as InstanceStore from "./instance-store". OpenCode uses this self-namespace re-export pattern in 265 modules (export * as Foo from "./foo"), and reads them through dynamic imports ineffect-cmd.ts,cli/cmd/tui.ts,cli/cmd/attach.ts,cli/cmd/run.ts, …Minimal repro (2 modules)
perry 0.5.1543 (origin/main 5603d63),
perry compile main.ts --no-auto-optimize:bun 1.3.14 (and node):
So the dynamic-import namespace object has the
InstanceStorekey but its value isundefined: theexport * as X from "./self"entry is not materialized for the dynamic namespace (only the static-import binding path resolves it). Worth checking the non-self case too (export * as Y from "./other"read throughimport()), andimport * as ns+ns.InstanceStoreon the dynamic namespace.Acceptance
export * as, via destructuring and via property read on the dynamic namespace).crates/perry/tests/in the style ofsource_graph_export_regressions.rs.opencode modelslists models from the native build (the first command past the bootstrap).