@sleds/cli 0.1.51 → 0.1.52
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 +248 -30
- package/package.json +1 -1
package/dist/sleds.mjs
CHANGED
|
@@ -5689,11 +5689,20 @@ var init_copy = __esm(() => {
|
|
|
5689
5689
|
});
|
|
5690
5690
|
|
|
5691
5691
|
// ../../packages/shared/src/slack/agent.ts
|
|
5692
|
+
var REPLY_RULES;
|
|
5692
5693
|
var init_agent = __esm(() => {
|
|
5693
5694
|
init_intake();
|
|
5694
5695
|
init_brief();
|
|
5695
5696
|
init_copy();
|
|
5696
5697
|
init_mention();
|
|
5698
|
+
REPLY_RULES = [
|
|
5699
|
+
"How to answer this reply:",
|
|
5700
|
+
'- If it answers nothing and changes nothing — thanks, "noted", "copy", "will do", or people talking to each other — set quiet to true and post nothing.',
|
|
5701
|
+
"- Never ask a question the thread already asked. If it is still open, say only what is still needed, once, in a few words.",
|
|
5702
|
+
"- If someone in the thread already gave the cause or a fix, do not ask the poster for details it makes moot. Say in one line what is left, or set quiet.",
|
|
5703
|
+
"- Keep it to what changed and what is next. No recap of the ask."
|
|
5704
|
+
].join(`
|
|
5705
|
+
`);
|
|
5697
5706
|
});
|
|
5698
5707
|
|
|
5699
5708
|
// ../../packages/shared/src/slack/channel.ts
|
|
@@ -8545,7 +8554,13 @@ function parseParked(v) {
|
|
|
8545
8554
|
...typeof a.effort === "string" ? { effort: a.effort } : {}
|
|
8546
8555
|
};
|
|
8547
8556
|
}
|
|
8548
|
-
return {
|
|
8557
|
+
return {
|
|
8558
|
+
question: v.question,
|
|
8559
|
+
at: v.at,
|
|
8560
|
+
...typeof v.screen === "string" ? { screen: v.screen } : {},
|
|
8561
|
+
...v.still === true ? { still: true } : {},
|
|
8562
|
+
...answerer ? { answerer } : {}
|
|
8563
|
+
};
|
|
8549
8564
|
}
|
|
8550
8565
|
function parseRun(v) {
|
|
8551
8566
|
if (!isObject8(v))
|
|
@@ -8585,7 +8600,10 @@ function parseRun(v) {
|
|
|
8585
8600
|
decisionId: v.permission.decisionId,
|
|
8586
8601
|
options: Array.isArray(v.permission.options) ? v.permission.options.filter((x) => typeof x === "string") : [],
|
|
8587
8602
|
at: v.permission.at,
|
|
8588
|
-
...v.permission.onScreen === true ? { onScreen: true } : {}
|
|
8603
|
+
...v.permission.onScreen === true ? { onScreen: true } : {},
|
|
8604
|
+
...typeof v.permission.pressedAt === "number" ? { pressedAt: v.permission.pressedAt } : {},
|
|
8605
|
+
...typeof v.permission.presses === "number" ? { presses: v.permission.presses } : {},
|
|
8606
|
+
...v.permission.gaveUp === true ? { gaveUp: true } : {}
|
|
8589
8607
|
}
|
|
8590
8608
|
} : {},
|
|
8591
8609
|
...isObject8(v.provider) && typeof v.provider.why === "string" && typeof v.provider.since === "number" && typeof v.provider.tries === "number" ? { provider: { why: v.provider.why, since: v.provider.since, tries: v.provider.tries } } : {},
|
|
@@ -11243,6 +11261,8 @@ var orcaLauncher = (o) => `#!/bin/sh
|
|
|
11243
11261
|
${execLine(agentShellCommand(o))}
|
|
11244
11262
|
`;
|
|
11245
11263
|
var orcaCommand = (launcher) => `sh ${shq2(launcher)}; exit`;
|
|
11264
|
+
var orcaRequestId = (env, text) => str8(obj(obj(env?.error)?.data)?.orchestrationRequestId) ?? text.match(/--retry-request ([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i)?.[1] ?? null;
|
|
11265
|
+
var ESC = "\x1B";
|
|
11246
11266
|
var GONE = /exit|clos|gone|dead|stopp|kill/i;
|
|
11247
11267
|
var orcaTerminalLive = (status, stdout) => {
|
|
11248
11268
|
const env = parseOrcaJson(stdout);
|
|
@@ -11327,6 +11347,7 @@ function orcaRunner(exec, deps = {}) {
|
|
|
11327
11347
|
}
|
|
11328
11348
|
return env;
|
|
11329
11349
|
};
|
|
11350
|
+
const retries = new Map;
|
|
11330
11351
|
return {
|
|
11331
11352
|
name: "orca",
|
|
11332
11353
|
makesWorktree: true,
|
|
@@ -11378,10 +11399,51 @@ function orcaRunner(exec, deps = {}) {
|
|
|
11378
11399
|
return r.status === 0 ? r.stdout : "";
|
|
11379
11400
|
},
|
|
11380
11401
|
send(h, text) {
|
|
11381
|
-
const
|
|
11382
|
-
|
|
11383
|
-
|
|
11402
|
+
const key = `${h.id}
|
|
11403
|
+
${text}`;
|
|
11404
|
+
const attempt = (retry) => {
|
|
11405
|
+
const r = exec("orca", [
|
|
11406
|
+
"terminal",
|
|
11407
|
+
"send",
|
|
11408
|
+
"--terminal",
|
|
11409
|
+
h.id,
|
|
11410
|
+
"--text",
|
|
11411
|
+
text,
|
|
11412
|
+
"--enter",
|
|
11413
|
+
...retry ? ["--retry-request", retry] : [],
|
|
11414
|
+
"--json"
|
|
11415
|
+
]);
|
|
11416
|
+
const env = parseOrcaJson(r.stdout);
|
|
11417
|
+
const ok = r.status === 0 && env?.ok !== false;
|
|
11418
|
+
return { r, env, ok, id: ok ? null : orcaRequestId(env, `${r.stderr}
|
|
11419
|
+
${r.stdout}`) };
|
|
11420
|
+
};
|
|
11421
|
+
const prior = retries.get(key);
|
|
11422
|
+
let a = attempt(prior);
|
|
11423
|
+
if (!a.ok && a.id && a.id !== prior)
|
|
11424
|
+
a = attempt(a.id);
|
|
11425
|
+
if (a.ok) {
|
|
11426
|
+
retries.delete(key);
|
|
11427
|
+
return;
|
|
11384
11428
|
}
|
|
11429
|
+
if (a.id)
|
|
11430
|
+
retries.set(key, a.id);
|
|
11431
|
+
else
|
|
11432
|
+
retries.delete(key);
|
|
11433
|
+
const why = orcaError(a.env) ?? (a.r.stderr.trim() || `exit ${a.r.status}`);
|
|
11434
|
+
throw new Error(`orca terminal send ${h.id} failed: ${why}`);
|
|
11435
|
+
},
|
|
11436
|
+
sendKey(h, key) {
|
|
11437
|
+
if (!isRunnerKey(key))
|
|
11438
|
+
throw new Error(`orca terminal send ${h.id}: no key ${JSON.stringify(key)}`);
|
|
11439
|
+
const what = `orca terminal send ${h.id} (key ${key})`;
|
|
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"]);
|
|
11385
11447
|
},
|
|
11386
11448
|
stop(h) {
|
|
11387
11449
|
exec("orca", ["terminal", "close", "--terminal", h.id]);
|
|
@@ -11449,7 +11511,7 @@ function beatBody(state, flags, host = {}, cap = {}) {
|
|
|
11449
11511
|
name: flags.name,
|
|
11450
11512
|
os: host.os ?? process.platform,
|
|
11451
11513
|
runner: flags.runner,
|
|
11452
|
-
version: host.version ?? "0.1.
|
|
11514
|
+
version: host.version ?? "0.1.52" ?? "dev",
|
|
11453
11515
|
running: live.length,
|
|
11454
11516
|
items: live.slice(0, BEAT_ITEMS).map((r) => `${r.item}/${r.node}`),
|
|
11455
11517
|
...cap.atOnce !== undefined ? { atOnce: cap.atOnce } : {},
|
|
@@ -12454,6 +12516,10 @@ function permissionsOf(s) {
|
|
|
12454
12516
|
const p = s;
|
|
12455
12517
|
return p && typeof p.openPermission === "function" && typeof p.clearPermission === "function" && typeof p.decisionOf === "function" ? s : null;
|
|
12456
12518
|
}
|
|
12519
|
+
function resumesOf(s) {
|
|
12520
|
+
const r = s;
|
|
12521
|
+
return r && typeof r.resumeParked === "function" ? s : null;
|
|
12522
|
+
}
|
|
12457
12523
|
var FAIL_LOG_MAX = 2000;
|
|
12458
12524
|
var UNREACHABLE3 = "SLEDS unreachable";
|
|
12459
12525
|
function keysIn(states, state) {
|
|
@@ -12638,6 +12704,9 @@ function profileOf(r) {
|
|
|
12638
12704
|
const atOnce = num5(p.atOnce);
|
|
12639
12705
|
if (atOnce !== undefined && atOnce >= 1)
|
|
12640
12706
|
out.atOnce = Math.round(atOnce);
|
|
12707
|
+
const seatAtOnce = num5(r.seatAtOnce);
|
|
12708
|
+
if (seatAtOnce !== undefined && Number.isInteger(seatAtOnce) && seatAtOnce >= 1)
|
|
12709
|
+
out.seatAtOnce = seatAtOnce;
|
|
12641
12710
|
if (typeof p.mcpStrict === "boolean")
|
|
12642
12711
|
out.mcpStrict = p.mcpStrict;
|
|
12643
12712
|
const holdCpu = num5(p.holdCpu);
|
|
@@ -13100,6 +13169,18 @@ function sledsSource(client, o) {
|
|
|
13100
13169
|
throw new Error(serverMessage(r));
|
|
13101
13170
|
return r.json.cleared === true;
|
|
13102
13171
|
},
|
|
13172
|
+
async resumeParked(runId, why, engine, leaseMin) {
|
|
13173
|
+
const r = await client.postFull("/proxy/run", { runId, engine, leaseMin, resumed: { why } });
|
|
13174
|
+
if (!r)
|
|
13175
|
+
throw new Error(`${UNREACHABLE3} — the resume not recorded`);
|
|
13176
|
+
if (r.status >= 300 || !r.json || r.json.ok === false)
|
|
13177
|
+
throw new Error(serverMessage(r));
|
|
13178
|
+
const leaseUntil = typeof r.json.leaseUntil === "number" ? r.json.leaseUntil : undefined;
|
|
13179
|
+
return {
|
|
13180
|
+
resumed: r.json.resumed === true,
|
|
13181
|
+
...leaseUntil !== undefined ? { leaseUntil } : {}
|
|
13182
|
+
};
|
|
13183
|
+
},
|
|
13103
13184
|
async decisionOf(item, decisionId) {
|
|
13104
13185
|
const route = await routeOf(item);
|
|
13105
13186
|
const decisions = Array.isArray(route?.decisions) ? route.decisions.filter(isObject8) : [];
|
|
@@ -13692,6 +13773,7 @@ async function tick(deps) {
|
|
|
13692
13773
|
deps.providerHold = d.providerHold;
|
|
13693
13774
|
deps.draining = d.draining;
|
|
13694
13775
|
deps.atOnce = d.atOnce;
|
|
13776
|
+
deps.seatAtOnceNoted = d.seatAtOnceNoted;
|
|
13695
13777
|
deps.runner = d.runner;
|
|
13696
13778
|
deps.runnerRefused = d.runnerRefused;
|
|
13697
13779
|
}
|
|
@@ -13763,6 +13845,10 @@ async function tickOnce(d) {
|
|
|
13763
13845
|
try {
|
|
13764
13846
|
open = runner.status(run.handle) === "running";
|
|
13765
13847
|
} catch {}
|
|
13848
|
+
if (open && await answeredInSession(d, runner, run)) {
|
|
13849
|
+
keep.push(run);
|
|
13850
|
+
continue;
|
|
13851
|
+
}
|
|
13766
13852
|
if (open || liveAnswerer(run))
|
|
13767
13853
|
keep.push(run);
|
|
13768
13854
|
else
|
|
@@ -14287,7 +14373,20 @@ async function settlePermission(d, runner, run, shown) {
|
|
|
14287
14373
|
const dialog = runner.readsSession ? permissionDialog(shown) : null;
|
|
14288
14374
|
const p = run.permission;
|
|
14289
14375
|
if (p) {
|
|
14290
|
-
const gone = runner.readsSession && (p.onScreen ? !dialog : (run.seenAt ?? 0) > p.at);
|
|
14376
|
+
const gone = runner.readsSession && (p.onScreen ? !dialog : (run.seenAt ?? 0) > (p.pressedAt ?? p.at));
|
|
14377
|
+
const answered = () => {
|
|
14378
|
+
run.permission = undefined;
|
|
14379
|
+
run.answeredAt = d.now();
|
|
14380
|
+
if (markFile)
|
|
14381
|
+
clearPermissionMark(markFile);
|
|
14382
|
+
};
|
|
14383
|
+
if (p.gaveUp) {
|
|
14384
|
+
if (!gone)
|
|
14385
|
+
return true;
|
|
14386
|
+
d.log(`${at}: the permission dialog was answered in the terminal`);
|
|
14387
|
+
answered();
|
|
14388
|
+
return false;
|
|
14389
|
+
}
|
|
14291
14390
|
let now;
|
|
14292
14391
|
try {
|
|
14293
14392
|
now = await perms.decisionOf(run.item, p.decisionId);
|
|
@@ -14296,14 +14395,42 @@ async function settlePermission(d, runner, run, shown) {
|
|
|
14296
14395
|
return true;
|
|
14297
14396
|
}
|
|
14298
14397
|
if (now?.state === "answered" && now.answer) {
|
|
14299
|
-
if (
|
|
14300
|
-
|
|
14301
|
-
|
|
14398
|
+
if (p.pressedAt === undefined) {
|
|
14399
|
+
if (gone)
|
|
14400
|
+
d.log(`${at}: the permission was answered after its dialog closed — not pressed`);
|
|
14401
|
+
else {
|
|
14402
|
+
const pressed = pressAnswer(d, runner, run, p.options, now.answer);
|
|
14403
|
+
if (!pressed)
|
|
14404
|
+
return true;
|
|
14405
|
+
if (pressed === "key") {
|
|
14406
|
+
run.permission = { ...p, pressedAt: d.now(), presses: 1 };
|
|
14407
|
+
return true;
|
|
14408
|
+
}
|
|
14409
|
+
}
|
|
14410
|
+
answered();
|
|
14302
14411
|
return true;
|
|
14303
|
-
|
|
14304
|
-
|
|
14305
|
-
if (
|
|
14306
|
-
|
|
14412
|
+
}
|
|
14413
|
+
const key = permissionKey(now.answer) ?? now.answer;
|
|
14414
|
+
if (gone) {
|
|
14415
|
+
d.log(`${at}: the permission is answered — pressed ${key}; the session goes on`);
|
|
14416
|
+
answered();
|
|
14417
|
+
return false;
|
|
14418
|
+
}
|
|
14419
|
+
const presses = p.presses ?? 1;
|
|
14420
|
+
if (presses >= PRESS_TRIES) {
|
|
14421
|
+
const why = `pressed ${key} ${presses} times; the dialog stayed — answer it in the terminal`;
|
|
14422
|
+
try {
|
|
14423
|
+
await perms.clearPermission(run.runId, why, d.engine);
|
|
14424
|
+
} catch (e) {
|
|
14425
|
+
d.log(`${at}: could not clear the permission, trying next tick: ${message(e)}`);
|
|
14426
|
+
return true;
|
|
14427
|
+
}
|
|
14428
|
+
d.log(`${at}: ${why}`);
|
|
14429
|
+
run.permission = { ...p, gaveUp: true };
|
|
14430
|
+
return true;
|
|
14431
|
+
}
|
|
14432
|
+
if (pressAnswer(d, runner, run, p.options, now.answer) === "key")
|
|
14433
|
+
run.permission = { ...p, pressedAt: d.now(), presses: presses + 1 };
|
|
14307
14434
|
return true;
|
|
14308
14435
|
}
|
|
14309
14436
|
if (now?.state !== "open" && now?.state !== "escalated") {
|
|
@@ -14353,6 +14480,7 @@ async function settlePermission(d, runner, run, shown) {
|
|
|
14353
14480
|
d.log(`${at}: stopped at a permission dialog — it waits for a person (${runner.watchHint(run.handle)})`);
|
|
14354
14481
|
return true;
|
|
14355
14482
|
}
|
|
14483
|
+
var PRESS_TRIES = 3;
|
|
14356
14484
|
function pressAnswer(d, runner, run, options, answer) {
|
|
14357
14485
|
const at = ref(run);
|
|
14358
14486
|
const key = permissionKey(answer);
|
|
@@ -14363,13 +14491,15 @@ function pressAnswer(d, runner, run, options, answer) {
|
|
|
14363
14491
|
runner.sendKey(run.handle, key);
|
|
14364
14492
|
else
|
|
14365
14493
|
runner.send(run.handle, key);
|
|
14494
|
+
if (runner.readsSession)
|
|
14495
|
+
return "key";
|
|
14366
14496
|
d.log(`${at}: the permission is answered — pressed ${key}; the session goes on`);
|
|
14367
14497
|
} else {
|
|
14368
14498
|
runner.sendKey?.(run.handle, "esc");
|
|
14369
14499
|
const note = runner.send(run.handle, answer);
|
|
14370
14500
|
d.log(`${at}: the permission is answered in words — Esc, then typed in${note ? ` (${note})` : ""}`);
|
|
14371
14501
|
}
|
|
14372
|
-
return
|
|
14502
|
+
return "done";
|
|
14373
14503
|
} catch (e) {
|
|
14374
14504
|
d.log(`${at}: could not press the permission's answer, trying next tick: ${message(e)}`);
|
|
14375
14505
|
return false;
|
|
@@ -14538,10 +14668,25 @@ async function rereadAtOnce(d) {
|
|
|
14538
14668
|
try {
|
|
14539
14669
|
next = await d.rereadAtOnce(profileOf2(d));
|
|
14540
14670
|
} catch {}
|
|
14541
|
-
if (next
|
|
14671
|
+
if (next !== null && next !== d.atOnce) {
|
|
14672
|
+
d.atOnce = next;
|
|
14673
|
+
d.log(`at once now ${next}, from your engine profile`);
|
|
14674
|
+
}
|
|
14675
|
+
await sayAtOnceDisagrees(d);
|
|
14676
|
+
}
|
|
14677
|
+
async function sayAtOnceDisagrees(d) {
|
|
14678
|
+
const seat = (await profileOf2(d)())?.seatAtOnce;
|
|
14679
|
+
if (seat === undefined)
|
|
14680
|
+
return;
|
|
14681
|
+
if (seat === d.atOnce) {
|
|
14682
|
+
d.seatAtOnceNoted = undefined;
|
|
14542
14683
|
return;
|
|
14543
|
-
|
|
14544
|
-
|
|
14684
|
+
}
|
|
14685
|
+
const pair = `${d.atOnce}/${seat}`;
|
|
14686
|
+
if (d.seatAtOnceNoted === pair)
|
|
14687
|
+
return;
|
|
14688
|
+
d.seatAtOnceNoted = pair;
|
|
14689
|
+
d.log(seat < d.atOnce ? `at once ${d.atOnce} on the engine, but this seat allows ${seat} — the server refuses a claim past ${seat} on it; set it in Settings` : `at once ${d.atOnce} on the engine, but this seat allows ${seat} — the engine takes only ${d.atOnce}; set it in Settings`);
|
|
14545
14690
|
}
|
|
14546
14691
|
async function rereadRunner(d) {
|
|
14547
14692
|
if (!d.rereadRunner)
|
|
@@ -14595,10 +14740,53 @@ function stopOpen(d, run, runner) {
|
|
|
14595
14740
|
}
|
|
14596
14741
|
}
|
|
14597
14742
|
function holdParked(d, runner, run, question) {
|
|
14598
|
-
run.parked = { question, at: d.now() };
|
|
14743
|
+
run.parked = { question, at: d.now(), ...run.seen ? { screen: run.seen } : {} };
|
|
14599
14744
|
run.leaseUntil = undefined;
|
|
14600
14745
|
setLane(d, runner, run.handle, "parked");
|
|
14601
14746
|
}
|
|
14747
|
+
async function answeredInSession(d, runner, run) {
|
|
14748
|
+
const parked = run.parked;
|
|
14749
|
+
const resumes = resumesOf(d.source);
|
|
14750
|
+
if (!resumes || !runner.readsSession || !run.runId)
|
|
14751
|
+
return false;
|
|
14752
|
+
let print;
|
|
14753
|
+
try {
|
|
14754
|
+
print = fingerprint(runner.read(run.handle));
|
|
14755
|
+
} catch {
|
|
14756
|
+
return false;
|
|
14757
|
+
}
|
|
14758
|
+
if (print === parked.screen) {
|
|
14759
|
+
parked.still = true;
|
|
14760
|
+
return false;
|
|
14761
|
+
}
|
|
14762
|
+
const moved = parked.still === true;
|
|
14763
|
+
parked.screen = print;
|
|
14764
|
+
parked.still = false;
|
|
14765
|
+
if (!moved)
|
|
14766
|
+
return false;
|
|
14767
|
+
let r;
|
|
14768
|
+
try {
|
|
14769
|
+
r = await resumes.resumeParked(run.runId, "answered in the session", d.engine, d.leaseMin);
|
|
14770
|
+
} catch (e) {
|
|
14771
|
+
d.log(`${ref(run)}: the parked session moved on, but SLEDS did not hear it: ${message(e)}`);
|
|
14772
|
+
return false;
|
|
14773
|
+
}
|
|
14774
|
+
if (!r.resumed) {
|
|
14775
|
+
d.log(`${ref(run)}: the parked session moved on, but the node is no longer parked on its run`);
|
|
14776
|
+
return false;
|
|
14777
|
+
}
|
|
14778
|
+
stopAnswerer(d, run);
|
|
14779
|
+
const now = d.now();
|
|
14780
|
+
run.parked = undefined;
|
|
14781
|
+
run.seen = print;
|
|
14782
|
+
run.seenAt = now;
|
|
14783
|
+
run.seenTicks = 0;
|
|
14784
|
+
run.answeredAt = now;
|
|
14785
|
+
run.leaseUntil = r.leaseUntil ?? now + d.leaseMin * 60000;
|
|
14786
|
+
setLane(d, runner, run.handle, "working");
|
|
14787
|
+
d.log(`${ref(run)}: answered in the session — out of Needs you, running again`);
|
|
14788
|
+
return true;
|
|
14789
|
+
}
|
|
14602
14790
|
function setLane(d, runner, h, lane) {
|
|
14603
14791
|
try {
|
|
14604
14792
|
runner.lane?.(h, lane);
|
|
@@ -17174,7 +17362,7 @@ async function fetchVersion(o) {
|
|
|
17174
17362
|
const platform = o.platform ?? process.platform;
|
|
17175
17363
|
const arch = o.arch ?? process.arch;
|
|
17176
17364
|
const publicKey = o.publicKey ?? RELEASE_PUBLIC_KEY;
|
|
17177
|
-
const running = o.running ?? "0.1.
|
|
17365
|
+
const running = o.running ?? "0.1.52";
|
|
17178
17366
|
if (!publicKey)
|
|
17179
17367
|
return { ok: false, why: "no release key yet" };
|
|
17180
17368
|
if (!VERSION_RE2.test(o.version))
|
|
@@ -18758,7 +18946,7 @@ function engineClient(o, org) {
|
|
|
18758
18946
|
return fetchClient({
|
|
18759
18947
|
...src,
|
|
18760
18948
|
timeoutMs: ENGINE_TIMEOUT_MS,
|
|
18761
|
-
version: "0.1.
|
|
18949
|
+
version: "0.1.52"
|
|
18762
18950
|
});
|
|
18763
18951
|
const asked = org?.trim() || env.SLEDS_ORG?.trim();
|
|
18764
18952
|
if (asked && !selectOrg(readConfig(o.home), org, env).seat)
|
|
@@ -19049,7 +19237,7 @@ async function driveEngine(o, flags, deps, until = {}) {
|
|
|
19049
19237
|
runner: deps.runner.name,
|
|
19050
19238
|
atOnce: flags.atOnce,
|
|
19051
19239
|
interval: flags.interval,
|
|
19052
|
-
cliVersion: "0.1.
|
|
19240
|
+
cliVersion: "0.1.52"
|
|
19053
19241
|
};
|
|
19054
19242
|
const beat = (checkedAt) => {
|
|
19055
19243
|
const m = deps.machine;
|
|
@@ -20906,7 +21094,7 @@ function engineClient2(o, org) {
|
|
|
20906
21094
|
return fetchClient({
|
|
20907
21095
|
...src,
|
|
20908
21096
|
timeoutMs: ENGINE_TIMEOUT_MS2,
|
|
20909
|
-
version: "0.1.
|
|
21097
|
+
version: "0.1.52"
|
|
20910
21098
|
});
|
|
20911
21099
|
const asked = org?.trim() || env.SLEDS_ORG?.trim();
|
|
20912
21100
|
if (asked && !selectOrg(readConfig(o.home), org, env).seat)
|
|
@@ -21232,7 +21420,7 @@ async function driveEngine2(o, flags, deps, until = {}) {
|
|
|
21232
21420
|
runner: deps.runner.name,
|
|
21233
21421
|
atOnce: flags.atOnce,
|
|
21234
21422
|
interval: flags.interval,
|
|
21235
|
-
cliVersion: "0.1.
|
|
21423
|
+
cliVersion: "0.1.52"
|
|
21236
21424
|
};
|
|
21237
21425
|
const beat = (checkedAt) => {
|
|
21238
21426
|
const m = deps.machine;
|
|
@@ -23320,7 +23508,7 @@ function contextFor(deps) {
|
|
|
23320
23508
|
...src,
|
|
23321
23509
|
fetchFn: deps.fetchFn,
|
|
23322
23510
|
timeoutMs: deps.timeoutMs,
|
|
23323
|
-
version: "0.1.
|
|
23511
|
+
version: "0.1.52"
|
|
23324
23512
|
}), deps.home, now) : null;
|
|
23325
23513
|
return {
|
|
23326
23514
|
channel: "code",
|
|
@@ -25834,14 +26022,16 @@ function routeReader(o, org) {
|
|
|
25834
26022
|
read: (k) => readOrSay(client, `/proxy/route?q=${encodeURIComponent(k)}`, k)
|
|
25835
26023
|
};
|
|
25836
26024
|
}
|
|
25837
|
-
var SLED_USAGE = "usage: sleds sled --json | sleds sled top <KEY> | sleds sled order <KEY>…";
|
|
26025
|
+
var SLED_USAGE = "usage: sleds sled --json | sleds sled top <KEY> | sleds sled order <KEY>… | sleds sled off <KEY> [--json]";
|
|
25838
26026
|
async function sledCmd(o) {
|
|
25839
26027
|
const log = o.log ?? console.log;
|
|
25840
26028
|
const error = o.error ?? console.error;
|
|
25841
26029
|
const top = o.argv[0] === "top" && o.argv.length === 2 && !o.argv[1]?.startsWith("-");
|
|
25842
26030
|
const keys = o.argv.slice(1);
|
|
25843
26031
|
const order = o.argv[0] === "order" && keys.length > 0 && keys.every((k) => k.trim() && !k.startsWith("-"));
|
|
25844
|
-
|
|
26032
|
+
const offArgs = o.argv.slice(1).filter((a) => a !== "--json");
|
|
26033
|
+
const off = o.argv[0] === "off" && offArgs.length === 1 && o.argv.length <= 3 && !!offArgs[0]?.trim() && !offArgs[0].startsWith("-");
|
|
26034
|
+
if (!top && !order && !off && (o.argv.length !== 1 || o.argv[0] !== "--json")) {
|
|
25845
26035
|
error(SLED_USAGE);
|
|
25846
26036
|
return 2;
|
|
25847
26037
|
}
|
|
@@ -25854,6 +26044,8 @@ async function sledCmd(o) {
|
|
|
25854
26044
|
return sledTop(client, o.argv[1], log, error);
|
|
25855
26045
|
if (order)
|
|
25856
26046
|
return sledOrder(client, keys, log, error);
|
|
26047
|
+
if (off)
|
|
26048
|
+
return sledOff(client, offArgs[0], o.argv.includes("--json"), log, error);
|
|
25857
26049
|
try {
|
|
25858
26050
|
log(JSON.stringify(await readOrSay(client, "/proxy/sled", "the sled")));
|
|
25859
26051
|
return 0;
|
|
@@ -25888,6 +26080,31 @@ async function sledOrder(client, keys, log, error) {
|
|
|
25888
26080
|
log(`${typeof r.json?.ordered === "number" ? r.json.ordered : keys.length} ordered on your sled`);
|
|
25889
26081
|
return 0;
|
|
25890
26082
|
}
|
|
26083
|
+
async function sledOff(client, key, json, log, error) {
|
|
26084
|
+
const r = await client.postFull("/proxy/sled/off", { project: key });
|
|
26085
|
+
if (!r) {
|
|
26086
|
+
error(`${key}: SLEDS unreachable — the sled is unchanged`);
|
|
26087
|
+
return 1;
|
|
26088
|
+
}
|
|
26089
|
+
if (r.status >= 300 || r.json?.ok === false) {
|
|
26090
|
+
error(typeof r.json?.error === "string" ? r.json.error : `${key}: HTTP ${r.status}`);
|
|
26091
|
+
return 1;
|
|
26092
|
+
}
|
|
26093
|
+
if (json) {
|
|
26094
|
+
log(JSON.stringify(r.json));
|
|
26095
|
+
return 0;
|
|
26096
|
+
}
|
|
26097
|
+
const k = typeof r.json?.key === "string" ? r.json.key : key;
|
|
26098
|
+
if (r.json?.changed === false) {
|
|
26099
|
+
log(`${k} was not on a sled`);
|
|
26100
|
+
return 0;
|
|
26101
|
+
}
|
|
26102
|
+
log(`${k} is off your sled — back in the pool`);
|
|
26103
|
+
const running = typeof r.json?.running === "number" ? r.json.running : 0;
|
|
26104
|
+
if (running > 0)
|
|
26105
|
+
log(`${running} running node${running === 1 ? "" : "s"} stopped`);
|
|
26106
|
+
return 0;
|
|
26107
|
+
}
|
|
25891
26108
|
|
|
25892
26109
|
// src/commands/run.ts
|
|
25893
26110
|
init_config();
|
|
@@ -27406,7 +27623,7 @@ var realPidAlive4 = (pid) => {
|
|
|
27406
27623
|
};
|
|
27407
27624
|
function machineClient(home, env) {
|
|
27408
27625
|
const src = meterSource(home, undefined, { env });
|
|
27409
|
-
return src ? fetchClient({ ...src, version: "0.1.
|
|
27626
|
+
return src ? fetchClient({ ...src, version: "0.1.52" }) : null;
|
|
27410
27627
|
}
|
|
27411
27628
|
async function noteAnswer2(home, a, now) {
|
|
27412
27629
|
try {
|
|
@@ -28026,6 +28243,7 @@ commands:
|
|
|
28026
28243
|
sled --json What is on your sled (mine with each route, proposed, sent), for a front end.
|
|
28027
28244
|
sleds sled top KEY put KEY first on your sled; the engine picks it next
|
|
28028
28245
|
sleds sled order KEY\u2026 those items in this order, in the places they hold; the rest stay
|
|
28246
|
+
sleds sled off KEY take KEY off your sled, back in the pool; its running nodes stop
|
|
28029
28247
|
route <key> Print an item's route: its nodes, what each waits on, what is ready, where each
|
|
28030
28248
|
run can be watched.
|
|
28031
28249
|
--dot Graphviz instead: \`sleds route QW-142 --dot | dot -Tpng -o route.png\`
|
|
@@ -28251,7 +28469,7 @@ var main = async (argv) => {
|
|
|
28251
28469
|
now: Date.now(),
|
|
28252
28470
|
stderr: (line) => console.error(line),
|
|
28253
28471
|
isTTY: !!process.stderr.isTTY,
|
|
28254
|
-
version: "0.1.
|
|
28472
|
+
version: "0.1.52"
|
|
28255
28473
|
});
|
|
28256
28474
|
switch (cmd) {
|
|
28257
28475
|
case "update":
|
|
@@ -28484,7 +28702,7 @@ ${renderHelpText(argv[1])}`);
|
|
|
28484
28702
|
case "version":
|
|
28485
28703
|
case "--version":
|
|
28486
28704
|
case "-v":
|
|
28487
|
-
console.log("sleds 0.1.
|
|
28705
|
+
console.log("sleds 0.1.52");
|
|
28488
28706
|
return 0;
|
|
28489
28707
|
default:
|
|
28490
28708
|
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.52",
|
|
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",
|