bosun 0.29.7 → 0.29.8

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/update-check.mjs +41 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bosun",
3
- "version": "0.29.7",
3
+ "version": "0.29.8",
4
4
  "description": "AI-powered orchestrator supervisor — manages AI agent executors with failover, auto-restarts on failure, analyzes crashes with Codex SDK, creates PRs via Vibe-Kanban API, and sends Telegram notifications. Supports N executors with weighted distribution, multi-repo projects, and auto-setup.",
5
5
  "type": "module",
6
6
  "license": "Apache 2.0",
package/update-check.mjs CHANGED
@@ -20,6 +20,7 @@ import { readFileSync, existsSync } from "node:fs";
20
20
  import { resolve, dirname, join } from "node:path";
21
21
  import { fileURLToPath } from "node:url";
22
22
  import { createInterface } from "node:readline";
23
+ import { get as httpsGet } from "node:https";
23
24
  import os from "node:os";
24
25
 
25
26
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -57,11 +58,21 @@ function runNpmCommand(args, options = {}) {
57
58
  if (process.platform !== "win32") {
58
59
  return execFileSync(process.execPath, [candidate, ...args], safeOptions);
59
60
  }
61
+ // On Windows, .cmd/.bat files are batch scripts that must be interpreted
62
+ // by cmd.exe. Without shell:true, execFileSync can fail with EINVAL on
63
+ // certain Node/nvm-for-windows configurations.
64
+ if (candidate.endsWith(".cmd") || candidate.endsWith(".bat")) {
65
+ return execFileSync(candidate, args, { ...safeOptions, shell: true });
66
+ }
60
67
  return execFileSync(candidate, args, safeOptions);
61
68
  }
62
69
  }
63
70
 
64
71
  const fallback = process.platform === "win32" ? "npm.cmd" : "npm";
72
+ // The fallback path also needs shell:true on Windows for .cmd resolution.
73
+ if (process.platform === "win32") {
74
+ return execFileSync(fallback, args, { ...safeOptions, shell: true });
75
+ }
65
76
  return execFileSync(fallback, args, safeOptions);
66
77
  }
67
78
 
@@ -103,18 +114,39 @@ async function writeCache(data) {
103
114
  // ── Registry query ───────────────────────────────────────────────────────────
104
115
 
105
116
  async function fetchLatestVersion() {
106
- // Try native fetch (Node 18+), fall back to npm view
117
+ // Use node:https instead of fetch() to avoid the undici connection-pool
118
+ // handles that cause a libuv assertion crash on Windows:
119
+ // Assertion failed: !(handle->flags & UV_HANDLE_CLOSING) [src\win\async.c:76]
120
+ // undici keeps internal uv_async_t handles alive after fetch() completes;
121
+ // calling process.exit() then tears them down mid-close.
107
122
  try {
108
- const res = await fetch(`https://registry.npmjs.org/${PKG_NAME}/latest`, {
109
- headers: { Accept: "application/json" },
110
- signal: AbortSignal.timeout(10000),
123
+ const version = await new Promise((resolve, reject) => {
124
+ const req = httpsGet(
125
+ `https://registry.npmjs.org/${PKG_NAME}/latest`,
126
+ { headers: { Accept: "application/json" }, timeout: 10000 },
127
+ (res) => {
128
+ if (res.statusCode < 200 || res.statusCode >= 300) {
129
+ res.resume(); // drain
130
+ return resolve(null);
131
+ }
132
+ let body = "";
133
+ res.setEncoding("utf8");
134
+ res.on("data", (chunk) => { body += chunk; });
135
+ res.on("end", () => {
136
+ try {
137
+ resolve(JSON.parse(body).version || null);
138
+ } catch {
139
+ resolve(null);
140
+ }
141
+ });
142
+ },
143
+ );
144
+ req.on("error", () => resolve(null));
145
+ req.on("timeout", () => { req.destroy(); resolve(null); });
111
146
  });
112
- if (res.ok) {
113
- const data = await res.json();
114
- return data.version || null;
115
- }
147
+ if (version) return version;
116
148
  } catch {
117
- // fetch failed, try npm view
149
+ // https.get failed, try npm view
118
150
  }
119
151
 
120
152
  try {