omnirush 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -400,20 +400,29 @@ export function createRefresher({ dir, origin, fetchImpl, now = () => Date.now()
400
400
  };
401
401
  }
402
402
 
403
- /** Best-effort browser open: xdg-open / open / cmd start. Never throws. */
403
+ /** Best-effort browser open. NEVER throws or crashes: the spawned child's
404
+ * 'error' event is always handled (ENOENT on a headless Linux box would
405
+ * otherwise take the CLI down — Foxtran's login crash). Linux tries a
406
+ * chain of openers; if all fail the caller's printed URL still works. */
404
407
  export function openBrowser(url) {
405
- try {
406
- if (process.platform === "darwin") {
407
- spawn("open", [url], { detached: true, stdio: "ignore" }).unref();
408
- return true;
409
- }
410
- if (process.platform === "win32") {
411
- spawn("cmd", ["/c", "start", "", url], { detached: true, stdio: "ignore" }).unref();
408
+ const spawnSafe = (cmd, args) => {
409
+ try {
410
+ const child = spawn(cmd, args, { detached: true, stdio: "ignore" });
411
+ child.on("error", () => undefined);
412
+ child.unref();
412
413
  return true;
414
+ } catch {
415
+ return false;
413
416
  }
414
- spawn("xdg-open", [url], { detached: true, stdio: "ignore" }).unref();
415
- return true;
416
- } catch {
417
- return false;
417
+ };
418
+ if (process.platform === "darwin") {
419
+ return spawnSafe("open", [url]);
420
+ }
421
+ if (process.platform === "win32") {
422
+ return spawnSafe("cmd", ["/c", "start", "", url]);
423
+ }
424
+ for (const opener of ["xdg-open", "sensible-browser", "gnome-open", "kde-open", "wslview"]) {
425
+ if (spawnSafe(opener, [url])) return true;
418
426
  }
427
+ return false;
419
428
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnirush",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Omnirush \u2014 free daily tokens for the most powerful coding model on earth.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -12,6 +12,7 @@
12
12
  import { execFileSync } from "node:child_process";
13
13
  import fs from "node:fs";
14
14
  import https from "node:https";
15
+ import zlib from "node:zlib";
15
16
  import path from "node:path";
16
17
  import { fileURLToPath } from "node:url";
17
18
 
@@ -23,13 +24,31 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
23
24
  const ROOT = path.resolve(__dirname, "..");
24
25
  const RUNTIME = path.join(ROOT, ".runtime", "bin");
25
26
 
27
+ function isMusl() {
28
+ // Node built for musl (Alpine et al.) reports no glibc runtime version.
29
+ try {
30
+ if (process.report) {
31
+ const header = process.report.getReport().header;
32
+ if (header && header.glibcVersionRuntime) return false;
33
+ }
34
+ } catch { /* fall through to the filesystem probe */ }
35
+ return fs.existsSync("/lib/ld-musl-x86_64.so.1") ||
36
+ fs.existsSync("/lib/ld-musl-aarch64.so.1");
37
+ }
38
+
26
39
  function platform() {
27
40
  const plat = process.platform; // linux | darwin | win32
28
41
  const arch = process.arch === "arm64" ? "aarch64" : "x64";
29
42
  if (plat === "win32") return "windows-x64";
43
+ if (plat === "linux" && isMusl()) return `${plat}-${arch}-musl`;
30
44
  return `${plat}-${arch}`;
31
45
  }
32
46
 
47
+ // bun's release assets say "aarch64", node's arch says "arm64".
48
+ function bunAssetPlat(plat) {
49
+ return plat.replace("arm64", "aarch64");
50
+ }
51
+
33
52
  function exe(name) {
34
53
  return name + (process.platform === "win32" ? ".exe" : "");
35
54
  }
@@ -55,22 +74,49 @@ function get(url, redirects = 0) {
55
74
  }
56
75
 
57
76
  function extractZip(buf, dest) {
58
- // Zero-dependency zip extraction via the system unzip/tar when present,
59
- // else fall back to PowerShell on Windows.
60
- const tmp = path.join(dest, "omnirush-bun.zip");
61
- fs.writeFileSync(tmp, buf);
62
- const isWin = process.platform === "win32";
63
- try {
64
- if (isWin) {
65
- execFileSync("powershell", ["-NoProfile", "-Command",
66
- `Expand-Archive -Path '${tmp}' -DestinationPath '${dest}' -Force`]);
77
+ // Pure-JS minimal ZIP reader (stored + deflate entries): zero external
78
+ // tools, so install works on ANY distro — debian-slim ships neither
79
+ // unzip nor python, busybox is not universal either.
80
+ // Layout: find End Of Central Directory -> walk the central directory ->
81
+ // per entry, slice the local payload and inflateRawSync when deflated.
82
+ const eocdSig = 0x06054b50;
83
+ let eocd = -1;
84
+ for (let i = buf.length - 22; i >= Math.max(0, buf.length - 66000); i--) {
85
+ if (buf.readUInt32LE(i) === eocdSig) { eocd = i; break; }
86
+ }
87
+ if (eocd < 0) throw new Error("omnirush postinstall: bad zip (no EOCD)");
88
+ const count = buf.readUInt16LE(eocd + 10);
89
+ let ptr = buf.readUInt32LE(eocd + 16); // central directory offset
90
+ for (let n = 0; n < count; n++) {
91
+ if (buf.readUInt32LE(ptr) !== 0x02014b50) {
92
+ throw new Error("omnirush postinstall: bad zip (central directory)");
93
+ }
94
+ const method = buf.readUInt16LE(ptr + 10);
95
+ const compSize = buf.readUInt32LE(ptr + 20);
96
+ const nameLen = buf.readUInt16LE(ptr + 28);
97
+ const extraLen = buf.readUInt16LE(ptr + 30);
98
+ const commentLen = buf.readUInt16LE(ptr + 32);
99
+ const localOffset = buf.readUInt32LE(ptr + 42);
100
+ const name = buf.slice(ptr + 46, ptr + 46 + nameLen).toString("utf8");
101
+ // Local header: sizes may be zero (streaming bit) — derive the payload
102
+ // start from the local name/extra lengths, sizes come from central.
103
+ const localNameLen = buf.readUInt16LE(localOffset + 26);
104
+ const localExtraLen = buf.readUInt16LE(localOffset + 28);
105
+ const dataStart = localOffset + 30 + localNameLen + localExtraLen;
106
+ const payload = buf.slice(dataStart, dataStart + compSize);
107
+ const outPath = path.join(dest, name);
108
+ if (name.endsWith("/")) {
109
+ fs.mkdirSync(outPath, { recursive: true });
67
110
  } else {
68
- execFileSync("python3", ["-m", "zipfile", "-e", tmp, dest]);
111
+ fs.mkdirSync(path.dirname(outPath), { recursive: true });
112
+ let data;
113
+ if (method === 0) data = payload;
114
+ else if (method === 8) data = zlib.inflateRawSync(payload);
115
+ else throw new Error(`omnirush postinstall: unsupported zip method ${method}`);
116
+ fs.writeFileSync(outPath, data);
69
117
  }
70
- } catch {
71
- execFileSync("unzip", ["-o", "-q", tmp, "-d", dest]);
118
+ ptr += 46 + nameLen + extraLen + commentLen;
72
119
  }
73
- fs.rmSync(tmp, { force: true });
74
120
  }
75
121
 
76
122
  function extractTarGz(buf, dest, stamp) {
@@ -102,15 +148,15 @@ function findFile(rootDir, fileName) {
102
148
  async function fetchBun(plat) {
103
149
  const existing = path.join(RUNTIME, exe("bun"));
104
150
  if (fs.existsSync(existing)) return;
105
- const zipUrl = `https://github.com/oven-sh/bun/releases/download/${BUN_VERSION}/bun-${plat}.zip`;
151
+ const zipUrl = `https://github.com/oven-sh/bun/releases/download/${BUN_VERSION}/bun-${bunAssetPlat(plat)}.zip`;
106
152
  process.stdout.write(`omnirush: downloading agent runtime (bun for ${plat})...\n`);
107
153
  const buf = await get(zipUrl);
108
154
  fs.mkdirSync(RUNTIME, { recursive: true });
109
155
  extractZip(buf, ROOT);
110
- const src = path.join(ROOT, `bun-${plat}`, exe("bun"));
156
+ const src = path.join(ROOT, `bun-${bunAssetPlat(plat)}`, exe("bun"));
111
157
  fs.copyFileSync(src, existing);
112
158
  if (process.platform !== "win32") fs.chmodSync(existing, 0o755);
113
- fs.rmSync(path.join(ROOT, `bun-${plat}`), { recursive: true, force: true });
159
+ fs.rmSync(path.join(ROOT, `bun-${bunAssetPlat(plat)}`), { recursive: true, force: true });
114
160
  console.log("omnirush: runtime ready");
115
161
  }
116
162
 
package/src/bin.js CHANGED
@@ -141,10 +141,22 @@ function agentGatewayUrl(auth) {
141
141
  return resolveGatewayUrl(process.env, auth?.gatewayUrl);
142
142
  }
143
143
 
144
+ function isMusl() {
145
+ // Node built for musl (Alpine et al.) reports no glibc runtime version.
146
+ try {
147
+ if (process.report) {
148
+ const header = process.report.getReport().header;
149
+ if (header && header.glibcVersionRuntime) return false;
150
+ }
151
+ } catch { /* fall through to the filesystem probe */ }
152
+ return fs.existsSync("/lib/ld-musl-x86_64.so.1") ||
153
+ fs.existsSync("/lib/ld-musl-aarch64.so.1");
154
+ }
155
+
144
156
  function findBun() {
145
- // Vendored per-platform bun first (bundled for linux-x64, darwin-arm64,
146
- // darwin-x64, windows-x64), then PATH, then the standard single-user
147
- // install location.
157
+ // Vendored per-platform bun first, then PATH, then the standard
158
+ // single-user install location. Linux packages ship both the glibc and
159
+ // the musl binary; the launcher picks by the running libc.
148
160
  const runtimeRoot = path.resolve(__dirname, "..", ".runtime");
149
161
  const plat = process.platform;
150
162
  const arch = process.arch === "arm64" ? "aarch64" : "x64";
@@ -157,8 +169,10 @@ function findBun() {
157
169
  if (dir) candidates.push(path.join(dir, "bun.exe"));
158
170
  }
159
171
  } else {
160
- if (plat === "linux" && arch === "x64") {
161
- candidates.push(path.join(runtimeRoot, "bin", "bun"));
172
+ if (plat === "linux") {
173
+ if (isMusl()) candidates.push(path.join(runtimeRoot, "bin", "bun-musl"));
174
+ else if (arch === "x64") candidates.push(path.join(runtimeRoot, "bin", "bun"));
175
+ candidates.push(path.join(runtimeRoot, "bin", `bun-${arch}${isMusl() ? "-musl" : ""}`));
162
176
  }
163
177
  candidates.push(path.join(runtimeRoot, `bun-${plat}-${arch}`, "bin", "bun"));
164
178
  for (const dir of (process.env.PATH || "").split(path.delimiter)) {
@@ -513,7 +527,7 @@ if (cmd === "login") await cmdLogin(argv.slice(1));
513
527
  else if (cmd === "logout") await cmdLogout();
514
528
  else if (cmd === "whoami") await cmdWhoami();
515
529
  else if (cmd === "doctor") await cmdDoctor();
516
- else if (cmd === "--version" || cmd === "-v") console.log("omnirush 0.3.0");
530
+ else if (cmd === "--version" || cmd === "-v") console.log("omnirush 0.3.2");
517
531
  else if (cmd === "collect") await cmdCollect(argv.slice(1));
518
532
  else if (cmd === undefined || cmd === "run") await cmdRun();
519
533
  else {