@sleds/cli 0.1.52 → 0.1.53
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/dist/sleds.mjs +122 -57
- package/package.json +1 -1
package/dist/sleds.mjs
CHANGED
|
@@ -8601,6 +8601,7 @@ function parseRun(v) {
|
|
|
8601
8601
|
options: Array.isArray(v.permission.options) ? v.permission.options.filter((x) => typeof x === "string") : [],
|
|
8602
8602
|
at: v.permission.at,
|
|
8603
8603
|
...v.permission.onScreen === true ? { onScreen: true } : {},
|
|
8604
|
+
...typeof v.permission.dialog === "string" ? { dialog: v.permission.dialog } : {},
|
|
8604
8605
|
...typeof v.permission.pressedAt === "number" ? { pressedAt: v.permission.pressedAt } : {},
|
|
8605
8606
|
...typeof v.permission.presses === "number" ? { presses: v.permission.presses } : {},
|
|
8606
8607
|
...v.permission.gaveUp === true ? { gaveUp: true } : {}
|
|
@@ -8615,12 +8616,21 @@ function parseRun(v) {
|
|
|
8615
8616
|
feedback: typeof v.pr.feedback === "number" ? v.pr.feedback : 0,
|
|
8616
8617
|
...typeof v.pr.authorFeedback === "number" ? { authorFeedback: v.pr.authorFeedback } : {},
|
|
8617
8618
|
...typeof v.pr.selfNudges === "number" ? { selfNudges: v.pr.selfNudges } : {},
|
|
8619
|
+
...isObject8(v.pr.feedbackRead) && typeof v.pr.feedbackRead.updatedAt === "string" && typeof v.pr.feedbackRead.all === "number" && typeof v.pr.feedbackRead.author === "number" && typeof v.pr.feedbackRead.at === "number" ? {
|
|
8620
|
+
feedbackRead: {
|
|
8621
|
+
updatedAt: v.pr.feedbackRead.updatedAt,
|
|
8622
|
+
all: v.pr.feedbackRead.all,
|
|
8623
|
+
author: v.pr.feedbackRead.author,
|
|
8624
|
+
at: v.pr.feedbackRead.at
|
|
8625
|
+
}
|
|
8626
|
+
} : {},
|
|
8618
8627
|
...v.pr.clear === true ? { clear: true } : {},
|
|
8619
8628
|
...typeof v.pr.ci === "string" ? { ci: v.pr.ci } : {},
|
|
8620
8629
|
...typeof v.pr.review === "string" ? { review: v.pr.review } : {},
|
|
8621
8630
|
...typeof v.pr.posted === "string" ? { posted: v.pr.posted } : {},
|
|
8622
8631
|
...Array.isArray(v.pr.failedHeads) ? { failedHeads: v.pr.failedHeads.filter((x) => typeof x === "string") } : {},
|
|
8623
8632
|
...typeof v.pr.conflict === "string" ? { conflict: v.pr.conflict } : {},
|
|
8633
|
+
...isObject8(v.pr.conflictCheck) && typeof v.pr.conflictCheck.head === "string" && typeof v.pr.conflictCheck.at === "number" ? { conflictCheck: { head: v.pr.conflictCheck.head, at: v.pr.conflictCheck.at } } : {},
|
|
8624
8634
|
...typeof v.pr.resolving === "string" ? { resolving: v.pr.resolving } : {},
|
|
8625
8635
|
...conflicted ? { conflicted } : {},
|
|
8626
8636
|
...typeof v.pr.reviewed === "string" ? { reviewed: v.pr.reviewed } : {},
|
|
@@ -10759,15 +10769,36 @@ var claudeAddDirFlag = (mainCheckout) => mainCheckout ? ` --add-dir=${shq(mainCh
|
|
|
10759
10769
|
var shq = (s) => `'${s.replace(/'/g, `'\\''`)}'`;
|
|
10760
10770
|
|
|
10761
10771
|
// src/runners/exec.ts
|
|
10772
|
+
var EXEC_TIMEOUT_MS = 2 * 60000;
|
|
10773
|
+
var EXEC_TIMEOUT_STATUS = 124;
|
|
10774
|
+
var timedOut = (r) => r.error?.code === "ETIMEDOUT";
|
|
10775
|
+
var logTimeouts = (exec, log) => (cmd, args, o) => {
|
|
10776
|
+
const r = exec(cmd, args, o);
|
|
10777
|
+
if (r.status === EXEC_TIMEOUT_STATUS && isTimeout(r.stderr))
|
|
10778
|
+
log(`exec timed out: ${[cmd, ...args].join(" ")} — ${r.stderr.split(`
|
|
10779
|
+
`)[0]}`);
|
|
10780
|
+
return r;
|
|
10781
|
+
};
|
|
10762
10782
|
var defaultExec = (cmd, args, o) => {
|
|
10783
|
+
const timeoutMs = o?.timeoutMs ?? EXEC_TIMEOUT_MS;
|
|
10763
10784
|
const r = spawnSync3(cmd, [...args], {
|
|
10764
10785
|
cwd: o?.cwd,
|
|
10765
10786
|
input: o?.input,
|
|
10766
10787
|
env: o?.env ? { ...process.env, ...o.env } : undefined,
|
|
10767
10788
|
encoding: "utf8",
|
|
10768
10789
|
shell: false,
|
|
10769
|
-
maxBuffer: 16 * 1024 * 1024
|
|
10790
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
10791
|
+
timeout: timeoutMs,
|
|
10792
|
+
killSignal: "SIGKILL"
|
|
10770
10793
|
});
|
|
10794
|
+
if (timedOut(r)) {
|
|
10795
|
+
return {
|
|
10796
|
+
status: EXEC_TIMEOUT_STATUS,
|
|
10797
|
+
stdout: r.stdout ?? "",
|
|
10798
|
+
stderr: `${cmd}: timed out after ${timeoutMs / 1000}s and was killed${r.stderr ? `
|
|
10799
|
+
${r.stderr}` : ""}`
|
|
10800
|
+
};
|
|
10801
|
+
}
|
|
10771
10802
|
if (r.error) {
|
|
10772
10803
|
return { status: 127, stdout: r.stdout ?? "", stderr: `${cmd}: ${r.error.message}` };
|
|
10773
10804
|
}
|
|
@@ -11436,14 +11467,7 @@ ${r.stdout}`) };
|
|
|
11436
11467
|
sendKey(h, key) {
|
|
11437
11468
|
if (!isRunnerKey(key))
|
|
11438
11469
|
throw new Error(`orca terminal send ${h.id}: no key ${JSON.stringify(key)}`);
|
|
11439
|
-
|
|
11440
|
-
const send = (args) => orca(["terminal", "send", "--terminal", h.id, ...args, "--json"], what);
|
|
11441
|
-
if (key === "esc") {
|
|
11442
|
-
send(["--text", ESC]);
|
|
11443
|
-
return;
|
|
11444
|
-
}
|
|
11445
|
-
send(["--text", key]);
|
|
11446
|
-
send(["--enter"]);
|
|
11470
|
+
orca(["terminal", "send", "--terminal", h.id, "--text", key === "esc" ? ESC : key, "--json"], `orca terminal send ${h.id} (key ${key})`);
|
|
11447
11471
|
},
|
|
11448
11472
|
stop(h) {
|
|
11449
11473
|
exec("orca", ["terminal", "close", "--terminal", h.id]);
|
|
@@ -11511,7 +11535,7 @@ function beatBody(state, flags, host = {}, cap = {}) {
|
|
|
11511
11535
|
name: flags.name,
|
|
11512
11536
|
os: host.os ?? process.platform,
|
|
11513
11537
|
runner: flags.runner,
|
|
11514
|
-
version: host.version ?? "0.1.
|
|
11538
|
+
version: host.version ?? "0.1.53" ?? "dev",
|
|
11515
11539
|
running: live.length,
|
|
11516
11540
|
items: live.slice(0, BEAT_ITEMS).map((r) => `${r.item}/${r.node}`),
|
|
11517
11541
|
...cap.atOnce !== undefined ? { atOnce: cap.atOnce } : {},
|
|
@@ -11911,6 +11935,7 @@ function parsePrView(stdout) {
|
|
|
11911
11935
|
feedback: 0,
|
|
11912
11936
|
authorFeedback: 0,
|
|
11913
11937
|
draft: o.isDraft === true,
|
|
11938
|
+
updatedAt: typeof o.updatedAt === "string" ? o.updatedAt : "",
|
|
11914
11939
|
...mock ? { mock } : {},
|
|
11915
11940
|
...typeof o.headRefOid === "string" && o.headRefOid ? { head: o.headRefOid } : {},
|
|
11916
11941
|
...typeof mergeCommit === "string" && mergeCommit ? { mergeCommit } : {}
|
|
@@ -11959,20 +11984,24 @@ function prFeedback(exec, repoPath, url, author) {
|
|
|
11959
11984
|
}
|
|
11960
11985
|
return total;
|
|
11961
11986
|
}
|
|
11962
|
-
function prView(exec, repoPath, url) {
|
|
11987
|
+
function prView(exec, repoPath, url, last) {
|
|
11963
11988
|
try {
|
|
11964
11989
|
const r = exec("gh", [
|
|
11965
11990
|
"pr",
|
|
11966
11991
|
"view",
|
|
11967
11992
|
url,
|
|
11968
11993
|
"--json",
|
|
11969
|
-
"state,author,statusCheckRollup,reviewDecision,
|
|
11994
|
+
"state,author,statusCheckRollup,reviewDecision,headRefOid,mergeable,baseRefName,mergeCommit,isDraft,body,updatedAt"
|
|
11970
11995
|
], { cwd: repoPath });
|
|
11971
11996
|
const view = r.status === 0 ? parsePrView(r.stdout) : null;
|
|
11972
11997
|
if (!view || view.state !== "OPEN")
|
|
11973
11998
|
return view;
|
|
11974
|
-
|
|
11975
|
-
|
|
11999
|
+
let read = view.updatedAt && last?.updatedAt === view.updatedAt ? last : undefined;
|
|
12000
|
+
if (!read) {
|
|
12001
|
+
const f = prFeedback(exec, repoPath, url, view.author);
|
|
12002
|
+
read = f && { ...f, updatedAt: view.updatedAt };
|
|
12003
|
+
}
|
|
12004
|
+
return read ? { ...view, feedback: read.all, authorFeedback: read.author, read } : view;
|
|
11976
12005
|
} catch {
|
|
11977
12006
|
return null;
|
|
11978
12007
|
}
|
|
@@ -13011,26 +13040,28 @@ function sledsSource(client, o) {
|
|
|
13011
13040
|
});
|
|
13012
13041
|
if (r?.status !== 409)
|
|
13013
13042
|
return "running";
|
|
13043
|
+
let route;
|
|
13044
|
+
try {
|
|
13045
|
+
route = await routeOf(claim.item);
|
|
13046
|
+
} catch {
|
|
13047
|
+
route = null;
|
|
13048
|
+
}
|
|
13049
|
+
if (!isObject8(route))
|
|
13050
|
+
return "running";
|
|
13014
13051
|
if (claim.kind === "draft") {
|
|
13015
|
-
|
|
13016
|
-
|
|
13017
|
-
|
|
13018
|
-
|
|
13019
|
-
|
|
13020
|
-
if (isObject8(route?.draftParked))
|
|
13021
|
-
return "parked";
|
|
13022
|
-
} catch {}
|
|
13052
|
+
const filed = Array.isArray(route.nodes) && route.nodes.length > 0;
|
|
13053
|
+
if (filed || isObject8(route.proposed))
|
|
13054
|
+
return "done";
|
|
13055
|
+
if (isObject8(route.draftParked))
|
|
13056
|
+
return "parked";
|
|
13023
13057
|
return "lost";
|
|
13024
13058
|
}
|
|
13025
|
-
|
|
13026
|
-
|
|
13027
|
-
|
|
13028
|
-
|
|
13029
|
-
|
|
13030
|
-
|
|
13031
|
-
if (state === "pr" || state === "landed" || state === "skipped")
|
|
13032
|
-
return "done";
|
|
13033
|
-
} catch {}
|
|
13059
|
+
const nodes = Array.isArray(route.nodes) ? route.nodes.filter(isObject8) : [];
|
|
13060
|
+
const state = nodes.find((n) => n.key === claim.node)?.state;
|
|
13061
|
+
if (state === "parked")
|
|
13062
|
+
return "parked";
|
|
13063
|
+
if (state === "pr" || state === "landed" || state === "skipped")
|
|
13064
|
+
return "done";
|
|
13034
13065
|
return "lost";
|
|
13035
13066
|
},
|
|
13036
13067
|
async report(claim, outcome, by) {
|
|
@@ -13526,6 +13557,7 @@ function fastForwardUntouched(exec, path, base, log) {
|
|
|
13526
13557
|
log?.(`${path}: fast-forwarded to origin/${base}`);
|
|
13527
13558
|
return true;
|
|
13528
13559
|
}
|
|
13560
|
+
var INSTALL_TIMEOUT_MS = 15 * 60000;
|
|
13529
13561
|
var MANAGERS = new Set(["pnpm", "npm", "yarn", "bun"]);
|
|
13530
13562
|
var INSTALL_VERBS = new Set(["install", "i", "ci"]);
|
|
13531
13563
|
function installArgv(command) {
|
|
@@ -13617,7 +13649,7 @@ function ensureInstalled(exec, path, fs, o = {}) {
|
|
|
13617
13649
|
return null;
|
|
13618
13650
|
const [cmd, ...args] = argv;
|
|
13619
13651
|
o.log?.(`${path}: no node_modules — running ${argv.join(" ")}`);
|
|
13620
|
-
const r = exec(cmd, args, { cwd: path });
|
|
13652
|
+
const r = exec(cmd, args, { cwd: path, timeoutMs: INSTALL_TIMEOUT_MS });
|
|
13621
13653
|
const ok = r.status === 0;
|
|
13622
13654
|
if (!ok)
|
|
13623
13655
|
o.log?.(`${path}: ${argv.join(" ")} failed (exit ${r.status}) — the session starts anyway: ${(r.stderr || r.stdout).trim().split(`
|
|
@@ -14364,6 +14396,10 @@ function permissionKey(answer) {
|
|
|
14364
14396
|
const m = /^\s*(\d|esc)\s*·/i.exec(answer);
|
|
14365
14397
|
return m ? m[1].toLowerCase() : null;
|
|
14366
14398
|
}
|
|
14399
|
+
function dialogPrint(dialog) {
|
|
14400
|
+
return [dialog.text, ...dialog.options.map((o) => `${o.key} · ${o.label}`)].join(`
|
|
14401
|
+
`);
|
|
14402
|
+
}
|
|
14367
14403
|
async function settlePermission(d, runner, run, shown) {
|
|
14368
14404
|
const perms = permissionsOf(d.source);
|
|
14369
14405
|
if (!perms || !run.runId)
|
|
@@ -14373,19 +14409,20 @@ async function settlePermission(d, runner, run, shown) {
|
|
|
14373
14409
|
const dialog = runner.readsSession ? permissionDialog(shown) : null;
|
|
14374
14410
|
const p = run.permission;
|
|
14375
14411
|
if (p) {
|
|
14376
|
-
const gone = runner.readsSession && (p.onScreen ? !dialog : (run.seenAt ?? 0) > (p.pressedAt ?? p.at));
|
|
14412
|
+
const gone = runner.readsSession && (p.onScreen ? !dialog || p.dialog !== undefined && dialogPrint(dialog) !== p.dialog : (run.seenAt ?? 0) > (p.pressedAt ?? p.at));
|
|
14377
14413
|
const answered = () => {
|
|
14378
14414
|
run.permission = undefined;
|
|
14379
14415
|
run.answeredAt = d.now();
|
|
14380
14416
|
if (markFile)
|
|
14381
14417
|
clearPermissionMark(markFile);
|
|
14382
14418
|
};
|
|
14419
|
+
const next = (held) => dialog ? settlePermission(d, runner, run, shown) : held;
|
|
14383
14420
|
if (p.gaveUp) {
|
|
14384
14421
|
if (!gone)
|
|
14385
14422
|
return true;
|
|
14386
14423
|
d.log(`${at}: the permission dialog was answered in the terminal`);
|
|
14387
14424
|
answered();
|
|
14388
|
-
return false;
|
|
14425
|
+
return next(false);
|
|
14389
14426
|
}
|
|
14390
14427
|
let now;
|
|
14391
14428
|
try {
|
|
@@ -14408,13 +14445,13 @@ async function settlePermission(d, runner, run, shown) {
|
|
|
14408
14445
|
}
|
|
14409
14446
|
}
|
|
14410
14447
|
answered();
|
|
14411
|
-
return true;
|
|
14448
|
+
return gone ? next(true) : true;
|
|
14412
14449
|
}
|
|
14413
14450
|
const key = permissionKey(now.answer) ?? now.answer;
|
|
14414
14451
|
if (gone) {
|
|
14415
14452
|
d.log(`${at}: the permission is answered — pressed ${key}; the session goes on`);
|
|
14416
14453
|
answered();
|
|
14417
|
-
return false;
|
|
14454
|
+
return next(false);
|
|
14418
14455
|
}
|
|
14419
14456
|
const presses = p.presses ?? 1;
|
|
14420
14457
|
if (presses >= PRESS_TRIES) {
|
|
@@ -14447,7 +14484,7 @@ async function settlePermission(d, runner, run, shown) {
|
|
|
14447
14484
|
}
|
|
14448
14485
|
d.log(`${at}: the permission dialog closed before an answer — cleared`);
|
|
14449
14486
|
run.permission = undefined;
|
|
14450
|
-
return false;
|
|
14487
|
+
return next(false);
|
|
14451
14488
|
}
|
|
14452
14489
|
let mark = markFile ? readPermissionMark(markFile) : null;
|
|
14453
14490
|
if (mark && markFile && (!isToolPermission(mark.message) || runner.readsSession && choicePicker(shown))) {
|
|
@@ -14473,7 +14510,7 @@ async function settlePermission(d, runner, run, shown) {
|
|
|
14473
14510
|
decisionId: opened.decisionId,
|
|
14474
14511
|
options,
|
|
14475
14512
|
at: d.now(),
|
|
14476
|
-
...dialog ? { onScreen: true } : {}
|
|
14513
|
+
...dialog ? { onScreen: true, dialog: dialogPrint(dialog) } : {}
|
|
14477
14514
|
};
|
|
14478
14515
|
if (markFile)
|
|
14479
14516
|
clearPermissionMark(markFile);
|
|
@@ -15361,6 +15398,8 @@ function ciNudge(url, failing) {
|
|
|
15361
15398
|
return `CI failed on your PR (${failing.join(", ")}): ${url}. Read the failing logs (gh pr checks ${url}), fix the cause, run the repo's gate, and push to the same branch.`;
|
|
15362
15399
|
}
|
|
15363
15400
|
var SELF_NUDGES = 2;
|
|
15401
|
+
var FEEDBACK_REREAD_MS = 10 * 60000;
|
|
15402
|
+
var CONFLICT_RECHECK_MS = 10 * 60000;
|
|
15364
15403
|
function reviewNudge(url, count) {
|
|
15365
15404
|
return `New review feedback on your PR (${count} ${count === 1 ? "comment" : "comments"} from people so far): ${url}. Read all of it (gh pr view ${url} --comments, and the inline threads), answer each comment on its own thread with the fix or a reasoned reply, push, and leave the threads for the reviewer to resolve. End every comment and reply you post on the PR with the line ${ENGINE_MARK} so the engine knows it is yours and not the reviewer's.`;
|
|
15366
15405
|
}
|
|
@@ -15401,9 +15440,12 @@ async function judgeLook(d, run, view) {
|
|
|
15401
15440
|
}
|
|
15402
15441
|
async function follow(d, state, run, claim, runner, finished, attention, changes, decided) {
|
|
15403
15442
|
const pr = run.pr;
|
|
15404
|
-
const
|
|
15443
|
+
const last = pr.feedbackRead && d.now() - pr.feedbackRead.at < FEEDBACK_REREAD_MS ? pr.feedbackRead : undefined;
|
|
15444
|
+
const view = d.prView(d.exec, run.repoPath, pr.url, last);
|
|
15405
15445
|
if (!view)
|
|
15406
15446
|
return true;
|
|
15447
|
+
if (view.read && view.read !== last)
|
|
15448
|
+
pr.feedbackRead = { ...view.read, at: d.now() };
|
|
15407
15449
|
await judgeLook(d, run, view);
|
|
15408
15450
|
if (view.state === "MERGED") {
|
|
15409
15451
|
await dropPermission(d, run, "the PR merged");
|
|
@@ -15457,6 +15499,7 @@ async function follow(d, state, run, claim, runner, finished, attention, changes
|
|
|
15457
15499
|
else if (view.mergeable === "MERGEABLE") {
|
|
15458
15500
|
pr.resolving = undefined;
|
|
15459
15501
|
pr.conflicted = undefined;
|
|
15502
|
+
pr.conflictCheck = undefined;
|
|
15460
15503
|
}
|
|
15461
15504
|
if (view.feedback > pr.feedback) {
|
|
15462
15505
|
const what = `${view.feedback - pr.feedback} new review comment(s)`;
|
|
@@ -15696,10 +15739,15 @@ async function judgeConflict(d, state, run, view, attention, decided) {
|
|
|
15696
15739
|
const pr = run.pr;
|
|
15697
15740
|
if (!d.mergeTree)
|
|
15698
15741
|
return;
|
|
15742
|
+
const check = pr.conflictCheck;
|
|
15743
|
+
if (view.head && check?.head === view.head && !pr.resolving && d.now() - check.at < CONFLICT_RECHECK_MS)
|
|
15744
|
+
return;
|
|
15699
15745
|
const base = view.base || d.defaultBranch(d.exec, run.repoPath);
|
|
15700
15746
|
const mt = d.mergeTree(d.exec, run.repoPath, base, run.branch);
|
|
15701
15747
|
if (!mt)
|
|
15702
15748
|
return;
|
|
15749
|
+
if (view.head)
|
|
15750
|
+
pr.conflictCheck = { head: view.head, at: d.now() };
|
|
15703
15751
|
if (pr.resolving === mt.sha && mt.files.length > 0 && !sessionRuns(d, run.handle)) {
|
|
15704
15752
|
pr.resolving = undefined;
|
|
15705
15753
|
const what = `${pr.url} still conflicts with ${base} on ${mt.files.join(", ")} after its session had the brief`;
|
|
@@ -17362,7 +17410,7 @@ async function fetchVersion(o) {
|
|
|
17362
17410
|
const platform = o.platform ?? process.platform;
|
|
17363
17411
|
const arch = o.arch ?? process.arch;
|
|
17364
17412
|
const publicKey = o.publicKey ?? RELEASE_PUBLIC_KEY;
|
|
17365
|
-
const running = o.running ?? "0.1.
|
|
17413
|
+
const running = o.running ?? "0.1.53";
|
|
17366
17414
|
if (!publicKey)
|
|
17367
17415
|
return { ok: false, why: "no release key yet" };
|
|
17368
17416
|
if (!VERSION_RE2.test(o.version))
|
|
@@ -18946,7 +18994,7 @@ function engineClient(o, org) {
|
|
|
18946
18994
|
return fetchClient({
|
|
18947
18995
|
...src,
|
|
18948
18996
|
timeoutMs: ENGINE_TIMEOUT_MS,
|
|
18949
|
-
version: "0.1.
|
|
18997
|
+
version: "0.1.53"
|
|
18950
18998
|
});
|
|
18951
18999
|
const asked = org?.trim() || env.SLEDS_ORG?.trim();
|
|
18952
19000
|
if (asked && !selectOrg(readConfig(o.home), org, env).seat)
|
|
@@ -19011,10 +19059,10 @@ function engineToken(o, org) {
|
|
|
19011
19059
|
}
|
|
19012
19060
|
var withToken = (token, now) => token ? { token, tokenNow: now } : {};
|
|
19013
19061
|
function engineDeps(o, flags, source, runner, stateName) {
|
|
19014
|
-
const
|
|
19062
|
+
const log = o.log ?? console.log;
|
|
19063
|
+
const exec = logTimeouts(guardGit(o.exec ?? defaultExec), log);
|
|
19015
19064
|
const cwd = o.cwd ?? process.cwd();
|
|
19016
19065
|
const exists = o.exists ?? realExists;
|
|
19017
|
-
const log = o.log ?? console.log;
|
|
19018
19066
|
const stateDir = engineStateDir(o, flags.org, flags.seat);
|
|
19019
19067
|
const file = statePath(stateDir, stateName);
|
|
19020
19068
|
const mcpOrg = flags.org && engineOrg(o, flags.org).seated ? flags.org : undefined;
|
|
@@ -19237,7 +19285,7 @@ async function driveEngine(o, flags, deps, until = {}) {
|
|
|
19237
19285
|
runner: deps.runner.name,
|
|
19238
19286
|
atOnce: flags.atOnce,
|
|
19239
19287
|
interval: flags.interval,
|
|
19240
|
-
cliVersion: "0.1.
|
|
19288
|
+
cliVersion: "0.1.53"
|
|
19241
19289
|
};
|
|
19242
19290
|
const beat = (checkedAt) => {
|
|
19243
19291
|
const m = deps.machine;
|
|
@@ -19429,7 +19477,7 @@ async function drive(o, flags, deps, until, beat) {
|
|
|
19429
19477
|
var SEAT_CHANGED_EXIT = 3;
|
|
19430
19478
|
function engineRunner(o, flags) {
|
|
19431
19479
|
const runnerFor = o.runnerFor ?? runnerFor2;
|
|
19432
|
-
return runnerFor(flags.runner, guardGit(o.exec ?? defaultExec), {
|
|
19480
|
+
return runnerFor(flags.runner, logTimeouts(guardGit(o.exec ?? defaultExec), o.log ?? console.log), {
|
|
19433
19481
|
...flags.runnerCmd ? { command: flags.runnerCmd } : {}
|
|
19434
19482
|
});
|
|
19435
19483
|
}
|
|
@@ -21094,7 +21142,7 @@ function engineClient2(o, org) {
|
|
|
21094
21142
|
return fetchClient({
|
|
21095
21143
|
...src,
|
|
21096
21144
|
timeoutMs: ENGINE_TIMEOUT_MS2,
|
|
21097
|
-
version: "0.1.
|
|
21145
|
+
version: "0.1.53"
|
|
21098
21146
|
});
|
|
21099
21147
|
const asked = org?.trim() || env.SLEDS_ORG?.trim();
|
|
21100
21148
|
if (asked && !selectOrg(readConfig(o.home), org, env).seat)
|
|
@@ -21181,10 +21229,10 @@ function engineCredential(o) {
|
|
|
21181
21229
|
})?.kind;
|
|
21182
21230
|
}
|
|
21183
21231
|
function engineDeps2(o, flags, source, runner, stateName) {
|
|
21184
|
-
const
|
|
21232
|
+
const log = o.log ?? console.log;
|
|
21233
|
+
const exec = logTimeouts(guardGit(o.exec ?? defaultExec), log);
|
|
21185
21234
|
const cwd = o.cwd ?? process.cwd();
|
|
21186
21235
|
const exists = o.exists ?? realExists2;
|
|
21187
|
-
const log = o.log ?? console.log;
|
|
21188
21236
|
const stateDir = engineStateDir2(o, flags.org, flags.seat);
|
|
21189
21237
|
const file = statePath(stateDir, stateName);
|
|
21190
21238
|
const mcpOrg = flags.org && engineOrg2(o, flags.org).seated ? flags.org : undefined;
|
|
@@ -21420,7 +21468,7 @@ async function driveEngine2(o, flags, deps, until = {}) {
|
|
|
21420
21468
|
runner: deps.runner.name,
|
|
21421
21469
|
atOnce: flags.atOnce,
|
|
21422
21470
|
interval: flags.interval,
|
|
21423
|
-
cliVersion: "0.1.
|
|
21471
|
+
cliVersion: "0.1.53"
|
|
21424
21472
|
};
|
|
21425
21473
|
const beat = (checkedAt) => {
|
|
21426
21474
|
const m = deps.machine;
|
|
@@ -21612,7 +21660,7 @@ async function drive2(o, flags, deps, until, beat) {
|
|
|
21612
21660
|
var SEAT_CHANGED_EXIT2 = 3;
|
|
21613
21661
|
function engineRunner2(o, flags) {
|
|
21614
21662
|
const runnerFor = o.runnerFor ?? runnerFor2;
|
|
21615
|
-
return runnerFor(flags.runner, guardGit(o.exec ?? defaultExec), {
|
|
21663
|
+
return runnerFor(flags.runner, logTimeouts(guardGit(o.exec ?? defaultExec), o.log ?? console.log), {
|
|
21616
21664
|
...flags.runnerCmd ? { command: flags.runnerCmd } : {}
|
|
21617
21665
|
});
|
|
21618
21666
|
}
|
|
@@ -23508,7 +23556,7 @@ function contextFor(deps) {
|
|
|
23508
23556
|
...src,
|
|
23509
23557
|
fetchFn: deps.fetchFn,
|
|
23510
23558
|
timeoutMs: deps.timeoutMs,
|
|
23511
|
-
version: "0.1.
|
|
23559
|
+
version: "0.1.53"
|
|
23512
23560
|
}), deps.home, now) : null;
|
|
23513
23561
|
return {
|
|
23514
23562
|
channel: "code",
|
|
@@ -26095,14 +26143,17 @@ async function sledOff(client, key, json, log, error) {
|
|
|
26095
26143
|
return 0;
|
|
26096
26144
|
}
|
|
26097
26145
|
const k = typeof r.json?.key === "string" ? r.json.key : key;
|
|
26146
|
+
const why = typeof r.json?.why === "string" && r.json.why.trim() ? r.json.why : null;
|
|
26098
26147
|
if (r.json?.changed === false) {
|
|
26099
|
-
|
|
26100
|
-
return
|
|
26148
|
+
error(why ?? `${k} was not on a sled`);
|
|
26149
|
+
return 1;
|
|
26101
26150
|
}
|
|
26102
26151
|
log(`${k} is off your sled — back in the pool`);
|
|
26103
26152
|
const running = typeof r.json?.running === "number" ? r.json.running : 0;
|
|
26104
26153
|
if (running > 0)
|
|
26105
26154
|
log(`${running} running node${running === 1 ? "" : "s"} stopped`);
|
|
26155
|
+
if (why)
|
|
26156
|
+
log(why);
|
|
26106
26157
|
return 0;
|
|
26107
26158
|
}
|
|
26108
26159
|
|
|
@@ -27623,7 +27674,7 @@ var realPidAlive4 = (pid) => {
|
|
|
27623
27674
|
};
|
|
27624
27675
|
function machineClient(home, env) {
|
|
27625
27676
|
const src = meterSource(home, undefined, { env });
|
|
27626
|
-
return src ? fetchClient({ ...src, version: "0.1.
|
|
27677
|
+
return src ? fetchClient({ ...src, version: "0.1.53" }) : null;
|
|
27627
27678
|
}
|
|
27628
27679
|
async function noteAnswer2(home, a, now) {
|
|
27629
27680
|
try {
|
|
@@ -28093,15 +28144,29 @@ var readConfig2 = (home) => {
|
|
|
28093
28144
|
|
|
28094
28145
|
// src/runners/exec.ts
|
|
28095
28146
|
import { spawn as spawn3, spawnSync as spawnSync10 } from "node:child_process";
|
|
28147
|
+
var EXEC_TIMEOUT_MS2 = 2 * 60000;
|
|
28148
|
+
var EXEC_TIMEOUT_STATUS2 = 124;
|
|
28149
|
+
var timedOut2 = (r) => r.error?.code === "ETIMEDOUT";
|
|
28096
28150
|
var defaultExec4 = (cmd, args, o) => {
|
|
28151
|
+
const timeoutMs = o?.timeoutMs ?? EXEC_TIMEOUT_MS2;
|
|
28097
28152
|
const r = spawnSync10(cmd, [...args], {
|
|
28098
28153
|
cwd: o?.cwd,
|
|
28099
28154
|
input: o?.input,
|
|
28100
28155
|
env: o?.env ? { ...process.env, ...o.env } : undefined,
|
|
28101
28156
|
encoding: "utf8",
|
|
28102
28157
|
shell: false,
|
|
28103
|
-
maxBuffer: 16 * 1024 * 1024
|
|
28158
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
28159
|
+
timeout: timeoutMs,
|
|
28160
|
+
killSignal: "SIGKILL"
|
|
28104
28161
|
});
|
|
28162
|
+
if (timedOut2(r)) {
|
|
28163
|
+
return {
|
|
28164
|
+
status: EXEC_TIMEOUT_STATUS2,
|
|
28165
|
+
stdout: r.stdout ?? "",
|
|
28166
|
+
stderr: `${cmd}: timed out after ${timeoutMs / 1000}s and was killed${r.stderr ? `
|
|
28167
|
+
${r.stderr}` : ""}`
|
|
28168
|
+
};
|
|
28169
|
+
}
|
|
28105
28170
|
if (r.error) {
|
|
28106
28171
|
return { status: 127, stdout: r.stdout ?? "", stderr: `${cmd}: ${r.error.message}` };
|
|
28107
28172
|
}
|
|
@@ -28469,7 +28534,7 @@ var main = async (argv) => {
|
|
|
28469
28534
|
now: Date.now(),
|
|
28470
28535
|
stderr: (line) => console.error(line),
|
|
28471
28536
|
isTTY: !!process.stderr.isTTY,
|
|
28472
|
-
version: "0.1.
|
|
28537
|
+
version: "0.1.53"
|
|
28473
28538
|
});
|
|
28474
28539
|
switch (cmd) {
|
|
28475
28540
|
case "update":
|
|
@@ -28702,7 +28767,7 @@ ${renderHelpText(argv[1])}`);
|
|
|
28702
28767
|
case "version":
|
|
28703
28768
|
case "--version":
|
|
28704
28769
|
case "-v":
|
|
28705
|
-
console.log("sleds 0.1.
|
|
28770
|
+
console.log("sleds 0.1.53");
|
|
28706
28771
|
return 0;
|
|
28707
28772
|
default:
|
|
28708
28773
|
console.error(`unknown command: ${cmd}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sleds/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.53",
|
|
4
4
|
"description": "SLEDS CLI — the cost and limits of AI agent work, decided at the wall. Point Claude Code at a SLEDS proxy; estimate before you run; hold, switch model, or run overnight when you hit a limit.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|