fix(coding-agent): dispatched CLI entry in Bun.build-compiled windows binaries

- Bun.build-API compiled Windows executables report import.meta.main === false
  (standalone loader keys the entry module with backslashes but registers the
  main path with forward slashes), so cli.ts never dispatched: the binary
  exited silently with code 0 and omp update rolled back after failing to
  verify the new version.
- Entry dispatch and worker-host declaration now also honor the define-folded
  PI_COMPILED marker, which is only true inside compiled binaries where the
  entry module is by definition the process entry.
- Verified on a Windows VM: --version prints omp/16.4.3 and --smoke-test
  passes (stats sync worker + tiny-model subprocess) on a cross-compiled
  binary; v16.4.3 release binary reproduces the silent exit.
This commit is contained in:
can1357
2026-07-11 11:08:55 +02:00
parent 3272b65742
commit 3d2568060a
2 changed files with 15 additions and 3 deletions
+4
View File
@@ -2,6 +2,10 @@
## [Unreleased]
### Fixed
- Fixed the Windows binary exiting silently without running the CLI (which also made `omp update` roll back with "could not verify updated version"): `Bun.build`-API compiled Windows executables report `import.meta.main === false`, so the entry dispatch in `cli.ts` never ran. The dispatch now also honors the compile-time `PI_COMPILED` marker.
## [16.4.3] - 2026-07-11
### Added
+11 -3
View File
@@ -37,6 +37,14 @@ if (Bun.semver.order(Bun.version, MIN_BUN_VERSION) < 0) {
process.title = APP_NAME;
// `Bun.build`-API compiled Windows executables report `import.meta.main ===
// false`: the standalone loader keys the entry module with native backslashes
// (`B:\~BUN\root\cli.js`) but registers the main path with forward slashes
// (`B:/~BUN/root/cli.js`), so Bun's internal match fails. `bun build --compile`
// CLI builds are unaffected. A compiled binary's entry module is by definition
// the process entry, so the define-folded PI_COMPILED marker stands in.
const isProcessEntry = import.meta.main || process.env.PI_COMPILED === "true";
// Worker-host entry declaration (Worker threads and worker subprocesses
// re-enter `Bun.main` with a hidden argv selector instead of loading separate
// worker entrypoints) happens inside `runCli` after profile bootstrap:
@@ -305,13 +313,13 @@ export async function runCli(argv: string[]): Promise<void> {
// Declare this module as the worker-host entry now that the active profile
// is resolved. The worker-host module is side-effect-free; importing
// `@oh-my-pi/pi-utils/env` here would snapshot the wrong agent `.env`.
// Gated on `import.meta.main`: only the real CLI process entry is a valid
// Gated on `isProcessEntry`: only the real CLI process entry is a valid
// worker host. Worker-thread re-entry already returned above at the
// `__omp_worker_` dispatch, and importers (`runCli` in profile-CLI tests,
// SDK embedding) have `import.meta.main === false` — declaring there would
// poison `workerHostEntry()` for the whole test process, forcing eval/stats/
// browser workers onto the same-realm inline fallback.
if (import.meta.main) declareWorkerHostEntry();
if (isProcessEntry) declareWorkerHostEntry();
if (resolvedArgv[0] === "--smoke-test") {
await runSmokeTest();
@@ -340,7 +348,7 @@ export async function runCli(argv: string[]): Promise<void> {
// launch the agent as a side effect. Worker threads re-enter this module as
// their entry with `import.meta.main === false`, so the worker-host dispatch
// is admitted via `!Bun.isMainThread`.
if (import.meta.main || !Bun.isMainThread) {
if (isProcessEntry || !Bun.isMainThread) {
runCli(process.argv.slice(2)).catch((err: unknown) => {
process.stderr.write(`${Bun.inspect(err, { colors: process.stderr.isTTY === true })}\n`);
process.exit(1);