@sleds/cli 0.1.38 → 0.1.39
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 +565 -191
- 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 ?? "") => {
|
|
@@ -10277,6 +10325,13 @@ function cmuxRunner(exec, deps = {}) {
|
|
|
10277
10325
|
return;
|
|
10278
10326
|
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
10327
|
},
|
|
10328
|
+
sendKey(h, key) {
|
|
10329
|
+
if (!isRunnerKey(key))
|
|
10330
|
+
throw new Error(`cmux send-key ${h.id}: no key ${JSON.stringify(key)}`);
|
|
10331
|
+
const r = cmux(["send-key", "--workspace", h.id, key === "esc" ? "escape" : key]);
|
|
10332
|
+
if (r.status !== 0)
|
|
10333
|
+
throw new Error(`cmux send-key ${h.id} failed: ${failed(r)}`);
|
|
10334
|
+
},
|
|
10280
10335
|
stop(h) {
|
|
10281
10336
|
cmux(["close-workspace", "--workspace", h.id]);
|
|
10282
10337
|
if (!h.group)
|
|
@@ -10327,12 +10382,12 @@ init_server();
|
|
|
10327
10382
|
init_config();
|
|
10328
10383
|
import {
|
|
10329
10384
|
appendFileSync as appendFileSync2,
|
|
10330
|
-
chmodSync as
|
|
10331
|
-
mkdirSync as
|
|
10332
|
-
readFileSync as
|
|
10385
|
+
chmodSync as chmodSync4,
|
|
10386
|
+
mkdirSync as mkdirSync12,
|
|
10387
|
+
readFileSync as readFileSync13,
|
|
10333
10388
|
existsSync as realExists,
|
|
10334
|
-
rmSync as
|
|
10335
|
-
writeFileSync as
|
|
10389
|
+
rmSync as rmSync4,
|
|
10390
|
+
writeFileSync as writeFileSync13
|
|
10336
10391
|
} from "node:fs";
|
|
10337
10392
|
import { hostname as hostname2 } from "node:os";
|
|
10338
10393
|
import { join as join15, resolve as resolve7 } from "node:path";
|
|
@@ -10347,7 +10402,7 @@ function beatBody(state, flags, host = {}, cap = {}) {
|
|
|
10347
10402
|
name: flags.name,
|
|
10348
10403
|
os: host.os ?? process.platform,
|
|
10349
10404
|
runner: flags.runner,
|
|
10350
|
-
version: host.version ?? "0.1.
|
|
10405
|
+
version: host.version ?? "0.1.39" ?? "dev",
|
|
10351
10406
|
running: live.length,
|
|
10352
10407
|
items: live.slice(0, BEAT_ITEMS).map((r) => `${r.item}/${r.node}`),
|
|
10353
10408
|
...cap.atOnce !== undefined ? { atOnce: cap.atOnce } : {},
|
|
@@ -11092,13 +11147,40 @@ function jiraFromEnv(epic, env = process.env) {
|
|
|
11092
11147
|
// src/engine/loop.ts
|
|
11093
11148
|
init_src();
|
|
11094
11149
|
|
|
11095
|
-
// src/
|
|
11096
|
-
|
|
11097
|
-
|
|
11098
|
-
|
|
11099
|
-
|
|
11100
|
-
|
|
11101
|
-
|
|
11150
|
+
// src/commands/permissionEvent.ts
|
|
11151
|
+
import { chmodSync as chmodSync3, mkdirSync as mkdirSync10, readFileSync as readFileSync10, renameSync as renameSync6, rmSync as rmSync3, writeFileSync as writeFileSync11 } from "node:fs";
|
|
11152
|
+
|
|
11153
|
+
// src/commands/seatEvent.ts
|
|
11154
|
+
init_config();
|
|
11155
|
+
init_meter();
|
|
11156
|
+
var HOOK_STDIN_TIMEOUT_MS = 1000;
|
|
11157
|
+
var isObject11 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
11158
|
+
var notificationType = (text) => {
|
|
11159
|
+
try {
|
|
11160
|
+
const raw = JSON.parse(text);
|
|
11161
|
+
if (!isObject11(raw))
|
|
11162
|
+
return;
|
|
11163
|
+
return typeof raw.notification_type === "string" ? raw.notification_type : undefined;
|
|
11164
|
+
} catch {
|
|
11165
|
+
return;
|
|
11166
|
+
}
|
|
11167
|
+
};
|
|
11168
|
+
|
|
11169
|
+
// src/commands/permissionEvent.ts
|
|
11170
|
+
var isObject12 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
11171
|
+
var readPermissionMark = (file) => {
|
|
11172
|
+
try {
|
|
11173
|
+
const raw = JSON.parse(readFileSync10(file, "utf8"));
|
|
11174
|
+
if (!isObject12(raw) || typeof raw.at !== "number")
|
|
11175
|
+
return null;
|
|
11176
|
+
return { message: typeof raw.message === "string" ? raw.message : "", at: raw.at };
|
|
11177
|
+
} catch {
|
|
11178
|
+
return null;
|
|
11179
|
+
}
|
|
11180
|
+
};
|
|
11181
|
+
var clearPermissionMark = (file) => {
|
|
11182
|
+
rmSync3(file, { force: true });
|
|
11183
|
+
};
|
|
11102
11184
|
|
|
11103
11185
|
// src/engine/answerer.ts
|
|
11104
11186
|
init_src();
|
|
@@ -11250,6 +11332,10 @@ function looksOf(s) {
|
|
|
11250
11332
|
const l = s;
|
|
11251
11333
|
return l && typeof l.openLook === "function" && typeof l.clearLook === "function" ? s : null;
|
|
11252
11334
|
}
|
|
11335
|
+
function permissionsOf(s) {
|
|
11336
|
+
const p = s;
|
|
11337
|
+
return p && typeof p.openPermission === "function" && typeof p.clearPermission === "function" && typeof p.decisionOf === "function" ? s : null;
|
|
11338
|
+
}
|
|
11253
11339
|
var FAIL_LOG_MAX = 2000;
|
|
11254
11340
|
var UNREACHABLE2 = "SLEDS unreachable";
|
|
11255
11341
|
function keysIn(states, state) {
|
|
@@ -11808,6 +11894,27 @@ function sledsSource(client, o) {
|
|
|
11808
11894
|
throw new Error(serverMessage(r));
|
|
11809
11895
|
return r.json.cleared === true;
|
|
11810
11896
|
},
|
|
11897
|
+
async openPermission(runId, p, engine) {
|
|
11898
|
+
const r = await client.postFull("/proxy/run", {
|
|
11899
|
+
runId,
|
|
11900
|
+
engine,
|
|
11901
|
+
event: { kind: "permission", md: p.md, about: { options: p.options } }
|
|
11902
|
+
});
|
|
11903
|
+
if (!r)
|
|
11904
|
+
throw new Error(`${UNREACHABLE2} — the permission not raised`);
|
|
11905
|
+
if (r.status >= 300 || !r.json || r.json.ok === false)
|
|
11906
|
+
throw new Error(serverMessage(r));
|
|
11907
|
+
const decisionId = str6(r.json.decisionId);
|
|
11908
|
+
return { opened: r.json.opened === true, ...decisionId ? { decisionId } : {} };
|
|
11909
|
+
},
|
|
11910
|
+
async clearPermission(runId, why, engine) {
|
|
11911
|
+
const r = await client.postFull("/proxy/run", { runId, engine, clearPermission: { why } });
|
|
11912
|
+
if (!r)
|
|
11913
|
+
throw new Error(`${UNREACHABLE2} — the permission not cleared`);
|
|
11914
|
+
if (r.status >= 300 || !r.json || r.json.ok === false)
|
|
11915
|
+
throw new Error(serverMessage(r));
|
|
11916
|
+
return r.json.cleared === true;
|
|
11917
|
+
},
|
|
11811
11918
|
async decisionOf(item, decisionId) {
|
|
11812
11919
|
const route = await routeOf(item);
|
|
11813
11920
|
const decisions = Array.isArray(route?.decisions) ? route.decisions.filter(isObject8) : [];
|
|
@@ -11939,6 +12046,63 @@ function askedAndStopped(screen) {
|
|
|
11939
12046
|
const last = (paras[paras.length - 1] ?? "").replace(/\s*\n\s*/g, " ");
|
|
11940
12047
|
return ASKS.test(last) || CONFIRMS.test(last);
|
|
11941
12048
|
}
|
|
12049
|
+
var DIALOG_ASKS = /^Do you want to .+\?$/;
|
|
12050
|
+
var DIALOG_OPTION = /^(❯\s*)?(\d)\.\s+(.+)$/;
|
|
12051
|
+
var DIALOG_FOOTER = /^(?:esc to |tab to |enter to |ctrl\+)/i;
|
|
12052
|
+
var unbox = (line) => line.trimEnd().replace(/^\s*[│┃║]\s?/, "").replace(/\s*[│┃║]$/, "");
|
|
12053
|
+
function permissionDialog(screen) {
|
|
12054
|
+
const raw = screen.split(`
|
|
12055
|
+
`);
|
|
12056
|
+
const lines = raw.map(unbox);
|
|
12057
|
+
let q = -1;
|
|
12058
|
+
for (let i = lines.length - 1;i >= 0; i--)
|
|
12059
|
+
if (DIALOG_ASKS.test(lines[i].trim())) {
|
|
12060
|
+
q = i;
|
|
12061
|
+
break;
|
|
12062
|
+
}
|
|
12063
|
+
if (q < 0)
|
|
12064
|
+
return null;
|
|
12065
|
+
const options = [];
|
|
12066
|
+
let cursors = 0;
|
|
12067
|
+
let i = q + 1;
|
|
12068
|
+
for (;i < lines.length; i++) {
|
|
12069
|
+
const t = lines[i].trim();
|
|
12070
|
+
const m = DIALOG_OPTION.exec(t);
|
|
12071
|
+
if (m) {
|
|
12072
|
+
if (m[2] !== String(options.length + 1))
|
|
12073
|
+
return null;
|
|
12074
|
+
if (m[1])
|
|
12075
|
+
cursors++;
|
|
12076
|
+
options.push({ key: m[2], label: m[3].replace(/\s*\(esc\)$/i, "") });
|
|
12077
|
+
} else if (t && options.length && !isRule(raw[i]) && !isPrompt(t) && !isFooter(t) && !DIALOG_FOOTER.test(t)) {
|
|
12078
|
+
const last = options[options.length - 1];
|
|
12079
|
+
last.label = `${last.label} ${t.replace(/\s*\(esc\)$/i, "")}`;
|
|
12080
|
+
} else
|
|
12081
|
+
break;
|
|
12082
|
+
}
|
|
12083
|
+
if (options.length < 2 || cursors !== 1)
|
|
12084
|
+
return null;
|
|
12085
|
+
for (;i < lines.length; i++) {
|
|
12086
|
+
const t = lines[i].trim();
|
|
12087
|
+
if (t && !isRule(raw[i]) && !DIALOG_FOOTER.test(t) && !isFooter(t))
|
|
12088
|
+
return null;
|
|
12089
|
+
}
|
|
12090
|
+
let from = 0;
|
|
12091
|
+
for (let j = q - 1;j >= 0; j--) {
|
|
12092
|
+
const t = lines[j].trim();
|
|
12093
|
+
if (isRule(raw[j]) || /^⏺/.test(t) || /^⎿/.test(t)) {
|
|
12094
|
+
from = j + 1;
|
|
12095
|
+
break;
|
|
12096
|
+
}
|
|
12097
|
+
}
|
|
12098
|
+
const body = lines.slice(from, q + 1);
|
|
12099
|
+
const indent = Math.min(...body.filter((l) => l.trim()).map((l) => /^\s*/.exec(l)[0].length));
|
|
12100
|
+
const text = body.map((l) => l.slice(indent)).join(`
|
|
12101
|
+
`).replace(/\n{3,}/g, `
|
|
12102
|
+
|
|
12103
|
+
`).trim();
|
|
12104
|
+
return { text, options };
|
|
12105
|
+
}
|
|
11942
12106
|
var PROVIDER_FAILURES = [
|
|
11943
12107
|
["connection lost", /\bconnection (?:lost|error)\b/i],
|
|
11944
12108
|
["credit balance too low", /\bcredit balance (?:is )?too low\b/i],
|
|
@@ -11961,7 +12125,7 @@ function providerFailure(screen) {
|
|
|
11961
12125
|
|
|
11962
12126
|
// src/engine/worktree.ts
|
|
11963
12127
|
init_src();
|
|
11964
|
-
import { appendFileSync, existsSync as existsSync12, mkdirSync as
|
|
12128
|
+
import { appendFileSync, existsSync as existsSync12, mkdirSync as mkdirSync11 } from "node:fs";
|
|
11965
12129
|
import { dirname as dirname11, isAbsolute, join as join14 } from "node:path";
|
|
11966
12130
|
function worktreePath(repoPath, name) {
|
|
11967
12131
|
return join14(repoPath, ".worktrees", name);
|
|
@@ -11987,7 +12151,7 @@ function defaultBranch(exec, repoPath) {
|
|
|
11987
12151
|
var realWorktreeFs = {
|
|
11988
12152
|
exists: existsSync12,
|
|
11989
12153
|
append: (p, text) => {
|
|
11990
|
-
|
|
12154
|
+
mkdirSync11(dirname11(p), { recursive: true });
|
|
11991
12155
|
appendFileSync(p, text);
|
|
11992
12156
|
}
|
|
11993
12157
|
};
|
|
@@ -12213,6 +12377,15 @@ function sandboxFor(d, name, cwd) {
|
|
|
12213
12377
|
throw new Error("sessions are sandboxed, but nothing writes their settings — not started");
|
|
12214
12378
|
return { sandbox: d.writeSandboxSettings(name, cwd) };
|
|
12215
12379
|
}
|
|
12380
|
+
function hooksFor(d, name) {
|
|
12381
|
+
if (d.sandbox || !d.writeHookSettings)
|
|
12382
|
+
return {};
|
|
12383
|
+
return { settingsFile: d.writeHookSettings(name) };
|
|
12384
|
+
}
|
|
12385
|
+
function mainCheckoutFor(d, cwd) {
|
|
12386
|
+
const main = d.mainCheckoutOf?.(cwd);
|
|
12387
|
+
return main ? { mainCheckout: main } : {};
|
|
12388
|
+
}
|
|
12216
12389
|
function engineMcpConfigFor(d, name, runToken, at, cwd) {
|
|
12217
12390
|
if (d.source.name !== "sleds" || d.agent?.trim() || !d.writeMcpConfig)
|
|
12218
12391
|
return;
|
|
@@ -12358,6 +12531,7 @@ async function tickOnce(d) {
|
|
|
12358
12531
|
}
|
|
12359
12532
|
continue;
|
|
12360
12533
|
} else if (pr) {
|
|
12534
|
+
await dropPermission(d, run, "the session opened its PR");
|
|
12361
12535
|
const outcome = { kind: "pr", ref: pr.url };
|
|
12362
12536
|
try {
|
|
12363
12537
|
await d.source.report(claim, outcome, d.engine);
|
|
@@ -12381,6 +12555,7 @@ async function tickOnce(d) {
|
|
|
12381
12555
|
}
|
|
12382
12556
|
}
|
|
12383
12557
|
if (status === "exited") {
|
|
12558
|
+
await dropPermission(d, run, "the session exited");
|
|
12384
12559
|
let log = "";
|
|
12385
12560
|
try {
|
|
12386
12561
|
log = runner.read(run.handle);
|
|
@@ -12430,6 +12605,11 @@ async function tickOnce(d) {
|
|
|
12430
12605
|
}
|
|
12431
12606
|
}
|
|
12432
12607
|
}
|
|
12608
|
+
if (await settlePermission(d, runner, run, shown)) {
|
|
12609
|
+
idle = false;
|
|
12610
|
+
asked = false;
|
|
12611
|
+
failing = null;
|
|
12612
|
+
}
|
|
12433
12613
|
const retry = failing !== null && (run.provider?.tries ?? 0) < PROVIDER_RETRIES;
|
|
12434
12614
|
if (idle || failing || needsHeartbeat(run.leaseUntil, d.now(), d.leaseMin)) {
|
|
12435
12615
|
let beat;
|
|
@@ -12680,6 +12860,8 @@ async function tickOnce(d) {
|
|
|
12680
12860
|
...launch.agent ? { agent: launch.agent } : {},
|
|
12681
12861
|
...mcpConfig ? { mcpConfig, ...d.strictMcp ? { strictMcp: true } : {} } : {},
|
|
12682
12862
|
...sandboxFor(d, name, worktree),
|
|
12863
|
+
...hooksFor(d, name),
|
|
12864
|
+
...mainCheckoutFor(d, worktree),
|
|
12683
12865
|
...claim.group ? { group: claim.group } : {}
|
|
12684
12866
|
};
|
|
12685
12867
|
} catch (e) {
|
|
@@ -12834,6 +13016,115 @@ function parkQuestion(screen, idleMin) {
|
|
|
12834
13016
|
function askedQuestion(screen) {
|
|
12835
13017
|
return `The session stopped and is waiting on an answer, with no PR. ${lastMessage(screen)}`;
|
|
12836
13018
|
}
|
|
13019
|
+
var MARK_OPTIONS = ["1 · Allow once", "esc · Deny"];
|
|
13020
|
+
function permissionKey(answer) {
|
|
13021
|
+
const m = /^\s*(\d|esc)\s*·/i.exec(answer);
|
|
13022
|
+
return m ? m[1].toLowerCase() : null;
|
|
13023
|
+
}
|
|
13024
|
+
async function settlePermission(d, runner, run, shown) {
|
|
13025
|
+
const perms = permissionsOf(d.source);
|
|
13026
|
+
if (!perms || !run.runId)
|
|
13027
|
+
return false;
|
|
13028
|
+
const at = ref(run);
|
|
13029
|
+
const markFile = d.permissionMark?.(sessionName(run.item, run.node));
|
|
13030
|
+
const dialog = runner.readsSession ? permissionDialog(shown) : null;
|
|
13031
|
+
const p = run.permission;
|
|
13032
|
+
if (p) {
|
|
13033
|
+
const gone = runner.readsSession && (p.onScreen ? !dialog : (run.seenAt ?? 0) > p.at);
|
|
13034
|
+
let now;
|
|
13035
|
+
try {
|
|
13036
|
+
now = await perms.decisionOf(run.item, p.decisionId);
|
|
13037
|
+
} catch (e) {
|
|
13038
|
+
d.log(`${at}: could not read the permission decision, asking next tick: ${message(e)}`);
|
|
13039
|
+
return true;
|
|
13040
|
+
}
|
|
13041
|
+
if (now?.state === "answered" && now.answer) {
|
|
13042
|
+
if (gone)
|
|
13043
|
+
d.log(`${at}: the permission was answered after its dialog closed — not pressed`);
|
|
13044
|
+
else if (!pressAnswer(d, runner, run, p.options, now.answer))
|
|
13045
|
+
return true;
|
|
13046
|
+
run.permission = undefined;
|
|
13047
|
+
run.answeredAt = d.now();
|
|
13048
|
+
if (markFile)
|
|
13049
|
+
clearPermissionMark(markFile);
|
|
13050
|
+
return true;
|
|
13051
|
+
}
|
|
13052
|
+
if (now?.state !== "open" && now?.state !== "escalated") {
|
|
13053
|
+
run.permission = undefined;
|
|
13054
|
+
return false;
|
|
13055
|
+
}
|
|
13056
|
+
if (!gone)
|
|
13057
|
+
return true;
|
|
13058
|
+
try {
|
|
13059
|
+
await perms.clearPermission(run.runId, "the dialog closed in the terminal", d.engine);
|
|
13060
|
+
} catch (e) {
|
|
13061
|
+
d.log(`${at}: could not clear the permission, trying next tick: ${message(e)}`);
|
|
13062
|
+
return true;
|
|
13063
|
+
}
|
|
13064
|
+
d.log(`${at}: the permission dialog closed before an answer — cleared`);
|
|
13065
|
+
run.permission = undefined;
|
|
13066
|
+
return false;
|
|
13067
|
+
}
|
|
13068
|
+
const mark = markFile ? readPermissionMark(markFile) : null;
|
|
13069
|
+
if (!dialog && !mark)
|
|
13070
|
+
return false;
|
|
13071
|
+
if (!dialog && runner.readsSession && !run.seenTicks)
|
|
13072
|
+
return false;
|
|
13073
|
+
const options = dialog ? dialog.options.map((o) => `${o.key} · ${o.label}`) : MARK_OPTIONS;
|
|
13074
|
+
const md = dialog?.text || mark?.message || "The session stopped at a permission dialog.";
|
|
13075
|
+
let opened;
|
|
13076
|
+
try {
|
|
13077
|
+
opened = await perms.openPermission(run.runId, { md, options }, d.engine);
|
|
13078
|
+
} catch (e) {
|
|
13079
|
+
d.log(`${at}: could not raise the permission dialog, trying next tick: ${message(e)}`);
|
|
13080
|
+
return true;
|
|
13081
|
+
}
|
|
13082
|
+
if (!opened.decisionId)
|
|
13083
|
+
return true;
|
|
13084
|
+
run.permission = {
|
|
13085
|
+
decisionId: opened.decisionId,
|
|
13086
|
+
options,
|
|
13087
|
+
at: d.now(),
|
|
13088
|
+
...dialog ? { onScreen: true } : {}
|
|
13089
|
+
};
|
|
13090
|
+
if (markFile)
|
|
13091
|
+
clearPermissionMark(markFile);
|
|
13092
|
+
d.log(`${at}: stopped at a permission dialog — it waits for a person (${runner.watchHint(run.handle)})`);
|
|
13093
|
+
return true;
|
|
13094
|
+
}
|
|
13095
|
+
function pressAnswer(d, runner, run, options, answer) {
|
|
13096
|
+
const at = ref(run);
|
|
13097
|
+
const key = permissionKey(answer);
|
|
13098
|
+
const offered = key !== null && options.some((o) => permissionKey(o) === key);
|
|
13099
|
+
try {
|
|
13100
|
+
if (key !== null && offered) {
|
|
13101
|
+
if (runner.sendKey)
|
|
13102
|
+
runner.sendKey(run.handle, key);
|
|
13103
|
+
else
|
|
13104
|
+
runner.send(run.handle, key);
|
|
13105
|
+
d.log(`${at}: the permission is answered — pressed ${key}; the session goes on`);
|
|
13106
|
+
} else {
|
|
13107
|
+
runner.sendKey?.(run.handle, "esc");
|
|
13108
|
+
const note = runner.send(run.handle, answer);
|
|
13109
|
+
d.log(`${at}: the permission is answered in words — Esc, then typed in${note ? ` (${note})` : ""}`);
|
|
13110
|
+
}
|
|
13111
|
+
return true;
|
|
13112
|
+
} catch (e) {
|
|
13113
|
+
d.log(`${at}: could not press the permission's answer, trying next tick: ${message(e)}`);
|
|
13114
|
+
return false;
|
|
13115
|
+
}
|
|
13116
|
+
}
|
|
13117
|
+
async function dropPermission(d, run, why) {
|
|
13118
|
+
const perms = permissionsOf(d.source);
|
|
13119
|
+
if (!run.permission || !perms || !run.runId)
|
|
13120
|
+
return;
|
|
13121
|
+
try {
|
|
13122
|
+
await perms.clearPermission(run.runId, why, d.engine);
|
|
13123
|
+
} catch (e) {
|
|
13124
|
+
d.log(`${ref(run)}: could not clear the permission (${why}): ${message(e)}`);
|
|
13125
|
+
}
|
|
13126
|
+
run.permission = undefined;
|
|
13127
|
+
}
|
|
12837
13128
|
var STILL_TICKS = 2;
|
|
12838
13129
|
function lastMessage(screen) {
|
|
12839
13130
|
const shown = stripTuiChrome(screen);
|
|
@@ -13267,6 +13558,8 @@ async function startAnswerer(d, answers, run) {
|
|
|
13267
13558
|
...launchOptions(launch),
|
|
13268
13559
|
...mcpConfig ? { mcpConfig, ...d.strictMcp ? { strictMcp: true } : {} } : {},
|
|
13269
13560
|
...sandboxFor(d, name, run.handle.cwd),
|
|
13561
|
+
...hooksFor(d, name),
|
|
13562
|
+
...mainCheckoutFor(d, run.handle.cwd),
|
|
13270
13563
|
...run.group ? { group: run.group } : {}
|
|
13271
13564
|
});
|
|
13272
13565
|
} catch (e) {
|
|
@@ -13441,7 +13734,9 @@ async function startDraft(d, claim, why, state, started, finished) {
|
|
|
13441
13734
|
permissionMode: d.permissionMode,
|
|
13442
13735
|
...launchOptions(launch),
|
|
13443
13736
|
...mcpConfig ? { mcpConfig, ...d.strictMcp ? { strictMcp: true } : {} } : {},
|
|
13444
|
-
...sandboxFor(d, name, worktree)
|
|
13737
|
+
...sandboxFor(d, name, worktree),
|
|
13738
|
+
...hooksFor(d, name),
|
|
13739
|
+
...mainCheckoutFor(d, worktree)
|
|
13445
13740
|
});
|
|
13446
13741
|
} catch (e) {
|
|
13447
13742
|
d.log(`${at}: could not start the drafter: ${message(e)}`);
|
|
@@ -14214,6 +14509,8 @@ function startResolver(d, run, e, answer) {
|
|
|
14214
14509
|
...launchOptions(launch),
|
|
14215
14510
|
...run.mcpConfig ? { mcpConfig: run.mcpConfig, ...d.strictMcp ? { strictMcp: true } : {} } : {},
|
|
14216
14511
|
...sandboxFor(d, name, run.handle.cwd),
|
|
14512
|
+
...hooksFor(d, name),
|
|
14513
|
+
...mainCheckoutFor(d, run.handle.cwd),
|
|
14217
14514
|
...run.group ? { group: run.group } : {}
|
|
14218
14515
|
});
|
|
14219
14516
|
} catch (err) {
|
|
@@ -14288,7 +14585,9 @@ async function startEventAnswerer(d, answers, state, dec, decided) {
|
|
|
14288
14585
|
permissionMode: d.permissionMode,
|
|
14289
14586
|
...launchOptions(launch),
|
|
14290
14587
|
...mcpConfig ? { mcpConfig, ...d.strictMcp ? { strictMcp: true } : {} } : {},
|
|
14291
|
-
...sandboxFor(d, name, worktree)
|
|
14588
|
+
...sandboxFor(d, name, worktree),
|
|
14589
|
+
...hooksFor(d, name),
|
|
14590
|
+
...mainCheckoutFor(d, worktree)
|
|
14292
14591
|
});
|
|
14293
14592
|
} catch (e) {
|
|
14294
14593
|
d.log(`${at}: could not start the ${KIND_SAYS[kind]} answerer — it goes to a person: ${message(e)}`);
|
|
@@ -14508,7 +14807,7 @@ function commandRunner(template, deps = {}) {
|
|
|
14508
14807
|
}
|
|
14509
14808
|
|
|
14510
14809
|
// src/runners/conductor.ts
|
|
14511
|
-
import { readFileSync as
|
|
14810
|
+
import { readFileSync as readFileSync11 } from "node:fs";
|
|
14512
14811
|
var obj = (v) => v !== null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
14513
14812
|
var str8 = (v) => typeof v === "string" && v.length > 0 ? v : null;
|
|
14514
14813
|
var CONDUCTOR_API = "https://api.conductor.build";
|
|
@@ -14606,7 +14905,7 @@ var ids = (h) => {
|
|
|
14606
14905
|
var ENDED = new Set(["archived", "deleted"]);
|
|
14607
14906
|
function conductorRunner(exec, deps = {}) {
|
|
14608
14907
|
const env = deps.env ?? process.env;
|
|
14609
|
-
const readFile = deps.readFile ?? ((p) =>
|
|
14908
|
+
const readFile = deps.readFile ?? ((p) => readFileSync11(p, "utf8"));
|
|
14610
14909
|
const now = deps.now ?? Date.now;
|
|
14611
14910
|
const base = env.CONDUCTOR_API_URL?.trim() || CONDUCTOR_API;
|
|
14612
14911
|
const key = () => {
|
|
@@ -14725,8 +15024,8 @@ ${renderTranscript(messages)}`;
|
|
|
14725
15024
|
var headlessScript = (o, log) => {
|
|
14726
15025
|
const prompt = `"$(cat ${shq2(o.promptFile)})"`;
|
|
14727
15026
|
const agent = o.agent?.trim();
|
|
14728
|
-
const cmd = agent ? `${sandboxedAgent(agent, o.sandbox)} ${prompt}` : [
|
|
14729
|
-
`${sandboxedAgent("claude", o.sandbox)} -p`,
|
|
15027
|
+
const cmd = agent ? `${sandboxedAgent(agent, o.sandbox, o.mainCheckout)} ${prompt}` : [
|
|
15028
|
+
`${sandboxedAgent("claude", o.sandbox, o.mainCheckout)} -p`,
|
|
14730
15029
|
prompt,
|
|
14731
15030
|
...o.mcpConfig ? [mcpConfigFlag(o).trim()] : [],
|
|
14732
15031
|
"--output-format stream-json --verbose",
|
|
@@ -14797,7 +15096,7 @@ function headlessRunner(deps = {}) {
|
|
|
14797
15096
|
|
|
14798
15097
|
// src/runners/managed.ts
|
|
14799
15098
|
init_src();
|
|
14800
|
-
import { readFileSync as
|
|
15099
|
+
import { readFileSync as readFileSync12 } from "node:fs";
|
|
14801
15100
|
var obj2 = (v) => v !== null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
14802
15101
|
var str9 = (v) => typeof v === "string" && v.length > 0 ? v : null;
|
|
14803
15102
|
var ANTHROPIC_API = "https://api.anthropic.com";
|
|
@@ -14933,7 +15232,7 @@ var statusLine2 = (session, events, now) => {
|
|
|
14933
15232
|
var YES = /^\s*(?:y|yes|allow|ok|okay|go|go ahead|approve[d]?)\b/i;
|
|
14934
15233
|
function managedRunner(exec, deps = {}) {
|
|
14935
15234
|
const env = deps.env ?? process.env;
|
|
14936
|
-
const readFile = deps.readFile ?? ((p) =>
|
|
15235
|
+
const readFile = deps.readFile ?? ((p) => readFileSync12(p, "utf8"));
|
|
14937
15236
|
const now = deps.now ?? Date.now;
|
|
14938
15237
|
const base = env.ANTHROPIC_BASE_URL?.trim() || ANTHROPIC_API;
|
|
14939
15238
|
const need = (name, where) => {
|
|
@@ -15103,7 +15402,7 @@ ${renderTranscript(eventMessages(all))}`;
|
|
|
15103
15402
|
}
|
|
15104
15403
|
|
|
15105
15404
|
// src/runners/orca.ts
|
|
15106
|
-
import { writeFileSync as
|
|
15405
|
+
import { writeFileSync as writeFileSync12 } from "node:fs";
|
|
15107
15406
|
var obj3 = (v) => v !== null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
15108
15407
|
var str10 = (v) => typeof v === "string" && v.length > 0 ? v : null;
|
|
15109
15408
|
var parseOrcaJson = (stdout) => {
|
|
@@ -15162,7 +15461,7 @@ var orcaTerminalLive = (status, stdout) => {
|
|
|
15162
15461
|
};
|
|
15163
15462
|
var launcherPath2 = (promptFile) => `${promptFile.replace(/\.md$/, "")}.orca.sh`;
|
|
15164
15463
|
function orcaRunner(exec, deps = {}) {
|
|
15165
|
-
const writeFile = deps.writeFile ?? ((p, t) =>
|
|
15464
|
+
const writeFile = deps.writeFile ?? ((p, t) => writeFileSync12(p, t, { mode: 384 }));
|
|
15166
15465
|
const orca = (args, what) => {
|
|
15167
15466
|
const r = exec("orca", args);
|
|
15168
15467
|
const env = parseOrcaJson(r.stdout);
|
|
@@ -15302,6 +15601,14 @@ function tmuxRunner(exec) {
|
|
|
15302
15601
|
}
|
|
15303
15602
|
exec("tmux", ["send-keys", "-t", tmuxPane(h.id), "Enter"]);
|
|
15304
15603
|
},
|
|
15604
|
+
sendKey(h, key) {
|
|
15605
|
+
if (!isRunnerKey(key))
|
|
15606
|
+
throw new Error(`tmux send-keys ${h.id}: no key ${JSON.stringify(key)}`);
|
|
15607
|
+
const r = exec("tmux", ["send-keys", "-t", tmuxPane(h.id), key === "esc" ? "Escape" : key]);
|
|
15608
|
+
if (r.status !== 0) {
|
|
15609
|
+
throw new Error(`tmux send-keys ${h.id} failed: ${r.stderr.trim() || `exit ${r.status}`}`);
|
|
15610
|
+
}
|
|
15611
|
+
},
|
|
15305
15612
|
stop(h) {
|
|
15306
15613
|
exec("tmux", ["kill-session", "-t", tmuxSession(h.id)]);
|
|
15307
15614
|
},
|
|
@@ -15727,7 +16034,7 @@ function realPidAlive(pid) {
|
|
|
15727
16034
|
function memberMcpConfigs(o, cwd) {
|
|
15728
16035
|
const read = o.readJson ?? ((p) => {
|
|
15729
16036
|
try {
|
|
15730
|
-
return JSON.parse(
|
|
16037
|
+
return JSON.parse(readFileSync13(p, "utf8"));
|
|
15731
16038
|
} catch {
|
|
15732
16039
|
return null;
|
|
15733
16040
|
}
|
|
@@ -15769,6 +16076,9 @@ function engineDeps(o, flags, source, runner, stateName) {
|
|
|
15769
16076
|
const repo = flags.repo ? resolve7(cwd, flags.repo) : undefined;
|
|
15770
16077
|
const reposDirs = splitReposDirs(flags.reposDir).map((d) => resolve7(cwd, d));
|
|
15771
16078
|
const { branch, prTitle } = flags;
|
|
16079
|
+
const hooksDir = join15(stateDir, "hooks");
|
|
16080
|
+
const permissionMark = (name) => join15(hooksDir, `${name}.permission.json`);
|
|
16081
|
+
const withHook = (name, settings) => applyPermissionHook(settings, [...o.sledsArgv ?? ["sleds"], "permission-event", "--mark", permissionMark(name)].map(shq2).join(" "));
|
|
15772
16082
|
return {
|
|
15773
16083
|
source,
|
|
15774
16084
|
runner,
|
|
@@ -15793,18 +16103,35 @@ function engineDeps(o, flags, source, runner, stateName) {
|
|
|
15793
16103
|
writeSandboxSettings: o.writeSandboxSettings ?? ((name, cwd) => {
|
|
15794
16104
|
const gitCommonDir = gitCommonDirOf(exec, cwd);
|
|
15795
16105
|
const dir = join15(stateDir, "sandbox");
|
|
15796
|
-
|
|
16106
|
+
mkdirSync12(dir, { recursive: true, mode: 448 });
|
|
15797
16107
|
const p = join15(dir, `${name}.json`);
|
|
15798
|
-
const
|
|
16108
|
+
const walls = engineSandboxSettings(o.home, o.env ?? process.env, gitCommonDir, [
|
|
15799
16109
|
...SANDBOX_DEFAULT_ALLOW,
|
|
15800
16110
|
...flags.sandboxAllow ?? []
|
|
15801
16111
|
]);
|
|
15802
|
-
|
|
16112
|
+
const settings = withHook(name, { ...walls });
|
|
16113
|
+
writeFileSync13(p, `${JSON.stringify(settings, null, 2)}
|
|
15803
16114
|
`, { mode: 384 });
|
|
15804
|
-
|
|
16115
|
+
chmodSync4(p, 384);
|
|
15805
16116
|
return { settingsFile: p, gitCommonDir };
|
|
15806
16117
|
})
|
|
15807
16118
|
} : {},
|
|
16119
|
+
writeHookSettings: (name) => {
|
|
16120
|
+
mkdirSync12(hooksDir, { recursive: true, mode: 448 });
|
|
16121
|
+
const p = join15(hooksDir, `${name}.json`);
|
|
16122
|
+
writeFileSync13(p, `${JSON.stringify(withHook(name, {}), null, 2)}
|
|
16123
|
+
`, { mode: 384 });
|
|
16124
|
+
chmodSync4(p, 384);
|
|
16125
|
+
return p;
|
|
16126
|
+
},
|
|
16127
|
+
permissionMark,
|
|
16128
|
+
mainCheckoutOf: o.mainCheckoutOf ?? ((cwd) => {
|
|
16129
|
+
try {
|
|
16130
|
+
return mainCheckoutOf(gitCommonDirOf(exec, cwd), cwd);
|
|
16131
|
+
} catch {
|
|
16132
|
+
return null;
|
|
16133
|
+
}
|
|
16134
|
+
}),
|
|
15808
16135
|
...branch ? { branchOf: (claim) => branchFor(branch, claim) } : {},
|
|
15809
16136
|
...prTitle ? { prTitleOf: (claim) => prTitleFor(prTitle, claim) } : {},
|
|
15810
16137
|
now: o.now ?? Date.now,
|
|
@@ -15819,7 +16146,7 @@ function engineDeps(o, flags, source, runner, stateName) {
|
|
|
15819
16146
|
}),
|
|
15820
16147
|
writeMcpConfig: o.writeMcpConfig ?? ((name, runToken, worktree) => {
|
|
15821
16148
|
const dir = join15(stateDir, "mcp");
|
|
15822
|
-
|
|
16149
|
+
mkdirSync12(dir, { recursive: true, mode: 448 });
|
|
15823
16150
|
const p = join15(dir, `${name}.json`);
|
|
15824
16151
|
let others = {};
|
|
15825
16152
|
if (flags.strictMcp && flags.mcpAllow?.length) {
|
|
@@ -15830,16 +16157,16 @@ function engineDeps(o, flags, source, runner, stateName) {
|
|
|
15830
16157
|
if (r.refused.length)
|
|
15831
16158
|
log(`${name}: MCP pass-through refused ${r.refused.join(", ")} — the run's sleds server is the only SLEDS one`);
|
|
15832
16159
|
}
|
|
15833
|
-
|
|
15834
|
-
|
|
16160
|
+
writeFileSync13(p, pinOrg2(engineMcpConfig(runToken, others), mcpOrg), { mode: 384 });
|
|
16161
|
+
chmodSync4(p, 384);
|
|
15835
16162
|
return p;
|
|
15836
16163
|
}),
|
|
15837
|
-
removeMcpConfig: o.removeMcpConfig ?? ((p) =>
|
|
16164
|
+
removeMcpConfig: o.removeMcpConfig ?? ((p) => rmSync4(p, { force: true })),
|
|
15838
16165
|
writePrompt: o.writePrompt ?? ((name, text) => {
|
|
15839
16166
|
const dir = join15(stateDir, "prompts");
|
|
15840
|
-
|
|
16167
|
+
mkdirSync12(dir, { recursive: true, mode: 448 });
|
|
15841
16168
|
const p = join15(dir, `${name}.md`);
|
|
15842
|
-
|
|
16169
|
+
writeFileSync13(p, text, { mode: 384 });
|
|
15843
16170
|
return p;
|
|
15844
16171
|
}),
|
|
15845
16172
|
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 +16250,7 @@ async function driveEngine(o, flags, deps, until = {}) {
|
|
|
15923
16250
|
runner: deps.runner.name,
|
|
15924
16251
|
atOnce: flags.atOnce,
|
|
15925
16252
|
interval: flags.interval,
|
|
15926
|
-
cliVersion: "0.1.
|
|
16253
|
+
cliVersion: "0.1.39"
|
|
15927
16254
|
};
|
|
15928
16255
|
const beat = (checkedAt) => {
|
|
15929
16256
|
const m = deps.machine;
|
|
@@ -16215,7 +16542,7 @@ async function enginePauseCmd(o) {
|
|
|
16215
16542
|
result.released++;
|
|
16216
16543
|
result.kept.push(run.handle.cwd);
|
|
16217
16544
|
if (run.mcpConfig)
|
|
16218
|
-
|
|
16545
|
+
rmSync4(run.mcpConfig, { force: true });
|
|
16219
16546
|
}
|
|
16220
16547
|
if (gone.size)
|
|
16221
16548
|
writeState(file, { ...state, runs: state.runs.filter((r) => !gone.has(r)) });
|
|
@@ -16237,19 +16564,19 @@ init_config();
|
|
|
16237
16564
|
init_state();
|
|
16238
16565
|
import {
|
|
16239
16566
|
existsSync as existsSync14,
|
|
16240
|
-
mkdirSync as
|
|
16241
|
-
readFileSync as
|
|
16567
|
+
mkdirSync as mkdirSync14,
|
|
16568
|
+
readFileSync as readFileSync14,
|
|
16242
16569
|
readdirSync as readdirSync2,
|
|
16243
16570
|
realpathSync,
|
|
16244
|
-
rmSync as
|
|
16245
|
-
writeFileSync as
|
|
16571
|
+
rmSync as rmSync6,
|
|
16572
|
+
writeFileSync as writeFileSync15
|
|
16246
16573
|
} from "node:fs";
|
|
16247
16574
|
import { hostname as hostname3 } from "node:os";
|
|
16248
16575
|
import { basename as basename4, dirname as dirname12, isAbsolute as isAbsolute2, join as join18 } from "node:path";
|
|
16249
16576
|
|
|
16250
16577
|
// src/schedule.ts
|
|
16251
16578
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
16252
|
-
import { existsSync as existsSync13, mkdirSync as
|
|
16579
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync13, rmSync as rmSync5, writeFileSync as writeFileSync14 } from "node:fs";
|
|
16253
16580
|
import { join as join16 } from "node:path";
|
|
16254
16581
|
var REVERT_LABEL = "ai.sleds.revert";
|
|
16255
16582
|
var defaultExec2 = (cmd, args) => {
|
|
@@ -16297,9 +16624,9 @@ var scheduleRevert = (d, deadlineMs) => {
|
|
|
16297
16624
|
if (d.platform === "darwin") {
|
|
16298
16625
|
const p = plistPath(d.home);
|
|
16299
16626
|
try {
|
|
16300
|
-
|
|
16627
|
+
mkdirSync13(join16(d.home, "Library", "LaunchAgents"), { recursive: true });
|
|
16301
16628
|
d.exec("launchctl", ["unload", p]);
|
|
16302
|
-
|
|
16629
|
+
writeFileSync14(p, buildLaunchdPlist(d.sledsArgv, deadline));
|
|
16303
16630
|
const r = d.exec("launchctl", ["load", p]);
|
|
16304
16631
|
if (r.ok)
|
|
16305
16632
|
return { kind: "launchd", detail: `launchd agent ${REVERT_LABEL}` };
|
|
@@ -16328,7 +16655,7 @@ var cancelRevert = (d, kind) => {
|
|
|
16328
16655
|
const p = plistPath(d.home);
|
|
16329
16656
|
if (existsSync13(p)) {
|
|
16330
16657
|
d.exec("launchctl", ["unload", p]);
|
|
16331
|
-
|
|
16658
|
+
rmSync5(p, { force: true });
|
|
16332
16659
|
}
|
|
16333
16660
|
}
|
|
16334
16661
|
if (kind === "systemd" || d.platform === "linux") {
|
|
@@ -16504,7 +16831,7 @@ function readEngines(dir, suffix, manager, parse) {
|
|
|
16504
16831
|
const path = join18(dir, name);
|
|
16505
16832
|
let parsed;
|
|
16506
16833
|
try {
|
|
16507
|
-
parsed = parse(
|
|
16834
|
+
parsed = parse(readFileSync14(path, "utf8"), name);
|
|
16508
16835
|
} catch {
|
|
16509
16836
|
parsed = null;
|
|
16510
16837
|
}
|
|
@@ -16558,7 +16885,7 @@ function engineInstall(o) {
|
|
|
16558
16885
|
const stateDir = seatStateDir(orgStateDir(baseDir, parsed.org), seat);
|
|
16559
16886
|
const label = engineLabel(parsed.name, parsed.org, seat);
|
|
16560
16887
|
const logPath = engineLogPath(stateDir, parsed.name);
|
|
16561
|
-
|
|
16888
|
+
mkdirSync14(stateDir, { recursive: true, mode: 448 });
|
|
16562
16889
|
const sledsArgv = stableArgv(o.sledsArgv, o.realpath);
|
|
16563
16890
|
const execPath = sledsArgv[0] ?? process.execPath;
|
|
16564
16891
|
const agentEnv = {
|
|
@@ -16571,7 +16898,7 @@ function engineInstall(o) {
|
|
|
16571
16898
|
if (platform === "linux")
|
|
16572
16899
|
return installUnit({ o, parsed, label, sledsArgv, env: agentEnv, logPath, exec });
|
|
16573
16900
|
const plist = enginePlistPath(o.home, parsed.name, parsed.org, seat);
|
|
16574
|
-
|
|
16901
|
+
mkdirSync14(dirname12(plist), { recursive: true });
|
|
16575
16902
|
if (existsSync14(plist))
|
|
16576
16903
|
exec("launchctl", ["unload", plist]);
|
|
16577
16904
|
for (const other of installedEngines(o.home)) {
|
|
@@ -16580,7 +16907,7 @@ function engineInstall(o) {
|
|
|
16580
16907
|
if (engineArg(other.programArgs, "name") !== parsed.name)
|
|
16581
16908
|
continue;
|
|
16582
16909
|
exec("launchctl", ["unload", other.plist]);
|
|
16583
|
-
|
|
16910
|
+
rmSync6(other.plist, { force: true });
|
|
16584
16911
|
log(`replaced ${other.label}, this engine as installed before`);
|
|
16585
16912
|
}
|
|
16586
16913
|
const legacy = enginePlistPath(o.home, parsed.name);
|
|
@@ -16588,12 +16915,12 @@ function engineInstall(o) {
|
|
|
16588
16915
|
const cfg = readConfig(o.home);
|
|
16589
16916
|
if (org.sole || parsed.org === (cfg.activeOrg ?? cfg.org?.slug)) {
|
|
16590
16917
|
exec("launchctl", ["unload", legacy]);
|
|
16591
|
-
|
|
16918
|
+
rmSync6(legacy, { force: true });
|
|
16592
16919
|
log(`replaced ${engineLabel(parsed.name)}, the engine installed before orgs`);
|
|
16593
16920
|
} else
|
|
16594
16921
|
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
16922
|
}
|
|
16596
|
-
|
|
16923
|
+
writeFileSync15(plist, buildEnginePlist({ label, sledsArgv, args: parsed.args, env: agentEnv, logPath }));
|
|
16597
16924
|
const r = exec("launchctl", ["load", plist]);
|
|
16598
16925
|
if (!r.ok) {
|
|
16599
16926
|
error(`launchctl load failed: ${r.stderr.trim() || "unknown"}`);
|
|
@@ -16613,7 +16940,7 @@ function installUnit(a) {
|
|
|
16613
16940
|
const unit = engineUnitPath(o.home, label);
|
|
16614
16941
|
const unitName = basename4(unit);
|
|
16615
16942
|
const systemctl = (...args) => exec("systemctl", ["--user", ...args]);
|
|
16616
|
-
|
|
16943
|
+
mkdirSync14(dirname12(unit), { recursive: true });
|
|
16617
16944
|
if (existsSync14(unit))
|
|
16618
16945
|
systemctl("stop", unitName);
|
|
16619
16946
|
for (const other of installedEngines(o.home)) {
|
|
@@ -16622,10 +16949,10 @@ function installUnit(a) {
|
|
|
16622
16949
|
if (engineArg(other.programArgs, "name") !== parsed.name)
|
|
16623
16950
|
continue;
|
|
16624
16951
|
systemctl("disable", "--now", basename4(other.plist));
|
|
16625
|
-
|
|
16952
|
+
rmSync6(other.plist, { force: true });
|
|
16626
16953
|
log(`replaced ${other.label}, this engine as installed before`);
|
|
16627
16954
|
}
|
|
16628
|
-
|
|
16955
|
+
writeFileSync15(unit, buildEngineUnit({
|
|
16629
16956
|
label,
|
|
16630
16957
|
name: parsed.name,
|
|
16631
16958
|
sledsArgv: a.sledsArgv,
|
|
@@ -16683,7 +17010,7 @@ function engineUninstall(o) {
|
|
|
16683
17010
|
exec("systemctl", ["--user", "disable", "--now", basename4(file)]);
|
|
16684
17011
|
else
|
|
16685
17012
|
exec("launchctl", ["unload", file]);
|
|
16686
|
-
|
|
17013
|
+
rmSync6(file, { force: true });
|
|
16687
17014
|
if (unit)
|
|
16688
17015
|
exec("systemctl", ["--user", "daemon-reload"]);
|
|
16689
17016
|
log(`engine:${name} removed: ${basename4(file, unit ? ".service" : ".plist")} — its sessions keep running`);
|
|
@@ -16691,7 +17018,7 @@ function engineUninstall(o) {
|
|
|
16691
17018
|
}
|
|
16692
17019
|
|
|
16693
17020
|
// src/commands/musher.ts
|
|
16694
|
-
import { existsSync as existsSync15, mkdirSync as
|
|
17021
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync15, readFileSync as readFileSync15, rmSync as rmSync7, writeFileSync as writeFileSync16 } from "node:fs";
|
|
16695
17022
|
init_config();
|
|
16696
17023
|
init_meter();
|
|
16697
17024
|
var defaultWhich = (cmd) => {
|
|
@@ -16724,7 +17051,7 @@ var musherAgentState = (home, env = process.env) => {
|
|
|
16724
17051
|
if (!existsSync15(plist))
|
|
16725
17052
|
return { installed: false, thisSeat: false };
|
|
16726
17053
|
try {
|
|
16727
|
-
const text =
|
|
17054
|
+
const text = readFileSync15(plist, "utf8");
|
|
16728
17055
|
const want = env.SLEDS_HOME?.trim();
|
|
16729
17056
|
const has = /<key>SLEDS_HOME<\/key>\s*<string>([^<]*)<\/string>/.exec(text)?.[1];
|
|
16730
17057
|
return { installed: true, thisSeat: (want ?? undefined) === (has ?? undefined) };
|
|
@@ -17084,7 +17411,7 @@ function sandboxChecks(o, env) {
|
|
|
17084
17411
|
const probe = join19(dir, SANDBOX_PROBE);
|
|
17085
17412
|
const work = mkdtempSync(join19(tmpdir(), "sleds-sandbox-"));
|
|
17086
17413
|
try {
|
|
17087
|
-
|
|
17414
|
+
writeFileSync17(probe, `${nonce}
|
|
17088
17415
|
`, { mode: 384 });
|
|
17089
17416
|
const settingsFile = join19(work, "settings.json");
|
|
17090
17417
|
const settings = sandboxSettings({
|
|
@@ -17092,7 +17419,7 @@ function sandboxChecks(o, env) {
|
|
|
17092
17419
|
gitCommonDir: work,
|
|
17093
17420
|
allow: SANDBOX_DEFAULT_ALLOW
|
|
17094
17421
|
});
|
|
17095
|
-
|
|
17422
|
+
writeFileSync17(settingsFile, JSON.stringify(settings, null, 2), { mode: 384 });
|
|
17096
17423
|
const prompt = `Run exactly this one Bash command, once, then reply with its complete output verbatim and nothing else:
|
|
17097
17424
|
|
|
17098
17425
|
${SANDBOX_PROBE_COMMAND}`;
|
|
@@ -17114,8 +17441,8 @@ ${SANDBOX_PROBE_COMMAND}`;
|
|
|
17114
17441
|
], { cwd: work });
|
|
17115
17442
|
return readSandboxProbe(run, nonce);
|
|
17116
17443
|
} finally {
|
|
17117
|
-
|
|
17118
|
-
|
|
17444
|
+
rmSync8(probe, { force: true });
|
|
17445
|
+
rmSync8(work, { recursive: true, force: true });
|
|
17119
17446
|
}
|
|
17120
17447
|
}
|
|
17121
17448
|
function engineChecks(o, env) {
|
|
@@ -17232,7 +17559,7 @@ function boxChecks(o, env, which, need) {
|
|
|
17232
17559
|
const file = boxEnvPath(o.home);
|
|
17233
17560
|
let named = false;
|
|
17234
17561
|
try {
|
|
17235
|
-
named = /^\s*(?:export\s+)?ANTHROPIC_API_KEY\s*=\s*\S/m.test(
|
|
17562
|
+
named = /^\s*(?:export\s+)?ANTHROPIC_API_KEY\s*=\s*\S/m.test(readFileSync16(file, "utf8"));
|
|
17236
17563
|
} catch {
|
|
17237
17564
|
named = false;
|
|
17238
17565
|
}
|
|
@@ -17336,12 +17663,12 @@ init_server();
|
|
|
17336
17663
|
init_config();
|
|
17337
17664
|
import {
|
|
17338
17665
|
appendFileSync as appendFileSync3,
|
|
17339
|
-
chmodSync as
|
|
17340
|
-
mkdirSync as
|
|
17341
|
-
readFileSync as
|
|
17666
|
+
chmodSync as chmodSync5,
|
|
17667
|
+
mkdirSync as mkdirSync16,
|
|
17668
|
+
readFileSync as readFileSync17,
|
|
17342
17669
|
existsSync as realExists2,
|
|
17343
|
-
rmSync as
|
|
17344
|
-
writeFileSync as
|
|
17670
|
+
rmSync as rmSync9,
|
|
17671
|
+
writeFileSync as writeFileSync18
|
|
17345
17672
|
} from "node:fs";
|
|
17346
17673
|
import { hostname as hostname4 } from "node:os";
|
|
17347
17674
|
import { join as join20, resolve as resolve9 } from "node:path";
|
|
@@ -17751,7 +18078,7 @@ function realPidAlive2(pid) {
|
|
|
17751
18078
|
function memberMcpConfigs2(o, cwd) {
|
|
17752
18079
|
const read = o.readJson ?? ((p) => {
|
|
17753
18080
|
try {
|
|
17754
|
-
return JSON.parse(
|
|
18081
|
+
return JSON.parse(readFileSync17(p, "utf8"));
|
|
17755
18082
|
} catch {
|
|
17756
18083
|
return null;
|
|
17757
18084
|
}
|
|
@@ -17793,6 +18120,9 @@ function engineDeps2(o, flags, source, runner, stateName) {
|
|
|
17793
18120
|
const repo = flags.repo ? resolve9(cwd, flags.repo) : undefined;
|
|
17794
18121
|
const reposDirs = splitReposDirs(flags.reposDir).map((d) => resolve9(cwd, d));
|
|
17795
18122
|
const { branch, prTitle } = flags;
|
|
18123
|
+
const hooksDir = join20(stateDir, "hooks");
|
|
18124
|
+
const permissionMark = (name) => join20(hooksDir, `${name}.permission.json`);
|
|
18125
|
+
const withHook = (name, settings) => applyPermissionHook(settings, [...o.sledsArgv ?? ["sleds"], "permission-event", "--mark", permissionMark(name)].map(shq2).join(" "));
|
|
17796
18126
|
return {
|
|
17797
18127
|
source,
|
|
17798
18128
|
runner,
|
|
@@ -17817,18 +18147,35 @@ function engineDeps2(o, flags, source, runner, stateName) {
|
|
|
17817
18147
|
writeSandboxSettings: o.writeSandboxSettings ?? ((name, cwd) => {
|
|
17818
18148
|
const gitCommonDir = gitCommonDirOf2(exec, cwd);
|
|
17819
18149
|
const dir = join20(stateDir, "sandbox");
|
|
17820
|
-
|
|
18150
|
+
mkdirSync16(dir, { recursive: true, mode: 448 });
|
|
17821
18151
|
const p = join20(dir, `${name}.json`);
|
|
17822
|
-
const
|
|
18152
|
+
const walls = engineSandboxSettings2(o.home, o.env ?? process.env, gitCommonDir, [
|
|
17823
18153
|
...SANDBOX_DEFAULT_ALLOW,
|
|
17824
18154
|
...flags.sandboxAllow ?? []
|
|
17825
18155
|
]);
|
|
17826
|
-
|
|
18156
|
+
const settings = withHook(name, { ...walls });
|
|
18157
|
+
writeFileSync18(p, `${JSON.stringify(settings, null, 2)}
|
|
17827
18158
|
`, { mode: 384 });
|
|
17828
|
-
|
|
18159
|
+
chmodSync5(p, 384);
|
|
17829
18160
|
return { settingsFile: p, gitCommonDir };
|
|
17830
18161
|
})
|
|
17831
18162
|
} : {},
|
|
18163
|
+
writeHookSettings: (name) => {
|
|
18164
|
+
mkdirSync16(hooksDir, { recursive: true, mode: 448 });
|
|
18165
|
+
const p = join20(hooksDir, `${name}.json`);
|
|
18166
|
+
writeFileSync18(p, `${JSON.stringify(withHook(name, {}), null, 2)}
|
|
18167
|
+
`, { mode: 384 });
|
|
18168
|
+
chmodSync5(p, 384);
|
|
18169
|
+
return p;
|
|
18170
|
+
},
|
|
18171
|
+
permissionMark,
|
|
18172
|
+
mainCheckoutOf: o.mainCheckoutOf ?? ((cwd) => {
|
|
18173
|
+
try {
|
|
18174
|
+
return mainCheckoutOf(gitCommonDirOf2(exec, cwd), cwd);
|
|
18175
|
+
} catch {
|
|
18176
|
+
return null;
|
|
18177
|
+
}
|
|
18178
|
+
}),
|
|
17832
18179
|
...branch ? { branchOf: (claim) => branchFor(branch, claim) } : {},
|
|
17833
18180
|
...prTitle ? { prTitleOf: (claim) => prTitleFor(prTitle, claim) } : {},
|
|
17834
18181
|
now: o.now ?? Date.now,
|
|
@@ -17843,7 +18190,7 @@ function engineDeps2(o, flags, source, runner, stateName) {
|
|
|
17843
18190
|
}),
|
|
17844
18191
|
writeMcpConfig: o.writeMcpConfig ?? ((name, runToken, worktree) => {
|
|
17845
18192
|
const dir = join20(stateDir, "mcp");
|
|
17846
|
-
|
|
18193
|
+
mkdirSync16(dir, { recursive: true, mode: 448 });
|
|
17847
18194
|
const p = join20(dir, `${name}.json`);
|
|
17848
18195
|
let others = {};
|
|
17849
18196
|
if (flags.strictMcp && flags.mcpAllow?.length) {
|
|
@@ -17854,16 +18201,16 @@ function engineDeps2(o, flags, source, runner, stateName) {
|
|
|
17854
18201
|
if (r.refused.length)
|
|
17855
18202
|
log(`${name}: MCP pass-through refused ${r.refused.join(", ")} — the run's sleds server is the only SLEDS one`);
|
|
17856
18203
|
}
|
|
17857
|
-
|
|
17858
|
-
|
|
18204
|
+
writeFileSync18(p, pinOrg3(engineMcpConfig(runToken, others), mcpOrg), { mode: 384 });
|
|
18205
|
+
chmodSync5(p, 384);
|
|
17859
18206
|
return p;
|
|
17860
18207
|
}),
|
|
17861
|
-
removeMcpConfig: o.removeMcpConfig ?? ((p) =>
|
|
18208
|
+
removeMcpConfig: o.removeMcpConfig ?? ((p) => rmSync9(p, { force: true })),
|
|
17862
18209
|
writePrompt: o.writePrompt ?? ((name, text) => {
|
|
17863
18210
|
const dir = join20(stateDir, "prompts");
|
|
17864
|
-
|
|
18211
|
+
mkdirSync16(dir, { recursive: true, mode: 448 });
|
|
17865
18212
|
const p = join20(dir, `${name}.md`);
|
|
17866
|
-
|
|
18213
|
+
writeFileSync18(p, text, { mode: 384 });
|
|
17867
18214
|
return p;
|
|
17868
18215
|
}),
|
|
17869
18216
|
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 +18303,7 @@ async function driveEngine2(o, flags, deps, until = {}) {
|
|
|
17956
18303
|
runner: deps.runner.name,
|
|
17957
18304
|
atOnce: flags.atOnce,
|
|
17958
18305
|
interval: flags.interval,
|
|
17959
|
-
cliVersion: "0.1.
|
|
18306
|
+
cliVersion: "0.1.39"
|
|
17960
18307
|
};
|
|
17961
18308
|
const beat = (checkedAt) => {
|
|
17962
18309
|
const m = deps.machine;
|
|
@@ -18362,7 +18709,7 @@ async function enginePauseCmd2(o) {
|
|
|
18362
18709
|
result.released++;
|
|
18363
18710
|
result.kept.push(run.handle.cwd);
|
|
18364
18711
|
if (run.mcpConfig)
|
|
18365
|
-
|
|
18712
|
+
rmSync9(run.mcpConfig, { force: true });
|
|
18366
18713
|
}
|
|
18367
18714
|
if (gone.size)
|
|
18368
18715
|
writeState(file, { ...state, runs: state.runs.filter((r) => !gone.has(r)) });
|
|
@@ -18384,12 +18731,12 @@ init_config();
|
|
|
18384
18731
|
init_state();
|
|
18385
18732
|
import {
|
|
18386
18733
|
existsSync as existsSync17,
|
|
18387
|
-
mkdirSync as
|
|
18388
|
-
readFileSync as
|
|
18734
|
+
mkdirSync as mkdirSync17,
|
|
18735
|
+
readFileSync as readFileSync18,
|
|
18389
18736
|
readdirSync as readdirSync4,
|
|
18390
18737
|
realpathSync as realpathSync2,
|
|
18391
|
-
rmSync as
|
|
18392
|
-
writeFileSync as
|
|
18738
|
+
rmSync as rmSync10,
|
|
18739
|
+
writeFileSync as writeFileSync19
|
|
18393
18740
|
} from "node:fs";
|
|
18394
18741
|
import { hostname as hostname5 } from "node:os";
|
|
18395
18742
|
import { basename as basename5, dirname as dirname13, isAbsolute as isAbsolute3, join as join21 } from "node:path";
|
|
@@ -18511,7 +18858,7 @@ function readEngines2(dir, suffix, manager, parse) {
|
|
|
18511
18858
|
const path = join21(dir, name);
|
|
18512
18859
|
let parsed;
|
|
18513
18860
|
try {
|
|
18514
|
-
parsed = parse(
|
|
18861
|
+
parsed = parse(readFileSync18(path, "utf8"), name);
|
|
18515
18862
|
} catch {
|
|
18516
18863
|
parsed = null;
|
|
18517
18864
|
}
|
|
@@ -18565,7 +18912,7 @@ function engineInstall2(o) {
|
|
|
18565
18912
|
const stateDir = seatStateDir(orgStateDir(baseDir, parsed.org), seat);
|
|
18566
18913
|
const label = engineLabel2(parsed.name, parsed.org, seat);
|
|
18567
18914
|
const logPath = engineLogPath2(stateDir, parsed.name);
|
|
18568
|
-
|
|
18915
|
+
mkdirSync17(stateDir, { recursive: true, mode: 448 });
|
|
18569
18916
|
const sledsArgv = stableArgv2(o.sledsArgv, o.realpath);
|
|
18570
18917
|
const execPath = sledsArgv[0] ?? process.execPath;
|
|
18571
18918
|
const agentEnv = {
|
|
@@ -18578,7 +18925,7 @@ function engineInstall2(o) {
|
|
|
18578
18925
|
if (platform === "linux")
|
|
18579
18926
|
return installUnit2({ o, parsed, label, sledsArgv, env: agentEnv, logPath, exec });
|
|
18580
18927
|
const plist = enginePlistPath2(o.home, parsed.name, parsed.org, seat);
|
|
18581
|
-
|
|
18928
|
+
mkdirSync17(dirname13(plist), { recursive: true });
|
|
18582
18929
|
if (existsSync17(plist))
|
|
18583
18930
|
exec("launchctl", ["unload", plist]);
|
|
18584
18931
|
for (const other of installedEngines2(o.home)) {
|
|
@@ -18587,7 +18934,7 @@ function engineInstall2(o) {
|
|
|
18587
18934
|
if (engineArg2(other.programArgs, "name") !== parsed.name)
|
|
18588
18935
|
continue;
|
|
18589
18936
|
exec("launchctl", ["unload", other.plist]);
|
|
18590
|
-
|
|
18937
|
+
rmSync10(other.plist, { force: true });
|
|
18591
18938
|
log(`replaced ${other.label}, this engine as installed before`);
|
|
18592
18939
|
}
|
|
18593
18940
|
const legacy = enginePlistPath2(o.home, parsed.name);
|
|
@@ -18595,12 +18942,12 @@ function engineInstall2(o) {
|
|
|
18595
18942
|
const cfg = readConfig(o.home);
|
|
18596
18943
|
if (org.sole || parsed.org === (cfg.activeOrg ?? cfg.org?.slug)) {
|
|
18597
18944
|
exec("launchctl", ["unload", legacy]);
|
|
18598
|
-
|
|
18945
|
+
rmSync10(legacy, { force: true });
|
|
18599
18946
|
log(`replaced ${engineLabel2(parsed.name)}, the engine installed before orgs`);
|
|
18600
18947
|
} else
|
|
18601
18948
|
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
18949
|
}
|
|
18603
|
-
|
|
18950
|
+
writeFileSync19(plist, buildEnginePlist2({ label, sledsArgv, args: parsed.args, env: agentEnv, logPath }));
|
|
18604
18951
|
const r = exec("launchctl", ["load", plist]);
|
|
18605
18952
|
if (!r.ok) {
|
|
18606
18953
|
error(`launchctl load failed: ${r.stderr.trim() || "unknown"}`);
|
|
@@ -18620,7 +18967,7 @@ function installUnit2(a) {
|
|
|
18620
18967
|
const unit = engineUnitPath(o.home, label);
|
|
18621
18968
|
const unitName = basename5(unit);
|
|
18622
18969
|
const systemctl = (...args) => exec("systemctl", ["--user", ...args]);
|
|
18623
|
-
|
|
18970
|
+
mkdirSync17(dirname13(unit), { recursive: true });
|
|
18624
18971
|
if (existsSync17(unit))
|
|
18625
18972
|
systemctl("stop", unitName);
|
|
18626
18973
|
for (const other of installedEngines2(o.home)) {
|
|
@@ -18629,10 +18976,10 @@ function installUnit2(a) {
|
|
|
18629
18976
|
if (engineArg2(other.programArgs, "name") !== parsed.name)
|
|
18630
18977
|
continue;
|
|
18631
18978
|
systemctl("disable", "--now", basename5(other.plist));
|
|
18632
|
-
|
|
18979
|
+
rmSync10(other.plist, { force: true });
|
|
18633
18980
|
log(`replaced ${other.label}, this engine as installed before`);
|
|
18634
18981
|
}
|
|
18635
|
-
|
|
18982
|
+
writeFileSync19(unit, buildEngineUnit({
|
|
18636
18983
|
label,
|
|
18637
18984
|
name: parsed.name,
|
|
18638
18985
|
sledsArgv: a.sledsArgv,
|
|
@@ -18690,7 +19037,7 @@ function engineUninstall2(o) {
|
|
|
18690
19037
|
exec("systemctl", ["--user", "disable", "--now", basename5(file)]);
|
|
18691
19038
|
else
|
|
18692
19039
|
exec("launchctl", ["unload", file]);
|
|
18693
|
-
|
|
19040
|
+
rmSync10(file, { force: true });
|
|
18694
19041
|
if (unit)
|
|
18695
19042
|
exec("systemctl", ["--user", "daemon-reload"]);
|
|
18696
19043
|
log(`engine:${name} removed: ${basename5(file, unit ? ".service" : ".plist")} — its sessions keep running`);
|
|
@@ -18821,7 +19168,7 @@ import { closeSync as closeSync3, fstatSync as fstatSync2, openSync as openSync3
|
|
|
18821
19168
|
import { hostname as hostname6 } from "node:os";
|
|
18822
19169
|
|
|
18823
19170
|
// src/commands/engineStatus.ts
|
|
18824
|
-
import { existsSync as existsSync18, readFileSync as
|
|
19171
|
+
import { existsSync as existsSync18, readFileSync as readFileSync19 } from "node:fs";
|
|
18825
19172
|
init_state();
|
|
18826
19173
|
|
|
18827
19174
|
// src/engine/status.ts
|
|
@@ -19111,7 +19458,7 @@ var engineLogCmd = (o) => {
|
|
|
19111
19458
|
|
|
19112
19459
|
// src/commands/engineProfile.ts
|
|
19113
19460
|
init_src();
|
|
19114
|
-
import { existsSync as existsSync19, readFileSync as
|
|
19461
|
+
import { existsSync as existsSync19, readFileSync as readFileSync20 } from "node:fs";
|
|
19115
19462
|
import { hostname as hostname7 } from "node:os";
|
|
19116
19463
|
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
19464
|
var PROFILE_FIELDS = [
|
|
@@ -19376,7 +19723,7 @@ async function engineProfileCmd(o) {
|
|
|
19376
19723
|
const rest = words.slice(1);
|
|
19377
19724
|
let stdin = null;
|
|
19378
19725
|
if (fromStdin) {
|
|
19379
|
-
const taken = cmuxPasswordFromJson((o.stdin ?? (() =>
|
|
19726
|
+
const taken = cmuxPasswordFromJson((o.stdin ?? (() => readFileSync20(0, "utf8")))());
|
|
19380
19727
|
if ("error" in taken || taken.password !== undefined && password !== undefined) {
|
|
19381
19728
|
error("error" in taken ? taken.error : "the cmux password is given once");
|
|
19382
19729
|
error(PROFILE_USAGE);
|
|
@@ -19461,7 +19808,7 @@ var keychainLine = (k) => k === "set" ? "cmuxPassword: set (Keychain)" : k === "
|
|
|
19461
19808
|
|
|
19462
19809
|
// src/commands/engineStatus.ts
|
|
19463
19810
|
init_state();
|
|
19464
|
-
import { existsSync as existsSync20, readFileSync as
|
|
19811
|
+
import { existsSync as existsSync20, readFileSync as readFileSync21 } from "node:fs";
|
|
19465
19812
|
import { hostname as hostname8 } from "node:os";
|
|
19466
19813
|
var ENGINE_STATUS_USAGE = "usage: sleds engine status [--name <n>] [--org <slug>] [--json]";
|
|
19467
19814
|
function parseStatusArgs(argv, host) {
|
|
@@ -19517,7 +19864,7 @@ function readEngineStatus(stateDir, engine, host, pidAlive, seat) {
|
|
|
19517
19864
|
}
|
|
19518
19865
|
function safeRead(path) {
|
|
19519
19866
|
try {
|
|
19520
|
-
return
|
|
19867
|
+
return readFileSync21(path, "utf8");
|
|
19521
19868
|
} catch {
|
|
19522
19869
|
return "";
|
|
19523
19870
|
}
|
|
@@ -19638,7 +19985,7 @@ init_meter();
|
|
|
19638
19985
|
|
|
19639
19986
|
// src/owed.ts
|
|
19640
19987
|
init_config();
|
|
19641
|
-
import { existsSync as existsSync21, mkdirSync as
|
|
19988
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync18, readFileSync as readFileSync22, renameSync as renameSync7, writeFileSync as writeFileSync20 } from "node:fs";
|
|
19642
19989
|
import { dirname as dirname14, join as join22 } from "node:path";
|
|
19643
19990
|
var owedPath = (home) => join22(configDir(home), "owed.json");
|
|
19644
19991
|
var sessionPath = (home) => join22(configDir(home), "session.json");
|
|
@@ -19659,17 +20006,17 @@ var readJson = (p) => {
|
|
|
19659
20006
|
if (!existsSync21(p))
|
|
19660
20007
|
return null;
|
|
19661
20008
|
try {
|
|
19662
|
-
return JSON.parse(
|
|
20009
|
+
return JSON.parse(readFileSync22(p, "utf8"));
|
|
19663
20010
|
} catch {
|
|
19664
20011
|
return null;
|
|
19665
20012
|
}
|
|
19666
20013
|
};
|
|
19667
20014
|
var writeJson = (p, v) => {
|
|
19668
|
-
|
|
20015
|
+
mkdirSync18(dirname14(p), { recursive: true, mode: 448 });
|
|
19669
20016
|
const tmp = `${p}.${process.pid}.tmp`;
|
|
19670
|
-
|
|
20017
|
+
writeFileSync20(tmp, `${JSON.stringify(v, null, 2)}
|
|
19671
20018
|
`, { mode: 384 });
|
|
19672
|
-
|
|
20019
|
+
renameSync7(tmp, p);
|
|
19673
20020
|
};
|
|
19674
20021
|
var readOwed = (home, now = Date.now()) => {
|
|
19675
20022
|
const f = readJson(owedPath(home));
|
|
@@ -19874,7 +20221,7 @@ var hooksOrg = (home, env = process.env) => {
|
|
|
19874
20221
|
};
|
|
19875
20222
|
|
|
19876
20223
|
// src/commands/init.ts
|
|
19877
|
-
import { mkdirSync as
|
|
20224
|
+
import { mkdirSync as mkdirSync19, writeFileSync as writeFileSync21 } from "node:fs";
|
|
19878
20225
|
import { createInterface } from "node:readline";
|
|
19879
20226
|
init_config();
|
|
19880
20227
|
init_state();
|
|
@@ -20561,8 +20908,8 @@ var init = async (o) => {
|
|
|
20561
20908
|
});
|
|
20562
20909
|
if (mcpLine)
|
|
20563
20910
|
wrote.push(mcpLine);
|
|
20564
|
-
|
|
20565
|
-
|
|
20911
|
+
mkdirSync19(skillDir(o.home), { recursive: true });
|
|
20912
|
+
writeFileSync21(skillPath(o.home), SKILL_MD);
|
|
20566
20913
|
wrote.push(`installed skill at ${skillPath(o.home)}`);
|
|
20567
20914
|
if (o.installMusher) {
|
|
20568
20915
|
const r = o.installMusher();
|
|
@@ -20686,7 +21033,7 @@ var login = async (o) => {
|
|
|
20686
21033
|
// src/commands/logout.ts
|
|
20687
21034
|
init_config();
|
|
20688
21035
|
init_state();
|
|
20689
|
-
import { existsSync as existsSync22, readFileSync as
|
|
21036
|
+
import { existsSync as existsSync22, readFileSync as readFileSync23, rmSync as rmSync11 } from "node:fs";
|
|
20690
21037
|
import { hostname as hostname10 } from "node:os";
|
|
20691
21038
|
init_settings();
|
|
20692
21039
|
var LOGOUT_USAGE = "usage: sleds logout [--org <slug>] [--json]";
|
|
@@ -20810,7 +21157,7 @@ async function logout(o) {
|
|
|
20810
21157
|
continue;
|
|
20811
21158
|
if (!e.org) {
|
|
20812
21159
|
(o.exec ?? defaultExec2)("launchctl", ["unload", e.plist]);
|
|
20813
|
-
|
|
21160
|
+
rmSync11(e.plist, { force: true });
|
|
20814
21161
|
continue;
|
|
20815
21162
|
}
|
|
20816
21163
|
engineUninstall({
|
|
@@ -20843,8 +21190,8 @@ async function logout(o) {
|
|
|
20843
21190
|
};
|
|
20844
21191
|
writeConfig(o.home, next);
|
|
20845
21192
|
const tp = tokenPath(o.home, env);
|
|
20846
|
-
if (existsSync22(tp) &&
|
|
20847
|
-
|
|
21193
|
+
if (existsSync22(tp) && readFileSync23(tp, "utf8").trim() === seat.token)
|
|
21194
|
+
rmSync11(tp, { force: true });
|
|
20848
21195
|
const active = next.activeOrg ?? next.org?.slug ?? null;
|
|
20849
21196
|
const result = { ok: true, email, org: slug, paused, active };
|
|
20850
21197
|
if (parsed.json)
|
|
@@ -20921,7 +21268,7 @@ var meter = async (o) => {
|
|
|
20921
21268
|
init_config();
|
|
20922
21269
|
init_meter();
|
|
20923
21270
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
20924
|
-
import { existsSync as existsSync23, mkdirSync as
|
|
21271
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync20, readFileSync as readFileSync24, rmSync as rmSync12, writeFileSync as writeFileSync22 } from "node:fs";
|
|
20925
21272
|
import { hostname as hostname11 } from "node:os";
|
|
20926
21273
|
import { dirname as dirname15 } from "node:path";
|
|
20927
21274
|
var defaultWhich3 = (cmd) => {
|
|
@@ -20961,8 +21308,8 @@ var musherInstall = (o) => {
|
|
|
20961
21308
|
const plist = musherPlistPath(o.home, env);
|
|
20962
21309
|
const label = musherLabel(env);
|
|
20963
21310
|
const dir = configDir(o.home, env);
|
|
20964
|
-
|
|
20965
|
-
|
|
21311
|
+
mkdirSync20(dirname15(plist), { recursive: true });
|
|
21312
|
+
mkdirSync20(dir, { recursive: true, mode: 448 });
|
|
20966
21313
|
const execPath = o.sledsArgv[0] ?? process.execPath;
|
|
20967
21314
|
const agentEnv = {
|
|
20968
21315
|
PATH: musherPath(o.home, execPath, env.PATH ?? ""),
|
|
@@ -20973,7 +21320,7 @@ var musherInstall = (o) => {
|
|
|
20973
21320
|
const exec = o.exec ?? defaultExecSync;
|
|
20974
21321
|
if (existsSync23(plist))
|
|
20975
21322
|
exec("launchctl", ["unload", plist]);
|
|
20976
|
-
|
|
21323
|
+
writeFileSync22(plist, buildMusherPlist({ sledsArgv: o.sledsArgv, env: agentEnv, logPath: musherLogPath(dir), label }));
|
|
20977
21324
|
const r = exec("launchctl", ["load", plist]);
|
|
20978
21325
|
if (!r.ok) {
|
|
20979
21326
|
error(`launchctl load failed: ${r.stderr.trim() || "unknown"}`);
|
|
@@ -20994,7 +21341,7 @@ var musherUninstall = (o) => {
|
|
|
20994
21341
|
const exec = o.exec ?? defaultExecSync;
|
|
20995
21342
|
if (existsSync23(plist)) {
|
|
20996
21343
|
exec("launchctl", ["unload", plist]);
|
|
20997
|
-
|
|
21344
|
+
rmSync12(plist, { force: true });
|
|
20998
21345
|
log(`musher removed: ${musherLabel(env)}`);
|
|
20999
21346
|
} else
|
|
21000
21347
|
log("musher was not installed.");
|
|
@@ -21257,7 +21604,7 @@ var on = (o) => {
|
|
|
21257
21604
|
init_config();
|
|
21258
21605
|
init_meter();
|
|
21259
21606
|
init_settings();
|
|
21260
|
-
import { existsSync as existsSync24, rmSync as
|
|
21607
|
+
import { existsSync as existsSync24, rmSync as rmSync13 } from "node:fs";
|
|
21261
21608
|
var ORG_USAGE = "usage: sleds org list [--json] | sleds org use <slug>";
|
|
21262
21609
|
var orgRows = (cfg, activeSlug) => {
|
|
21263
21610
|
const seats = { ...cfg.orgs ?? {} };
|
|
@@ -21334,7 +21681,7 @@ var orgUse = (o) => {
|
|
|
21334
21681
|
writeSettings(o.home, removeProxy(settings));
|
|
21335
21682
|
}
|
|
21336
21683
|
try {
|
|
21337
|
-
|
|
21684
|
+
rmSync13(meterCachePath(o.home), { force: true });
|
|
21338
21685
|
} catch {}
|
|
21339
21686
|
log(`Active org: ${seat.org?.name ? `${seat.org.name} (${slug})` : slug}${seat.email ? ` · ${seat.email}` : ""}.`);
|
|
21340
21687
|
log("Claude Code, the status line and the hooks act as this org now.");
|
|
@@ -21360,7 +21707,7 @@ var orgCmd = (o) => {
|
|
|
21360
21707
|
// src/commands/pack.ts
|
|
21361
21708
|
init_src();
|
|
21362
21709
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
21363
|
-
import { writeFileSync as
|
|
21710
|
+
import { writeFileSync as writeFileSync23 } from "node:fs";
|
|
21364
21711
|
import { join as join23 } from "node:path";
|
|
21365
21712
|
function packFileName(key) {
|
|
21366
21713
|
return `pack-${slugify(key, 80) || "item"}.md`;
|
|
@@ -21390,22 +21737,43 @@ var packCmd = async (o) => {
|
|
|
21390
21737
|
return 0;
|
|
21391
21738
|
}
|
|
21392
21739
|
const path = join23(o.cwd ?? process.cwd(), packFileName(key));
|
|
21393
|
-
(o.write ?? ((p, t) =>
|
|
21740
|
+
(o.write ?? ((p, t) => writeFileSync23(p, t.endsWith(`
|
|
21394
21741
|
`) ? t : `${t}
|
|
21395
21742
|
`)))(path, r.text);
|
|
21396
21743
|
log(`Wrote ${path} — hand it to any model. \`sleds pack ${key} --run\` starts Claude Code with it.`);
|
|
21397
21744
|
return 0;
|
|
21398
21745
|
};
|
|
21399
21746
|
|
|
21400
|
-
// src/commands/
|
|
21401
|
-
|
|
21402
|
-
|
|
21403
|
-
|
|
21404
|
-
|
|
21405
|
-
|
|
21406
|
-
|
|
21747
|
+
// src/commands/permissionEvent.ts
|
|
21748
|
+
import { chmodSync as chmodSync6, mkdirSync as mkdirSync21, readFileSync as readFileSync25, renameSync as renameSync8, rmSync as rmSync14, writeFileSync as writeFileSync24 } from "node:fs";
|
|
21749
|
+
import { dirname as dirname16 } from "node:path";
|
|
21750
|
+
var isObject13 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
21751
|
+
var messageOf = (text) => {
|
|
21752
|
+
try {
|
|
21753
|
+
const raw = JSON.parse(text);
|
|
21754
|
+
return isObject13(raw) && typeof raw.message === "string" ? raw.message : "";
|
|
21755
|
+
} catch {
|
|
21756
|
+
return "";
|
|
21757
|
+
}
|
|
21758
|
+
};
|
|
21759
|
+
var permissionEvent = async (o) => {
|
|
21760
|
+
try {
|
|
21761
|
+
const input = o.stdin ?? await readStdin(HOOK_STDIN_TIMEOUT_MS);
|
|
21762
|
+
if (!o.mark || notificationType(input) !== "permission_prompt")
|
|
21763
|
+
return 0;
|
|
21764
|
+
const mark = { message: messageOf(input), at: (o.now ?? Date.now)() };
|
|
21765
|
+
mkdirSync21(dirname16(o.mark), { recursive: true, mode: 448 });
|
|
21766
|
+
const tmp = `${o.mark}.${process.pid}.tmp`;
|
|
21767
|
+
writeFileSync24(tmp, `${JSON.stringify(mark)}
|
|
21768
|
+
`, { mode: 384 });
|
|
21769
|
+
renameSync8(tmp, o.mark);
|
|
21770
|
+
chmodSync6(o.mark, 384);
|
|
21771
|
+
} catch {}
|
|
21772
|
+
return 0;
|
|
21773
|
+
};
|
|
21407
21774
|
|
|
21408
21775
|
// src/commands/promptEvent.ts
|
|
21776
|
+
init_config();
|
|
21409
21777
|
var LABEL = {
|
|
21410
21778
|
fiveHour: "5-hour",
|
|
21411
21779
|
sevenDay: "weekly",
|
|
@@ -21488,7 +21856,7 @@ var promptEvent = async (o) => {
|
|
|
21488
21856
|
|
|
21489
21857
|
// src/commands/route.ts
|
|
21490
21858
|
init_src();
|
|
21491
|
-
import { readFileSync as
|
|
21859
|
+
import { readFileSync as readFileSync26 } from "node:fs";
|
|
21492
21860
|
import { hostname as hostname12 } from "node:os";
|
|
21493
21861
|
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
21862
|
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 +22029,7 @@ async function answerCmd(o, argv) {
|
|
|
21661
22029
|
const words = argv.filter((a) => a !== "--json" && a !== "--stdin");
|
|
21662
22030
|
const ref = words[0] ?? "";
|
|
21663
22031
|
const slash = ref.lastIndexOf("/");
|
|
21664
|
-
const answer = (fromStdin ? (o.stdin ?? (() =>
|
|
22032
|
+
const answer = (fromStdin ? (o.stdin ?? (() => readFileSync26(0, "utf8")))() : words.slice(1).join(" ")).trim();
|
|
21665
22033
|
if (slash <= 0 || slash === ref.length - 1 || fromStdin && words.length > 1) {
|
|
21666
22034
|
error(ANSWER_USAGE);
|
|
21667
22035
|
return 2;
|
|
@@ -21858,7 +22226,7 @@ async function decisionCmd(o, argv) {
|
|
|
21858
22226
|
error(DECISION_USAGE);
|
|
21859
22227
|
return 2;
|
|
21860
22228
|
}
|
|
21861
|
-
const md = seen || routeAlone ? "" : (fromStdin ? (o.stdin ?? (() =>
|
|
22229
|
+
const md = seen || routeAlone ? "" : (fromStdin ? (o.stdin ?? (() => readFileSync26(0, "utf8")))() : rest.join(" ")).trim();
|
|
21862
22230
|
if (!seen && !routeAlone && (!md || fromStdin && rest.length > 0)) {
|
|
21863
22231
|
error(md ? DECISION_USAGE : `${answer ? "an answer" : "an overrule"} needs some text`);
|
|
21864
22232
|
return 2;
|
|
@@ -21999,7 +22367,7 @@ function approvedLine(key, j) {
|
|
|
21999
22367
|
function readNodes(o, a) {
|
|
22000
22368
|
let text;
|
|
22001
22369
|
try {
|
|
22002
|
-
text = a.file ? (o.readFile ?? ((p) =>
|
|
22370
|
+
text = a.file ? (o.readFile ?? ((p) => readFileSync26(p, "utf8")))(a.file) : (o.stdin ?? (() => readFileSync26(0, "utf8")))();
|
|
22003
22371
|
} catch (e) {
|
|
22004
22372
|
return { error: e instanceof Error ? e.message : String(e) };
|
|
22005
22373
|
}
|
|
@@ -22273,11 +22641,11 @@ var run = async (o) => {
|
|
|
22273
22641
|
init_config();
|
|
22274
22642
|
init_meter();
|
|
22275
22643
|
var HOOK_STDIN_TIMEOUT_MS2 = 1000;
|
|
22276
|
-
var
|
|
22277
|
-
var
|
|
22644
|
+
var isObject14 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
22645
|
+
var notificationType2 = (text) => {
|
|
22278
22646
|
try {
|
|
22279
22647
|
const raw = JSON.parse(text);
|
|
22280
|
-
if (!
|
|
22648
|
+
if (!isObject14(raw))
|
|
22281
22649
|
return;
|
|
22282
22650
|
return typeof raw.notification_type === "string" ? raw.notification_type : undefined;
|
|
22283
22651
|
} catch {
|
|
@@ -22288,7 +22656,7 @@ var seatEvent = async (o) => {
|
|
|
22288
22656
|
const log = o.log ?? console.log;
|
|
22289
22657
|
const now = (o.now ?? Date.now)();
|
|
22290
22658
|
const input = o.stdin ?? await readStdin(HOOK_STDIN_TIMEOUT_MS2);
|
|
22291
|
-
const kind =
|
|
22659
|
+
const kind = notificationType2(input);
|
|
22292
22660
|
try {
|
|
22293
22661
|
const key = seatKeyFor(o.home, process.env);
|
|
22294
22662
|
const state = readSeatState(o.home, key);
|
|
@@ -22310,12 +22678,12 @@ var seatEvent = async (o) => {
|
|
|
22310
22678
|
|
|
22311
22679
|
// src/commands/seatSync.ts
|
|
22312
22680
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
22313
|
-
import { existsSync as existsSync25, mkdirSync as
|
|
22681
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync22, readFileSync as readFileSync27, readdirSync as readdirSync5, rmSync as rmSync16, writeFileSync as writeFileSync25 } from "node:fs";
|
|
22314
22682
|
import { platform as platform2 } from "node:os";
|
|
22315
|
-
import { dirname as
|
|
22683
|
+
import { dirname as dirname17, join as join25 } from "node:path";
|
|
22316
22684
|
|
|
22317
22685
|
// src/cookieDb.ts
|
|
22318
|
-
import { copyFileSync, rmSync as
|
|
22686
|
+
import { copyFileSync, rmSync as rmSync15 } from "node:fs";
|
|
22319
22687
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
22320
22688
|
import { join as join24 } from "node:path";
|
|
22321
22689
|
var QUERY = "SELECT name, hex(encrypted_value) AS ev FROM cookies WHERE host_key LIKE '%claude.ai%'";
|
|
@@ -22353,7 +22721,7 @@ async function readCookieRows(dbPath) {
|
|
|
22353
22721
|
return rows.map((r) => ({ name: r.name, encrypted_value: Buffer.from(r.ev, "hex") }));
|
|
22354
22722
|
} finally {
|
|
22355
22723
|
try {
|
|
22356
|
-
|
|
22724
|
+
rmSync15(copy, { force: true });
|
|
22357
22725
|
} catch {}
|
|
22358
22726
|
}
|
|
22359
22727
|
}
|
|
@@ -22438,8 +22806,8 @@ function resolveProfileDir(localStateJson, profile) {
|
|
|
22438
22806
|
if (localStateJson) {
|
|
22439
22807
|
try {
|
|
22440
22808
|
const raw = JSON.parse(localStateJson);
|
|
22441
|
-
const p =
|
|
22442
|
-
if (p &&
|
|
22809
|
+
const p = isObject15(raw) && isObject15(raw.profile) ? raw.profile : null;
|
|
22810
|
+
if (p && isObject15(p.info_cache))
|
|
22443
22811
|
cache = p.info_cache;
|
|
22444
22812
|
} catch {}
|
|
22445
22813
|
}
|
|
@@ -22448,7 +22816,7 @@ function resolveProfileDir(localStateJson, profile) {
|
|
|
22448
22816
|
const want = profile.toLowerCase();
|
|
22449
22817
|
const hits = [];
|
|
22450
22818
|
for (const [dir, info] of Object.entries(cache)) {
|
|
22451
|
-
if (!
|
|
22819
|
+
if (!isObject15(info))
|
|
22452
22820
|
continue;
|
|
22453
22821
|
const match = ["name", "user_name", "gaia_name"].some((k) => {
|
|
22454
22822
|
const v = info[k];
|
|
@@ -22487,15 +22855,15 @@ function sourceArgs(source) {
|
|
|
22487
22855
|
function seatTokenPath(home, source) {
|
|
22488
22856
|
return `${home}/.config/sleds/${launchLabel(source).slice("ai.sleds.".length)}.token`;
|
|
22489
22857
|
}
|
|
22490
|
-
var
|
|
22858
|
+
var isObject15 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
22491
22859
|
var num7 = (v) => typeof v === "number" && Number.isFinite(v) ? v : undefined;
|
|
22492
22860
|
var round22 = (n) => Math.round(n * 100) / 100;
|
|
22493
22861
|
function parseUsageResponse(raw, now = Date.now()) {
|
|
22494
|
-
if (!
|
|
22862
|
+
if (!isObject15(raw))
|
|
22495
22863
|
return null;
|
|
22496
22864
|
const out = { capturedAt: now, models: {} };
|
|
22497
22865
|
for (const [k, v] of Object.entries(raw)) {
|
|
22498
|
-
if (!
|
|
22866
|
+
if (!isObject15(v))
|
|
22499
22867
|
continue;
|
|
22500
22868
|
if (k === "extra_usage") {
|
|
22501
22869
|
const credits = num7(v.used_credits);
|
|
@@ -22660,7 +23028,7 @@ function findCookieDb(home, source) {
|
|
|
22660
23028
|
return db;
|
|
22661
23029
|
}
|
|
22662
23030
|
const localStatePath = join25(root, "Local State");
|
|
22663
|
-
const localState = existsSync25(localStatePath) ?
|
|
23031
|
+
const localState = existsSync25(localStatePath) ? readFileSync27(localStatePath, "utf8") : null;
|
|
22664
23032
|
const wanted = source.profile ?? "Default";
|
|
22665
23033
|
const { dir, ambiguous } = resolveProfileDir(localState, wanted);
|
|
22666
23034
|
if (ambiguous)
|
|
@@ -22743,16 +23111,16 @@ function install(home, argv, source, log) {
|
|
|
22743
23111
|
return 1;
|
|
22744
23112
|
}
|
|
22745
23113
|
const dir = join25(home, "Library", "LaunchAgents");
|
|
22746
|
-
|
|
23114
|
+
mkdirSync22(dir, { recursive: true });
|
|
22747
23115
|
const path = plistPath2(home, source);
|
|
22748
23116
|
const tokenPath = seatTokenPath(home, source);
|
|
22749
|
-
|
|
23117
|
+
rmSync16(tokenPath, { force: true });
|
|
22750
23118
|
if (source.token) {
|
|
22751
|
-
|
|
22752
|
-
|
|
23119
|
+
mkdirSync22(dirname17(tokenPath), { recursive: true, mode: 448 });
|
|
23120
|
+
writeFileSync25(tokenPath, `${source.token}
|
|
22753
23121
|
`, { mode: 384 });
|
|
22754
23122
|
}
|
|
22755
|
-
|
|
23123
|
+
writeFileSync25(path, launchAgentPlist(bun, script, home, source), { mode: 384 });
|
|
22756
23124
|
try {
|
|
22757
23125
|
execFileSync4("launchctl", ["unload", path], { stdio: "ignore" });
|
|
22758
23126
|
} catch {}
|
|
@@ -22765,7 +23133,7 @@ function uninstall(home, source, log) {
|
|
|
22765
23133
|
try {
|
|
22766
23134
|
execFileSync4("launchctl", ["unload", "-w", path], { stdio: "ignore" });
|
|
22767
23135
|
} catch {}
|
|
22768
|
-
|
|
23136
|
+
rmSync16(seatTokenPath(home, source), { force: true });
|
|
22769
23137
|
log(existsSync25(path) ? `seat-sync timer removed (${path} can be deleted)` : "no seat-sync timer");
|
|
22770
23138
|
return 0;
|
|
22771
23139
|
}
|
|
@@ -22840,7 +23208,7 @@ var seatSync = async (o) => {
|
|
|
22840
23208
|
};
|
|
22841
23209
|
function readSeatToken(home, source) {
|
|
22842
23210
|
try {
|
|
22843
|
-
return
|
|
23211
|
+
return readFileSync27(seatTokenPath(home, source), "utf8").trim() || undefined;
|
|
22844
23212
|
} catch {
|
|
22845
23213
|
return;
|
|
22846
23214
|
}
|
|
@@ -22923,7 +23291,7 @@ var sessionEvent = async (o) => {
|
|
|
22923
23291
|
|
|
22924
23292
|
// src/commands/specEvent.ts
|
|
22925
23293
|
init_meter();
|
|
22926
|
-
import { readFileSync as
|
|
23294
|
+
import { readFileSync as readFileSync28, statSync as statSync2 } from "node:fs";
|
|
22927
23295
|
import { basename as basename6, isAbsolute as isAbsolute4, relative } from "node:path";
|
|
22928
23296
|
var HOOK_STDIN_TIMEOUT_MS3 = 1000;
|
|
22929
23297
|
var ESTIMATE_TIMEOUT_MS = 4000;
|
|
@@ -22979,7 +23347,7 @@ function readFileOrNull(path) {
|
|
|
22979
23347
|
try {
|
|
22980
23348
|
if (statSync2(path).size > 2000000)
|
|
22981
23349
|
return null;
|
|
22982
|
-
return
|
|
23350
|
+
return readFileSync28(path, "utf8");
|
|
22983
23351
|
} catch {
|
|
22984
23352
|
return null;
|
|
22985
23353
|
}
|
|
@@ -23308,10 +23676,10 @@ var announce = (o, events) => {
|
|
|
23308
23676
|
|
|
23309
23677
|
// src/commands/stopEvent.ts
|
|
23310
23678
|
init_meter();
|
|
23311
|
-
import { existsSync as existsSync27, readFileSync as
|
|
23679
|
+
import { existsSync as existsSync27, readFileSync as readFileSync29 } from "node:fs";
|
|
23312
23680
|
|
|
23313
23681
|
// src/transcript.ts
|
|
23314
|
-
var
|
|
23682
|
+
var isObject16 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
23315
23683
|
var n = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
23316
23684
|
function sumTranscript(text) {
|
|
23317
23685
|
const seen = new Set;
|
|
@@ -23332,7 +23700,7 @@ function sumTranscript(text) {
|
|
|
23332
23700
|
} catch {
|
|
23333
23701
|
continue;
|
|
23334
23702
|
}
|
|
23335
|
-
if (!
|
|
23703
|
+
if (!isObject16(j) || j.type !== "assistant" || !isObject16(j.message))
|
|
23336
23704
|
continue;
|
|
23337
23705
|
const m = j.message;
|
|
23338
23706
|
const id = typeof m.id === "string" ? m.id : typeof j.uuid === "string" ? j.uuid : undefined;
|
|
@@ -23341,7 +23709,7 @@ function sumTranscript(text) {
|
|
|
23341
23709
|
continue;
|
|
23342
23710
|
seen.add(id);
|
|
23343
23711
|
}
|
|
23344
|
-
const u =
|
|
23712
|
+
const u = isObject16(m.usage) ? m.usage : undefined;
|
|
23345
23713
|
if (!u)
|
|
23346
23714
|
continue;
|
|
23347
23715
|
const input = n(u.input_tokens);
|
|
@@ -23404,7 +23772,7 @@ async function postTranscript(o, payload, now) {
|
|
|
23404
23772
|
const src = meterSource(o.home);
|
|
23405
23773
|
if (!src)
|
|
23406
23774
|
return false;
|
|
23407
|
-
const read = o.readFile ?? ((p) => existsSync27(p) ?
|
|
23775
|
+
const read = o.readFile ?? ((p) => existsSync27(p) ? readFileSync29(p, "utf8") : null);
|
|
23408
23776
|
let text;
|
|
23409
23777
|
try {
|
|
23410
23778
|
text = read(path);
|
|
@@ -23482,7 +23850,7 @@ var stopEvent = async (o) => {
|
|
|
23482
23850
|
|
|
23483
23851
|
// src/commands/uninstall.ts
|
|
23484
23852
|
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
23485
|
-
import { existsSync as existsSync28, rmSync as
|
|
23853
|
+
import { existsSync as existsSync28, rmSync as rmSync17 } from "node:fs";
|
|
23486
23854
|
init_config();
|
|
23487
23855
|
init_meter();
|
|
23488
23856
|
init_settings();
|
|
@@ -23543,19 +23911,19 @@ var uninstall2 = (o) => {
|
|
|
23543
23911
|
}
|
|
23544
23912
|
for (const file of [meterCachePath(o.home), ...allSeatStatePaths(o.home)]) {
|
|
23545
23913
|
if (existsSync28(file)) {
|
|
23546
|
-
|
|
23914
|
+
rmSync17(file, { force: true });
|
|
23547
23915
|
removed.push(file);
|
|
23548
23916
|
}
|
|
23549
23917
|
}
|
|
23550
23918
|
const skill = skillDir(o.home);
|
|
23551
23919
|
if (existsSync28(skill)) {
|
|
23552
|
-
|
|
23920
|
+
rmSync17(skill, { recursive: true, force: true });
|
|
23553
23921
|
removed.push(skill);
|
|
23554
23922
|
}
|
|
23555
23923
|
const plist = musherPlistPath(o.home);
|
|
23556
23924
|
if (existsSync28(plist)) {
|
|
23557
23925
|
(o.unloadAgent ?? defaultUnload)(plist);
|
|
23558
|
-
|
|
23926
|
+
rmSync17(plist, { force: true });
|
|
23559
23927
|
removed.push(`launchd agent ${musherLabel()}`);
|
|
23560
23928
|
}
|
|
23561
23929
|
if (removed.length === 0) {
|
|
@@ -23708,17 +24076,17 @@ var webhooksCmd = async (o) => {
|
|
|
23708
24076
|
|
|
23709
24077
|
// src/config.ts
|
|
23710
24078
|
init_settings();
|
|
23711
|
-
import { chmodSync as
|
|
24079
|
+
import { chmodSync as chmodSync7, existsSync as existsSync29, mkdirSync as mkdirSync23, readFileSync as readFileSync30, renameSync as renameSync9, writeFileSync as writeFileSync26 } from "node:fs";
|
|
23712
24080
|
import { join as join26, resolve as resolve10 } from "node:path";
|
|
23713
24081
|
var configDir2 = (home, env = process.env) => {
|
|
23714
24082
|
const o = env.SLEDS_HOME?.trim();
|
|
23715
24083
|
return o ? resolve10(home, o) : join26(home, ".config", "sleds");
|
|
23716
24084
|
};
|
|
23717
24085
|
var configPath2 = (home) => join26(configDir2(home), "config.json");
|
|
23718
|
-
var
|
|
24086
|
+
var isObject17 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
23719
24087
|
var optString2 = (v) => typeof v === "string" ? v : undefined;
|
|
23720
24088
|
var parsePriorEnv2 = (v) => {
|
|
23721
|
-
if (!
|
|
24089
|
+
if (!isObject17(v))
|
|
23722
24090
|
return;
|
|
23723
24091
|
const out = {};
|
|
23724
24092
|
const url = optString2(v[BASE_URL_KEY]);
|
|
@@ -23733,7 +24101,7 @@ var parsePriorEnv2 = (v) => {
|
|
|
23733
24101
|
};
|
|
23734
24102
|
var parseSchedule2 = (v) => v === "launchd" || v === "systemd" || v === "manual" ? v : undefined;
|
|
23735
24103
|
var parseConfig2 = (raw) => {
|
|
23736
|
-
if (!
|
|
24104
|
+
if (!isObject17(raw))
|
|
23737
24105
|
return {};
|
|
23738
24106
|
const cfg = {};
|
|
23739
24107
|
const token = optString2(raw.token);
|
|
@@ -23783,11 +24151,11 @@ var parseConfig2 = (raw) => {
|
|
|
23783
24151
|
return cfg;
|
|
23784
24152
|
};
|
|
23785
24153
|
var parseOrgs2 = (raw) => {
|
|
23786
|
-
if (!
|
|
24154
|
+
if (!isObject17(raw))
|
|
23787
24155
|
return;
|
|
23788
24156
|
const out = {};
|
|
23789
24157
|
for (const [slug, v] of Object.entries(raw)) {
|
|
23790
|
-
if (!
|
|
24158
|
+
if (!isObject17(v))
|
|
23791
24159
|
continue;
|
|
23792
24160
|
const token = optString2(v.token);
|
|
23793
24161
|
if (!token)
|
|
@@ -23806,7 +24174,7 @@ var parseOrgs2 = (raw) => {
|
|
|
23806
24174
|
return Object.keys(out).length > 0 ? out : undefined;
|
|
23807
24175
|
};
|
|
23808
24176
|
var parseMusher2 = (raw) => {
|
|
23809
|
-
if (!
|
|
24177
|
+
if (!isObject17(raw))
|
|
23810
24178
|
return;
|
|
23811
24179
|
const out = {};
|
|
23812
24180
|
const pm = optString2(raw.permissionMode);
|
|
@@ -23822,7 +24190,7 @@ var parseMusher2 = (raw) => {
|
|
|
23822
24190
|
return out;
|
|
23823
24191
|
};
|
|
23824
24192
|
var parseOrgInfo2 = (raw) => {
|
|
23825
|
-
if (!
|
|
24193
|
+
if (!isObject17(raw) || !isObject17(raw.capabilities))
|
|
23826
24194
|
return;
|
|
23827
24195
|
const name = optString2(raw.name);
|
|
23828
24196
|
const slug = optString2(raw.slug);
|
|
@@ -23848,7 +24216,7 @@ var readConfig2 = (home) => {
|
|
|
23848
24216
|
const p = configPath2(home);
|
|
23849
24217
|
if (!existsSync29(p))
|
|
23850
24218
|
return {};
|
|
23851
|
-
return parseConfig2(JSON.parse(
|
|
24219
|
+
return parseConfig2(JSON.parse(readFileSync30(p, "utf8")));
|
|
23852
24220
|
};
|
|
23853
24221
|
|
|
23854
24222
|
// src/runners/exec.ts
|
|
@@ -23900,7 +24268,7 @@ var defaultExec5 = (cmd, args) => {
|
|
|
23900
24268
|
};
|
|
23901
24269
|
|
|
23902
24270
|
// src/settings.ts
|
|
23903
|
-
import { dirname as
|
|
24271
|
+
import { dirname as dirname18, join as join27, resolve as resolve11 } from "node:path";
|
|
23904
24272
|
var withSeatEnv2 = (command, home, env = process.env, org) => {
|
|
23905
24273
|
const parts = [];
|
|
23906
24274
|
const sh = env.SLEDS_HOME?.trim();
|
|
@@ -23923,15 +24291,16 @@ var pinOrg4 = (command, org) => {
|
|
|
23923
24291
|
return `${lead}SLEDS_ORG=${shellWord2(slug)} ${bare.slice(lead.length)}`;
|
|
23924
24292
|
};
|
|
23925
24293
|
var shellWord2 = (v) => /^[\w./~-]+$/.test(v) ? v : `'${v.replace(/'/g, "'\\''")}'`;
|
|
23926
|
-
var
|
|
24294
|
+
var isObject18 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
23927
24295
|
var isSledsHookFor2 = (sub) => (entry) => {
|
|
23928
|
-
if (!
|
|
24296
|
+
if (!isObject18(entry) || !Array.isArray(entry.hooks))
|
|
23929
24297
|
return false;
|
|
23930
24298
|
const re = new RegExp(`\\b${sub}\\b`);
|
|
23931
|
-
return entry.hooks.some((h) =>
|
|
24299
|
+
return entry.hooks.some((h) => isObject18(h) && h.type === "command" && typeof h.command === "string" && re.test(h.command));
|
|
23932
24300
|
};
|
|
23933
24301
|
var isSledsSessionHook2 = isSledsHookFor2("session-event");
|
|
23934
24302
|
var isSledsStopHook2 = isSledsHookFor2("stop-event");
|
|
24303
|
+
var isSledsPermissionHook2 = isSledsHookFor2("permission-event");
|
|
23935
24304
|
|
|
23936
24305
|
// src/index.ts
|
|
23937
24306
|
var USAGE3 = `usage: sleds <command> [options]
|
|
@@ -24081,6 +24450,8 @@ commands:
|
|
|
24081
24450
|
statusline Print the one-line meter Claude Code shows (installed by init; 10s cache).
|
|
24082
24451
|
hooks Register the Claude Code Notification hook for seat limits (init does this too).
|
|
24083
24452
|
seat-event Claude Code hook: record a seat wall and say how to continue. Reads hook JSON on stdin.
|
|
24453
|
+
permission-event --mark <file> Claude Code Notification hook the engine gives its sessions: on
|
|
24454
|
+
a permission dialog, write {message, at} to <file> for the engine. Local; exits 0.
|
|
24084
24455
|
session-event Claude Code SessionStart hook: states the loop and the rows this machine still
|
|
24085
24456
|
owes before the first turn. Reads hook JSON on stdin.
|
|
24086
24457
|
stop-event Claude Code Stop hook: a session that estimated a row and posted no actual is asked
|
|
@@ -24225,7 +24596,8 @@ var main = async (argv) => {
|
|
|
24225
24596
|
exec: defaultExec4,
|
|
24226
24597
|
runnerFor: runnerFor3,
|
|
24227
24598
|
sleep: (ms) => new Promise((r) => setTimeout(r, ms)),
|
|
24228
|
-
shouldStop: () => stopping
|
|
24599
|
+
shouldStop: () => stopping,
|
|
24600
|
+
sledsArgv: sledsArgv()
|
|
24229
24601
|
};
|
|
24230
24602
|
return cmd === "engine" ? engineCmd(io) : routeCmd(io);
|
|
24231
24603
|
}
|
|
@@ -24332,6 +24704,8 @@ var main = async (argv) => {
|
|
|
24332
24704
|
});
|
|
24333
24705
|
case "seat-event":
|
|
24334
24706
|
return seatEvent({ home });
|
|
24707
|
+
case "permission-event":
|
|
24708
|
+
return permissionEvent({ mark: stringFlag(flags, "mark") });
|
|
24335
24709
|
case "spec-event":
|
|
24336
24710
|
return specEvent({ home });
|
|
24337
24711
|
case "prompt-event":
|
|
@@ -24389,7 +24763,7 @@ ${renderHelpText(argv[1])}`);
|
|
|
24389
24763
|
case "version":
|
|
24390
24764
|
case "--version":
|
|
24391
24765
|
case "-v":
|
|
24392
|
-
console.log("sleds 0.1.
|
|
24766
|
+
console.log("sleds 0.1.39");
|
|
24393
24767
|
return 0;
|
|
24394
24768
|
default:
|
|
24395
24769
|
console.error(`unknown command: ${cmd}
|