feat: add Node.js entry point and build script#18324
Conversation
Greptile SummaryThis PR adds two new files to support a Node.js distribution of opencode: a thin entry point (
Confidence Score: 2/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Dev as Developer
participant BN as build-node.ts (Bun)
participant FS as migration/ directory
participant Bundler as Bun.build()
participant Dist as dist/node.js
participant Node as Node.js process
Dev->>BN: bun run script/build-node.ts
BN->>FS: readdir migration/ (filter timestamp dirs)
FS-->>BN: sorted migration dir names
BN->>FS: read each migration.sql
FS-->>BN: SQL content per migration
BN->>BN: parse timestamp from dir name (Date.UTC)
BN->>Bundler: Bun.build({ target:"node", entrypoints:["src/node.ts"], define:{OPENCODE_MIGRATIONS} })
Bundler-->>BN: BuildOutput (success/failure — currently unchecked)
BN->>Dist: writes dist/node.js (ESM bundle)
Note over BN: Prints "Build complete" regardless of success
Dev->>Node: node dist/node.js
Node->>Dist: execute entry point
Dist->>Dist: import Server from ./server/server
Dist->>Dist: Server.listen({ port:1338, hostname:"0.0.0.0" })
Note over Dist: Currently calls Bun.serve() internally<br/>(requires future Hono/node-server refactor)
Dist-->>Node: server object logged to stdout
|
| target: "node", | ||
| entrypoints: ["./src/node.ts"], | ||
| outdir: "./dist", | ||
| format: "esm", | ||
| external: ["jsonc-parser"], | ||
| define: { | ||
| OPENCODE_MIGRATIONS: JSON.stringify(migrations), | ||
| }, | ||
| }) | ||
|
|
There was a problem hiding this comment.
Bun.build() result unchecked — build failures will be silently swallowed
Bun.build() (without the compile option) does not throw on failure — it resolves with { success: false, logs: [...] }. As written, the script will always print "Build complete" regardless of whether the bundle actually succeeded, making build errors invisible in CI or local runs.
| target: "node", | |
| entrypoints: ["./src/node.ts"], | |
| outdir: "./dist", | |
| format: "esm", | |
| external: ["jsonc-parser"], | |
| define: { | |
| OPENCODE_MIGRATIONS: JSON.stringify(migrations), | |
| }, | |
| }) | |
| const result = await Bun.build({ | |
| target: "node", | |
| entrypoints: ["./src/node.ts"], | |
| outdir: "./dist", | |
| format: "esm", | |
| external: ["jsonc-parser"], | |
| define: { | |
| OPENCODE_MIGRATIONS: JSON.stringify(migrations), | |
| }, | |
| }) | |
| if (!result.success) { | |
| for (const log of result.logs) console.error(log) | |
| process.exit(1) | |
| } |
| await fs.promises.readdir(path.join(dir, "migration"), { | ||
| withFileTypes: true, | ||
| }) |
There was a problem hiding this comment.
Multi-word variable and single-use variable — AGENTS.md naming rules
Per the repo's style guide, multi-word camelCase names should be avoided in favour of single-word alternatives, and variables used only once should be inlined to reduce total variable count.
migrationDirs→dirs__filenameis used exactly once (to produce__dirname);__dirnameis also used exactly once (to producedir). Both can be collapsed:
| await fs.promises.readdir(path.join(dir, "migration"), { | |
| withFileTypes: true, | |
| }) | |
| const dir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..") |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
packages/opencode/src/node.ts
Outdated
| const result = await Server.listen({ | ||
| port: 1338, | ||
| hostname: "0.0.0.0", | ||
| }) |
There was a problem hiding this comment.
Hardcoded
0.0.0.0 with no override path
Binding to 0.0.0.0 exposes the server on every network interface (including external/public ones). Unlike the existing Bun entry point (src/index.ts) which accepts runtime flags, this Node.js entry point offers no way to restrict the bind address without recompiling. Consider reading the hostname (and port) from an environment variable or CLI argument so operators can restrict to 127.0.0.1 in production-adjacent deployments.
Adds src/node.ts as a Node.js entry point that starts the server on port 1338, and script/build-node.ts that bundles it with DB migrations embedded at build time via Bun.build. Note: depends on the Hono/node-server server refactoring (opencode-2-0) for Server.listen() to return a proper async listener.
Summary
src/node.tsas a Node.js entry point that starts the server on port 1338script/build-node.tsthat bundles the entry point with DB migrations embedded at build time viaBun.buildDepends on the Hono/node-server server refactoring in opencode-2-0 for
Server.listen()to work under Node.js.