wildcrane-runner 0.6.6 → 0.6.9
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.
- package/README.md +8 -2
- package/dist/akb/dist/kanban.mjs +2100 -2260
- package/dist/akb/package.json +1 -1
- package/dist/launcher.mjs +65 -17
- package/dist/runner.mjs +1178 -520
- package/package.json +1 -1
package/dist/akb/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"wildcrane","version":"0.11.
|
|
1
|
+
{"name":"wildcrane","version":"0.11.8","akbContract":4,"type":"module","private":true}
|
package/dist/launcher.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// wildcrane-runner 0.6.
|
|
1
|
+
// wildcrane-runner 0.6.9 — built by runner/scripts/build.mjs. Do not edit.
|
|
2
2
|
import { createRequire as __ai4kanbanRequire } from 'node:module'
|
|
3
3
|
const require = __ai4kanbanRequire(import.meta.url)
|
|
4
4
|
|
|
@@ -107,9 +107,10 @@ function status(line) {
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
// src/protocol.ts
|
|
110
|
-
var VERSION = true ? "0.6.
|
|
110
|
+
var VERSION = true ? "0.6.9" : "0.0.0";
|
|
111
111
|
var EXIT_REFUSED = 10;
|
|
112
112
|
var EXIT_OUTDATED = 11;
|
|
113
|
+
var EXIT_UPDATE = 12;
|
|
113
114
|
|
|
114
115
|
// src/update.ts
|
|
115
116
|
import crypto2 from "node:crypto";
|
|
@@ -273,8 +274,8 @@ async function askTarget(machine) {
|
|
|
273
274
|
signal: AbortSignal.timeout(ASK_MS)
|
|
274
275
|
});
|
|
275
276
|
if (!answer.ok) return null;
|
|
276
|
-
const { version } = await answer.json();
|
|
277
|
-
return typeof version === "string" && version ? version : null;
|
|
277
|
+
const { version, restartable } = await answer.json();
|
|
278
|
+
return typeof version === "string" && /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(version) ? { version, restartable: restartable === true } : null;
|
|
278
279
|
} catch {
|
|
279
280
|
return null;
|
|
280
281
|
}
|
|
@@ -283,7 +284,7 @@ async function candidates(own) {
|
|
|
283
284
|
const state = readState();
|
|
284
285
|
const proven = state.good.find((v) => fs3.existsSync(entryOf(versionDir(v))));
|
|
285
286
|
const current = proven && compare(proven, own.version) > 0 ? { version: proven, entry: entryOf(versionDir(proven)) } : own;
|
|
286
|
-
const target = await askTarget(machineId());
|
|
287
|
+
const target = (await askTarget(machineId()))?.version;
|
|
287
288
|
if (!target || target === current.version || state.bad.includes(target)) return [current];
|
|
288
289
|
if (target === own.version) return [own, current];
|
|
289
290
|
const got = await install(target);
|
|
@@ -294,16 +295,56 @@ async function candidates(own) {
|
|
|
294
295
|
if (got.why === "node") status(t.nodeTooOld(got.detail));
|
|
295
296
|
return [current];
|
|
296
297
|
}
|
|
297
|
-
function runOnce(candidate) {
|
|
298
|
+
function runOnce(candidate, options) {
|
|
298
299
|
return new Promise((resolve) => {
|
|
299
300
|
const child = spawn(process.execPath, [candidate.entry], {
|
|
300
|
-
stdio: ["
|
|
301
|
-
env: { ...process.env, WILDCRANE_RUNNER_VERSION: candidate.version }
|
|
301
|
+
stdio: ["ignore", options.quiet ? 2 : "inherit", "inherit", "ipc"],
|
|
302
|
+
env: { ...process.env, WILDCRANE_RUNNER_VERSION: candidate.version, WILDCRANE_RUNNER_KIND: options.kind ?? "terminal" }
|
|
302
303
|
});
|
|
304
|
+
options.onSpawn?.((type) => {
|
|
305
|
+
if (child.connected) child.send({ type }, () => {
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
let update = null;
|
|
309
|
+
let checking = false;
|
|
310
|
+
const check = async () => {
|
|
311
|
+
if (checking || stopping || update) return;
|
|
312
|
+
checking = true;
|
|
313
|
+
try {
|
|
314
|
+
const desired = await askTarget(machineId());
|
|
315
|
+
if (!desired?.restartable) return;
|
|
316
|
+
const target = desired.version;
|
|
317
|
+
if (!target || target === candidate.version || readState().bad.includes(target)) return;
|
|
318
|
+
const got = await install(target);
|
|
319
|
+
if (!got.ok) {
|
|
320
|
+
status("Runner \u66F4\u65B0\u4E0B\u8F7D\u5931\u8D25\uFF0C\u7EE7\u7EED\u8FD0\u884C\u5F53\u524D\u7248\u672C\uFF0C\u7A0D\u540E\u91CD\u8BD5\u3002");
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
if (stopping || child.exitCode !== null || child.signalCode !== null) return;
|
|
324
|
+
if ((await askTarget(machineId()))?.version !== target) return;
|
|
325
|
+
update = { version: target, entry: entryOf(got.dir), fresh: !readState().good.includes(target) };
|
|
326
|
+
child.send({ type: "update" }, () => {
|
|
327
|
+
});
|
|
328
|
+
} finally {
|
|
329
|
+
checking = false;
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
const poll = setInterval(() => {
|
|
333
|
+
if (connected) void check().catch(() => {
|
|
334
|
+
});
|
|
335
|
+
}, Number(process.env.WILDCRANE_UPDATE_MS) || 6e4);
|
|
303
336
|
let connected = false;
|
|
304
337
|
let timer = null;
|
|
305
338
|
let timedOut = false;
|
|
306
339
|
let stopping = false;
|
|
340
|
+
let forceKill;
|
|
341
|
+
if (candidate.fresh) {
|
|
342
|
+
timer = setTimeout(() => {
|
|
343
|
+
timedOut = true;
|
|
344
|
+
child.kill("SIGTERM");
|
|
345
|
+
forceKill = setTimeout(() => child.kill("SIGKILL"), 5e3);
|
|
346
|
+
}, Number(process.env.WILDCRANE_CONNECT_MS) || CONNECT_MS);
|
|
347
|
+
}
|
|
307
348
|
const forward = (signal) => () => {
|
|
308
349
|
stopping = true;
|
|
309
350
|
child.kill(signal);
|
|
@@ -312,13 +353,11 @@ function runOnce(candidate) {
|
|
|
312
353
|
const onTerm = forward("SIGTERM");
|
|
313
354
|
process.on("SIGINT", onInt);
|
|
314
355
|
process.on("SIGTERM", onTerm);
|
|
356
|
+
options.signal?.addEventListener("abort", onTerm, { once: true });
|
|
357
|
+
if (options.signal?.aborted) onTerm();
|
|
315
358
|
child.on("message", (message) => {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
timedOut = true;
|
|
319
|
-
child.kill("SIGTERM");
|
|
320
|
-
}, Number(process.env.WILDCRANE_CONNECT_MS) || CONNECT_MS);
|
|
321
|
-
}
|
|
359
|
+
options.onMessage?.(message);
|
|
360
|
+
if (message.type === "update-deferred") update = null;
|
|
322
361
|
if (message.type === "waiting" && timer) {
|
|
323
362
|
clearTimeout(timer);
|
|
324
363
|
timer = null;
|
|
@@ -334,9 +373,13 @@ function runOnce(candidate) {
|
|
|
334
373
|
}
|
|
335
374
|
});
|
|
336
375
|
child.on("exit", (code, signal) => {
|
|
376
|
+
clearInterval(poll);
|
|
377
|
+
clearTimeout(forceKill);
|
|
337
378
|
if (timer) clearTimeout(timer);
|
|
338
379
|
process.off("SIGINT", onInt);
|
|
339
380
|
process.off("SIGTERM", onTerm);
|
|
381
|
+
options.signal?.removeEventListener("abort", onTerm);
|
|
382
|
+
if (code === EXIT_UPDATE && update && !stopping) return resolve({ update });
|
|
340
383
|
if (connected || !candidate.fresh || stopping) return resolve({ exit: code ?? (signal ? 1 : 0) });
|
|
341
384
|
if (timedOut) return resolve({ failed: "timeout" });
|
|
342
385
|
if (code === 0 || code === EXIT_REFUSED || code === EXIT_OUTDATED) return resolve({ exit: code });
|
|
@@ -344,13 +387,18 @@ function runOnce(candidate) {
|
|
|
344
387
|
});
|
|
345
388
|
});
|
|
346
389
|
}
|
|
347
|
-
async function launch(own) {
|
|
390
|
+
async function launch(own, options = {}) {
|
|
348
391
|
const list = await candidates(own);
|
|
349
392
|
for (let i = 0; i < list.length; i++) {
|
|
393
|
+
if (options.signal?.aborted) return 0;
|
|
350
394
|
const candidate = list[i];
|
|
351
|
-
const outcome = await runOnce(candidate);
|
|
395
|
+
const outcome = await runOnce(candidate, options);
|
|
352
396
|
if ("exit" in outcome) return outcome.exit;
|
|
353
|
-
if (
|
|
397
|
+
if ("update" in outcome) {
|
|
398
|
+
list.splice(i + 1, list.length, outcome.update, candidate);
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
markBad(candidate.version);
|
|
354
402
|
const next = list[i + 1];
|
|
355
403
|
if (next) status(t.rolledBack(next.version));
|
|
356
404
|
}
|