wildcrane-runner 0.6.5 → 0.6.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.
- package/README.md +10 -14
- package/dist/akb/bin/ai4kanban.mjs +2 -21
- package/dist/akb/dist/kanban.mjs +2092 -2313
- package/dist/akb/package.json +1 -1
- package/dist/launcher.mjs +69 -34
- package/dist/runner.mjs +743 -672
- 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.7","akbContract":3,"type":"module","private":true}
|
package/dist/launcher.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// wildcrane-runner 0.6.
|
|
1
|
+
// wildcrane-runner 0.6.8 — 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
|
|
|
@@ -50,8 +50,8 @@ function cloudEndpoints() {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
// src/i18n.ts
|
|
53
|
-
var ZH_HOLDER = { "claude-code": "Claude Code", codex: "Codex", terminal: "\u672C\u673A\u7EC8\u7AEF"
|
|
54
|
-
var EN_HOLDER = { "claude-code": "Claude Code", codex: "Codex", terminal: "the terminal"
|
|
53
|
+
var ZH_HOLDER = { "claude-code": "Claude Code", codex: "Codex", terminal: "\u672C\u673A\u7EC8\u7AEF" };
|
|
54
|
+
var EN_HOLDER = { "claude-code": "Claude Code", codex: "Codex", terminal: "the terminal" };
|
|
55
55
|
var ZH = {
|
|
56
56
|
signIn: (url) => `\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u767B\u5F55 WildCrane\uFF1A
|
|
57
57
|
${url}`,
|
|
@@ -70,13 +70,7 @@ ${url}`,
|
|
|
70
70
|
const who = holder ? ZH_HOLDER[holder] : "\u672C\u673A\u53E6\u4E00\u4E2A\u7A0B\u5E8F";
|
|
71
71
|
return `${who}\u5DF2\u5728\u8FD0\u884C\u4E00\u4E2A WildCrane \u5B9E\u4F8B\uFF0C\u8D1F\u8D23\u63A5\u6536\u6240\u6709\u8FD0\u884C\u4EFB\u52A1\u3002\u5F53\u524D\u5B9E\u4F8B\u5DF2\u6682\u505C\uFF0C${who}\u5173\u95ED\u540E\u5C06\u7531\u5F53\u524D\u5B9E\u4F8B\u63A5\u66FF\u3002`;
|
|
72
72
|
},
|
|
73
|
-
stopped: () => "\u5DF2\u505C\u6B62"
|
|
74
|
-
reviewTitle: () => "\u5F85\u4F60\u5BA1\u6838",
|
|
75
|
-
reviewBody: (task) => `\u300C${task}\u300D\u5F85\u5BA1\u6838`,
|
|
76
|
-
doneTitle: () => "\u4EFB\u52A1\u5DF2\u5B8C\u6210",
|
|
77
|
-
failedTitle: () => "\u4EFB\u52A1\u5931\u8D25",
|
|
78
|
-
commentTitle: (task) => `\u300C${task}\u300D\u6709\u65B0\u8BC4\u8BBA`,
|
|
79
|
-
commentBody: (who, text) => `${who}\uFF1A${text}`
|
|
73
|
+
stopped: () => "\u5DF2\u505C\u6B62"
|
|
80
74
|
};
|
|
81
75
|
var EN = {
|
|
82
76
|
signIn: (url) => `Sign in to WildCrane in your browser:
|
|
@@ -96,13 +90,7 @@ ${url}`,
|
|
|
96
90
|
const who = holder ? EN_HOLDER[holder] : "another app on this computer";
|
|
97
91
|
return `${who[0].toUpperCase()}${who.slice(1)} is already running a WildCrane instance that takes all run tasks. This instance is paused and takes over when ${who} closes.`;
|
|
98
92
|
},
|
|
99
|
-
stopped: () => "Stopped"
|
|
100
|
-
reviewTitle: () => "Needs your review",
|
|
101
|
-
reviewBody: (task) => `"${task}" is ready for review`,
|
|
102
|
-
doneTitle: () => "Task finished",
|
|
103
|
-
failedTitle: () => "Task failed",
|
|
104
|
-
commentTitle: (task) => `New comment on ${task}`,
|
|
105
|
-
commentBody: (who, text) => `${who}: ${text}`
|
|
93
|
+
stopped: () => "Stopped"
|
|
106
94
|
};
|
|
107
95
|
function isChinese(env = process.env) {
|
|
108
96
|
const lang = env.LC_ALL || env.LC_MESSAGES || env.LANG || Intl.DateTimeFormat().resolvedOptions().locale;
|
|
@@ -119,9 +107,10 @@ function status(line) {
|
|
|
119
107
|
}
|
|
120
108
|
|
|
121
109
|
// src/protocol.ts
|
|
122
|
-
var VERSION = true ? "0.6.
|
|
110
|
+
var VERSION = true ? "0.6.8" : "0.0.0";
|
|
123
111
|
var EXIT_REFUSED = 10;
|
|
124
112
|
var EXIT_OUTDATED = 11;
|
|
113
|
+
var EXIT_UPDATE = 12;
|
|
125
114
|
|
|
126
115
|
// src/update.ts
|
|
127
116
|
import crypto2 from "node:crypto";
|
|
@@ -285,8 +274,8 @@ async function askTarget(machine) {
|
|
|
285
274
|
signal: AbortSignal.timeout(ASK_MS)
|
|
286
275
|
});
|
|
287
276
|
if (!answer.ok) return null;
|
|
288
|
-
const { version } = await answer.json();
|
|
289
|
-
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;
|
|
290
279
|
} catch {
|
|
291
280
|
return null;
|
|
292
281
|
}
|
|
@@ -295,9 +284,8 @@ async function candidates(own) {
|
|
|
295
284
|
const state = readState();
|
|
296
285
|
const proven = state.good.find((v) => fs3.existsSync(entryOf(versionDir(v))));
|
|
297
286
|
const current = proven && compare(proven, own.version) > 0 ? { version: proven, entry: entryOf(versionDir(proven)) } : own;
|
|
298
|
-
const target = await askTarget(machineId());
|
|
287
|
+
const target = (await askTarget(machineId()))?.version;
|
|
299
288
|
if (!target || target === current.version || state.bad.includes(target)) return [current];
|
|
300
|
-
if (process.env.WILDCRANE_DESKTOP && compare(target, own.version) < 0) return [current];
|
|
301
289
|
if (target === own.version) return [own, current];
|
|
302
290
|
const got = await install(target);
|
|
303
291
|
if (got.ok) {
|
|
@@ -307,16 +295,56 @@ async function candidates(own) {
|
|
|
307
295
|
if (got.why === "node") status(t.nodeTooOld(got.detail));
|
|
308
296
|
return [current];
|
|
309
297
|
}
|
|
310
|
-
function runOnce(candidate) {
|
|
298
|
+
function runOnce(candidate, options) {
|
|
311
299
|
return new Promise((resolve) => {
|
|
312
300
|
const child = spawn(process.execPath, [candidate.entry], {
|
|
313
|
-
stdio: ["
|
|
314
|
-
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" }
|
|
315
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);
|
|
316
336
|
let connected = false;
|
|
317
337
|
let timer = null;
|
|
318
338
|
let timedOut = false;
|
|
319
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
|
+
}
|
|
320
348
|
const forward = (signal) => () => {
|
|
321
349
|
stopping = true;
|
|
322
350
|
child.kill(signal);
|
|
@@ -325,13 +353,11 @@ function runOnce(candidate) {
|
|
|
325
353
|
const onTerm = forward("SIGTERM");
|
|
326
354
|
process.on("SIGINT", onInt);
|
|
327
355
|
process.on("SIGTERM", onTerm);
|
|
356
|
+
options.signal?.addEventListener("abort", onTerm, { once: true });
|
|
357
|
+
if (options.signal?.aborted) onTerm();
|
|
328
358
|
child.on("message", (message) => {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
timedOut = true;
|
|
332
|
-
child.kill("SIGTERM");
|
|
333
|
-
}, Number(process.env.WILDCRANE_CONNECT_MS) || CONNECT_MS);
|
|
334
|
-
}
|
|
359
|
+
options.onMessage?.(message);
|
|
360
|
+
if (message.type === "update-deferred") update = null;
|
|
335
361
|
if (message.type === "waiting" && timer) {
|
|
336
362
|
clearTimeout(timer);
|
|
337
363
|
timer = null;
|
|
@@ -347,9 +373,13 @@ function runOnce(candidate) {
|
|
|
347
373
|
}
|
|
348
374
|
});
|
|
349
375
|
child.on("exit", (code, signal) => {
|
|
376
|
+
clearInterval(poll);
|
|
377
|
+
clearTimeout(forceKill);
|
|
350
378
|
if (timer) clearTimeout(timer);
|
|
351
379
|
process.off("SIGINT", onInt);
|
|
352
380
|
process.off("SIGTERM", onTerm);
|
|
381
|
+
options.signal?.removeEventListener("abort", onTerm);
|
|
382
|
+
if (code === EXIT_UPDATE && update && !stopping) return resolve({ update });
|
|
353
383
|
if (connected || !candidate.fresh || stopping) return resolve({ exit: code ?? (signal ? 1 : 0) });
|
|
354
384
|
if (timedOut) return resolve({ failed: "timeout" });
|
|
355
385
|
if (code === 0 || code === EXIT_REFUSED || code === EXIT_OUTDATED) return resolve({ exit: code });
|
|
@@ -357,13 +387,18 @@ function runOnce(candidate) {
|
|
|
357
387
|
});
|
|
358
388
|
});
|
|
359
389
|
}
|
|
360
|
-
async function launch(own) {
|
|
390
|
+
async function launch(own, options = {}) {
|
|
361
391
|
const list = await candidates(own);
|
|
362
392
|
for (let i = 0; i < list.length; i++) {
|
|
393
|
+
if (options.signal?.aborted) return 0;
|
|
363
394
|
const candidate = list[i];
|
|
364
|
-
const outcome = await runOnce(candidate);
|
|
395
|
+
const outcome = await runOnce(candidate, options);
|
|
365
396
|
if ("exit" in outcome) return outcome.exit;
|
|
366
|
-
if (
|
|
397
|
+
if ("update" in outcome) {
|
|
398
|
+
list.splice(i + 1, list.length, outcome.update, candidate);
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
markBad(candidate.version);
|
|
367
402
|
const next = list[i + 1];
|
|
368
403
|
if (next) status(t.rolledBack(next.version));
|
|
369
404
|
}
|