@sleds/cli 0.1.53 → 0.1.55
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 +206 -77
- package/package.json +1 -1
package/dist/sleds.mjs
CHANGED
|
@@ -8557,8 +8557,8 @@ function parseParked(v) {
|
|
|
8557
8557
|
return {
|
|
8558
8558
|
question: v.question,
|
|
8559
8559
|
at: v.at,
|
|
8560
|
-
...typeof v.
|
|
8561
|
-
...v.
|
|
8560
|
+
...typeof v.words === "string" ? { words: v.words, ...v.still === true ? { still: true } : {} } : {},
|
|
8561
|
+
...typeof v.seatFull === "string" && v.seatFull ? { seatFull: v.seatFull } : {},
|
|
8562
8562
|
...answerer ? { answerer } : {}
|
|
8563
8563
|
};
|
|
8564
8564
|
}
|
|
@@ -8603,6 +8603,7 @@ function parseRun(v) {
|
|
|
8603
8603
|
...v.permission.onScreen === true ? { onScreen: true } : {},
|
|
8604
8604
|
...typeof v.permission.dialog === "string" ? { dialog: v.permission.dialog } : {},
|
|
8605
8605
|
...typeof v.permission.pressedAt === "number" ? { pressedAt: v.permission.pressedAt } : {},
|
|
8606
|
+
...typeof v.permission.pressedOn === "string" ? { pressedOn: v.permission.pressedOn } : {},
|
|
8606
8607
|
...typeof v.permission.presses === "number" ? { presses: v.permission.presses } : {},
|
|
8607
8608
|
...v.permission.gaveUp === true ? { gaveUp: true } : {}
|
|
8608
8609
|
}
|
|
@@ -11535,7 +11536,7 @@ function beatBody(state, flags, host = {}, cap = {}) {
|
|
|
11535
11536
|
name: flags.name,
|
|
11536
11537
|
os: host.os ?? process.platform,
|
|
11537
11538
|
runner: flags.runner,
|
|
11538
|
-
version: host.version ?? "0.1.
|
|
11539
|
+
version: host.version ?? "0.1.55" ?? "dev",
|
|
11539
11540
|
running: live.length,
|
|
11540
11541
|
items: live.slice(0, BEAT_ITEMS).map((r) => `${r.item}/${r.node}`),
|
|
11541
11542
|
...cap.atOnce !== undefined ? { atOnce: cap.atOnce } : {},
|
|
@@ -13207,9 +13208,12 @@ function sledsSource(client, o) {
|
|
|
13207
13208
|
if (r.status >= 300 || !r.json || r.json.ok === false)
|
|
13208
13209
|
throw new Error(serverMessage(r));
|
|
13209
13210
|
const leaseUntil = typeof r.json.leaseUntil === "number" ? r.json.leaseUntil : undefined;
|
|
13211
|
+
const resumed = r.json.resumed === true;
|
|
13212
|
+
const seatFull = !resumed && typeof r.json.seatFull === "string" ? r.json.seatFull : "";
|
|
13210
13213
|
return {
|
|
13211
|
-
resumed
|
|
13212
|
-
...leaseUntil !== undefined ? { leaseUntil } : {}
|
|
13214
|
+
resumed,
|
|
13215
|
+
...leaseUntil !== undefined ? { leaseUntil } : {},
|
|
13216
|
+
...seatFull ? { seatFull } : {}
|
|
13213
13217
|
};
|
|
13214
13218
|
},
|
|
13215
13219
|
async decisionOf(item, decisionId) {
|
|
@@ -13733,6 +13737,9 @@ function fingerprint(text) {
|
|
|
13733
13737
|
}
|
|
13734
13738
|
return (h >>> 0).toString(16);
|
|
13735
13739
|
}
|
|
13740
|
+
function wordsPrint(screen) {
|
|
13741
|
+
return fingerprint(stripTuiChrome(screen));
|
|
13742
|
+
}
|
|
13736
13743
|
function sandboxFor(d, name, cwd, allow) {
|
|
13737
13744
|
if (!d.sandbox)
|
|
13738
13745
|
return {};
|
|
@@ -13877,14 +13884,18 @@ async function tickOnce(d) {
|
|
|
13877
13884
|
try {
|
|
13878
13885
|
open = runner.status(run.handle) === "running";
|
|
13879
13886
|
} catch {}
|
|
13880
|
-
if (open &&
|
|
13881
|
-
|
|
13887
|
+
if (!open && !liveAnswerer(run)) {
|
|
13888
|
+
d.log(`${ref(run)}: the parked session closed — its answer will start a new one`);
|
|
13882
13889
|
continue;
|
|
13883
13890
|
}
|
|
13884
|
-
if (
|
|
13885
|
-
|
|
13886
|
-
|
|
13887
|
-
|
|
13891
|
+
if (await parkedBeat(d, run, claim) === "done") {
|
|
13892
|
+
d.log(`${ref(run)}: no longer waits for an answer — its node was skipped`);
|
|
13893
|
+
stopAnswerer(d, run);
|
|
13894
|
+
continue;
|
|
13895
|
+
}
|
|
13896
|
+
if (open)
|
|
13897
|
+
await answeredInSession(d, runner, run);
|
|
13898
|
+
keep.push(run);
|
|
13888
13899
|
continue;
|
|
13889
13900
|
}
|
|
13890
13901
|
if (run.pr) {
|
|
@@ -13999,7 +14010,7 @@ async function tickOnce(d) {
|
|
|
13999
14010
|
if (beat === "parked") {
|
|
14000
14011
|
const question = "the session parked itself; the question is on the route";
|
|
14001
14012
|
d.log(`${ref(run)}: parked with a question — the session waits for the answer (${runner.watchHint(run.handle)})`);
|
|
14002
|
-
holdParked(d, runner, run, question);
|
|
14013
|
+
holdParked(d, runner, run, question, shown);
|
|
14003
14014
|
finished.push({ item: run.item, node: run.node, outcome: { kind: "park", question } });
|
|
14004
14015
|
keep.push(run);
|
|
14005
14016
|
continue;
|
|
@@ -14034,7 +14045,7 @@ async function tickOnce(d) {
|
|
|
14034
14045
|
}
|
|
14035
14046
|
d.log(`${ref(run)}: ${why}, tries spent — parked for a person (${runner.watchHint(run.handle)})`);
|
|
14036
14047
|
run.provider = undefined;
|
|
14037
|
-
holdParked(d, runner, run, question);
|
|
14048
|
+
holdParked(d, runner, run, question, shown);
|
|
14038
14049
|
finished.push({ item: run.item, node: run.node, outcome });
|
|
14039
14050
|
keep.push(run);
|
|
14040
14051
|
continue;
|
|
@@ -14055,7 +14066,7 @@ async function tickOnce(d) {
|
|
|
14055
14066
|
continue;
|
|
14056
14067
|
}
|
|
14057
14068
|
d.log(asked ? `${ref(run)}: stopped on a question with no PR — parked with its last message as the question (${runner.watchHint(run.handle)})` : `${ref(run)}: idle ${d.idleMin} min with no PR — parked with its last message as the question (${runner.watchHint(run.handle)})`);
|
|
14058
|
-
holdParked(d, runner, run, question);
|
|
14069
|
+
holdParked(d, runner, run, question, shown);
|
|
14059
14070
|
finished.push({ item: run.item, node: run.node, outcome });
|
|
14060
14071
|
keep.push(run);
|
|
14061
14072
|
continue;
|
|
@@ -14081,7 +14092,25 @@ async function tickOnce(d) {
|
|
|
14081
14092
|
state.decisions = kept;
|
|
14082
14093
|
save();
|
|
14083
14094
|
}
|
|
14084
|
-
|
|
14095
|
+
let items;
|
|
14096
|
+
try {
|
|
14097
|
+
items = await d.source.read();
|
|
14098
|
+
} catch (e) {
|
|
14099
|
+
if (e instanceof SeatTokenError)
|
|
14100
|
+
throw e;
|
|
14101
|
+
save();
|
|
14102
|
+
return {
|
|
14103
|
+
started: [],
|
|
14104
|
+
finished,
|
|
14105
|
+
...counts(state),
|
|
14106
|
+
attention,
|
|
14107
|
+
done: false,
|
|
14108
|
+
items: [],
|
|
14109
|
+
changes,
|
|
14110
|
+
decisions: decided,
|
|
14111
|
+
readFailed: message(e)
|
|
14112
|
+
};
|
|
14113
|
+
}
|
|
14085
14114
|
const takeNone = seat.gone;
|
|
14086
14115
|
for (const it of items)
|
|
14087
14116
|
if (it.draft && !takeNone && !startsHeld(d))
|
|
@@ -14322,18 +14351,23 @@ async function tickOnce(d) {
|
|
|
14322
14351
|
started.push({ item: claim.item, node: claim.node, watch, watchTarget: watchTarget(handle) });
|
|
14323
14352
|
}
|
|
14324
14353
|
const done = items.length > 0 && items.every((i) => i.landed) && state.runs.length === 0;
|
|
14325
|
-
const following = state.runs.filter((r) => r.pr).length;
|
|
14326
|
-
const parked = state.runs.filter((r) => r.parked).length;
|
|
14327
14354
|
return {
|
|
14328
14355
|
started,
|
|
14329
14356
|
finished,
|
|
14330
|
-
|
|
14331
|
-
following,
|
|
14357
|
+
...counts(state),
|
|
14332
14358
|
attention,
|
|
14333
14359
|
done,
|
|
14334
14360
|
items,
|
|
14335
14361
|
changes,
|
|
14336
|
-
decisions: decided
|
|
14362
|
+
decisions: decided
|
|
14363
|
+
};
|
|
14364
|
+
}
|
|
14365
|
+
function counts(state) {
|
|
14366
|
+
const following = state.runs.filter((r) => r.pr).length;
|
|
14367
|
+
const parked = state.runs.filter((r) => r.parked).length;
|
|
14368
|
+
return {
|
|
14369
|
+
running: state.runs.length - following - parked,
|
|
14370
|
+
following,
|
|
14337
14371
|
followed: state.runs.flatMap((r) => r.pr ? [{ item: r.item, node: r.node, url: r.pr.url, ...r.pr.ci ? { ci: r.pr.ci } : {} }] : [])
|
|
14338
14372
|
};
|
|
14339
14373
|
}
|
|
@@ -14409,7 +14443,7 @@ async function settlePermission(d, runner, run, shown) {
|
|
|
14409
14443
|
const dialog = runner.readsSession ? permissionDialog(shown) : null;
|
|
14410
14444
|
const p = run.permission;
|
|
14411
14445
|
if (p) {
|
|
14412
|
-
const gone = runner.readsSession && (p.onScreen ? !dialog || p.dialog !== undefined && dialogPrint(dialog) !== p.dialog : (run.seenAt ?? 0) > (p.pressedAt ?? p.at));
|
|
14446
|
+
const gone = runner.readsSession && (p.onScreen ? !dialog || p.dialog !== undefined && dialogPrint(dialog) !== p.dialog || p.pressedOn !== undefined && fingerprint(shown) !== p.pressedOn : (run.seenAt ?? 0) > (p.pressedAt ?? p.at));
|
|
14413
14447
|
const answered = () => {
|
|
14414
14448
|
run.permission = undefined;
|
|
14415
14449
|
run.answeredAt = d.now();
|
|
@@ -14440,7 +14474,12 @@ async function settlePermission(d, runner, run, shown) {
|
|
|
14440
14474
|
if (!pressed)
|
|
14441
14475
|
return true;
|
|
14442
14476
|
if (pressed === "key") {
|
|
14443
|
-
run.permission = {
|
|
14477
|
+
run.permission = {
|
|
14478
|
+
...p,
|
|
14479
|
+
pressedAt: d.now(),
|
|
14480
|
+
pressedOn: fingerprint(shown),
|
|
14481
|
+
presses: 1
|
|
14482
|
+
};
|
|
14444
14483
|
return true;
|
|
14445
14484
|
}
|
|
14446
14485
|
}
|
|
@@ -14467,7 +14506,12 @@ async function settlePermission(d, runner, run, shown) {
|
|
|
14467
14506
|
return true;
|
|
14468
14507
|
}
|
|
14469
14508
|
if (pressAnswer(d, runner, run, p.options, now.answer) === "key")
|
|
14470
|
-
run.permission = {
|
|
14509
|
+
run.permission = {
|
|
14510
|
+
...p,
|
|
14511
|
+
pressedAt: d.now(),
|
|
14512
|
+
pressedOn: fingerprint(shown),
|
|
14513
|
+
presses: presses + 1
|
|
14514
|
+
};
|
|
14471
14515
|
return true;
|
|
14472
14516
|
}
|
|
14473
14517
|
if (now?.state !== "open" && now?.state !== "escalated") {
|
|
@@ -14776,8 +14820,12 @@ function stopOpen(d, run, runner) {
|
|
|
14776
14820
|
d.log(`${ref(run)}: could not stop the left-open session: ${message(e)}`);
|
|
14777
14821
|
}
|
|
14778
14822
|
}
|
|
14779
|
-
function holdParked(d, runner, run, question) {
|
|
14780
|
-
run.parked = {
|
|
14823
|
+
function holdParked(d, runner, run, question, shown) {
|
|
14824
|
+
run.parked = {
|
|
14825
|
+
question,
|
|
14826
|
+
at: d.now(),
|
|
14827
|
+
...runner.readsSession ? { words: wordsPrint(shown) } : {}
|
|
14828
|
+
};
|
|
14781
14829
|
run.leaseUntil = undefined;
|
|
14782
14830
|
setLane(d, runner, run.handle, "parked");
|
|
14783
14831
|
}
|
|
@@ -14786,21 +14834,27 @@ async function answeredInSession(d, runner, run) {
|
|
|
14786
14834
|
const resumes = resumesOf(d.source);
|
|
14787
14835
|
if (!resumes || !runner.readsSession || !run.runId)
|
|
14788
14836
|
return false;
|
|
14789
|
-
let
|
|
14837
|
+
let shown;
|
|
14790
14838
|
try {
|
|
14791
|
-
|
|
14839
|
+
shown = runner.read(run.handle);
|
|
14792
14840
|
} catch {
|
|
14793
14841
|
return false;
|
|
14794
14842
|
}
|
|
14795
|
-
|
|
14796
|
-
|
|
14797
|
-
|
|
14843
|
+
const words = wordsPrint(shown);
|
|
14844
|
+
const waiting = parked.seatFull !== undefined;
|
|
14845
|
+
if (waiting) {
|
|
14846
|
+
parked.words = words;
|
|
14847
|
+
} else {
|
|
14848
|
+
if (words === parked.words) {
|
|
14849
|
+
parked.still = true;
|
|
14850
|
+
return false;
|
|
14851
|
+
}
|
|
14852
|
+
const moved = parked.still === true;
|
|
14853
|
+
parked.words = words;
|
|
14854
|
+
parked.still = false;
|
|
14855
|
+
if (!moved)
|
|
14856
|
+
return false;
|
|
14798
14857
|
}
|
|
14799
|
-
const moved = parked.still === true;
|
|
14800
|
-
parked.screen = print;
|
|
14801
|
-
parked.still = false;
|
|
14802
|
-
if (!moved)
|
|
14803
|
-
return false;
|
|
14804
14858
|
let r;
|
|
14805
14859
|
try {
|
|
14806
14860
|
r = await resumes.resumeParked(run.runId, "answered in the session", d.engine, d.leaseMin);
|
|
@@ -14808,14 +14862,21 @@ async function answeredInSession(d, runner, run) {
|
|
|
14808
14862
|
d.log(`${ref(run)}: the parked session moved on, but SLEDS did not hear it: ${message(e)}`);
|
|
14809
14863
|
return false;
|
|
14810
14864
|
}
|
|
14865
|
+
if (!r.resumed && r.seatFull) {
|
|
14866
|
+
if (!waiting)
|
|
14867
|
+
d.log(`${ref(run)}: answered in the session, but ${r.seatFull} — stays in Needs you until a slot frees`);
|
|
14868
|
+
parked.seatFull = r.seatFull;
|
|
14869
|
+
return false;
|
|
14870
|
+
}
|
|
14811
14871
|
if (!r.resumed) {
|
|
14872
|
+
parked.seatFull = undefined;
|
|
14812
14873
|
d.log(`${ref(run)}: the parked session moved on, but the node is no longer parked on its run`);
|
|
14813
14874
|
return false;
|
|
14814
14875
|
}
|
|
14815
14876
|
stopAnswerer(d, run);
|
|
14816
14877
|
const now = d.now();
|
|
14817
14878
|
run.parked = undefined;
|
|
14818
|
-
run.seen =
|
|
14879
|
+
run.seen = fingerprint(shown);
|
|
14819
14880
|
run.seenAt = now;
|
|
14820
14881
|
run.seenTicks = 0;
|
|
14821
14882
|
run.answeredAt = now;
|
|
@@ -15185,6 +15246,14 @@ async function endUnposted(d, answers, a, runner, at, over) {
|
|
|
15185
15246
|
return false;
|
|
15186
15247
|
}
|
|
15187
15248
|
}
|
|
15249
|
+
async function parkedBeat(d, run, claim) {
|
|
15250
|
+
try {
|
|
15251
|
+
return await d.source.heartbeat(claim);
|
|
15252
|
+
} catch (e) {
|
|
15253
|
+
d.log(`${ref(run)}: heartbeat failed, retrying next tick: ${message(e)}`);
|
|
15254
|
+
return "running";
|
|
15255
|
+
}
|
|
15256
|
+
}
|
|
15188
15257
|
function stopAnswerer(d, run) {
|
|
15189
15258
|
const a = liveAnswerer(run);
|
|
15190
15259
|
if (!a)
|
|
@@ -16287,6 +16356,41 @@ async function settleEvent(d, events, state, dec, attention, decided) {
|
|
|
16287
16356
|
|
|
16288
16357
|
// src/commands/engine.ts
|
|
16289
16358
|
init_machine();
|
|
16359
|
+
|
|
16360
|
+
// src/engine/sledsBreaker.ts
|
|
16361
|
+
var SLEDS_DOWN_ERROR = "SledsDownError";
|
|
16362
|
+
function why(e) {
|
|
16363
|
+
const name = e instanceof Error ? e.name : "";
|
|
16364
|
+
return name === "TimeoutError" || name === "AbortError" ? "timed out" : "could not be reached";
|
|
16365
|
+
}
|
|
16366
|
+
function sledsBreaker(fetchFn = fetch) {
|
|
16367
|
+
let down = null;
|
|
16368
|
+
let pass = 0;
|
|
16369
|
+
return {
|
|
16370
|
+
async fetch(input, init) {
|
|
16371
|
+
if (down !== null) {
|
|
16372
|
+
const e = new Error(`skipped — SLEDS ${down} earlier this tick`);
|
|
16373
|
+
e.name = SLEDS_DOWN_ERROR;
|
|
16374
|
+
throw e;
|
|
16375
|
+
}
|
|
16376
|
+
const started = pass;
|
|
16377
|
+
try {
|
|
16378
|
+
return await fetchFn(input, init);
|
|
16379
|
+
} catch (e) {
|
|
16380
|
+
if (started === pass && down === null)
|
|
16381
|
+
down = why(e);
|
|
16382
|
+
throw e;
|
|
16383
|
+
}
|
|
16384
|
+
},
|
|
16385
|
+
reset() {
|
|
16386
|
+
down = null;
|
|
16387
|
+
pass++;
|
|
16388
|
+
},
|
|
16389
|
+
tripped: () => down
|
|
16390
|
+
};
|
|
16391
|
+
}
|
|
16392
|
+
|
|
16393
|
+
// src/commands/engine.ts
|
|
16290
16394
|
init_state();
|
|
16291
16395
|
init_meter();
|
|
16292
16396
|
|
|
@@ -17410,7 +17514,7 @@ async function fetchVersion(o) {
|
|
|
17410
17514
|
const platform = o.platform ?? process.platform;
|
|
17411
17515
|
const arch = o.arch ?? process.arch;
|
|
17412
17516
|
const publicKey = o.publicKey ?? RELEASE_PUBLIC_KEY;
|
|
17413
|
-
const running = o.running ?? "0.1.
|
|
17517
|
+
const running = o.running ?? "0.1.55";
|
|
17414
17518
|
if (!publicKey)
|
|
17415
17519
|
return { ok: false, why: "no release key yet" };
|
|
17416
17520
|
if (!VERSION_RE2.test(o.version))
|
|
@@ -18985,7 +19089,7 @@ async function withProfile(client, flags, given, home, retry) {
|
|
|
18985
19089
|
}
|
|
18986
19090
|
var NOT_SET_UP2 = "SLEDS is not set up on this machine. Run `sleds init` first.";
|
|
18987
19091
|
var ENGINE_TIMEOUT_MS = 15000;
|
|
18988
|
-
function engineClient(o, org) {
|
|
19092
|
+
function engineClient(o, org, breaker) {
|
|
18989
19093
|
if (o.client)
|
|
18990
19094
|
return o.client;
|
|
18991
19095
|
const env = o.env ?? process.env;
|
|
@@ -18993,8 +19097,9 @@ function engineClient(o, org) {
|
|
|
18993
19097
|
if (src)
|
|
18994
19098
|
return fetchClient({
|
|
18995
19099
|
...src,
|
|
19100
|
+
...breaker ? { fetchFn: breaker.fetch } : {},
|
|
18996
19101
|
timeoutMs: ENGINE_TIMEOUT_MS,
|
|
18997
|
-
version: "0.1.
|
|
19102
|
+
version: "0.1.55"
|
|
18998
19103
|
});
|
|
18999
19104
|
const asked = org?.trim() || env.SLEDS_ORG?.trim();
|
|
19000
19105
|
if (asked && !selectOrg(readConfig(o.home), org, env).seat)
|
|
@@ -19012,9 +19117,9 @@ function engineOrg(o, flag) {
|
|
|
19012
19117
|
known.delete(slug);
|
|
19013
19118
|
return { slug, seated: Boolean(cfg.orgs?.[slug]), sole: known.size === 0 };
|
|
19014
19119
|
}
|
|
19015
|
-
function orgClient(o, flag) {
|
|
19120
|
+
function orgClient(o, flag, breaker) {
|
|
19016
19121
|
const org = engineOrg(o, flag);
|
|
19017
|
-
return engineClient(o, org.seated ? org.slug ?? undefined : flag);
|
|
19122
|
+
return engineClient(o, org.seated ? org.slug ?? undefined : flag, breaker);
|
|
19018
19123
|
}
|
|
19019
19124
|
function realPidAlive2(pid) {
|
|
19020
19125
|
try {
|
|
@@ -19285,7 +19390,7 @@ async function driveEngine(o, flags, deps, until = {}) {
|
|
|
19285
19390
|
runner: deps.runner.name,
|
|
19286
19391
|
atOnce: flags.atOnce,
|
|
19287
19392
|
interval: flags.interval,
|
|
19288
|
-
cliVersion: "0.1.
|
|
19393
|
+
cliVersion: "0.1.55"
|
|
19289
19394
|
};
|
|
19290
19395
|
const beat = (checkedAt) => {
|
|
19291
19396
|
const m = deps.machine;
|
|
@@ -19366,35 +19471,42 @@ async function drive(o, flags, deps, until, beat) {
|
|
|
19366
19471
|
await until.beforeFirstTick?.();
|
|
19367
19472
|
for (;; ) {
|
|
19368
19473
|
let report = null;
|
|
19474
|
+
let why;
|
|
19475
|
+
until.breaker?.reset();
|
|
19369
19476
|
try {
|
|
19370
19477
|
report = await tick(deps);
|
|
19478
|
+
why = report.readFailed;
|
|
19371
19479
|
} catch (e) {
|
|
19480
|
+
why = e instanceof Error ? e.message : String(e);
|
|
19481
|
+
}
|
|
19482
|
+
if (why !== undefined) {
|
|
19372
19483
|
down++;
|
|
19373
|
-
const why = e instanceof Error ? e.message : String(e);
|
|
19374
19484
|
if (down === 1 || flags.once)
|
|
19375
19485
|
event({
|
|
19376
19486
|
kind: "sleds-down",
|
|
19377
19487
|
text: why,
|
|
19378
19488
|
...flags.once ? {} : { aside: `· retrying every ${flags.interval} s` }
|
|
19379
19489
|
});
|
|
19380
|
-
if (flags.once)
|
|
19490
|
+
if (flags.once && !report)
|
|
19381
19491
|
return 1;
|
|
19382
19492
|
}
|
|
19383
19493
|
beat(now());
|
|
19384
|
-
const leave = await until.afterTick?.(report !== null);
|
|
19494
|
+
const leave = await until.afterTick?.(report !== null && !report.readFailed);
|
|
19385
19495
|
if (typeof leave === "number") {
|
|
19386
19496
|
if (statusShown)
|
|
19387
19497
|
write("\r\x1B[2K");
|
|
19388
19498
|
return leave;
|
|
19389
19499
|
}
|
|
19390
19500
|
if (report) {
|
|
19391
|
-
if (
|
|
19392
|
-
|
|
19393
|
-
|
|
19394
|
-
|
|
19395
|
-
|
|
19396
|
-
|
|
19397
|
-
|
|
19501
|
+
if (!report.readFailed) {
|
|
19502
|
+
if (down > 0)
|
|
19503
|
+
event({
|
|
19504
|
+
kind: "sleds-back",
|
|
19505
|
+
text: "back",
|
|
19506
|
+
aside: `after ${down} failed ${down === 1 ? "read" : "reads"}`
|
|
19507
|
+
});
|
|
19508
|
+
down = 0;
|
|
19509
|
+
}
|
|
19398
19510
|
running = report.running;
|
|
19399
19511
|
if (report.seatChanged || report.tokenChanged) {
|
|
19400
19512
|
if (statusShown)
|
|
@@ -19444,6 +19556,8 @@ async function drive(o, flags, deps, until, beat) {
|
|
|
19444
19556
|
pr: a.url
|
|
19445
19557
|
});
|
|
19446
19558
|
}
|
|
19559
|
+
if (flags.once && report.readFailed)
|
|
19560
|
+
return 1;
|
|
19447
19561
|
if (until.done && report.done) {
|
|
19448
19562
|
if (statusShown)
|
|
19449
19563
|
write("\r\x1B[2K");
|
|
@@ -21133,7 +21247,7 @@ async function withProfile2(client, flags, given, home, retry) {
|
|
|
21133
21247
|
}
|
|
21134
21248
|
var NOT_SET_UP3 = "SLEDS is not set up on this machine. Run `sleds init` first.";
|
|
21135
21249
|
var ENGINE_TIMEOUT_MS2 = 15000;
|
|
21136
|
-
function engineClient2(o, org) {
|
|
21250
|
+
function engineClient2(o, org, breaker) {
|
|
21137
21251
|
if (o.client)
|
|
21138
21252
|
return o.client;
|
|
21139
21253
|
const env = o.env ?? process.env;
|
|
@@ -21141,8 +21255,9 @@ function engineClient2(o, org) {
|
|
|
21141
21255
|
if (src)
|
|
21142
21256
|
return fetchClient({
|
|
21143
21257
|
...src,
|
|
21258
|
+
...breaker ? { fetchFn: breaker.fetch } : {},
|
|
21144
21259
|
timeoutMs: ENGINE_TIMEOUT_MS2,
|
|
21145
|
-
version: "0.1.
|
|
21260
|
+
version: "0.1.55"
|
|
21146
21261
|
});
|
|
21147
21262
|
const asked = org?.trim() || env.SLEDS_ORG?.trim();
|
|
21148
21263
|
if (asked && !selectOrg(readConfig(o.home), org, env).seat)
|
|
@@ -21160,9 +21275,9 @@ function engineOrg2(o, flag) {
|
|
|
21160
21275
|
known.delete(slug);
|
|
21161
21276
|
return { slug, seated: Boolean(cfg.orgs?.[slug]), sole: known.size === 0 };
|
|
21162
21277
|
}
|
|
21163
|
-
function orgClient2(o, flag) {
|
|
21278
|
+
function orgClient2(o, flag, breaker) {
|
|
21164
21279
|
const org = engineOrg2(o, flag);
|
|
21165
|
-
return engineClient2(o, org.seated ? org.slug ?? undefined : flag);
|
|
21280
|
+
return engineClient2(o, org.seated ? org.slug ?? undefined : flag, breaker);
|
|
21166
21281
|
}
|
|
21167
21282
|
async function jiraWritesAtStart(gate, epic) {
|
|
21168
21283
|
const no = await gate.ask({
|
|
@@ -21468,7 +21583,7 @@ async function driveEngine2(o, flags, deps, until = {}) {
|
|
|
21468
21583
|
runner: deps.runner.name,
|
|
21469
21584
|
atOnce: flags.atOnce,
|
|
21470
21585
|
interval: flags.interval,
|
|
21471
|
-
cliVersion: "0.1.
|
|
21586
|
+
cliVersion: "0.1.55"
|
|
21472
21587
|
};
|
|
21473
21588
|
const beat = (checkedAt) => {
|
|
21474
21589
|
const m = deps.machine;
|
|
@@ -21549,35 +21664,42 @@ async function drive2(o, flags, deps, until, beat) {
|
|
|
21549
21664
|
await until.beforeFirstTick?.();
|
|
21550
21665
|
for (;; ) {
|
|
21551
21666
|
let report = null;
|
|
21667
|
+
let why;
|
|
21668
|
+
until.breaker?.reset();
|
|
21552
21669
|
try {
|
|
21553
21670
|
report = await tick(deps);
|
|
21671
|
+
why = report.readFailed;
|
|
21554
21672
|
} catch (e) {
|
|
21673
|
+
why = e instanceof Error ? e.message : String(e);
|
|
21674
|
+
}
|
|
21675
|
+
if (why !== undefined) {
|
|
21555
21676
|
down++;
|
|
21556
|
-
const why = e instanceof Error ? e.message : String(e);
|
|
21557
21677
|
if (down === 1 || flags.once)
|
|
21558
21678
|
event({
|
|
21559
21679
|
kind: "sleds-down",
|
|
21560
21680
|
text: why,
|
|
21561
21681
|
...flags.once ? {} : { aside: `· retrying every ${flags.interval} s` }
|
|
21562
21682
|
});
|
|
21563
|
-
if (flags.once)
|
|
21683
|
+
if (flags.once && !report)
|
|
21564
21684
|
return 1;
|
|
21565
21685
|
}
|
|
21566
21686
|
beat(now());
|
|
21567
|
-
const leave = await until.afterTick?.(report !== null);
|
|
21687
|
+
const leave = await until.afterTick?.(report !== null && !report.readFailed);
|
|
21568
21688
|
if (typeof leave === "number") {
|
|
21569
21689
|
if (statusShown)
|
|
21570
21690
|
write("\r\x1B[2K");
|
|
21571
21691
|
return leave;
|
|
21572
21692
|
}
|
|
21573
21693
|
if (report) {
|
|
21574
|
-
if (
|
|
21575
|
-
|
|
21576
|
-
|
|
21577
|
-
|
|
21578
|
-
|
|
21579
|
-
|
|
21580
|
-
|
|
21694
|
+
if (!report.readFailed) {
|
|
21695
|
+
if (down > 0)
|
|
21696
|
+
event({
|
|
21697
|
+
kind: "sleds-back",
|
|
21698
|
+
text: "back",
|
|
21699
|
+
aside: `after ${down} failed ${down === 1 ? "read" : "reads"}`
|
|
21700
|
+
});
|
|
21701
|
+
down = 0;
|
|
21702
|
+
}
|
|
21581
21703
|
running = report.running;
|
|
21582
21704
|
if (report.seatChanged || report.tokenChanged) {
|
|
21583
21705
|
if (statusShown)
|
|
@@ -21627,6 +21749,8 @@ async function drive2(o, flags, deps, until, beat) {
|
|
|
21627
21749
|
pr: a.url
|
|
21628
21750
|
});
|
|
21629
21751
|
}
|
|
21752
|
+
if (flags.once && report.readFailed)
|
|
21753
|
+
return 1;
|
|
21630
21754
|
if (until.done && report.done) {
|
|
21631
21755
|
if (statusShown)
|
|
21632
21756
|
write("\r\x1B[2K");
|
|
@@ -21702,17 +21826,22 @@ var engineCmd = async (o) => {
|
|
|
21702
21826
|
error(kept.refused);
|
|
21703
21827
|
return 1;
|
|
21704
21828
|
}
|
|
21829
|
+
const breaker = sledsBreaker(o.fetch);
|
|
21705
21830
|
let client;
|
|
21706
21831
|
let pickup;
|
|
21707
21832
|
if (!flags.jira && (o.client || !o.source)) {
|
|
21708
|
-
const c = orgClient2(o, given);
|
|
21833
|
+
const c = orgClient2(o, given, breaker);
|
|
21709
21834
|
if ("error" in c) {
|
|
21710
21835
|
error(c.error);
|
|
21711
21836
|
return 1;
|
|
21712
21837
|
}
|
|
21713
21838
|
client = c;
|
|
21839
|
+
const sleep = o.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
21714
21840
|
const p = await withProfile2(c, flags, parsed.given, o.home, {
|
|
21715
|
-
sleep:
|
|
21841
|
+
sleep: async (ms) => {
|
|
21842
|
+
await sleep(ms);
|
|
21843
|
+
breaker.reset();
|
|
21844
|
+
}
|
|
21716
21845
|
});
|
|
21717
21846
|
flags = p.flags;
|
|
21718
21847
|
pickup = p.pickup;
|
|
@@ -21748,7 +21877,7 @@ var engineCmd = async (o) => {
|
|
|
21748
21877
|
error(missing);
|
|
21749
21878
|
return 1;
|
|
21750
21879
|
}
|
|
21751
|
-
const c = o.client ?? orgClient2(o, given);
|
|
21880
|
+
const c = o.client ?? orgClient2(o, given, breaker);
|
|
21752
21881
|
if ("error" in c) {
|
|
21753
21882
|
error(`--jira asks SLEDS before every write to Jira (spec 39), so it needs a seat: ${c.error}`);
|
|
21754
21883
|
return 1;
|
|
@@ -21881,7 +22010,7 @@ var engineCmd = async (o) => {
|
|
|
21881
22010
|
};
|
|
21882
22011
|
}
|
|
21883
22012
|
try {
|
|
21884
|
-
return await driveEngine2(o, flags, deps, { afterTick, beforeFirstTick });
|
|
22013
|
+
return await driveEngine2(o, flags, deps, { afterTick, beforeFirstTick, breaker });
|
|
21885
22014
|
} finally {
|
|
21886
22015
|
watch.stop();
|
|
21887
22016
|
}
|
|
@@ -23556,7 +23685,7 @@ function contextFor(deps) {
|
|
|
23556
23685
|
...src,
|
|
23557
23686
|
fetchFn: deps.fetchFn,
|
|
23558
23687
|
timeoutMs: deps.timeoutMs,
|
|
23559
|
-
version: "0.1.
|
|
23688
|
+
version: "0.1.55"
|
|
23560
23689
|
}), deps.home, now) : null;
|
|
23561
23690
|
return {
|
|
23562
23691
|
channel: "code",
|
|
@@ -26281,7 +26410,7 @@ function parseSeatRevokeArgs(argv) {
|
|
|
26281
26410
|
}
|
|
26282
26411
|
return { box, yes, json };
|
|
26283
26412
|
}
|
|
26284
|
-
function
|
|
26413
|
+
function why2(j, status) {
|
|
26285
26414
|
if (typeof j?.reason === "string")
|
|
26286
26415
|
return j.reason;
|
|
26287
26416
|
if (typeof j?.error === "string")
|
|
@@ -26319,7 +26448,7 @@ async function seatRevokeCmd(o) {
|
|
|
26319
26448
|
return ok ? 0 : 1;
|
|
26320
26449
|
}
|
|
26321
26450
|
if (!ok) {
|
|
26322
|
-
error(clean(`nothing revoked — ${
|
|
26451
|
+
error(clean(`nothing revoked — ${why2(r.json, r.status)}`));
|
|
26323
26452
|
return 1;
|
|
26324
26453
|
}
|
|
26325
26454
|
const label = typeof r.json?.label === "string" ? r.json.label : a.box ? `box:${a.box}` : "";
|
|
@@ -27674,7 +27803,7 @@ var realPidAlive4 = (pid) => {
|
|
|
27674
27803
|
};
|
|
27675
27804
|
function machineClient(home, env) {
|
|
27676
27805
|
const src = meterSource(home, undefined, { env });
|
|
27677
|
-
return src ? fetchClient({ ...src, version: "0.1.
|
|
27806
|
+
return src ? fetchClient({ ...src, version: "0.1.55" }) : null;
|
|
27678
27807
|
}
|
|
27679
27808
|
async function noteAnswer2(home, a, now) {
|
|
27680
27809
|
try {
|
|
@@ -28534,7 +28663,7 @@ var main = async (argv) => {
|
|
|
28534
28663
|
now: Date.now(),
|
|
28535
28664
|
stderr: (line) => console.error(line),
|
|
28536
28665
|
isTTY: !!process.stderr.isTTY,
|
|
28537
|
-
version: "0.1.
|
|
28666
|
+
version: "0.1.55"
|
|
28538
28667
|
});
|
|
28539
28668
|
switch (cmd) {
|
|
28540
28669
|
case "update":
|
|
@@ -28767,7 +28896,7 @@ ${renderHelpText(argv[1])}`);
|
|
|
28767
28896
|
case "version":
|
|
28768
28897
|
case "--version":
|
|
28769
28898
|
case "-v":
|
|
28770
|
-
console.log("sleds 0.1.
|
|
28899
|
+
console.log("sleds 0.1.55");
|
|
28771
28900
|
return 0;
|
|
28772
28901
|
default:
|
|
28773
28902
|
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.55",
|
|
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",
|