@sleds/cli 0.1.38 → 0.1.40
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 +591 -197
- package/package.json +1 -1
package/dist/sleds.mjs
CHANGED
|
@@ -894,7 +894,7 @@ var init_verbs = __esm(() => {
|
|
|
894
894
|
mcp: "a `Worth:` line in the spec you estimate (`Worth: high · $5k–20k · Acme renewal`)",
|
|
895
895
|
claudeCode: "`SLEDS-Worth:` line in the PR body",
|
|
896
896
|
app: "Work › the item › Worth…",
|
|
897
|
-
how: "A level, dollars when you know them, a note. Yours to state
|
|
897
|
+
how: "A level, dollars when you know them, a note. Yours to state — the tracker's priority is urgency, never worth; blank stays blank."
|
|
898
898
|
},
|
|
899
899
|
{
|
|
900
900
|
id: "intake",
|
|
@@ -5524,6 +5524,21 @@ var init_confluence = __esm(() => {
|
|
|
5524
5524
|
CONFLUENCE_READ_SCOPES_LINE = CONFLUENCE_READ_SCOPES.join(", ");
|
|
5525
5525
|
});
|
|
5526
5526
|
|
|
5527
|
+
// ../../packages/shared/src/tracker/fieldMap.ts
|
|
5528
|
+
var FILLED_ON_CREATE;
|
|
5529
|
+
var init_fieldMap = __esm(() => {
|
|
5530
|
+
FILLED_ON_CREATE = new Set([
|
|
5531
|
+
"summary",
|
|
5532
|
+
"description",
|
|
5533
|
+
"project",
|
|
5534
|
+
"issuetype",
|
|
5535
|
+
"parent",
|
|
5536
|
+
"reporter",
|
|
5537
|
+
"labels",
|
|
5538
|
+
"priority"
|
|
5539
|
+
]);
|
|
5540
|
+
});
|
|
5541
|
+
|
|
5527
5542
|
// ../../packages/shared/src/help/whatsNew.ts
|
|
5528
5543
|
var SEPT_30 = "/whats-new/2026-09-30", WHATS_NEW;
|
|
5529
5544
|
var init_whatsNew = __esm(() => {
|
|
@@ -7153,7 +7168,10 @@ var BASE_URL_KEY = "ANTHROPIC_BASE_URL", AUTH_TOKEN_KEY = "ANTHROPIC_AUTH_TOKEN"
|
|
|
7153
7168
|
if (!list.some(ours))
|
|
7154
7169
|
return { ...settings };
|
|
7155
7170
|
return withEventHooks(settings, event, list.filter((e) => !ours(e)));
|
|
7156
|
-
}, applySessionHook = (settings, command) => applyOnce(settings, SESSION_EVENT, isSledsSessionHook, sessionHookEntry(command)), removeSessionHook = (settings) => removeOurs(settings, SESSION_EVENT, isSledsSessionHook), hasSessionHook = (settings) => eventHooks(settings, SESSION_EVENT).some(isSledsSessionHook), applyStopHook = (settings, command) => applyOnce(settings, STOP_EVENT, isSledsStopHook, stopHookEntry(command)), removeStopHook = (settings) => removeOurs(settings, STOP_EVENT, isSledsStopHook), hasStopHook = (settings) => eventHooks(settings, STOP_EVENT).some(isSledsStopHook),
|
|
7171
|
+
}, applySessionHook = (settings, command) => applyOnce(settings, SESSION_EVENT, isSledsSessionHook, sessionHookEntry(command)), removeSessionHook = (settings) => removeOurs(settings, SESSION_EVENT, isSledsSessionHook), hasSessionHook = (settings) => eventHooks(settings, SESSION_EVENT).some(isSledsSessionHook), applyStopHook = (settings, command) => applyOnce(settings, STOP_EVENT, isSledsStopHook, stopHookEntry(command)), removeStopHook = (settings) => removeOurs(settings, STOP_EVENT, isSledsStopHook), hasStopHook = (settings) => eventHooks(settings, STOP_EVENT).some(isSledsStopHook), PERMISSION_EVENT_MATCHER = "permission_prompt", PERMISSION_EVENT_TIMEOUT_S = 5, isSledsPermissionHook, permissionHookEntry = (command) => ({
|
|
7172
|
+
matcher: PERMISSION_EVENT_MATCHER,
|
|
7173
|
+
hooks: [{ type: "command", command, timeout: PERMISSION_EVENT_TIMEOUT_S }]
|
|
7174
|
+
}), applyPermissionHook = (settings, command) => applyOnce(settings, NOTIFICATION_EVENT, isSledsPermissionHook, permissionHookEntry(command)), isSeatToken = (token) => /^sled_[A-Za-z0-9_-]+$/.test(token), maskToken = (token) => token.length <= 9 ? `${token.slice(0, 5)}…` : `${token.slice(0, 9)}…`, serialize = (settings) => `${JSON.stringify(settings, null, 2)}
|
|
7157
7175
|
`, hasClaudeCode = (home, env = process.env) => existsSync(claudeDir(home, env)), readSettings = (home, env = process.env) => {
|
|
7158
7176
|
const p = settingsPath(home, env);
|
|
7159
7177
|
if (!existsSync(p))
|
|
@@ -7193,6 +7211,7 @@ var init_settings = __esm(() => {
|
|
|
7193
7211
|
ORG_EXPORT = /(?:^|\s)SLEDS_ORG=(?:'[^']*'|\S+)(?=\s)/;
|
|
7194
7212
|
isSledsSessionHook = isSledsHookFor("session-event");
|
|
7195
7213
|
isSledsStopHook = isSledsHookFor("stop-event");
|
|
7214
|
+
isSledsPermissionHook = isSledsHookFor("permission-event");
|
|
7196
7215
|
});
|
|
7197
7216
|
|
|
7198
7217
|
// src/config.ts
|
|
@@ -7520,6 +7539,7 @@ var init_src = __esm(() => {
|
|
|
7520
7539
|
init_template();
|
|
7521
7540
|
init_statusMap();
|
|
7522
7541
|
init_confluence();
|
|
7542
|
+
init_fieldMap();
|
|
7523
7543
|
init_whatsNew();
|
|
7524
7544
|
init_cheatSheet();
|
|
7525
7545
|
init_pack2();
|
|
@@ -7935,6 +7955,14 @@ function parseRun(v) {
|
|
|
7935
7955
|
...typeof v.seenTicks === "number" ? { seenTicks: v.seenTicks } : {},
|
|
7936
7956
|
...typeof v.answeredAt === "number" ? { answeredAt: v.answeredAt } : {},
|
|
7937
7957
|
...typeof v.band === "string" ? { band: v.band } : {},
|
|
7958
|
+
...isObject8(v.permission) && typeof v.permission.decisionId === "string" && typeof v.permission.at === "number" ? {
|
|
7959
|
+
permission: {
|
|
7960
|
+
decisionId: v.permission.decisionId,
|
|
7961
|
+
options: Array.isArray(v.permission.options) ? v.permission.options.filter((x) => typeof x === "string") : [],
|
|
7962
|
+
at: v.permission.at,
|
|
7963
|
+
...v.permission.onScreen === true ? { onScreen: true } : {}
|
|
7964
|
+
}
|
|
7965
|
+
} : {},
|
|
7938
7966
|
...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 } } : {},
|
|
7939
7967
|
...parked ? { parked } : {},
|
|
7940
7968
|
...isObject8(v.pr) && typeof v.pr.url === "string" ? {
|
|
@@ -8210,6 +8238,7 @@ init_intake();
|
|
|
8210
8238
|
init_template();
|
|
8211
8239
|
init_statusMap();
|
|
8212
8240
|
init_confluence();
|
|
8241
|
+
init_fieldMap();
|
|
8213
8242
|
init_whatsNew();
|
|
8214
8243
|
init_cheatSheet();
|
|
8215
8244
|
init_pack2();
|
|
@@ -9385,10 +9414,10 @@ import {
|
|
|
9385
9414
|
existsSync as existsSync16,
|
|
9386
9415
|
lstatSync,
|
|
9387
9416
|
mkdtempSync,
|
|
9388
|
-
readFileSync as
|
|
9417
|
+
readFileSync as readFileSync16,
|
|
9389
9418
|
readlinkSync,
|
|
9390
|
-
rmSync as
|
|
9391
|
-
writeFileSync as
|
|
9419
|
+
rmSync as rmSync8,
|
|
9420
|
+
writeFileSync as writeFileSync17
|
|
9392
9421
|
} from "node:fs";
|
|
9393
9422
|
import { tmpdir } from "node:os";
|
|
9394
9423
|
import { join as join19, resolve as resolve8 } from "node:path";
|
|
@@ -9880,6 +9909,14 @@ var withCodexSandbox = (agent, gitCommonDir) => {
|
|
|
9880
9909
|
return line;
|
|
9881
9910
|
return `${line} --sandbox workspace-write --add-dir ${shq(gitCommonDir)} -c sandbox_workspace_write.network_access=true`;
|
|
9882
9911
|
};
|
|
9912
|
+
var mainCheckoutOf = (gitCommonDir, cwd) => {
|
|
9913
|
+
const dir = gitCommonDir.replace(/\/+$/, "");
|
|
9914
|
+
if (!dir.endsWith("/.git"))
|
|
9915
|
+
return null;
|
|
9916
|
+
const main = dir.slice(0, -"/.git".length);
|
|
9917
|
+
return main && main !== cwd.replace(/\/+$/, "") ? main : null;
|
|
9918
|
+
};
|
|
9919
|
+
var claudeAddDirFlag = (mainCheckout) => mainCheckout ? ` --add-dir=${shq(mainCheckout)}` : "";
|
|
9883
9920
|
var shq = (s) => `'${s.replace(/'/g, `'\\''`)}'`;
|
|
9884
9921
|
|
|
9885
9922
|
// src/runners/exec.ts
|
|
@@ -9904,21 +9941,23 @@ var agentShellCommand = (o) => {
|
|
|
9904
9941
|
const prompt = `"$(cat ${shq2(o.promptFile)})"`;
|
|
9905
9942
|
const agent = o.agent?.trim();
|
|
9906
9943
|
if (agent)
|
|
9907
|
-
return `${sandboxedAgent(agent, o.sandbox)} ${prompt}`;
|
|
9944
|
+
return `${sandboxedAgent(agent, o.sandbox, o.mainCheckout)} ${prompt}`;
|
|
9908
9945
|
const model = o.model ? ` --model ${shq2(o.model)}` : "";
|
|
9909
9946
|
const effort = o.effort ? ` --effort ${shq2(o.effort)}` : "";
|
|
9910
|
-
return `${sandboxedAgent("claude", o.sandbox)}${mcpConfigFlag(o)} --permission-mode ${shq2(o.permissionMode)}${model}${effort} ${prompt}`;
|
|
9947
|
+
return `${sandboxedAgent("claude", o.sandbox, o.mainCheckout)}${hookSettingsFlag(o)}${mcpConfigFlag(o)} --permission-mode ${shq2(o.permissionMode)}${model}${effort} ${prompt}`;
|
|
9911
9948
|
};
|
|
9912
|
-
var sandboxedAgent = (agent, sandbox) => {
|
|
9913
|
-
if (!sandbox)
|
|
9914
|
-
return agent;
|
|
9949
|
+
var sandboxedAgent = (agent, sandbox, mainCheckout) => {
|
|
9915
9950
|
const kind = sandboxAgentKind(agent);
|
|
9951
|
+
const line = kind === "claude" ? `${agent}${claudeAddDirFlag(mainCheckout)}` : agent;
|
|
9952
|
+
if (!sandbox)
|
|
9953
|
+
return line;
|
|
9916
9954
|
if (kind === "claude")
|
|
9917
|
-
return `env -u SLEDS_TOKEN ${
|
|
9955
|
+
return `env -u SLEDS_TOKEN ${line} --settings ${shq2(sandbox.settingsFile)}`;
|
|
9918
9956
|
if (kind === "codex")
|
|
9919
9957
|
return `env -u SLEDS_TOKEN ${withCodexSandbox(agent, sandbox.gitCommonDir)}`;
|
|
9920
9958
|
return agent;
|
|
9921
9959
|
};
|
|
9960
|
+
var hookSettingsFlag = (o) => o.settingsFile && !o.sandbox ? ` --settings ${shq2(o.settingsFile)}` : "";
|
|
9922
9961
|
var mcpConfigFlag = (o) => o.mcpConfig ? ` --mcp-config ${shq2(o.mcpConfig)}${o.strictMcp ? " --strict-mcp-config" : ""}` : "";
|
|
9923
9962
|
var defaultSpawnDetached = (cmd, args, o) => {
|
|
9924
9963
|
const child = spawn(cmd, [...args], { cwd: o.cwd, detached: true, stdio: "ignore" });
|
|
@@ -9971,6 +10010,15 @@ var tailText = (s, bytes = 4096) => {
|
|
|
9971
10010
|
return nl >= 0 && nl < cut.length - 1 ? cut.slice(nl + 1) : cut;
|
|
9972
10011
|
};
|
|
9973
10012
|
|
|
10013
|
+
// src/runners/types.ts
|
|
10014
|
+
var watchTarget = (h) => ({
|
|
10015
|
+
runner: h.runner,
|
|
10016
|
+
handle: h.id,
|
|
10017
|
+
...h.log ? { log: h.log } : {},
|
|
10018
|
+
...h.group ? { group: h.group } : {}
|
|
10019
|
+
});
|
|
10020
|
+
var isRunnerKey = (key) => /^(?:[1-9]|esc)$/.test(key);
|
|
10021
|
+
|
|
9974
10022
|
// src/runners/cmux.ts
|
|
9975
10023
|
var CMUX_APP_BIN = "/Applications/cmux.app/Contents/Resources/bin/cmux";
|
|
9976
10024
|
var resolveCmuxBin = (exists = existsSync11, path = process.env.PATH ?? "") => {
|
|
@@ -10112,6 +10160,10 @@ var cmuxProbeReason = (r) => {
|
|
|
10112
10160
|
};
|
|
10113
10161
|
var cmuxAuthRefused = (r) => r.status !== 0 && /\b(auth_required|unauthorized|authentication required|invalid password)\b/i.test(`${r.stderr}
|
|
10114
10162
|
${r.stdout}`);
|
|
10163
|
+
var cmuxNeedsForce = (r) => r.status !== 0 && /\bconfirmation_required\b|--force\b/i.test(`${r.stderr}
|
|
10164
|
+
${r.stdout}`);
|
|
10165
|
+
var CMUX_LIST_TRIES = 20;
|
|
10166
|
+
var CMUX_LIST_WAIT_MS = 250;
|
|
10115
10167
|
var CMUX_SETTLE_MS = 300;
|
|
10116
10168
|
var CMUX_ENTER_RETRIES = 2;
|
|
10117
10169
|
var PROMPT_LINE = /^[\s│|]*[>❯›]\s?(.*)$/;
|
|
@@ -10165,6 +10217,12 @@ function cmuxRunner(exec, deps = {}) {
|
|
|
10165
10217
|
return pw ? run(args) : r;
|
|
10166
10218
|
};
|
|
10167
10219
|
const failed = cmuxFailure;
|
|
10220
|
+
const closeWorkspace = (id) => {
|
|
10221
|
+
const c = cmux(["close-workspace", "--workspace", id]);
|
|
10222
|
+
if (!cmuxNeedsForce(c))
|
|
10223
|
+
return c.status === 0;
|
|
10224
|
+
return cmux(["close-workspace", "--workspace", id, "--force"]).status === 0;
|
|
10225
|
+
};
|
|
10168
10226
|
return {
|
|
10169
10227
|
name: "cmux",
|
|
10170
10228
|
makesWorktree: false,
|
|
@@ -10204,19 +10262,29 @@ function cmuxRunner(exec, deps = {}) {
|
|
|
10204
10262
|
const why = failed(r);
|
|
10205
10263
|
const l = cmux(["--id-format", "both", "list-workspaces"]);
|
|
10206
10264
|
const stray = l.status === 0 ? cmuxIdForName(l.stdout, o.name) : null;
|
|
10207
|
-
const left = l.status !== 0 || (stray ?
|
|
10265
|
+
const left = l.status !== 0 || (stray ? !closeWorkspace(stray) : namedLines(l.stdout, o.name).length > 0);
|
|
10208
10266
|
throw new Error(`cmux workspace create ${o.name} failed: ${why}${left ? `; ${UNWATCHED}` : ""}`);
|
|
10209
10267
|
}
|
|
10210
10268
|
let id = parseCmuxWorkspace(r.stdout);
|
|
10211
10269
|
const ref = id ? null : parseCmuxRef(r.stdout);
|
|
10212
10270
|
let closed = false;
|
|
10213
10271
|
if (ref) {
|
|
10214
|
-
|
|
10215
|
-
|
|
10216
|
-
|
|
10217
|
-
|
|
10272
|
+
let listed = null;
|
|
10273
|
+
for (let i = 0;i < CMUX_LIST_TRIES; i++) {
|
|
10274
|
+
if (i > 0)
|
|
10275
|
+
sleep(CMUX_LIST_WAIT_MS);
|
|
10276
|
+
const l = cmux(["--id-format", "both", "list-workspaces"]);
|
|
10277
|
+
if (l.status !== 0)
|
|
10278
|
+
continue;
|
|
10279
|
+
listed = l.stdout;
|
|
10280
|
+
if (namedLines(l.stdout, o.name).length > 0)
|
|
10281
|
+
break;
|
|
10282
|
+
}
|
|
10283
|
+
if (listed !== null) {
|
|
10284
|
+
id = cmuxIdForRef(listed, ref, o.name);
|
|
10285
|
+
const stray = id ? null : cmuxIdForName(listed, o.name);
|
|
10218
10286
|
if (stray)
|
|
10219
|
-
closed =
|
|
10287
|
+
closed = closeWorkspace(stray);
|
|
10220
10288
|
}
|
|
10221
10289
|
}
|
|
10222
10290
|
if (!id) {
|
|
@@ -10277,6 +10345,13 @@ function cmuxRunner(exec, deps = {}) {
|
|
|
10277
10345
|
return;
|
|
10278
10346
|
return pending() ? `the Enter was swallowed; pressed it ${again} more times and the text is still in the input` : `the Enter was swallowed; pressed it again${again > 1 ? ` (${again}×)` : ""}`;
|
|
10279
10347
|
},
|
|
10348
|
+
sendKey(h, key) {
|
|
10349
|
+
if (!isRunnerKey(key))
|
|
10350
|
+
throw new Error(`cmux send-key ${h.id}: no key ${JSON.stringify(key)}`);
|
|
10351
|
+
const r = cmux(["send-key", "--workspace", h.id, key === "esc" ? "escape" : key]);
|
|
10352
|
+
if (r.status !== 0)
|
|
10353
|
+
throw new Error(`cmux send-key ${h.id} failed: ${failed(r)}`);
|
|
10354
|
+
},
|
|
10280
10355
|
stop(h) {
|
|
10281
10356
|
cmux(["close-workspace", "--workspace", h.id]);
|
|
10282
10357
|
if (!h.group)
|
|
@@ -10327,12 +10402,12 @@ init_server();
|
|
|
10327
10402
|
init_config();
|
|
10328
10403
|
import {
|
|
10329
10404
|
appendFileSync as appendFileSync2,
|
|
10330
|
-
chmodSync as
|
|
10331
|
-
mkdirSync as
|
|
10332
|
-
readFileSync as
|
|
10405
|
+
chmodSync as chmodSync4,
|
|
10406
|
+
mkdirSync as mkdirSync12,
|
|
10407
|
+
readFileSync as readFileSync13,
|
|
10333
10408
|
existsSync as realExists,
|
|
10334
|
-
rmSync as
|
|
10335
|
-
writeFileSync as
|
|
10409
|
+
rmSync as rmSync4,
|
|
10410
|
+
writeFileSync as writeFileSync13
|
|
10336
10411
|
} from "node:fs";
|
|
10337
10412
|
import { hostname as hostname2 } from "node:os";
|
|
10338
10413
|
import { join as join15, resolve as resolve7 } from "node:path";
|
|
@@ -10347,7 +10422,7 @@ function beatBody(state, flags, host = {}, cap = {}) {
|
|
|
10347
10422
|
name: flags.name,
|
|
10348
10423
|
os: host.os ?? process.platform,
|
|
10349
10424
|
runner: flags.runner,
|
|
10350
|
-
version: host.version ?? "0.1.
|
|
10425
|
+
version: host.version ?? "0.1.40" ?? "dev",
|
|
10351
10426
|
running: live.length,
|
|
10352
10427
|
items: live.slice(0, BEAT_ITEMS).map((r) => `${r.item}/${r.node}`),
|
|
10353
10428
|
...cap.atOnce !== undefined ? { atOnce: cap.atOnce } : {},
|
|
@@ -11092,13 +11167,40 @@ function jiraFromEnv(epic, env = process.env) {
|
|
|
11092
11167
|
// src/engine/loop.ts
|
|
11093
11168
|
init_src();
|
|
11094
11169
|
|
|
11095
|
-
// src/
|
|
11096
|
-
|
|
11097
|
-
|
|
11098
|
-
|
|
11099
|
-
|
|
11100
|
-
|
|
11101
|
-
|
|
11170
|
+
// src/commands/permissionEvent.ts
|
|
11171
|
+
import { chmodSync as chmodSync3, mkdirSync as mkdirSync10, readFileSync as readFileSync10, renameSync as renameSync6, rmSync as rmSync3, writeFileSync as writeFileSync11 } from "node:fs";
|
|
11172
|
+
|
|
11173
|
+
// src/commands/seatEvent.ts
|
|
11174
|
+
init_config();
|
|
11175
|
+
init_meter();
|
|
11176
|
+
var HOOK_STDIN_TIMEOUT_MS = 1000;
|
|
11177
|
+
var isObject11 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
11178
|
+
var notificationType = (text) => {
|
|
11179
|
+
try {
|
|
11180
|
+
const raw = JSON.parse(text);
|
|
11181
|
+
if (!isObject11(raw))
|
|
11182
|
+
return;
|
|
11183
|
+
return typeof raw.notification_type === "string" ? raw.notification_type : undefined;
|
|
11184
|
+
} catch {
|
|
11185
|
+
return;
|
|
11186
|
+
}
|
|
11187
|
+
};
|
|
11188
|
+
|
|
11189
|
+
// src/commands/permissionEvent.ts
|
|
11190
|
+
var isObject12 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
11191
|
+
var readPermissionMark = (file) => {
|
|
11192
|
+
try {
|
|
11193
|
+
const raw = JSON.parse(readFileSync10(file, "utf8"));
|
|
11194
|
+
if (!isObject12(raw) || typeof raw.at !== "number")
|
|
11195
|
+
return null;
|
|
11196
|
+
return { message: typeof raw.message === "string" ? raw.message : "", at: raw.at };
|
|
11197
|
+
} catch {
|
|
11198
|
+
return null;
|
|
11199
|
+
}
|
|
11200
|
+
};
|
|
11201
|
+
var clearPermissionMark = (file) => {
|
|
11202
|
+
rmSync3(file, { force: true });
|
|
11203
|
+
};
|
|
11102
11204
|
|
|
11103
11205
|
// src/engine/answerer.ts
|
|
11104
11206
|
init_src();
|
|
@@ -11250,6 +11352,10 @@ function looksOf(s) {
|
|
|
11250
11352
|
const l = s;
|
|
11251
11353
|
return l && typeof l.openLook === "function" && typeof l.clearLook === "function" ? s : null;
|
|
11252
11354
|
}
|
|
11355
|
+
function permissionsOf(s) {
|
|
11356
|
+
const p = s;
|
|
11357
|
+
return p && typeof p.openPermission === "function" && typeof p.clearPermission === "function" && typeof p.decisionOf === "function" ? s : null;
|
|
11358
|
+
}
|
|
11253
11359
|
var FAIL_LOG_MAX = 2000;
|
|
11254
11360
|
var UNREACHABLE2 = "SLEDS unreachable";
|
|
11255
11361
|
function keysIn(states, state) {
|
|
@@ -11808,6 +11914,27 @@ function sledsSource(client, o) {
|
|
|
11808
11914
|
throw new Error(serverMessage(r));
|
|
11809
11915
|
return r.json.cleared === true;
|
|
11810
11916
|
},
|
|
11917
|
+
async openPermission(runId, p, engine) {
|
|
11918
|
+
const r = await client.postFull("/proxy/run", {
|
|
11919
|
+
runId,
|
|
11920
|
+
engine,
|
|
11921
|
+
event: { kind: "permission", md: p.md, about: { options: p.options } }
|
|
11922
|
+
});
|
|
11923
|
+
if (!r)
|
|
11924
|
+
throw new Error(`${UNREACHABLE2} — the permission not raised`);
|
|
11925
|
+
if (r.status >= 300 || !r.json || r.json.ok === false)
|
|
11926
|
+
throw new Error(serverMessage(r));
|
|
11927
|
+
const decisionId = str6(r.json.decisionId);
|
|
11928
|
+
return { opened: r.json.opened === true, ...decisionId ? { decisionId } : {} };
|
|
11929
|
+
},
|
|
11930
|
+
async clearPermission(runId, why, engine) {
|
|
11931
|
+
const r = await client.postFull("/proxy/run", { runId, engine, clearPermission: { why } });
|
|
11932
|
+
if (!r)
|
|
11933
|
+
throw new Error(`${UNREACHABLE2} — the permission not cleared`);
|
|
11934
|
+
if (r.status >= 300 || !r.json || r.json.ok === false)
|
|
11935
|
+
throw new Error(serverMessage(r));
|
|
11936
|
+
return r.json.cleared === true;
|
|
11937
|
+
},
|
|
11811
11938
|
async decisionOf(item, decisionId) {
|
|
11812
11939
|
const route = await routeOf(item);
|
|
11813
11940
|
const decisions = Array.isArray(route?.decisions) ? route.decisions.filter(isObject8) : [];
|
|
@@ -11939,6 +12066,63 @@ function askedAndStopped(screen) {
|
|
|
11939
12066
|
const last = (paras[paras.length - 1] ?? "").replace(/\s*\n\s*/g, " ");
|
|
11940
12067
|
return ASKS.test(last) || CONFIRMS.test(last);
|
|
11941
12068
|
}
|
|
12069
|
+
var DIALOG_ASKS = /^Do you want to .+\?$/;
|
|
12070
|
+
var DIALOG_OPTION = /^(❯\s*)?(\d)\.\s+(.+)$/;
|
|
12071
|
+
var DIALOG_FOOTER = /^(?:esc to |tab to |enter to |ctrl\+)/i;
|
|
12072
|
+
var unbox = (line) => line.trimEnd().replace(/^\s*[│┃║]\s?/, "").replace(/\s*[│┃║]$/, "");
|
|
12073
|
+
function permissionDialog(screen) {
|
|
12074
|
+
const raw = screen.split(`
|
|
12075
|
+
`);
|
|
12076
|
+
const lines = raw.map(unbox);
|
|
12077
|
+
let q = -1;
|
|
12078
|
+
for (let i = lines.length - 1;i >= 0; i--)
|
|
12079
|
+
if (DIALOG_ASKS.test(lines[i].trim())) {
|
|
12080
|
+
q = i;
|
|
12081
|
+
break;
|
|
12082
|
+
}
|
|
12083
|
+
if (q < 0)
|
|
12084
|
+
return null;
|
|
12085
|
+
const options = [];
|
|
12086
|
+
let cursors = 0;
|
|
12087
|
+
let i = q + 1;
|
|
12088
|
+
for (;i < lines.length; i++) {
|
|
12089
|
+
const t = lines[i].trim();
|
|
12090
|
+
const m = DIALOG_OPTION.exec(t);
|
|
12091
|
+
if (m) {
|
|
12092
|
+
if (m[2] !== String(options.length + 1))
|
|
12093
|
+
return null;
|
|
12094
|
+
if (m[1])
|
|
12095
|
+
cursors++;
|
|
12096
|
+
options.push({ key: m[2], label: m[3].replace(/\s*\(esc\)$/i, "") });
|
|
12097
|
+
} else if (t && options.length && !isRule(raw[i]) && !isPrompt(t) && !isFooter(t) && !DIALOG_FOOTER.test(t)) {
|
|
12098
|
+
const last = options[options.length - 1];
|
|
12099
|
+
last.label = `${last.label} ${t.replace(/\s*\(esc\)$/i, "")}`;
|
|
12100
|
+
} else
|
|
12101
|
+
break;
|
|
12102
|
+
}
|
|
12103
|
+
if (options.length < 2 || cursors !== 1)
|
|
12104
|
+
return null;
|
|
12105
|
+
for (;i < lines.length; i++) {
|
|
12106
|
+
const t = lines[i].trim();
|
|
12107
|
+
if (t && !isRule(raw[i]) && !DIALOG_FOOTER.test(t) && !isFooter(t))
|
|
12108
|
+
return null;
|
|
12109
|
+
}
|
|
12110
|
+
let from = 0;
|
|
12111
|
+
for (let j = q - 1;j >= 0; j--) {
|
|
12112
|
+
const t = lines[j].trim();
|
|
12113
|
+
if (isRule(raw[j]) || /^⏺/.test(t) || /^⎿/.test(t)) {
|
|
12114
|
+
from = j + 1;
|
|
12115
|
+
break;
|
|
12116
|
+
}
|
|
12117
|
+
}
|
|
12118
|
+
const body = lines.slice(from, q + 1);
|
|
12119
|
+
const indent = Math.min(...body.filter((l) => l.trim()).map((l) => /^\s*/.exec(l)[0].length));
|
|
12120
|
+
const text = body.map((l) => l.slice(indent)).join(`
|
|
12121
|
+
`).replace(/\n{3,}/g, `
|
|
12122
|
+
|
|
12123
|
+
`).trim();
|
|
12124
|
+
return { text, options };
|
|
12125
|
+
}
|
|
11942
12126
|
var PROVIDER_FAILURES = [
|
|
11943
12127
|
["connection lost", /\bconnection (?:lost|error)\b/i],
|
|
11944
12128
|
["credit balance too low", /\bcredit balance (?:is )?too low\b/i],
|
|
@@ -11961,7 +12145,7 @@ function providerFailure(screen) {
|
|
|
11961
12145
|
|
|
11962
12146
|
// src/engine/worktree.ts
|
|
11963
12147
|
init_src();
|
|
11964
|
-
import { appendFileSync, existsSync as existsSync12, mkdirSync as
|
|
12148
|
+
import { appendFileSync, existsSync as existsSync12, mkdirSync as mkdirSync11 } from "node:fs";
|
|
11965
12149
|
import { dirname as dirname11, isAbsolute, join as join14 } from "node:path";
|
|
11966
12150
|
function worktreePath(repoPath, name) {
|
|
11967
12151
|
return join14(repoPath, ".worktrees", name);
|
|
@@ -11987,7 +12171,7 @@ function defaultBranch(exec, repoPath) {
|
|
|
11987
12171
|
var realWorktreeFs = {
|
|
11988
12172
|
exists: existsSync12,
|
|
11989
12173
|
append: (p, text) => {
|
|
11990
|
-
|
|
12174
|
+
mkdirSync11(dirname11(p), { recursive: true });
|
|
11991
12175
|
appendFileSync(p, text);
|
|
11992
12176
|
}
|
|
11993
12177
|
};
|
|
@@ -12213,6 +12397,15 @@ function sandboxFor(d, name, cwd) {
|
|
|
12213
12397
|
throw new Error("sessions are sandboxed, but nothing writes their settings — not started");
|
|
12214
12398
|
return { sandbox: d.writeSandboxSettings(name, cwd) };
|
|
12215
12399
|
}
|
|
12400
|
+
function hooksFor(d, name) {
|
|
12401
|
+
if (d.sandbox || !d.writeHookSettings)
|
|
12402
|
+
return {};
|
|
12403
|
+
return { settingsFile: d.writeHookSettings(name) };
|
|
12404
|
+
}
|
|
12405
|
+
function mainCheckoutFor(d, cwd) {
|
|
12406
|
+
const main = d.mainCheckoutOf?.(cwd);
|
|
12407
|
+
return main ? { mainCheckout: main } : {};
|
|
12408
|
+
}
|
|
12216
12409
|
function engineMcpConfigFor(d, name, runToken, at, cwd) {
|
|
12217
12410
|
if (d.source.name !== "sleds" || d.agent?.trim() || !d.writeMcpConfig)
|
|
12218
12411
|
return;
|
|
@@ -12358,6 +12551,7 @@ async function tickOnce(d) {
|
|
|
12358
12551
|
}
|
|
12359
12552
|
continue;
|
|
12360
12553
|
} else if (pr) {
|
|
12554
|
+
await dropPermission(d, run, "the session opened its PR");
|
|
12361
12555
|
const outcome = { kind: "pr", ref: pr.url };
|
|
12362
12556
|
try {
|
|
12363
12557
|
await d.source.report(claim, outcome, d.engine);
|
|
@@ -12381,6 +12575,7 @@ async function tickOnce(d) {
|
|
|
12381
12575
|
}
|
|
12382
12576
|
}
|
|
12383
12577
|
if (status === "exited") {
|
|
12578
|
+
await dropPermission(d, run, "the session exited");
|
|
12384
12579
|
let log = "";
|
|
12385
12580
|
try {
|
|
12386
12581
|
log = runner.read(run.handle);
|
|
@@ -12430,6 +12625,11 @@ async function tickOnce(d) {
|
|
|
12430
12625
|
}
|
|
12431
12626
|
}
|
|
12432
12627
|
}
|
|
12628
|
+
if (await settlePermission(d, runner, run, shown)) {
|
|
12629
|
+
idle = false;
|
|
12630
|
+
asked = false;
|
|
12631
|
+
failing = null;
|
|
12632
|
+
}
|
|
12433
12633
|
const retry = failing !== null && (run.provider?.tries ?? 0) < PROVIDER_RETRIES;
|
|
12434
12634
|
if (idle || failing || needsHeartbeat(run.leaseUntil, d.now(), d.leaseMin)) {
|
|
12435
12635
|
let beat;
|
|
@@ -12680,6 +12880,8 @@ async function tickOnce(d) {
|
|
|
12680
12880
|
...launch.agent ? { agent: launch.agent } : {},
|
|
12681
12881
|
...mcpConfig ? { mcpConfig, ...d.strictMcp ? { strictMcp: true } : {} } : {},
|
|
12682
12882
|
...sandboxFor(d, name, worktree),
|
|
12883
|
+
...hooksFor(d, name),
|
|
12884
|
+
...mainCheckoutFor(d, worktree),
|
|
12683
12885
|
...claim.group ? { group: claim.group } : {}
|
|
12684
12886
|
};
|
|
12685
12887
|
} catch (e) {
|
|
@@ -12834,6 +13036,115 @@ function parkQuestion(screen, idleMin) {
|
|
|
12834
13036
|
function askedQuestion(screen) {
|
|
12835
13037
|
return `The session stopped and is waiting on an answer, with no PR. ${lastMessage(screen)}`;
|
|
12836
13038
|
}
|
|
13039
|
+
var MARK_OPTIONS = ["1 · Allow once", "esc · Deny"];
|
|
13040
|
+
function permissionKey(answer) {
|
|
13041
|
+
const m = /^\s*(\d|esc)\s*·/i.exec(answer);
|
|
13042
|
+
return m ? m[1].toLowerCase() : null;
|
|
13043
|
+
}
|
|
13044
|
+
async function settlePermission(d, runner, run, shown) {
|
|
13045
|
+
const perms = permissionsOf(d.source);
|
|
13046
|
+
if (!perms || !run.runId)
|
|
13047
|
+
return false;
|
|
13048
|
+
const at = ref(run);
|
|
13049
|
+
const markFile = d.permissionMark?.(sessionName(run.item, run.node));
|
|
13050
|
+
const dialog = runner.readsSession ? permissionDialog(shown) : null;
|
|
13051
|
+
const p = run.permission;
|
|
13052
|
+
if (p) {
|
|
13053
|
+
const gone = runner.readsSession && (p.onScreen ? !dialog : (run.seenAt ?? 0) > p.at);
|
|
13054
|
+
let now;
|
|
13055
|
+
try {
|
|
13056
|
+
now = await perms.decisionOf(run.item, p.decisionId);
|
|
13057
|
+
} catch (e) {
|
|
13058
|
+
d.log(`${at}: could not read the permission decision, asking next tick: ${message(e)}`);
|
|
13059
|
+
return true;
|
|
13060
|
+
}
|
|
13061
|
+
if (now?.state === "answered" && now.answer) {
|
|
13062
|
+
if (gone)
|
|
13063
|
+
d.log(`${at}: the permission was answered after its dialog closed — not pressed`);
|
|
13064
|
+
else if (!pressAnswer(d, runner, run, p.options, now.answer))
|
|
13065
|
+
return true;
|
|
13066
|
+
run.permission = undefined;
|
|
13067
|
+
run.answeredAt = d.now();
|
|
13068
|
+
if (markFile)
|
|
13069
|
+
clearPermissionMark(markFile);
|
|
13070
|
+
return true;
|
|
13071
|
+
}
|
|
13072
|
+
if (now?.state !== "open" && now?.state !== "escalated") {
|
|
13073
|
+
run.permission = undefined;
|
|
13074
|
+
return false;
|
|
13075
|
+
}
|
|
13076
|
+
if (!gone)
|
|
13077
|
+
return true;
|
|
13078
|
+
try {
|
|
13079
|
+
await perms.clearPermission(run.runId, "the dialog closed in the terminal", d.engine);
|
|
13080
|
+
} catch (e) {
|
|
13081
|
+
d.log(`${at}: could not clear the permission, trying next tick: ${message(e)}`);
|
|
13082
|
+
return true;
|
|
13083
|
+
}
|
|
13084
|
+
d.log(`${at}: the permission dialog closed before an answer — cleared`);
|
|
13085
|
+
run.permission = undefined;
|
|
13086
|
+
return false;
|
|
13087
|
+
}
|
|
13088
|
+
const mark = markFile ? readPermissionMark(markFile) : null;
|
|
13089
|
+
if (!dialog && !mark)
|
|
13090
|
+
return false;
|
|
13091
|
+
if (!dialog && runner.readsSession && !run.seenTicks)
|
|
13092
|
+
return false;
|
|
13093
|
+
const options = dialog ? dialog.options.map((o) => `${o.key} · ${o.label}`) : MARK_OPTIONS;
|
|
13094
|
+
const md = dialog?.text || mark?.message || "The session stopped at a permission dialog.";
|
|
13095
|
+
let opened;
|
|
13096
|
+
try {
|
|
13097
|
+
opened = await perms.openPermission(run.runId, { md, options }, d.engine);
|
|
13098
|
+
} catch (e) {
|
|
13099
|
+
d.log(`${at}: could not raise the permission dialog, trying next tick: ${message(e)}`);
|
|
13100
|
+
return true;
|
|
13101
|
+
}
|
|
13102
|
+
if (!opened.decisionId)
|
|
13103
|
+
return true;
|
|
13104
|
+
run.permission = {
|
|
13105
|
+
decisionId: opened.decisionId,
|
|
13106
|
+
options,
|
|
13107
|
+
at: d.now(),
|
|
13108
|
+
...dialog ? { onScreen: true } : {}
|
|
13109
|
+
};
|
|
13110
|
+
if (markFile)
|
|
13111
|
+
clearPermissionMark(markFile);
|
|
13112
|
+
d.log(`${at}: stopped at a permission dialog — it waits for a person (${runner.watchHint(run.handle)})`);
|
|
13113
|
+
return true;
|
|
13114
|
+
}
|
|
13115
|
+
function pressAnswer(d, runner, run, options, answer) {
|
|
13116
|
+
const at = ref(run);
|
|
13117
|
+
const key = permissionKey(answer);
|
|
13118
|
+
const offered = key !== null && options.some((o) => permissionKey(o) === key);
|
|
13119
|
+
try {
|
|
13120
|
+
if (key !== null && offered) {
|
|
13121
|
+
if (runner.sendKey)
|
|
13122
|
+
runner.sendKey(run.handle, key);
|
|
13123
|
+
else
|
|
13124
|
+
runner.send(run.handle, key);
|
|
13125
|
+
d.log(`${at}: the permission is answered — pressed ${key}; the session goes on`);
|
|
13126
|
+
} else {
|
|
13127
|
+
runner.sendKey?.(run.handle, "esc");
|
|
13128
|
+
const note = runner.send(run.handle, answer);
|
|
13129
|
+
d.log(`${at}: the permission is answered in words — Esc, then typed in${note ? ` (${note})` : ""}`);
|
|
13130
|
+
}
|
|
13131
|
+
return true;
|
|
13132
|
+
} catch (e) {
|
|
13133
|
+
d.log(`${at}: could not press the permission's answer, trying next tick: ${message(e)}`);
|
|
13134
|
+
return false;
|
|
13135
|
+
}
|
|
13136
|
+
}
|
|
13137
|
+
async function dropPermission(d, run, why) {
|
|
13138
|
+
const perms = permissionsOf(d.source);
|
|
13139
|
+
if (!run.permission || !perms || !run.runId)
|
|
13140
|
+
return;
|
|
13141
|
+
try {
|
|
13142
|
+
await perms.clearPermission(run.runId, why, d.engine);
|
|
13143
|
+
} catch (e) {
|
|
13144
|
+
d.log(`${ref(run)}: could not clear the permission (${why}): ${message(e)}`);
|
|
13145
|
+
}
|
|
13146
|
+
run.permission = undefined;
|
|
13147
|
+
}
|
|
12837
13148
|
var STILL_TICKS = 2;
|
|
12838
13149
|
function lastMessage(screen) {
|
|
12839
13150
|
const shown = stripTuiChrome(screen);
|
|
@@ -13267,6 +13578,8 @@ async function startAnswerer(d, answers, run) {
|
|
|
13267
13578
|
...launchOptions(launch),
|
|
13268
13579
|
...mcpConfig ? { mcpConfig, ...d.strictMcp ? { strictMcp: true } : {} } : {},
|
|
13269
13580
|
...sandboxFor(d, name, run.handle.cwd),
|
|
13581
|
+
...hooksFor(d, name),
|
|
13582
|
+
...mainCheckoutFor(d, run.handle.cwd),
|
|
13270
13583
|
...run.group ? { group: run.group } : {}
|
|
13271
13584
|
});
|
|
13272
13585
|
} catch (e) {
|
|
@@ -13441,7 +13754,9 @@ async function startDraft(d, claim, why, state, started, finished) {
|
|
|
13441
13754
|
permissionMode: d.permissionMode,
|
|
13442
13755
|
...launchOptions(launch),
|
|
13443
13756
|
...mcpConfig ? { mcpConfig, ...d.strictMcp ? { strictMcp: true } : {} } : {},
|
|
13444
|
-
...sandboxFor(d, name, worktree)
|
|
13757
|
+
...sandboxFor(d, name, worktree),
|
|
13758
|
+
...hooksFor(d, name),
|
|
13759
|
+
...mainCheckoutFor(d, worktree)
|
|
13445
13760
|
});
|
|
13446
13761
|
} catch (e) {
|
|
13447
13762
|
d.log(`${at}: could not start the drafter: ${message(e)}`);
|
|
@@ -14214,6 +14529,8 @@ function startResolver(d, run, e, answer) {
|
|
|
14214
14529
|
...launchOptions(launch),
|
|
14215
14530
|
...run.mcpConfig ? { mcpConfig: run.mcpConfig, ...d.strictMcp ? { strictMcp: true } : {} } : {},
|
|
14216
14531
|
...sandboxFor(d, name, run.handle.cwd),
|
|
14532
|
+
...hooksFor(d, name),
|
|
14533
|
+
...mainCheckoutFor(d, run.handle.cwd),
|
|
14217
14534
|
...run.group ? { group: run.group } : {}
|
|
14218
14535
|
});
|
|
14219
14536
|
} catch (err) {
|
|
@@ -14288,7 +14605,9 @@ async function startEventAnswerer(d, answers, state, dec, decided) {
|
|
|
14288
14605
|
permissionMode: d.permissionMode,
|
|
14289
14606
|
...launchOptions(launch),
|
|
14290
14607
|
...mcpConfig ? { mcpConfig, ...d.strictMcp ? { strictMcp: true } : {} } : {},
|
|
14291
|
-
...sandboxFor(d, name, worktree)
|
|
14608
|
+
...sandboxFor(d, name, worktree),
|
|
14609
|
+
...hooksFor(d, name),
|
|
14610
|
+
...mainCheckoutFor(d, worktree)
|
|
14292
14611
|
});
|
|
14293
14612
|
} catch (e) {
|
|
14294
14613
|
d.log(`${at}: could not start the ${KIND_SAYS[kind]} answerer — it goes to a person: ${message(e)}`);
|
|
@@ -14508,7 +14827,7 @@ function commandRunner(template, deps = {}) {
|
|
|
14508
14827
|
}
|
|
14509
14828
|
|
|
14510
14829
|
// src/runners/conductor.ts
|
|
14511
|
-
import { readFileSync as
|
|
14830
|
+
import { readFileSync as readFileSync11 } from "node:fs";
|
|
14512
14831
|
var obj = (v) => v !== null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
14513
14832
|
var str8 = (v) => typeof v === "string" && v.length > 0 ? v : null;
|
|
14514
14833
|
var CONDUCTOR_API = "https://api.conductor.build";
|
|
@@ -14606,7 +14925,7 @@ var ids = (h) => {
|
|
|
14606
14925
|
var ENDED = new Set(["archived", "deleted"]);
|
|
14607
14926
|
function conductorRunner(exec, deps = {}) {
|
|
14608
14927
|
const env = deps.env ?? process.env;
|
|
14609
|
-
const readFile = deps.readFile ?? ((p) =>
|
|
14928
|
+
const readFile = deps.readFile ?? ((p) => readFileSync11(p, "utf8"));
|
|
14610
14929
|
const now = deps.now ?? Date.now;
|
|
14611
14930
|
const base = env.CONDUCTOR_API_URL?.trim() || CONDUCTOR_API;
|
|
14612
14931
|
const key = () => {
|
|
@@ -14725,8 +15044,8 @@ ${renderTranscript(messages)}`;
|
|
|
14725
15044
|
var headlessScript = (o, log) => {
|
|
14726
15045
|
const prompt = `"$(cat ${shq2(o.promptFile)})"`;
|
|
14727
15046
|
const agent = o.agent?.trim();
|
|
14728
|
-
const cmd = agent ? `${sandboxedAgent(agent, o.sandbox)} ${prompt}` : [
|
|
14729
|
-
`${sandboxedAgent("claude", o.sandbox)} -p`,
|
|
15047
|
+
const cmd = agent ? `${sandboxedAgent(agent, o.sandbox, o.mainCheckout)} ${prompt}` : [
|
|
15048
|
+
`${sandboxedAgent("claude", o.sandbox, o.mainCheckout)} -p`,
|
|
14730
15049
|
prompt,
|
|
14731
15050
|
...o.mcpConfig ? [mcpConfigFlag(o).trim()] : [],
|
|
14732
15051
|
"--output-format stream-json --verbose",
|
|
@@ -14797,7 +15116,7 @@ function headlessRunner(deps = {}) {
|
|
|
14797
15116
|
|
|
14798
15117
|
// src/runners/managed.ts
|
|
14799
15118
|
init_src();
|
|
14800
|
-
import { readFileSync as
|
|
15119
|
+
import { readFileSync as readFileSync12 } from "node:fs";
|
|
14801
15120
|
var obj2 = (v) => v !== null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
14802
15121
|
var str9 = (v) => typeof v === "string" && v.length > 0 ? v : null;
|
|
14803
15122
|
var ANTHROPIC_API = "https://api.anthropic.com";
|
|
@@ -14933,7 +15252,7 @@ var statusLine2 = (session, events, now) => {
|
|
|
14933
15252
|
var YES = /^\s*(?:y|yes|allow|ok|okay|go|go ahead|approve[d]?)\b/i;
|
|
14934
15253
|
function managedRunner(exec, deps = {}) {
|
|
14935
15254
|
const env = deps.env ?? process.env;
|
|
14936
|
-
const readFile = deps.readFile ?? ((p) =>
|
|
15255
|
+
const readFile = deps.readFile ?? ((p) => readFileSync12(p, "utf8"));
|
|
14937
15256
|
const now = deps.now ?? Date.now;
|
|
14938
15257
|
const base = env.ANTHROPIC_BASE_URL?.trim() || ANTHROPIC_API;
|
|
14939
15258
|
const need = (name, where) => {
|
|
@@ -15103,7 +15422,7 @@ ${renderTranscript(eventMessages(all))}`;
|
|
|
15103
15422
|
}
|
|
15104
15423
|
|
|
15105
15424
|
// src/runners/orca.ts
|
|
15106
|
-
import { writeFileSync as
|
|
15425
|
+
import { writeFileSync as writeFileSync12 } from "node:fs";
|
|
15107
15426
|
var obj3 = (v) => v !== null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
15108
15427
|
var str10 = (v) => typeof v === "string" && v.length > 0 ? v : null;
|
|
15109
15428
|
var parseOrcaJson = (stdout) => {
|
|
@@ -15162,7 +15481,7 @@ var orcaTerminalLive = (status, stdout) => {
|
|
|
15162
15481
|
};
|
|
15163
15482
|
var launcherPath2 = (promptFile) => `${promptFile.replace(/\.md$/, "")}.orca.sh`;
|
|
15164
15483
|
function orcaRunner(exec, deps = {}) {
|
|
15165
|
-
const writeFile = deps.writeFile ?? ((p, t) =>
|
|
15484
|
+
const writeFile = deps.writeFile ?? ((p, t) => writeFileSync12(p, t, { mode: 384 }));
|
|
15166
15485
|
const orca = (args, what) => {
|
|
15167
15486
|
const r = exec("orca", args);
|
|
15168
15487
|
const env = parseOrcaJson(r.stdout);
|
|
@@ -15302,6 +15621,14 @@ function tmuxRunner(exec) {
|
|
|
15302
15621
|
}
|
|
15303
15622
|
exec("tmux", ["send-keys", "-t", tmuxPane(h.id), "Enter"]);
|
|
15304
15623
|
},
|
|
15624
|
+
sendKey(h, key) {
|
|
15625
|
+
if (!isRunnerKey(key))
|
|
15626
|
+
throw new Error(`tmux send-keys ${h.id}: no key ${JSON.stringify(key)}`);
|
|
15627
|
+
const r = exec("tmux", ["send-keys", "-t", tmuxPane(h.id), key === "esc" ? "Escape" : key]);
|
|
15628
|
+
if (r.status !== 0) {
|
|
15629
|
+
throw new Error(`tmux send-keys ${h.id} failed: ${r.stderr.trim() || `exit ${r.status}`}`);
|
|
15630
|
+
}
|
|
15631
|
+
},
|
|
15305
15632
|
stop(h) {
|
|
15306
15633
|
exec("tmux", ["kill-session", "-t", tmuxSession(h.id)]);
|
|
15307
15634
|
},
|
|
@@ -15727,7 +16054,7 @@ function realPidAlive(pid) {
|
|
|
15727
16054
|
function memberMcpConfigs(o, cwd) {
|
|
15728
16055
|
const read = o.readJson ?? ((p) => {
|
|
15729
16056
|
try {
|
|
15730
|
-
return JSON.parse(
|
|
16057
|
+
return JSON.parse(readFileSync13(p, "utf8"));
|
|
15731
16058
|
} catch {
|
|
15732
16059
|
return null;
|
|
15733
16060
|
}
|
|
@@ -15769,6 +16096,9 @@ function engineDeps(o, flags, source, runner, stateName) {
|
|
|
15769
16096
|
const repo = flags.repo ? resolve7(cwd, flags.repo) : undefined;
|
|
15770
16097
|
const reposDirs = splitReposDirs(flags.reposDir).map((d) => resolve7(cwd, d));
|
|
15771
16098
|
const { branch, prTitle } = flags;
|
|
16099
|
+
const hooksDir = join15(stateDir, "hooks");
|
|
16100
|
+
const permissionMark = (name) => join15(hooksDir, `${name}.permission.json`);
|
|
16101
|
+
const withHook = (name, settings) => applyPermissionHook(settings, [...o.sledsArgv ?? ["sleds"], "permission-event", "--mark", permissionMark(name)].map(shq2).join(" "));
|
|
15772
16102
|
return {
|
|
15773
16103
|
source,
|
|
15774
16104
|
runner,
|
|
@@ -15793,18 +16123,35 @@ function engineDeps(o, flags, source, runner, stateName) {
|
|
|
15793
16123
|
writeSandboxSettings: o.writeSandboxSettings ?? ((name, cwd) => {
|
|
15794
16124
|
const gitCommonDir = gitCommonDirOf(exec, cwd);
|
|
15795
16125
|
const dir = join15(stateDir, "sandbox");
|
|
15796
|
-
|
|
16126
|
+
mkdirSync12(dir, { recursive: true, mode: 448 });
|
|
15797
16127
|
const p = join15(dir, `${name}.json`);
|
|
15798
|
-
const
|
|
16128
|
+
const walls = engineSandboxSettings(o.home, o.env ?? process.env, gitCommonDir, [
|
|
15799
16129
|
...SANDBOX_DEFAULT_ALLOW,
|
|
15800
16130
|
...flags.sandboxAllow ?? []
|
|
15801
16131
|
]);
|
|
15802
|
-
|
|
16132
|
+
const settings = withHook(name, { ...walls });
|
|
16133
|
+
writeFileSync13(p, `${JSON.stringify(settings, null, 2)}
|
|
15803
16134
|
`, { mode: 384 });
|
|
15804
|
-
|
|
16135
|
+
chmodSync4(p, 384);
|
|
15805
16136
|
return { settingsFile: p, gitCommonDir };
|
|
15806
16137
|
})
|
|
15807
16138
|
} : {},
|
|
16139
|
+
writeHookSettings: (name) => {
|
|
16140
|
+
mkdirSync12(hooksDir, { recursive: true, mode: 448 });
|
|
16141
|
+
const p = join15(hooksDir, `${name}.json`);
|
|
16142
|
+
writeFileSync13(p, `${JSON.stringify(withHook(name, {}), null, 2)}
|
|
16143
|
+
`, { mode: 384 });
|
|
16144
|
+
chmodSync4(p, 384);
|
|
16145
|
+
return p;
|
|
16146
|
+
},
|
|
16147
|
+
permissionMark,
|
|
16148
|
+
mainCheckoutOf: o.mainCheckoutOf ?? ((cwd) => {
|
|
16149
|
+
try {
|
|
16150
|
+
return mainCheckoutOf(gitCommonDirOf(exec, cwd), cwd);
|
|
16151
|
+
} catch {
|
|
16152
|
+
return null;
|
|
16153
|
+
}
|
|
16154
|
+
}),
|
|
15808
16155
|
...branch ? { branchOf: (claim) => branchFor(branch, claim) } : {},
|
|
15809
16156
|
...prTitle ? { prTitleOf: (claim) => prTitleFor(prTitle, claim) } : {},
|
|
15810
16157
|
now: o.now ?? Date.now,
|
|
@@ -15819,7 +16166,7 @@ function engineDeps(o, flags, source, runner, stateName) {
|
|
|
15819
16166
|
}),
|
|
15820
16167
|
writeMcpConfig: o.writeMcpConfig ?? ((name, runToken, worktree) => {
|
|
15821
16168
|
const dir = join15(stateDir, "mcp");
|
|
15822
|
-
|
|
16169
|
+
mkdirSync12(dir, { recursive: true, mode: 448 });
|
|
15823
16170
|
const p = join15(dir, `${name}.json`);
|
|
15824
16171
|
let others = {};
|
|
15825
16172
|
if (flags.strictMcp && flags.mcpAllow?.length) {
|
|
@@ -15830,16 +16177,16 @@ function engineDeps(o, flags, source, runner, stateName) {
|
|
|
15830
16177
|
if (r.refused.length)
|
|
15831
16178
|
log(`${name}: MCP pass-through refused ${r.refused.join(", ")} — the run's sleds server is the only SLEDS one`);
|
|
15832
16179
|
}
|
|
15833
|
-
|
|
15834
|
-
|
|
16180
|
+
writeFileSync13(p, pinOrg2(engineMcpConfig(runToken, others), mcpOrg), { mode: 384 });
|
|
16181
|
+
chmodSync4(p, 384);
|
|
15835
16182
|
return p;
|
|
15836
16183
|
}),
|
|
15837
|
-
removeMcpConfig: o.removeMcpConfig ?? ((p) =>
|
|
16184
|
+
removeMcpConfig: o.removeMcpConfig ?? ((p) => rmSync4(p, { force: true })),
|
|
15838
16185
|
writePrompt: o.writePrompt ?? ((name, text) => {
|
|
15839
16186
|
const dir = join15(stateDir, "prompts");
|
|
15840
|
-
|
|
16187
|
+
mkdirSync12(dir, { recursive: true, mode: 448 });
|
|
15841
16188
|
const p = join15(dir, `${name}.md`);
|
|
15842
|
-
|
|
16189
|
+
writeFileSync13(p, text, { mode: 384 });
|
|
15843
16190
|
return p;
|
|
15844
16191
|
}),
|
|
15845
16192
|
ensureWorktree: (e, repoPath, branch, path, base, install) => ensureWorktree(e, repoPath, branch, path, base, o.worktreeFs ?? { ...realWorktreeFs, exists }, { ...install ? { command: install } : {}, log: o.log ?? console.log }),
|
|
@@ -15923,7 +16270,7 @@ async function driveEngine(o, flags, deps, until = {}) {
|
|
|
15923
16270
|
runner: deps.runner.name,
|
|
15924
16271
|
atOnce: flags.atOnce,
|
|
15925
16272
|
interval: flags.interval,
|
|
15926
|
-
cliVersion: "0.1.
|
|
16273
|
+
cliVersion: "0.1.40"
|
|
15927
16274
|
};
|
|
15928
16275
|
const beat = (checkedAt) => {
|
|
15929
16276
|
const m = deps.machine;
|
|
@@ -16215,7 +16562,7 @@ async function enginePauseCmd(o) {
|
|
|
16215
16562
|
result.released++;
|
|
16216
16563
|
result.kept.push(run.handle.cwd);
|
|
16217
16564
|
if (run.mcpConfig)
|
|
16218
|
-
|
|
16565
|
+
rmSync4(run.mcpConfig, { force: true });
|
|
16219
16566
|
}
|
|
16220
16567
|
if (gone.size)
|
|
16221
16568
|
writeState(file, { ...state, runs: state.runs.filter((r) => !gone.has(r)) });
|
|
@@ -16237,19 +16584,19 @@ init_config();
|
|
|
16237
16584
|
init_state();
|
|
16238
16585
|
import {
|
|
16239
16586
|
existsSync as existsSync14,
|
|
16240
|
-
mkdirSync as
|
|
16241
|
-
readFileSync as
|
|
16587
|
+
mkdirSync as mkdirSync14,
|
|
16588
|
+
readFileSync as readFileSync14,
|
|
16242
16589
|
readdirSync as readdirSync2,
|
|
16243
16590
|
realpathSync,
|
|
16244
|
-
rmSync as
|
|
16245
|
-
writeFileSync as
|
|
16591
|
+
rmSync as rmSync6,
|
|
16592
|
+
writeFileSync as writeFileSync15
|
|
16246
16593
|
} from "node:fs";
|
|
16247
16594
|
import { hostname as hostname3 } from "node:os";
|
|
16248
16595
|
import { basename as basename4, dirname as dirname12, isAbsolute as isAbsolute2, join as join18 } from "node:path";
|
|
16249
16596
|
|
|
16250
16597
|
// src/schedule.ts
|
|
16251
16598
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
16252
|
-
import { existsSync as existsSync13, mkdirSync as
|
|
16599
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync13, rmSync as rmSync5, writeFileSync as writeFileSync14 } from "node:fs";
|
|
16253
16600
|
import { join as join16 } from "node:path";
|
|
16254
16601
|
var REVERT_LABEL = "ai.sleds.revert";
|
|
16255
16602
|
var defaultExec2 = (cmd, args) => {
|
|
@@ -16297,9 +16644,9 @@ var scheduleRevert = (d, deadlineMs) => {
|
|
|
16297
16644
|
if (d.platform === "darwin") {
|
|
16298
16645
|
const p = plistPath(d.home);
|
|
16299
16646
|
try {
|
|
16300
|
-
|
|
16647
|
+
mkdirSync13(join16(d.home, "Library", "LaunchAgents"), { recursive: true });
|
|
16301
16648
|
d.exec("launchctl", ["unload", p]);
|
|
16302
|
-
|
|
16649
|
+
writeFileSync14(p, buildLaunchdPlist(d.sledsArgv, deadline));
|
|
16303
16650
|
const r = d.exec("launchctl", ["load", p]);
|
|
16304
16651
|
if (r.ok)
|
|
16305
16652
|
return { kind: "launchd", detail: `launchd agent ${REVERT_LABEL}` };
|
|
@@ -16328,7 +16675,7 @@ var cancelRevert = (d, kind) => {
|
|
|
16328
16675
|
const p = plistPath(d.home);
|
|
16329
16676
|
if (existsSync13(p)) {
|
|
16330
16677
|
d.exec("launchctl", ["unload", p]);
|
|
16331
|
-
|
|
16678
|
+
rmSync5(p, { force: true });
|
|
16332
16679
|
}
|
|
16333
16680
|
}
|
|
16334
16681
|
if (kind === "systemd" || d.platform === "linux") {
|
|
@@ -16504,7 +16851,7 @@ function readEngines(dir, suffix, manager, parse) {
|
|
|
16504
16851
|
const path = join18(dir, name);
|
|
16505
16852
|
let parsed;
|
|
16506
16853
|
try {
|
|
16507
|
-
parsed = parse(
|
|
16854
|
+
parsed = parse(readFileSync14(path, "utf8"), name);
|
|
16508
16855
|
} catch {
|
|
16509
16856
|
parsed = null;
|
|
16510
16857
|
}
|
|
@@ -16558,7 +16905,7 @@ function engineInstall(o) {
|
|
|
16558
16905
|
const stateDir = seatStateDir(orgStateDir(baseDir, parsed.org), seat);
|
|
16559
16906
|
const label = engineLabel(parsed.name, parsed.org, seat);
|
|
16560
16907
|
const logPath = engineLogPath(stateDir, parsed.name);
|
|
16561
|
-
|
|
16908
|
+
mkdirSync14(stateDir, { recursive: true, mode: 448 });
|
|
16562
16909
|
const sledsArgv = stableArgv(o.sledsArgv, o.realpath);
|
|
16563
16910
|
const execPath = sledsArgv[0] ?? process.execPath;
|
|
16564
16911
|
const agentEnv = {
|
|
@@ -16571,7 +16918,7 @@ function engineInstall(o) {
|
|
|
16571
16918
|
if (platform === "linux")
|
|
16572
16919
|
return installUnit({ o, parsed, label, sledsArgv, env: agentEnv, logPath, exec });
|
|
16573
16920
|
const plist = enginePlistPath(o.home, parsed.name, parsed.org, seat);
|
|
16574
|
-
|
|
16921
|
+
mkdirSync14(dirname12(plist), { recursive: true });
|
|
16575
16922
|
if (existsSync14(plist))
|
|
16576
16923
|
exec("launchctl", ["unload", plist]);
|
|
16577
16924
|
for (const other of installedEngines(o.home)) {
|
|
@@ -16580,7 +16927,7 @@ function engineInstall(o) {
|
|
|
16580
16927
|
if (engineArg(other.programArgs, "name") !== parsed.name)
|
|
16581
16928
|
continue;
|
|
16582
16929
|
exec("launchctl", ["unload", other.plist]);
|
|
16583
|
-
|
|
16930
|
+
rmSync6(other.plist, { force: true });
|
|
16584
16931
|
log(`replaced ${other.label}, this engine as installed before`);
|
|
16585
16932
|
}
|
|
16586
16933
|
const legacy = enginePlistPath(o.home, parsed.name);
|
|
@@ -16588,12 +16935,12 @@ function engineInstall(o) {
|
|
|
16588
16935
|
const cfg = readConfig(o.home);
|
|
16589
16936
|
if (org.sole || parsed.org === (cfg.activeOrg ?? cfg.org?.slug)) {
|
|
16590
16937
|
exec("launchctl", ["unload", legacy]);
|
|
16591
|
-
|
|
16938
|
+
rmSync6(legacy, { force: true });
|
|
16592
16939
|
log(`replaced ${engineLabel(parsed.name)}, the engine installed before orgs`);
|
|
16593
16940
|
} else
|
|
16594
16941
|
log(`note: ${engineLabel(parsed.name)} (installed before orgs) still runs — \`sleds engine uninstall --name ${parsed.name}\` removes it if it was this org's`);
|
|
16595
16942
|
}
|
|
16596
|
-
|
|
16943
|
+
writeFileSync15(plist, buildEnginePlist({ label, sledsArgv, args: parsed.args, env: agentEnv, logPath }));
|
|
16597
16944
|
const r = exec("launchctl", ["load", plist]);
|
|
16598
16945
|
if (!r.ok) {
|
|
16599
16946
|
error(`launchctl load failed: ${r.stderr.trim() || "unknown"}`);
|
|
@@ -16613,7 +16960,7 @@ function installUnit(a) {
|
|
|
16613
16960
|
const unit = engineUnitPath(o.home, label);
|
|
16614
16961
|
const unitName = basename4(unit);
|
|
16615
16962
|
const systemctl = (...args) => exec("systemctl", ["--user", ...args]);
|
|
16616
|
-
|
|
16963
|
+
mkdirSync14(dirname12(unit), { recursive: true });
|
|
16617
16964
|
if (existsSync14(unit))
|
|
16618
16965
|
systemctl("stop", unitName);
|
|
16619
16966
|
for (const other of installedEngines(o.home)) {
|
|
@@ -16622,10 +16969,10 @@ function installUnit(a) {
|
|
|
16622
16969
|
if (engineArg(other.programArgs, "name") !== parsed.name)
|
|
16623
16970
|
continue;
|
|
16624
16971
|
systemctl("disable", "--now", basename4(other.plist));
|
|
16625
|
-
|
|
16972
|
+
rmSync6(other.plist, { force: true });
|
|
16626
16973
|
log(`replaced ${other.label}, this engine as installed before`);
|
|
16627
16974
|
}
|
|
16628
|
-
|
|
16975
|
+
writeFileSync15(unit, buildEngineUnit({
|
|
16629
16976
|
label,
|
|
16630
16977
|
name: parsed.name,
|
|
16631
16978
|
sledsArgv: a.sledsArgv,
|
|
@@ -16683,7 +17030,7 @@ function engineUninstall(o) {
|
|
|
16683
17030
|
exec("systemctl", ["--user", "disable", "--now", basename4(file)]);
|
|
16684
17031
|
else
|
|
16685
17032
|
exec("launchctl", ["unload", file]);
|
|
16686
|
-
|
|
17033
|
+
rmSync6(file, { force: true });
|
|
16687
17034
|
if (unit)
|
|
16688
17035
|
exec("systemctl", ["--user", "daemon-reload"]);
|
|
16689
17036
|
log(`engine:${name} removed: ${basename4(file, unit ? ".service" : ".plist")} — its sessions keep running`);
|
|
@@ -16691,7 +17038,7 @@ function engineUninstall(o) {
|
|
|
16691
17038
|
}
|
|
16692
17039
|
|
|
16693
17040
|
// src/commands/musher.ts
|
|
16694
|
-
import { existsSync as existsSync15, mkdirSync as
|
|
17041
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync15, readFileSync as readFileSync15, rmSync as rmSync7, writeFileSync as writeFileSync16 } from "node:fs";
|
|
16695
17042
|
init_config();
|
|
16696
17043
|
init_meter();
|
|
16697
17044
|
var defaultWhich = (cmd) => {
|
|
@@ -16724,7 +17071,7 @@ var musherAgentState = (home, env = process.env) => {
|
|
|
16724
17071
|
if (!existsSync15(plist))
|
|
16725
17072
|
return { installed: false, thisSeat: false };
|
|
16726
17073
|
try {
|
|
16727
|
-
const text =
|
|
17074
|
+
const text = readFileSync15(plist, "utf8");
|
|
16728
17075
|
const want = env.SLEDS_HOME?.trim();
|
|
16729
17076
|
const has = /<key>SLEDS_HOME<\/key>\s*<string>([^<]*)<\/string>/.exec(text)?.[1];
|
|
16730
17077
|
return { installed: true, thisSeat: (want ?? undefined) === (has ?? undefined) };
|
|
@@ -17084,7 +17431,7 @@ function sandboxChecks(o, env) {
|
|
|
17084
17431
|
const probe = join19(dir, SANDBOX_PROBE);
|
|
17085
17432
|
const work = mkdtempSync(join19(tmpdir(), "sleds-sandbox-"));
|
|
17086
17433
|
try {
|
|
17087
|
-
|
|
17434
|
+
writeFileSync17(probe, `${nonce}
|
|
17088
17435
|
`, { mode: 384 });
|
|
17089
17436
|
const settingsFile = join19(work, "settings.json");
|
|
17090
17437
|
const settings = sandboxSettings({
|
|
@@ -17092,7 +17439,7 @@ function sandboxChecks(o, env) {
|
|
|
17092
17439
|
gitCommonDir: work,
|
|
17093
17440
|
allow: SANDBOX_DEFAULT_ALLOW
|
|
17094
17441
|
});
|
|
17095
|
-
|
|
17442
|
+
writeFileSync17(settingsFile, JSON.stringify(settings, null, 2), { mode: 384 });
|
|
17096
17443
|
const prompt = `Run exactly this one Bash command, once, then reply with its complete output verbatim and nothing else:
|
|
17097
17444
|
|
|
17098
17445
|
${SANDBOX_PROBE_COMMAND}`;
|
|
@@ -17114,8 +17461,8 @@ ${SANDBOX_PROBE_COMMAND}`;
|
|
|
17114
17461
|
], { cwd: work });
|
|
17115
17462
|
return readSandboxProbe(run, nonce);
|
|
17116
17463
|
} finally {
|
|
17117
|
-
|
|
17118
|
-
|
|
17464
|
+
rmSync8(probe, { force: true });
|
|
17465
|
+
rmSync8(work, { recursive: true, force: true });
|
|
17119
17466
|
}
|
|
17120
17467
|
}
|
|
17121
17468
|
function engineChecks(o, env) {
|
|
@@ -17232,7 +17579,7 @@ function boxChecks(o, env, which, need) {
|
|
|
17232
17579
|
const file = boxEnvPath(o.home);
|
|
17233
17580
|
let named = false;
|
|
17234
17581
|
try {
|
|
17235
|
-
named = /^\s*(?:export\s+)?ANTHROPIC_API_KEY\s*=\s*\S/m.test(
|
|
17582
|
+
named = /^\s*(?:export\s+)?ANTHROPIC_API_KEY\s*=\s*\S/m.test(readFileSync16(file, "utf8"));
|
|
17236
17583
|
} catch {
|
|
17237
17584
|
named = false;
|
|
17238
17585
|
}
|
|
@@ -17336,12 +17683,12 @@ init_server();
|
|
|
17336
17683
|
init_config();
|
|
17337
17684
|
import {
|
|
17338
17685
|
appendFileSync as appendFileSync3,
|
|
17339
|
-
chmodSync as
|
|
17340
|
-
mkdirSync as
|
|
17341
|
-
readFileSync as
|
|
17686
|
+
chmodSync as chmodSync5,
|
|
17687
|
+
mkdirSync as mkdirSync16,
|
|
17688
|
+
readFileSync as readFileSync17,
|
|
17342
17689
|
existsSync as realExists2,
|
|
17343
|
-
rmSync as
|
|
17344
|
-
writeFileSync as
|
|
17690
|
+
rmSync as rmSync9,
|
|
17691
|
+
writeFileSync as writeFileSync18
|
|
17345
17692
|
} from "node:fs";
|
|
17346
17693
|
import { hostname as hostname4 } from "node:os";
|
|
17347
17694
|
import { join as join20, resolve as resolve9 } from "node:path";
|
|
@@ -17751,7 +18098,7 @@ function realPidAlive2(pid) {
|
|
|
17751
18098
|
function memberMcpConfigs2(o, cwd) {
|
|
17752
18099
|
const read = o.readJson ?? ((p) => {
|
|
17753
18100
|
try {
|
|
17754
|
-
return JSON.parse(
|
|
18101
|
+
return JSON.parse(readFileSync17(p, "utf8"));
|
|
17755
18102
|
} catch {
|
|
17756
18103
|
return null;
|
|
17757
18104
|
}
|
|
@@ -17793,6 +18140,9 @@ function engineDeps2(o, flags, source, runner, stateName) {
|
|
|
17793
18140
|
const repo = flags.repo ? resolve9(cwd, flags.repo) : undefined;
|
|
17794
18141
|
const reposDirs = splitReposDirs(flags.reposDir).map((d) => resolve9(cwd, d));
|
|
17795
18142
|
const { branch, prTitle } = flags;
|
|
18143
|
+
const hooksDir = join20(stateDir, "hooks");
|
|
18144
|
+
const permissionMark = (name) => join20(hooksDir, `${name}.permission.json`);
|
|
18145
|
+
const withHook = (name, settings) => applyPermissionHook(settings, [...o.sledsArgv ?? ["sleds"], "permission-event", "--mark", permissionMark(name)].map(shq2).join(" "));
|
|
17796
18146
|
return {
|
|
17797
18147
|
source,
|
|
17798
18148
|
runner,
|
|
@@ -17817,18 +18167,35 @@ function engineDeps2(o, flags, source, runner, stateName) {
|
|
|
17817
18167
|
writeSandboxSettings: o.writeSandboxSettings ?? ((name, cwd) => {
|
|
17818
18168
|
const gitCommonDir = gitCommonDirOf2(exec, cwd);
|
|
17819
18169
|
const dir = join20(stateDir, "sandbox");
|
|
17820
|
-
|
|
18170
|
+
mkdirSync16(dir, { recursive: true, mode: 448 });
|
|
17821
18171
|
const p = join20(dir, `${name}.json`);
|
|
17822
|
-
const
|
|
18172
|
+
const walls = engineSandboxSettings2(o.home, o.env ?? process.env, gitCommonDir, [
|
|
17823
18173
|
...SANDBOX_DEFAULT_ALLOW,
|
|
17824
18174
|
...flags.sandboxAllow ?? []
|
|
17825
18175
|
]);
|
|
17826
|
-
|
|
18176
|
+
const settings = withHook(name, { ...walls });
|
|
18177
|
+
writeFileSync18(p, `${JSON.stringify(settings, null, 2)}
|
|
17827
18178
|
`, { mode: 384 });
|
|
17828
|
-
|
|
18179
|
+
chmodSync5(p, 384);
|
|
17829
18180
|
return { settingsFile: p, gitCommonDir };
|
|
17830
18181
|
})
|
|
17831
18182
|
} : {},
|
|
18183
|
+
writeHookSettings: (name) => {
|
|
18184
|
+
mkdirSync16(hooksDir, { recursive: true, mode: 448 });
|
|
18185
|
+
const p = join20(hooksDir, `${name}.json`);
|
|
18186
|
+
writeFileSync18(p, `${JSON.stringify(withHook(name, {}), null, 2)}
|
|
18187
|
+
`, { mode: 384 });
|
|
18188
|
+
chmodSync5(p, 384);
|
|
18189
|
+
return p;
|
|
18190
|
+
},
|
|
18191
|
+
permissionMark,
|
|
18192
|
+
mainCheckoutOf: o.mainCheckoutOf ?? ((cwd) => {
|
|
18193
|
+
try {
|
|
18194
|
+
return mainCheckoutOf(gitCommonDirOf2(exec, cwd), cwd);
|
|
18195
|
+
} catch {
|
|
18196
|
+
return null;
|
|
18197
|
+
}
|
|
18198
|
+
}),
|
|
17832
18199
|
...branch ? { branchOf: (claim) => branchFor(branch, claim) } : {},
|
|
17833
18200
|
...prTitle ? { prTitleOf: (claim) => prTitleFor(prTitle, claim) } : {},
|
|
17834
18201
|
now: o.now ?? Date.now,
|
|
@@ -17843,7 +18210,7 @@ function engineDeps2(o, flags, source, runner, stateName) {
|
|
|
17843
18210
|
}),
|
|
17844
18211
|
writeMcpConfig: o.writeMcpConfig ?? ((name, runToken, worktree) => {
|
|
17845
18212
|
const dir = join20(stateDir, "mcp");
|
|
17846
|
-
|
|
18213
|
+
mkdirSync16(dir, { recursive: true, mode: 448 });
|
|
17847
18214
|
const p = join20(dir, `${name}.json`);
|
|
17848
18215
|
let others = {};
|
|
17849
18216
|
if (flags.strictMcp && flags.mcpAllow?.length) {
|
|
@@ -17854,16 +18221,16 @@ function engineDeps2(o, flags, source, runner, stateName) {
|
|
|
17854
18221
|
if (r.refused.length)
|
|
17855
18222
|
log(`${name}: MCP pass-through refused ${r.refused.join(", ")} — the run's sleds server is the only SLEDS one`);
|
|
17856
18223
|
}
|
|
17857
|
-
|
|
17858
|
-
|
|
18224
|
+
writeFileSync18(p, pinOrg3(engineMcpConfig(runToken, others), mcpOrg), { mode: 384 });
|
|
18225
|
+
chmodSync5(p, 384);
|
|
17859
18226
|
return p;
|
|
17860
18227
|
}),
|
|
17861
|
-
removeMcpConfig: o.removeMcpConfig ?? ((p) =>
|
|
18228
|
+
removeMcpConfig: o.removeMcpConfig ?? ((p) => rmSync9(p, { force: true })),
|
|
17862
18229
|
writePrompt: o.writePrompt ?? ((name, text) => {
|
|
17863
18230
|
const dir = join20(stateDir, "prompts");
|
|
17864
|
-
|
|
18231
|
+
mkdirSync16(dir, { recursive: true, mode: 448 });
|
|
17865
18232
|
const p = join20(dir, `${name}.md`);
|
|
17866
|
-
|
|
18233
|
+
writeFileSync18(p, text, { mode: 384 });
|
|
17867
18234
|
return p;
|
|
17868
18235
|
}),
|
|
17869
18236
|
ensureWorktree: (e, repoPath, branch, path, base, install) => ensureWorktree(e, repoPath, branch, path, base, o.worktreeFs ?? { ...realWorktreeFs, exists }, { ...install ? { command: install } : {}, log: o.log ?? console.log }),
|
|
@@ -17956,7 +18323,7 @@ async function driveEngine2(o, flags, deps, until = {}) {
|
|
|
17956
18323
|
runner: deps.runner.name,
|
|
17957
18324
|
atOnce: flags.atOnce,
|
|
17958
18325
|
interval: flags.interval,
|
|
17959
|
-
cliVersion: "0.1.
|
|
18326
|
+
cliVersion: "0.1.40"
|
|
17960
18327
|
};
|
|
17961
18328
|
const beat = (checkedAt) => {
|
|
17962
18329
|
const m = deps.machine;
|
|
@@ -18362,7 +18729,7 @@ async function enginePauseCmd2(o) {
|
|
|
18362
18729
|
result.released++;
|
|
18363
18730
|
result.kept.push(run.handle.cwd);
|
|
18364
18731
|
if (run.mcpConfig)
|
|
18365
|
-
|
|
18732
|
+
rmSync9(run.mcpConfig, { force: true });
|
|
18366
18733
|
}
|
|
18367
18734
|
if (gone.size)
|
|
18368
18735
|
writeState(file, { ...state, runs: state.runs.filter((r) => !gone.has(r)) });
|
|
@@ -18384,12 +18751,12 @@ init_config();
|
|
|
18384
18751
|
init_state();
|
|
18385
18752
|
import {
|
|
18386
18753
|
existsSync as existsSync17,
|
|
18387
|
-
mkdirSync as
|
|
18388
|
-
readFileSync as
|
|
18754
|
+
mkdirSync as mkdirSync17,
|
|
18755
|
+
readFileSync as readFileSync18,
|
|
18389
18756
|
readdirSync as readdirSync4,
|
|
18390
18757
|
realpathSync as realpathSync2,
|
|
18391
|
-
rmSync as
|
|
18392
|
-
writeFileSync as
|
|
18758
|
+
rmSync as rmSync10,
|
|
18759
|
+
writeFileSync as writeFileSync19
|
|
18393
18760
|
} from "node:fs";
|
|
18394
18761
|
import { hostname as hostname5 } from "node:os";
|
|
18395
18762
|
import { basename as basename5, dirname as dirname13, isAbsolute as isAbsolute3, join as join21 } from "node:path";
|
|
@@ -18511,7 +18878,7 @@ function readEngines2(dir, suffix, manager, parse) {
|
|
|
18511
18878
|
const path = join21(dir, name);
|
|
18512
18879
|
let parsed;
|
|
18513
18880
|
try {
|
|
18514
|
-
parsed = parse(
|
|
18881
|
+
parsed = parse(readFileSync18(path, "utf8"), name);
|
|
18515
18882
|
} catch {
|
|
18516
18883
|
parsed = null;
|
|
18517
18884
|
}
|
|
@@ -18565,7 +18932,7 @@ function engineInstall2(o) {
|
|
|
18565
18932
|
const stateDir = seatStateDir(orgStateDir(baseDir, parsed.org), seat);
|
|
18566
18933
|
const label = engineLabel2(parsed.name, parsed.org, seat);
|
|
18567
18934
|
const logPath = engineLogPath2(stateDir, parsed.name);
|
|
18568
|
-
|
|
18935
|
+
mkdirSync17(stateDir, { recursive: true, mode: 448 });
|
|
18569
18936
|
const sledsArgv = stableArgv2(o.sledsArgv, o.realpath);
|
|
18570
18937
|
const execPath = sledsArgv[0] ?? process.execPath;
|
|
18571
18938
|
const agentEnv = {
|
|
@@ -18578,7 +18945,7 @@ function engineInstall2(o) {
|
|
|
18578
18945
|
if (platform === "linux")
|
|
18579
18946
|
return installUnit2({ o, parsed, label, sledsArgv, env: agentEnv, logPath, exec });
|
|
18580
18947
|
const plist = enginePlistPath2(o.home, parsed.name, parsed.org, seat);
|
|
18581
|
-
|
|
18948
|
+
mkdirSync17(dirname13(plist), { recursive: true });
|
|
18582
18949
|
if (existsSync17(plist))
|
|
18583
18950
|
exec("launchctl", ["unload", plist]);
|
|
18584
18951
|
for (const other of installedEngines2(o.home)) {
|
|
@@ -18587,7 +18954,7 @@ function engineInstall2(o) {
|
|
|
18587
18954
|
if (engineArg2(other.programArgs, "name") !== parsed.name)
|
|
18588
18955
|
continue;
|
|
18589
18956
|
exec("launchctl", ["unload", other.plist]);
|
|
18590
|
-
|
|
18957
|
+
rmSync10(other.plist, { force: true });
|
|
18591
18958
|
log(`replaced ${other.label}, this engine as installed before`);
|
|
18592
18959
|
}
|
|
18593
18960
|
const legacy = enginePlistPath2(o.home, parsed.name);
|
|
@@ -18595,12 +18962,12 @@ function engineInstall2(o) {
|
|
|
18595
18962
|
const cfg = readConfig(o.home);
|
|
18596
18963
|
if (org.sole || parsed.org === (cfg.activeOrg ?? cfg.org?.slug)) {
|
|
18597
18964
|
exec("launchctl", ["unload", legacy]);
|
|
18598
|
-
|
|
18965
|
+
rmSync10(legacy, { force: true });
|
|
18599
18966
|
log(`replaced ${engineLabel2(parsed.name)}, the engine installed before orgs`);
|
|
18600
18967
|
} else
|
|
18601
18968
|
log(`note: ${engineLabel2(parsed.name)} (installed before orgs) still runs — \`sleds engine uninstall --name ${parsed.name}\` removes it if it was this org's`);
|
|
18602
18969
|
}
|
|
18603
|
-
|
|
18970
|
+
writeFileSync19(plist, buildEnginePlist2({ label, sledsArgv, args: parsed.args, env: agentEnv, logPath }));
|
|
18604
18971
|
const r = exec("launchctl", ["load", plist]);
|
|
18605
18972
|
if (!r.ok) {
|
|
18606
18973
|
error(`launchctl load failed: ${r.stderr.trim() || "unknown"}`);
|
|
@@ -18620,7 +18987,7 @@ function installUnit2(a) {
|
|
|
18620
18987
|
const unit = engineUnitPath(o.home, label);
|
|
18621
18988
|
const unitName = basename5(unit);
|
|
18622
18989
|
const systemctl = (...args) => exec("systemctl", ["--user", ...args]);
|
|
18623
|
-
|
|
18990
|
+
mkdirSync17(dirname13(unit), { recursive: true });
|
|
18624
18991
|
if (existsSync17(unit))
|
|
18625
18992
|
systemctl("stop", unitName);
|
|
18626
18993
|
for (const other of installedEngines2(o.home)) {
|
|
@@ -18629,10 +18996,10 @@ function installUnit2(a) {
|
|
|
18629
18996
|
if (engineArg2(other.programArgs, "name") !== parsed.name)
|
|
18630
18997
|
continue;
|
|
18631
18998
|
systemctl("disable", "--now", basename5(other.plist));
|
|
18632
|
-
|
|
18999
|
+
rmSync10(other.plist, { force: true });
|
|
18633
19000
|
log(`replaced ${other.label}, this engine as installed before`);
|
|
18634
19001
|
}
|
|
18635
|
-
|
|
19002
|
+
writeFileSync19(unit, buildEngineUnit({
|
|
18636
19003
|
label,
|
|
18637
19004
|
name: parsed.name,
|
|
18638
19005
|
sledsArgv: a.sledsArgv,
|
|
@@ -18690,7 +19057,7 @@ function engineUninstall2(o) {
|
|
|
18690
19057
|
exec("systemctl", ["--user", "disable", "--now", basename5(file)]);
|
|
18691
19058
|
else
|
|
18692
19059
|
exec("launchctl", ["unload", file]);
|
|
18693
|
-
|
|
19060
|
+
rmSync10(file, { force: true });
|
|
18694
19061
|
if (unit)
|
|
18695
19062
|
exec("systemctl", ["--user", "daemon-reload"]);
|
|
18696
19063
|
log(`engine:${name} removed: ${basename5(file, unit ? ".service" : ".plist")} — its sessions keep running`);
|
|
@@ -18821,7 +19188,7 @@ import { closeSync as closeSync3, fstatSync as fstatSync2, openSync as openSync3
|
|
|
18821
19188
|
import { hostname as hostname6 } from "node:os";
|
|
18822
19189
|
|
|
18823
19190
|
// src/commands/engineStatus.ts
|
|
18824
|
-
import { existsSync as existsSync18, readFileSync as
|
|
19191
|
+
import { existsSync as existsSync18, readFileSync as readFileSync19 } from "node:fs";
|
|
18825
19192
|
init_state();
|
|
18826
19193
|
|
|
18827
19194
|
// src/engine/status.ts
|
|
@@ -19111,7 +19478,7 @@ var engineLogCmd = (o) => {
|
|
|
19111
19478
|
|
|
19112
19479
|
// src/commands/engineProfile.ts
|
|
19113
19480
|
init_src();
|
|
19114
|
-
import { existsSync as existsSync19, readFileSync as
|
|
19481
|
+
import { existsSync as existsSync19, readFileSync as readFileSync20 } from "node:fs";
|
|
19115
19482
|
import { hostname as hostname7 } from "node:os";
|
|
19116
19483
|
var PROFILE_USAGE = "usage: sleds engine profile [--json] | sleds engine profile set <field>=<value>… [--workspace] [--json] | sleds engine profile set --stdin [--workspace] [--json] | sleds engine profile --strict-mcp [--mcp-allow <a,b>] | --no-strict-mcp [--workspace] [--json] | sleds engine profile --sandbox [--sandbox-allow <a,b>] | --no-sandbox [--workspace] [--json] | sleds engine profile set --hold on|off [--workspace] [--json] | sleds engine profile set cmuxPassword=<pw> | --cmux-password <pw> [--json]";
|
|
19117
19484
|
var PROFILE_FIELDS = [
|
|
@@ -19376,7 +19743,7 @@ async function engineProfileCmd(o) {
|
|
|
19376
19743
|
const rest = words.slice(1);
|
|
19377
19744
|
let stdin = null;
|
|
19378
19745
|
if (fromStdin) {
|
|
19379
|
-
const taken = cmuxPasswordFromJson((o.stdin ?? (() =>
|
|
19746
|
+
const taken = cmuxPasswordFromJson((o.stdin ?? (() => readFileSync20(0, "utf8")))());
|
|
19380
19747
|
if ("error" in taken || taken.password !== undefined && password !== undefined) {
|
|
19381
19748
|
error("error" in taken ? taken.error : "the cmux password is given once");
|
|
19382
19749
|
error(PROFILE_USAGE);
|
|
@@ -19461,7 +19828,7 @@ var keychainLine = (k) => k === "set" ? "cmuxPassword: set (Keychain)" : k === "
|
|
|
19461
19828
|
|
|
19462
19829
|
// src/commands/engineStatus.ts
|
|
19463
19830
|
init_state();
|
|
19464
|
-
import { existsSync as existsSync20, readFileSync as
|
|
19831
|
+
import { existsSync as existsSync20, readFileSync as readFileSync21 } from "node:fs";
|
|
19465
19832
|
import { hostname as hostname8 } from "node:os";
|
|
19466
19833
|
var ENGINE_STATUS_USAGE = "usage: sleds engine status [--name <n>] [--org <slug>] [--json]";
|
|
19467
19834
|
function parseStatusArgs(argv, host) {
|
|
@@ -19517,7 +19884,7 @@ function readEngineStatus(stateDir, engine, host, pidAlive, seat) {
|
|
|
19517
19884
|
}
|
|
19518
19885
|
function safeRead(path) {
|
|
19519
19886
|
try {
|
|
19520
|
-
return
|
|
19887
|
+
return readFileSync21(path, "utf8");
|
|
19521
19888
|
} catch {
|
|
19522
19889
|
return "";
|
|
19523
19890
|
}
|
|
@@ -19638,7 +20005,7 @@ init_meter();
|
|
|
19638
20005
|
|
|
19639
20006
|
// src/owed.ts
|
|
19640
20007
|
init_config();
|
|
19641
|
-
import { existsSync as existsSync21, mkdirSync as
|
|
20008
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync18, readFileSync as readFileSync22, renameSync as renameSync7, writeFileSync as writeFileSync20 } from "node:fs";
|
|
19642
20009
|
import { dirname as dirname14, join as join22 } from "node:path";
|
|
19643
20010
|
var owedPath = (home) => join22(configDir(home), "owed.json");
|
|
19644
20011
|
var sessionPath = (home) => join22(configDir(home), "session.json");
|
|
@@ -19659,17 +20026,17 @@ var readJson = (p) => {
|
|
|
19659
20026
|
if (!existsSync21(p))
|
|
19660
20027
|
return null;
|
|
19661
20028
|
try {
|
|
19662
|
-
return JSON.parse(
|
|
20029
|
+
return JSON.parse(readFileSync22(p, "utf8"));
|
|
19663
20030
|
} catch {
|
|
19664
20031
|
return null;
|
|
19665
20032
|
}
|
|
19666
20033
|
};
|
|
19667
20034
|
var writeJson = (p, v) => {
|
|
19668
|
-
|
|
20035
|
+
mkdirSync18(dirname14(p), { recursive: true, mode: 448 });
|
|
19669
20036
|
const tmp = `${p}.${process.pid}.tmp`;
|
|
19670
|
-
|
|
20037
|
+
writeFileSync20(tmp, `${JSON.stringify(v, null, 2)}
|
|
19671
20038
|
`, { mode: 384 });
|
|
19672
|
-
|
|
20039
|
+
renameSync7(tmp, p);
|
|
19673
20040
|
};
|
|
19674
20041
|
var readOwed = (home, now = Date.now()) => {
|
|
19675
20042
|
const f = readJson(owedPath(home));
|
|
@@ -19874,7 +20241,7 @@ var hooksOrg = (home, env = process.env) => {
|
|
|
19874
20241
|
};
|
|
19875
20242
|
|
|
19876
20243
|
// src/commands/init.ts
|
|
19877
|
-
import { mkdirSync as
|
|
20244
|
+
import { mkdirSync as mkdirSync19, writeFileSync as writeFileSync21 } from "node:fs";
|
|
19878
20245
|
import { createInterface } from "node:readline";
|
|
19879
20246
|
init_config();
|
|
19880
20247
|
init_state();
|
|
@@ -20561,8 +20928,8 @@ var init = async (o) => {
|
|
|
20561
20928
|
});
|
|
20562
20929
|
if (mcpLine)
|
|
20563
20930
|
wrote.push(mcpLine);
|
|
20564
|
-
|
|
20565
|
-
|
|
20931
|
+
mkdirSync19(skillDir(o.home), { recursive: true });
|
|
20932
|
+
writeFileSync21(skillPath(o.home), SKILL_MD);
|
|
20566
20933
|
wrote.push(`installed skill at ${skillPath(o.home)}`);
|
|
20567
20934
|
if (o.installMusher) {
|
|
20568
20935
|
const r = o.installMusher();
|
|
@@ -20686,7 +21053,7 @@ var login = async (o) => {
|
|
|
20686
21053
|
// src/commands/logout.ts
|
|
20687
21054
|
init_config();
|
|
20688
21055
|
init_state();
|
|
20689
|
-
import { existsSync as existsSync22, readFileSync as
|
|
21056
|
+
import { existsSync as existsSync22, readFileSync as readFileSync23, rmSync as rmSync11 } from "node:fs";
|
|
20690
21057
|
import { hostname as hostname10 } from "node:os";
|
|
20691
21058
|
init_settings();
|
|
20692
21059
|
var LOGOUT_USAGE = "usage: sleds logout [--org <slug>] [--json]";
|
|
@@ -20810,7 +21177,7 @@ async function logout(o) {
|
|
|
20810
21177
|
continue;
|
|
20811
21178
|
if (!e.org) {
|
|
20812
21179
|
(o.exec ?? defaultExec2)("launchctl", ["unload", e.plist]);
|
|
20813
|
-
|
|
21180
|
+
rmSync11(e.plist, { force: true });
|
|
20814
21181
|
continue;
|
|
20815
21182
|
}
|
|
20816
21183
|
engineUninstall({
|
|
@@ -20843,8 +21210,8 @@ async function logout(o) {
|
|
|
20843
21210
|
};
|
|
20844
21211
|
writeConfig(o.home, next);
|
|
20845
21212
|
const tp = tokenPath(o.home, env);
|
|
20846
|
-
if (existsSync22(tp) &&
|
|
20847
|
-
|
|
21213
|
+
if (existsSync22(tp) && readFileSync23(tp, "utf8").trim() === seat.token)
|
|
21214
|
+
rmSync11(tp, { force: true });
|
|
20848
21215
|
const active = next.activeOrg ?? next.org?.slug ?? null;
|
|
20849
21216
|
const result = { ok: true, email, org: slug, paused, active };
|
|
20850
21217
|
if (parsed.json)
|
|
@@ -20921,7 +21288,7 @@ var meter = async (o) => {
|
|
|
20921
21288
|
init_config();
|
|
20922
21289
|
init_meter();
|
|
20923
21290
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
20924
|
-
import { existsSync as existsSync23, mkdirSync as
|
|
21291
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync20, readFileSync as readFileSync24, rmSync as rmSync12, writeFileSync as writeFileSync22 } from "node:fs";
|
|
20925
21292
|
import { hostname as hostname11 } from "node:os";
|
|
20926
21293
|
import { dirname as dirname15 } from "node:path";
|
|
20927
21294
|
var defaultWhich3 = (cmd) => {
|
|
@@ -20961,8 +21328,8 @@ var musherInstall = (o) => {
|
|
|
20961
21328
|
const plist = musherPlistPath(o.home, env);
|
|
20962
21329
|
const label = musherLabel(env);
|
|
20963
21330
|
const dir = configDir(o.home, env);
|
|
20964
|
-
|
|
20965
|
-
|
|
21331
|
+
mkdirSync20(dirname15(plist), { recursive: true });
|
|
21332
|
+
mkdirSync20(dir, { recursive: true, mode: 448 });
|
|
20966
21333
|
const execPath = o.sledsArgv[0] ?? process.execPath;
|
|
20967
21334
|
const agentEnv = {
|
|
20968
21335
|
PATH: musherPath(o.home, execPath, env.PATH ?? ""),
|
|
@@ -20973,7 +21340,7 @@ var musherInstall = (o) => {
|
|
|
20973
21340
|
const exec = o.exec ?? defaultExecSync;
|
|
20974
21341
|
if (existsSync23(plist))
|
|
20975
21342
|
exec("launchctl", ["unload", plist]);
|
|
20976
|
-
|
|
21343
|
+
writeFileSync22(plist, buildMusherPlist({ sledsArgv: o.sledsArgv, env: agentEnv, logPath: musherLogPath(dir), label }));
|
|
20977
21344
|
const r = exec("launchctl", ["load", plist]);
|
|
20978
21345
|
if (!r.ok) {
|
|
20979
21346
|
error(`launchctl load failed: ${r.stderr.trim() || "unknown"}`);
|
|
@@ -20994,7 +21361,7 @@ var musherUninstall = (o) => {
|
|
|
20994
21361
|
const exec = o.exec ?? defaultExecSync;
|
|
20995
21362
|
if (existsSync23(plist)) {
|
|
20996
21363
|
exec("launchctl", ["unload", plist]);
|
|
20997
|
-
|
|
21364
|
+
rmSync12(plist, { force: true });
|
|
20998
21365
|
log(`musher removed: ${musherLabel(env)}`);
|
|
20999
21366
|
} else
|
|
21000
21367
|
log("musher was not installed.");
|
|
@@ -21257,7 +21624,7 @@ var on = (o) => {
|
|
|
21257
21624
|
init_config();
|
|
21258
21625
|
init_meter();
|
|
21259
21626
|
init_settings();
|
|
21260
|
-
import { existsSync as existsSync24, rmSync as
|
|
21627
|
+
import { existsSync as existsSync24, rmSync as rmSync13 } from "node:fs";
|
|
21261
21628
|
var ORG_USAGE = "usage: sleds org list [--json] | sleds org use <slug>";
|
|
21262
21629
|
var orgRows = (cfg, activeSlug) => {
|
|
21263
21630
|
const seats = { ...cfg.orgs ?? {} };
|
|
@@ -21334,7 +21701,7 @@ var orgUse = (o) => {
|
|
|
21334
21701
|
writeSettings(o.home, removeProxy(settings));
|
|
21335
21702
|
}
|
|
21336
21703
|
try {
|
|
21337
|
-
|
|
21704
|
+
rmSync13(meterCachePath(o.home), { force: true });
|
|
21338
21705
|
} catch {}
|
|
21339
21706
|
log(`Active org: ${seat.org?.name ? `${seat.org.name} (${slug})` : slug}${seat.email ? ` · ${seat.email}` : ""}.`);
|
|
21340
21707
|
log("Claude Code, the status line and the hooks act as this org now.");
|
|
@@ -21360,7 +21727,7 @@ var orgCmd = (o) => {
|
|
|
21360
21727
|
// src/commands/pack.ts
|
|
21361
21728
|
init_src();
|
|
21362
21729
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
21363
|
-
import { writeFileSync as
|
|
21730
|
+
import { writeFileSync as writeFileSync23 } from "node:fs";
|
|
21364
21731
|
import { join as join23 } from "node:path";
|
|
21365
21732
|
function packFileName(key) {
|
|
21366
21733
|
return `pack-${slugify(key, 80) || "item"}.md`;
|
|
@@ -21390,22 +21757,43 @@ var packCmd = async (o) => {
|
|
|
21390
21757
|
return 0;
|
|
21391
21758
|
}
|
|
21392
21759
|
const path = join23(o.cwd ?? process.cwd(), packFileName(key));
|
|
21393
|
-
(o.write ?? ((p, t) =>
|
|
21760
|
+
(o.write ?? ((p, t) => writeFileSync23(p, t.endsWith(`
|
|
21394
21761
|
`) ? t : `${t}
|
|
21395
21762
|
`)))(path, r.text);
|
|
21396
21763
|
log(`Wrote ${path} — hand it to any model. \`sleds pack ${key} --run\` starts Claude Code with it.`);
|
|
21397
21764
|
return 0;
|
|
21398
21765
|
};
|
|
21399
21766
|
|
|
21400
|
-
// src/commands/
|
|
21401
|
-
|
|
21402
|
-
|
|
21403
|
-
|
|
21404
|
-
|
|
21405
|
-
|
|
21406
|
-
|
|
21767
|
+
// src/commands/permissionEvent.ts
|
|
21768
|
+
import { chmodSync as chmodSync6, mkdirSync as mkdirSync21, readFileSync as readFileSync25, renameSync as renameSync8, rmSync as rmSync14, writeFileSync as writeFileSync24 } from "node:fs";
|
|
21769
|
+
import { dirname as dirname16 } from "node:path";
|
|
21770
|
+
var isObject13 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
21771
|
+
var messageOf = (text) => {
|
|
21772
|
+
try {
|
|
21773
|
+
const raw = JSON.parse(text);
|
|
21774
|
+
return isObject13(raw) && typeof raw.message === "string" ? raw.message : "";
|
|
21775
|
+
} catch {
|
|
21776
|
+
return "";
|
|
21777
|
+
}
|
|
21778
|
+
};
|
|
21779
|
+
var permissionEvent = async (o) => {
|
|
21780
|
+
try {
|
|
21781
|
+
const input = o.stdin ?? await readStdin(HOOK_STDIN_TIMEOUT_MS);
|
|
21782
|
+
if (!o.mark || notificationType(input) !== "permission_prompt")
|
|
21783
|
+
return 0;
|
|
21784
|
+
const mark = { message: messageOf(input), at: (o.now ?? Date.now)() };
|
|
21785
|
+
mkdirSync21(dirname16(o.mark), { recursive: true, mode: 448 });
|
|
21786
|
+
const tmp = `${o.mark}.${process.pid}.tmp`;
|
|
21787
|
+
writeFileSync24(tmp, `${JSON.stringify(mark)}
|
|
21788
|
+
`, { mode: 384 });
|
|
21789
|
+
renameSync8(tmp, o.mark);
|
|
21790
|
+
chmodSync6(o.mark, 384);
|
|
21791
|
+
} catch {}
|
|
21792
|
+
return 0;
|
|
21793
|
+
};
|
|
21407
21794
|
|
|
21408
21795
|
// src/commands/promptEvent.ts
|
|
21796
|
+
init_config();
|
|
21409
21797
|
var LABEL = {
|
|
21410
21798
|
fiveHour: "5-hour",
|
|
21411
21799
|
sevenDay: "weekly",
|
|
@@ -21488,7 +21876,7 @@ var promptEvent = async (o) => {
|
|
|
21488
21876
|
|
|
21489
21877
|
// src/commands/route.ts
|
|
21490
21878
|
init_src();
|
|
21491
|
-
import { readFileSync as
|
|
21879
|
+
import { readFileSync as readFileSync26 } from "node:fs";
|
|
21492
21880
|
import { hostname as hostname12 } from "node:os";
|
|
21493
21881
|
var ARM_USAGE = "usage: sleds route arm <key> [--off] [--json] [--name <engine>] [--at-once <n>] [--runner tmux|headless|command|orca|cmux] [--runner-cmd '<launcher>'] [--agent '<command>'] [--mode <permission-mode>] [--model <id>] [--effort <e>] [--branch '<template>'] [--pr-title '<template>'] [--repos-dir <dir>]";
|
|
21494
21882
|
var USAGE = "usage: sleds route <key> [--long | --dot | --json] | sleds route arm <key> [--off] [--json] | sleds route answer <key>/<node> --stdin | sleds route propose <key> --file <nodes.json> | sleds route approve <key> | sleds route redraft <key> | sleds route single <key> | sleds route decisions [<key>] [--flagged] | sleds route decision <key> <id> --seen | --answer --stdin [--route accept|keep|redraft] | --keep-route | --apply [--answer --stdin] | --overrule --stdin | --ready | sleds route run <key> [--at-once <n>] [--runner tmux|headless|command|orca|cmux] [--runner-cmd '<launcher>'] [--agent '<command>'] [--interval <s>] [--lease <min>] [--idle <min>] [--repo <path>] [--repos-dir <dir>] [--mode <permission-mode>] [--model <id>] [--branch '<template>'] [--pr-title '<template>'] [--once]";
|
|
@@ -21661,7 +22049,7 @@ async function answerCmd(o, argv) {
|
|
|
21661
22049
|
const words = argv.filter((a) => a !== "--json" && a !== "--stdin");
|
|
21662
22050
|
const ref = words[0] ?? "";
|
|
21663
22051
|
const slash = ref.lastIndexOf("/");
|
|
21664
|
-
const answer = (fromStdin ? (o.stdin ?? (() =>
|
|
22052
|
+
const answer = (fromStdin ? (o.stdin ?? (() => readFileSync26(0, "utf8")))() : words.slice(1).join(" ")).trim();
|
|
21665
22053
|
if (slash <= 0 || slash === ref.length - 1 || fromStdin && words.length > 1) {
|
|
21666
22054
|
error(ANSWER_USAGE);
|
|
21667
22055
|
return 2;
|
|
@@ -21858,7 +22246,7 @@ async function decisionCmd(o, argv) {
|
|
|
21858
22246
|
error(DECISION_USAGE);
|
|
21859
22247
|
return 2;
|
|
21860
22248
|
}
|
|
21861
|
-
const md = seen || routeAlone ? "" : (fromStdin ? (o.stdin ?? (() =>
|
|
22249
|
+
const md = seen || routeAlone ? "" : (fromStdin ? (o.stdin ?? (() => readFileSync26(0, "utf8")))() : rest.join(" ")).trim();
|
|
21862
22250
|
if (!seen && !routeAlone && (!md || fromStdin && rest.length > 0)) {
|
|
21863
22251
|
error(md ? DECISION_USAGE : `${answer ? "an answer" : "an overrule"} needs some text`);
|
|
21864
22252
|
return 2;
|
|
@@ -21999,7 +22387,7 @@ function approvedLine(key, j) {
|
|
|
21999
22387
|
function readNodes(o, a) {
|
|
22000
22388
|
let text;
|
|
22001
22389
|
try {
|
|
22002
|
-
text = a.file ? (o.readFile ?? ((p) =>
|
|
22390
|
+
text = a.file ? (o.readFile ?? ((p) => readFileSync26(p, "utf8")))(a.file) : (o.stdin ?? (() => readFileSync26(0, "utf8")))();
|
|
22003
22391
|
} catch (e) {
|
|
22004
22392
|
return { error: e instanceof Error ? e.message : String(e) };
|
|
22005
22393
|
}
|
|
@@ -22273,11 +22661,11 @@ var run = async (o) => {
|
|
|
22273
22661
|
init_config();
|
|
22274
22662
|
init_meter();
|
|
22275
22663
|
var HOOK_STDIN_TIMEOUT_MS2 = 1000;
|
|
22276
|
-
var
|
|
22277
|
-
var
|
|
22664
|
+
var isObject14 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
22665
|
+
var notificationType2 = (text) => {
|
|
22278
22666
|
try {
|
|
22279
22667
|
const raw = JSON.parse(text);
|
|
22280
|
-
if (!
|
|
22668
|
+
if (!isObject14(raw))
|
|
22281
22669
|
return;
|
|
22282
22670
|
return typeof raw.notification_type === "string" ? raw.notification_type : undefined;
|
|
22283
22671
|
} catch {
|
|
@@ -22288,7 +22676,7 @@ var seatEvent = async (o) => {
|
|
|
22288
22676
|
const log = o.log ?? console.log;
|
|
22289
22677
|
const now = (o.now ?? Date.now)();
|
|
22290
22678
|
const input = o.stdin ?? await readStdin(HOOK_STDIN_TIMEOUT_MS2);
|
|
22291
|
-
const kind =
|
|
22679
|
+
const kind = notificationType2(input);
|
|
22292
22680
|
try {
|
|
22293
22681
|
const key = seatKeyFor(o.home, process.env);
|
|
22294
22682
|
const state = readSeatState(o.home, key);
|
|
@@ -22310,12 +22698,12 @@ var seatEvent = async (o) => {
|
|
|
22310
22698
|
|
|
22311
22699
|
// src/commands/seatSync.ts
|
|
22312
22700
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
22313
|
-
import { existsSync as existsSync25, mkdirSync as
|
|
22701
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync22, readFileSync as readFileSync27, readdirSync as readdirSync5, rmSync as rmSync16, writeFileSync as writeFileSync25 } from "node:fs";
|
|
22314
22702
|
import { platform as platform2 } from "node:os";
|
|
22315
|
-
import { dirname as
|
|
22703
|
+
import { dirname as dirname17, join as join25 } from "node:path";
|
|
22316
22704
|
|
|
22317
22705
|
// src/cookieDb.ts
|
|
22318
|
-
import { copyFileSync, rmSync as
|
|
22706
|
+
import { copyFileSync, rmSync as rmSync15 } from "node:fs";
|
|
22319
22707
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
22320
22708
|
import { join as join24 } from "node:path";
|
|
22321
22709
|
var QUERY = "SELECT name, hex(encrypted_value) AS ev FROM cookies WHERE host_key LIKE '%claude.ai%'";
|
|
@@ -22353,7 +22741,7 @@ async function readCookieRows(dbPath) {
|
|
|
22353
22741
|
return rows.map((r) => ({ name: r.name, encrypted_value: Buffer.from(r.ev, "hex") }));
|
|
22354
22742
|
} finally {
|
|
22355
22743
|
try {
|
|
22356
|
-
|
|
22744
|
+
rmSync15(copy, { force: true });
|
|
22357
22745
|
} catch {}
|
|
22358
22746
|
}
|
|
22359
22747
|
}
|
|
@@ -22438,8 +22826,8 @@ function resolveProfileDir(localStateJson, profile) {
|
|
|
22438
22826
|
if (localStateJson) {
|
|
22439
22827
|
try {
|
|
22440
22828
|
const raw = JSON.parse(localStateJson);
|
|
22441
|
-
const p =
|
|
22442
|
-
if (p &&
|
|
22829
|
+
const p = isObject15(raw) && isObject15(raw.profile) ? raw.profile : null;
|
|
22830
|
+
if (p && isObject15(p.info_cache))
|
|
22443
22831
|
cache = p.info_cache;
|
|
22444
22832
|
} catch {}
|
|
22445
22833
|
}
|
|
@@ -22448,7 +22836,7 @@ function resolveProfileDir(localStateJson, profile) {
|
|
|
22448
22836
|
const want = profile.toLowerCase();
|
|
22449
22837
|
const hits = [];
|
|
22450
22838
|
for (const [dir, info] of Object.entries(cache)) {
|
|
22451
|
-
if (!
|
|
22839
|
+
if (!isObject15(info))
|
|
22452
22840
|
continue;
|
|
22453
22841
|
const match = ["name", "user_name", "gaia_name"].some((k) => {
|
|
22454
22842
|
const v = info[k];
|
|
@@ -22487,15 +22875,15 @@ function sourceArgs(source) {
|
|
|
22487
22875
|
function seatTokenPath(home, source) {
|
|
22488
22876
|
return `${home}/.config/sleds/${launchLabel(source).slice("ai.sleds.".length)}.token`;
|
|
22489
22877
|
}
|
|
22490
|
-
var
|
|
22878
|
+
var isObject15 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
22491
22879
|
var num7 = (v) => typeof v === "number" && Number.isFinite(v) ? v : undefined;
|
|
22492
22880
|
var round22 = (n) => Math.round(n * 100) / 100;
|
|
22493
22881
|
function parseUsageResponse(raw, now = Date.now()) {
|
|
22494
|
-
if (!
|
|
22882
|
+
if (!isObject15(raw))
|
|
22495
22883
|
return null;
|
|
22496
22884
|
const out = { capturedAt: now, models: {} };
|
|
22497
22885
|
for (const [k, v] of Object.entries(raw)) {
|
|
22498
|
-
if (!
|
|
22886
|
+
if (!isObject15(v))
|
|
22499
22887
|
continue;
|
|
22500
22888
|
if (k === "extra_usage") {
|
|
22501
22889
|
const credits = num7(v.used_credits);
|
|
@@ -22660,7 +23048,7 @@ function findCookieDb(home, source) {
|
|
|
22660
23048
|
return db;
|
|
22661
23049
|
}
|
|
22662
23050
|
const localStatePath = join25(root, "Local State");
|
|
22663
|
-
const localState = existsSync25(localStatePath) ?
|
|
23051
|
+
const localState = existsSync25(localStatePath) ? readFileSync27(localStatePath, "utf8") : null;
|
|
22664
23052
|
const wanted = source.profile ?? "Default";
|
|
22665
23053
|
const { dir, ambiguous } = resolveProfileDir(localState, wanted);
|
|
22666
23054
|
if (ambiguous)
|
|
@@ -22743,16 +23131,16 @@ function install(home, argv, source, log) {
|
|
|
22743
23131
|
return 1;
|
|
22744
23132
|
}
|
|
22745
23133
|
const dir = join25(home, "Library", "LaunchAgents");
|
|
22746
|
-
|
|
23134
|
+
mkdirSync22(dir, { recursive: true });
|
|
22747
23135
|
const path = plistPath2(home, source);
|
|
22748
23136
|
const tokenPath = seatTokenPath(home, source);
|
|
22749
|
-
|
|
23137
|
+
rmSync16(tokenPath, { force: true });
|
|
22750
23138
|
if (source.token) {
|
|
22751
|
-
|
|
22752
|
-
|
|
23139
|
+
mkdirSync22(dirname17(tokenPath), { recursive: true, mode: 448 });
|
|
23140
|
+
writeFileSync25(tokenPath, `${source.token}
|
|
22753
23141
|
`, { mode: 384 });
|
|
22754
23142
|
}
|
|
22755
|
-
|
|
23143
|
+
writeFileSync25(path, launchAgentPlist(bun, script, home, source), { mode: 384 });
|
|
22756
23144
|
try {
|
|
22757
23145
|
execFileSync4("launchctl", ["unload", path], { stdio: "ignore" });
|
|
22758
23146
|
} catch {}
|
|
@@ -22765,7 +23153,7 @@ function uninstall(home, source, log) {
|
|
|
22765
23153
|
try {
|
|
22766
23154
|
execFileSync4("launchctl", ["unload", "-w", path], { stdio: "ignore" });
|
|
22767
23155
|
} catch {}
|
|
22768
|
-
|
|
23156
|
+
rmSync16(seatTokenPath(home, source), { force: true });
|
|
22769
23157
|
log(existsSync25(path) ? `seat-sync timer removed (${path} can be deleted)` : "no seat-sync timer");
|
|
22770
23158
|
return 0;
|
|
22771
23159
|
}
|
|
@@ -22840,7 +23228,7 @@ var seatSync = async (o) => {
|
|
|
22840
23228
|
};
|
|
22841
23229
|
function readSeatToken(home, source) {
|
|
22842
23230
|
try {
|
|
22843
|
-
return
|
|
23231
|
+
return readFileSync27(seatTokenPath(home, source), "utf8").trim() || undefined;
|
|
22844
23232
|
} catch {
|
|
22845
23233
|
return;
|
|
22846
23234
|
}
|
|
@@ -22923,7 +23311,7 @@ var sessionEvent = async (o) => {
|
|
|
22923
23311
|
|
|
22924
23312
|
// src/commands/specEvent.ts
|
|
22925
23313
|
init_meter();
|
|
22926
|
-
import { readFileSync as
|
|
23314
|
+
import { readFileSync as readFileSync28, statSync as statSync2 } from "node:fs";
|
|
22927
23315
|
import { basename as basename6, isAbsolute as isAbsolute4, relative } from "node:path";
|
|
22928
23316
|
var HOOK_STDIN_TIMEOUT_MS3 = 1000;
|
|
22929
23317
|
var ESTIMATE_TIMEOUT_MS = 4000;
|
|
@@ -22979,7 +23367,7 @@ function readFileOrNull(path) {
|
|
|
22979
23367
|
try {
|
|
22980
23368
|
if (statSync2(path).size > 2000000)
|
|
22981
23369
|
return null;
|
|
22982
|
-
return
|
|
23370
|
+
return readFileSync28(path, "utf8");
|
|
22983
23371
|
} catch {
|
|
22984
23372
|
return null;
|
|
22985
23373
|
}
|
|
@@ -23308,10 +23696,10 @@ var announce = (o, events) => {
|
|
|
23308
23696
|
|
|
23309
23697
|
// src/commands/stopEvent.ts
|
|
23310
23698
|
init_meter();
|
|
23311
|
-
import { existsSync as existsSync27, readFileSync as
|
|
23699
|
+
import { existsSync as existsSync27, readFileSync as readFileSync29 } from "node:fs";
|
|
23312
23700
|
|
|
23313
23701
|
// src/transcript.ts
|
|
23314
|
-
var
|
|
23702
|
+
var isObject16 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
23315
23703
|
var n = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
23316
23704
|
function sumTranscript(text) {
|
|
23317
23705
|
const seen = new Set;
|
|
@@ -23332,7 +23720,7 @@ function sumTranscript(text) {
|
|
|
23332
23720
|
} catch {
|
|
23333
23721
|
continue;
|
|
23334
23722
|
}
|
|
23335
|
-
if (!
|
|
23723
|
+
if (!isObject16(j) || j.type !== "assistant" || !isObject16(j.message))
|
|
23336
23724
|
continue;
|
|
23337
23725
|
const m = j.message;
|
|
23338
23726
|
const id = typeof m.id === "string" ? m.id : typeof j.uuid === "string" ? j.uuid : undefined;
|
|
@@ -23341,7 +23729,7 @@ function sumTranscript(text) {
|
|
|
23341
23729
|
continue;
|
|
23342
23730
|
seen.add(id);
|
|
23343
23731
|
}
|
|
23344
|
-
const u =
|
|
23732
|
+
const u = isObject16(m.usage) ? m.usage : undefined;
|
|
23345
23733
|
if (!u)
|
|
23346
23734
|
continue;
|
|
23347
23735
|
const input = n(u.input_tokens);
|
|
@@ -23404,7 +23792,7 @@ async function postTranscript(o, payload, now) {
|
|
|
23404
23792
|
const src = meterSource(o.home);
|
|
23405
23793
|
if (!src)
|
|
23406
23794
|
return false;
|
|
23407
|
-
const read = o.readFile ?? ((p) => existsSync27(p) ?
|
|
23795
|
+
const read = o.readFile ?? ((p) => existsSync27(p) ? readFileSync29(p, "utf8") : null);
|
|
23408
23796
|
let text;
|
|
23409
23797
|
try {
|
|
23410
23798
|
text = read(path);
|
|
@@ -23482,7 +23870,7 @@ var stopEvent = async (o) => {
|
|
|
23482
23870
|
|
|
23483
23871
|
// src/commands/uninstall.ts
|
|
23484
23872
|
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
23485
|
-
import { existsSync as existsSync28, rmSync as
|
|
23873
|
+
import { existsSync as existsSync28, rmSync as rmSync17 } from "node:fs";
|
|
23486
23874
|
init_config();
|
|
23487
23875
|
init_meter();
|
|
23488
23876
|
init_settings();
|
|
@@ -23543,19 +23931,19 @@ var uninstall2 = (o) => {
|
|
|
23543
23931
|
}
|
|
23544
23932
|
for (const file of [meterCachePath(o.home), ...allSeatStatePaths(o.home)]) {
|
|
23545
23933
|
if (existsSync28(file)) {
|
|
23546
|
-
|
|
23934
|
+
rmSync17(file, { force: true });
|
|
23547
23935
|
removed.push(file);
|
|
23548
23936
|
}
|
|
23549
23937
|
}
|
|
23550
23938
|
const skill = skillDir(o.home);
|
|
23551
23939
|
if (existsSync28(skill)) {
|
|
23552
|
-
|
|
23940
|
+
rmSync17(skill, { recursive: true, force: true });
|
|
23553
23941
|
removed.push(skill);
|
|
23554
23942
|
}
|
|
23555
23943
|
const plist = musherPlistPath(o.home);
|
|
23556
23944
|
if (existsSync28(plist)) {
|
|
23557
23945
|
(o.unloadAgent ?? defaultUnload)(plist);
|
|
23558
|
-
|
|
23946
|
+
rmSync17(plist, { force: true });
|
|
23559
23947
|
removed.push(`launchd agent ${musherLabel()}`);
|
|
23560
23948
|
}
|
|
23561
23949
|
if (removed.length === 0) {
|
|
@@ -23708,17 +24096,17 @@ var webhooksCmd = async (o) => {
|
|
|
23708
24096
|
|
|
23709
24097
|
// src/config.ts
|
|
23710
24098
|
init_settings();
|
|
23711
|
-
import { chmodSync as
|
|
24099
|
+
import { chmodSync as chmodSync7, existsSync as existsSync29, mkdirSync as mkdirSync23, readFileSync as readFileSync30, renameSync as renameSync9, writeFileSync as writeFileSync26 } from "node:fs";
|
|
23712
24100
|
import { join as join26, resolve as resolve10 } from "node:path";
|
|
23713
24101
|
var configDir2 = (home, env = process.env) => {
|
|
23714
24102
|
const o = env.SLEDS_HOME?.trim();
|
|
23715
24103
|
return o ? resolve10(home, o) : join26(home, ".config", "sleds");
|
|
23716
24104
|
};
|
|
23717
24105
|
var configPath2 = (home) => join26(configDir2(home), "config.json");
|
|
23718
|
-
var
|
|
24106
|
+
var isObject17 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
23719
24107
|
var optString2 = (v) => typeof v === "string" ? v : undefined;
|
|
23720
24108
|
var parsePriorEnv2 = (v) => {
|
|
23721
|
-
if (!
|
|
24109
|
+
if (!isObject17(v))
|
|
23722
24110
|
return;
|
|
23723
24111
|
const out = {};
|
|
23724
24112
|
const url = optString2(v[BASE_URL_KEY]);
|
|
@@ -23733,7 +24121,7 @@ var parsePriorEnv2 = (v) => {
|
|
|
23733
24121
|
};
|
|
23734
24122
|
var parseSchedule2 = (v) => v === "launchd" || v === "systemd" || v === "manual" ? v : undefined;
|
|
23735
24123
|
var parseConfig2 = (raw) => {
|
|
23736
|
-
if (!
|
|
24124
|
+
if (!isObject17(raw))
|
|
23737
24125
|
return {};
|
|
23738
24126
|
const cfg = {};
|
|
23739
24127
|
const token = optString2(raw.token);
|
|
@@ -23783,11 +24171,11 @@ var parseConfig2 = (raw) => {
|
|
|
23783
24171
|
return cfg;
|
|
23784
24172
|
};
|
|
23785
24173
|
var parseOrgs2 = (raw) => {
|
|
23786
|
-
if (!
|
|
24174
|
+
if (!isObject17(raw))
|
|
23787
24175
|
return;
|
|
23788
24176
|
const out = {};
|
|
23789
24177
|
for (const [slug, v] of Object.entries(raw)) {
|
|
23790
|
-
if (!
|
|
24178
|
+
if (!isObject17(v))
|
|
23791
24179
|
continue;
|
|
23792
24180
|
const token = optString2(v.token);
|
|
23793
24181
|
if (!token)
|
|
@@ -23806,7 +24194,7 @@ var parseOrgs2 = (raw) => {
|
|
|
23806
24194
|
return Object.keys(out).length > 0 ? out : undefined;
|
|
23807
24195
|
};
|
|
23808
24196
|
var parseMusher2 = (raw) => {
|
|
23809
|
-
if (!
|
|
24197
|
+
if (!isObject17(raw))
|
|
23810
24198
|
return;
|
|
23811
24199
|
const out = {};
|
|
23812
24200
|
const pm = optString2(raw.permissionMode);
|
|
@@ -23822,7 +24210,7 @@ var parseMusher2 = (raw) => {
|
|
|
23822
24210
|
return out;
|
|
23823
24211
|
};
|
|
23824
24212
|
var parseOrgInfo2 = (raw) => {
|
|
23825
|
-
if (!
|
|
24213
|
+
if (!isObject17(raw) || !isObject17(raw.capabilities))
|
|
23826
24214
|
return;
|
|
23827
24215
|
const name = optString2(raw.name);
|
|
23828
24216
|
const slug = optString2(raw.slug);
|
|
@@ -23848,7 +24236,7 @@ var readConfig2 = (home) => {
|
|
|
23848
24236
|
const p = configPath2(home);
|
|
23849
24237
|
if (!existsSync29(p))
|
|
23850
24238
|
return {};
|
|
23851
|
-
return parseConfig2(JSON.parse(
|
|
24239
|
+
return parseConfig2(JSON.parse(readFileSync30(p, "utf8")));
|
|
23852
24240
|
};
|
|
23853
24241
|
|
|
23854
24242
|
// src/runners/exec.ts
|
|
@@ -23900,7 +24288,7 @@ var defaultExec5 = (cmd, args) => {
|
|
|
23900
24288
|
};
|
|
23901
24289
|
|
|
23902
24290
|
// src/settings.ts
|
|
23903
|
-
import { dirname as
|
|
24291
|
+
import { dirname as dirname18, join as join27, resolve as resolve11 } from "node:path";
|
|
23904
24292
|
var withSeatEnv2 = (command, home, env = process.env, org) => {
|
|
23905
24293
|
const parts = [];
|
|
23906
24294
|
const sh = env.SLEDS_HOME?.trim();
|
|
@@ -23923,15 +24311,16 @@ var pinOrg4 = (command, org) => {
|
|
|
23923
24311
|
return `${lead}SLEDS_ORG=${shellWord2(slug)} ${bare.slice(lead.length)}`;
|
|
23924
24312
|
};
|
|
23925
24313
|
var shellWord2 = (v) => /^[\w./~-]+$/.test(v) ? v : `'${v.replace(/'/g, "'\\''")}'`;
|
|
23926
|
-
var
|
|
24314
|
+
var isObject18 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
23927
24315
|
var isSledsHookFor2 = (sub) => (entry) => {
|
|
23928
|
-
if (!
|
|
24316
|
+
if (!isObject18(entry) || !Array.isArray(entry.hooks))
|
|
23929
24317
|
return false;
|
|
23930
24318
|
const re = new RegExp(`\\b${sub}\\b`);
|
|
23931
|
-
return entry.hooks.some((h) =>
|
|
24319
|
+
return entry.hooks.some((h) => isObject18(h) && h.type === "command" && typeof h.command === "string" && re.test(h.command));
|
|
23932
24320
|
};
|
|
23933
24321
|
var isSledsSessionHook2 = isSledsHookFor2("session-event");
|
|
23934
24322
|
var isSledsStopHook2 = isSledsHookFor2("stop-event");
|
|
24323
|
+
var isSledsPermissionHook2 = isSledsHookFor2("permission-event");
|
|
23935
24324
|
|
|
23936
24325
|
// src/index.ts
|
|
23937
24326
|
var USAGE3 = `usage: sleds <command> [options]
|
|
@@ -24081,6 +24470,8 @@ commands:
|
|
|
24081
24470
|
statusline Print the one-line meter Claude Code shows (installed by init; 10s cache).
|
|
24082
24471
|
hooks Register the Claude Code Notification hook for seat limits (init does this too).
|
|
24083
24472
|
seat-event Claude Code hook: record a seat wall and say how to continue. Reads hook JSON on stdin.
|
|
24473
|
+
permission-event --mark <file> Claude Code Notification hook the engine gives its sessions: on
|
|
24474
|
+
a permission dialog, write {message, at} to <file> for the engine. Local; exits 0.
|
|
24084
24475
|
session-event Claude Code SessionStart hook: states the loop and the rows this machine still
|
|
24085
24476
|
owes before the first turn. Reads hook JSON on stdin.
|
|
24086
24477
|
stop-event Claude Code Stop hook: a session that estimated a row and posted no actual is asked
|
|
@@ -24225,7 +24616,8 @@ var main = async (argv) => {
|
|
|
24225
24616
|
exec: defaultExec4,
|
|
24226
24617
|
runnerFor: runnerFor3,
|
|
24227
24618
|
sleep: (ms) => new Promise((r) => setTimeout(r, ms)),
|
|
24228
|
-
shouldStop: () => stopping
|
|
24619
|
+
shouldStop: () => stopping,
|
|
24620
|
+
sledsArgv: sledsArgv()
|
|
24229
24621
|
};
|
|
24230
24622
|
return cmd === "engine" ? engineCmd(io) : routeCmd(io);
|
|
24231
24623
|
}
|
|
@@ -24332,6 +24724,8 @@ var main = async (argv) => {
|
|
|
24332
24724
|
});
|
|
24333
24725
|
case "seat-event":
|
|
24334
24726
|
return seatEvent({ home });
|
|
24727
|
+
case "permission-event":
|
|
24728
|
+
return permissionEvent({ mark: stringFlag(flags, "mark") });
|
|
24335
24729
|
case "spec-event":
|
|
24336
24730
|
return specEvent({ home });
|
|
24337
24731
|
case "prompt-event":
|
|
@@ -24389,7 +24783,7 @@ ${renderHelpText(argv[1])}`);
|
|
|
24389
24783
|
case "version":
|
|
24390
24784
|
case "--version":
|
|
24391
24785
|
case "-v":
|
|
24392
|
-
console.log("sleds 0.1.
|
|
24786
|
+
console.log("sleds 0.1.40");
|
|
24393
24787
|
return 0;
|
|
24394
24788
|
default:
|
|
24395
24789
|
console.error(`unknown command: ${cmd}
|