@sleds/cli 0.1.68 → 0.1.69

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.
Files changed (2) hide show
  1. package/dist/sleds.mjs +176 -63
  2. package/package.json +1 -1
package/dist/sleds.mjs CHANGED
@@ -11563,7 +11563,20 @@ var mainCheckoutOf = (gitCommonDir, cwd) => {
11563
11563
  const main = dir.slice(0, -"/.git".length);
11564
11564
  return main && main !== cwd.replace(/\/+$/, "") ? main : null;
11565
11565
  };
11566
- var claudeAddDirFlag = (mainCheckout) => mainCheckout ? ` --add-dir=${shq(mainCheckout)}` : "";
11566
+ var trimDir = (dir) => dir.replace(/\/+$/, "") || "/";
11567
+ var within = (path, dir) => {
11568
+ const p = trimDir(path);
11569
+ const d = trimDir(dir);
11570
+ return p === d || p.startsWith(d === "/" ? "/" : `${d}/`);
11571
+ };
11572
+ var sessionReadDirs = (o) => {
11573
+ const cwd = trimDir(o.cwd);
11574
+ const dirs = [o.mainCheckout, ...o.worktrees ?? [], o.pnpmStore].filter((d) => !!d?.trim()).map(trimDir);
11575
+ return [...new Set(dirs)].filter((d) => d !== cwd);
11576
+ };
11577
+ var readOnlyDirs = (readDirs, cwd, keep = []) => readDirs.filter((d) => ![cwd, ...keep].some((p) => within(p, d)));
11578
+ var readOnlyDenyRules = (dirs) => dirs.map((d) => `Edit(${absRule(d)})`);
11579
+ var claudeAddDirFlag = (dirs = []) => dirs.map((d) => ` --add-dir=${shq(d)}`).join("");
11567
11580
  var shq = (s) => `'${s.replace(/'/g, `'\\''`)}'`;
11568
11581
 
11569
11582
  // src/runners/exec.ts
@@ -11609,15 +11622,15 @@ var agentShellCommand = (o) => {
11609
11622
  const prompt = `"$(cat ${shq2(o.promptFile)})"`;
11610
11623
  const agent = o.agent?.trim();
11611
11624
  if (agent)
11612
- return `${sandboxedAgent(agent, o.sandbox, o.mainCheckout)} ${prompt}`;
11625
+ return `${sandboxedAgent(agent, o.sandbox, o.readDirs)} ${prompt}`;
11613
11626
  const model = o.model ? ` --model ${shq2(o.model)}` : "";
11614
11627
  const effort = o.effort ? ` --effort ${shq2(o.effort)}` : "";
11615
- return `${sandboxedAgent("claude", o.sandbox, o.mainCheckout)}${hookSettingsFlag(o)}${mcpConfigFlag(o)} --permission-mode ${shq2(o.permissionMode)}${model}${effort} ${prompt}`;
11628
+ return `${sandboxedAgent("claude", o.sandbox, o.readDirs)}${hookSettingsFlag(o)}${mcpConfigFlag(o)} --permission-mode ${shq2(o.permissionMode)}${model}${effort} ${prompt}`;
11616
11629
  };
11617
11630
  var execLine = (cmd) => /^[A-Za-z_][A-Za-z0-9_]*=/.test(cmd) ? `exec env ${cmd}` : `exec ${cmd}`;
11618
- var sandboxedAgent = (agent, sandbox, mainCheckout) => {
11631
+ var sandboxedAgent = (agent, sandbox, readDirs) => {
11619
11632
  const kind = sandboxAgentKind(agent);
11620
- const line = kind === "claude" ? `${agent}${claudeAddDirFlag(mainCheckout)}` : agent;
11633
+ const line = kind === "claude" ? `${agent}${claudeAddDirFlag(readDirs)}` : agent;
11621
11634
  if (!sandbox)
11622
11635
  return line;
11623
11636
  if (kind === "claude")
@@ -12340,7 +12353,7 @@ function beatBody(state, flags, host = {}, cap = {}) {
12340
12353
  name: flags.name,
12341
12354
  os: host.os ?? process.platform,
12342
12355
  runner: flags.runner,
12343
- version: host.version ?? "0.1.68" ?? "dev",
12356
+ version: host.version ?? "0.1.69" ?? "dev",
12344
12357
  running: live.length,
12345
12358
  items: live.slice(0, BEAT_ITEMS).map((r) => `${r.item}/${r.node}`),
12346
12359
  ...cap.atOnce !== undefined ? { atOnce: cap.atOnce } : {},
@@ -14955,21 +14968,29 @@ function fingerprint(text) {
14955
14968
  function wordsPrint(screen) {
14956
14969
  return fingerprint(stripTuiChrome(screen));
14957
14970
  }
14958
- function sandboxFor(d, name, cwd, allow) {
14971
+ function sandboxFor(d, name, cwd, allow, readOnly) {
14959
14972
  if (!d.sandbox)
14960
14973
  return {};
14961
14974
  if (!d.writeSandboxSettings)
14962
14975
  throw new Error("sessions are sandboxed, but nothing writes their settings — not started");
14963
- return { sandbox: d.writeSandboxSettings(name, cwd, allow) };
14976
+ return { sandbox: d.writeSandboxSettings(name, cwd, allow, readOnly) };
14964
14977
  }
14965
- function hooksFor(d, name, allow) {
14978
+ function hooksFor(d, name, allow, readOnly) {
14966
14979
  if (d.sandbox || !d.writeHookSettings)
14967
14980
  return {};
14968
- return { settingsFile: d.writeHookSettings(name, allow) };
14981
+ return { settingsFile: d.writeHookSettings(name, allow, readOnly) };
14969
14982
  }
14970
- function mainCheckoutFor(d, cwd) {
14971
- const main = d.mainCheckoutOf?.(cwd);
14972
- return main ? { mainCheckout: main } : {};
14983
+ function wallsFor(d, name, cwd, allow) {
14984
+ let readDirs = [];
14985
+ try {
14986
+ readDirs = d.readDirsOf?.(cwd) ?? [];
14987
+ } catch {}
14988
+ const readOnly = readOnlyDirs(readDirs, cwd);
14989
+ return {
14990
+ ...sandboxFor(d, name, cwd, allow, readOnly),
14991
+ ...hooksFor(d, name, allow, readOnly),
14992
+ ...readDirs.length ? { readDirs } : {}
14993
+ };
14973
14994
  }
14974
14995
  function engineMcpConfigFor(d, name, runToken, at, cwd) {
14975
14996
  if (d.source.name !== "sleds" || d.agent?.trim() || !d.writeMcpConfig)
@@ -15519,9 +15540,7 @@ async function tickOnce(d) {
15519
15540
  ...launch.effort && !launch.agent ? { effort: launch.effort } : {},
15520
15541
  ...launch.agent ? { agent: launch.agent } : {},
15521
15542
  ...mcpConfig ? { mcpConfig, ...d.strictMcp ? { strictMcp: true } : {} } : {},
15522
- ...sandboxFor(d, name, worktree, allow),
15523
- ...hooksFor(d, name, allow),
15524
- ...mainCheckoutFor(d, worktree),
15543
+ ...wallsFor(d, name, worktree, allow),
15525
15544
  ...claim.group ? { group: claim.group } : {}
15526
15545
  };
15527
15546
  } catch (e) {
@@ -16398,9 +16417,7 @@ async function startAnswerer(d, answers, run) {
16398
16417
  permissionMode: d.permissionMode,
16399
16418
  ...launchOptions(launch),
16400
16419
  ...mcpConfig ? { mcpConfig, ...d.strictMcp ? { strictMcp: true } : {} } : {},
16401
- ...sandboxFor(d, name, run.handle.cwd),
16402
- ...hooksFor(d, name),
16403
- ...mainCheckoutFor(d, run.handle.cwd),
16420
+ ...wallsFor(d, name, run.handle.cwd),
16404
16421
  ...run.group ? { group: run.group } : {}
16405
16422
  });
16406
16423
  } catch (e) {
@@ -16608,9 +16625,7 @@ async function startDraft(d, claim, why, state, started, finished) {
16608
16625
  permissionMode: d.permissionMode,
16609
16626
  ...launchOptions(launch),
16610
16627
  ...mcpConfig ? { mcpConfig, ...d.strictMcp ? { strictMcp: true } : {} } : {},
16611
- ...sandboxFor(d, name, worktree),
16612
- ...hooksFor(d, name),
16613
- ...mainCheckoutFor(d, worktree)
16628
+ ...wallsFor(d, name, worktree)
16614
16629
  });
16615
16630
  } catch (e) {
16616
16631
  d.log(`${at}: could not start the drafter: ${message(e)}`);
@@ -16789,9 +16804,7 @@ async function startMock(d, claim, state, started, finished) {
16789
16804
  promptFile: d.writePrompt(name, prompt),
16790
16805
  permissionMode: d.permissionMode,
16791
16806
  ...launchOptions(launch),
16792
- ...sandboxFor(d, name, worktree, allow),
16793
- ...hooksFor(d, name, allow),
16794
- ...mainCheckoutFor(d, worktree)
16807
+ ...wallsFor(d, name, worktree, allow)
16795
16808
  });
16796
16809
  } catch (e) {
16797
16810
  await fail(`the engine could not start the session: ${message(e)}`);
@@ -17678,9 +17691,7 @@ function restartInWorktree(d, run, name, prompt, base) {
17678
17691
  permissionMode: d.permissionMode,
17679
17692
  ...launchOptions(launch),
17680
17693
  ...run.mcpConfig ? { mcpConfig: run.mcpConfig, ...d.strictMcp ? { strictMcp: true } : {} } : {},
17681
- ...sandboxFor(d, name, run.handle.cwd),
17682
- ...hooksFor(d, name),
17683
- ...mainCheckoutFor(d, run.handle.cwd),
17694
+ ...wallsFor(d, name, run.handle.cwd),
17684
17695
  ...run.group ? { group: run.group } : {}
17685
17696
  };
17686
17697
  run.handle = runner.makesWorktree ? runner.reopen(run.handle, o) : runner.start(o);
@@ -17814,9 +17825,7 @@ async function startEventAnswerer(d, answers, state, dec, decided) {
17814
17825
  permissionMode: d.permissionMode,
17815
17826
  ...launchOptions(launch),
17816
17827
  ...mcpConfig ? { mcpConfig, ...d.strictMcp ? { strictMcp: true } : {} } : {},
17817
- ...sandboxFor(d, name, worktree),
17818
- ...hooksFor(d, name),
17819
- ...mainCheckoutFor(d, worktree)
17828
+ ...wallsFor(d, name, worktree)
17820
17829
  });
17821
17830
  } catch (e) {
17822
17831
  d.log(`${at}: could not start the ${KIND_SAYS[kind]} answerer — it goes to a person: ${message(e)}`);
@@ -18344,8 +18353,8 @@ ${renderTranscript(messages)}`;
18344
18353
  var headlessScript = (o, log) => {
18345
18354
  const prompt = `"$(cat ${shq2(o.promptFile)})"`;
18346
18355
  const agent = o.agent?.trim();
18347
- const cmd = agent ? `${sandboxedAgent(agent, o.sandbox, o.mainCheckout)} ${prompt}` : [
18348
- `${sandboxedAgent("claude", o.sandbox, o.mainCheckout)} -p`,
18356
+ const cmd = agent ? `${sandboxedAgent(agent, o.sandbox, o.readDirs)} ${prompt}` : [
18357
+ `${sandboxedAgent("claude", o.sandbox, o.readDirs)} -p`,
18349
18358
  prompt,
18350
18359
  ...o.mcpConfig ? [mcpConfigFlag(o).trim()] : [],
18351
18360
  "--output-format stream-json --verbose",
@@ -19224,7 +19233,7 @@ async function fetchVersion(o) {
19224
19233
  const platform = o.platform ?? process.platform;
19225
19234
  const arch = o.arch ?? process.arch;
19226
19235
  const publicKey = o.publicKey ?? RELEASE_PUBLIC_KEY;
19227
- const running = o.running ?? "0.1.68";
19236
+ const running = o.running ?? "0.1.69";
19228
19237
  if (!publicKey)
19229
19238
  return { ok: false, why: "no release key yet" };
19230
19239
  if (!VERSION_RE2.test(o.version))
@@ -20450,7 +20459,7 @@ function engineUpdater(o) {
20450
20459
 
20451
20460
  // src/version.ts
20452
20461
  function cliVersion(env) {
20453
- return "0.1.68";
20462
+ return "0.1.69";
20454
20463
  }
20455
20464
 
20456
20465
  // src/commands/update.ts
@@ -20836,7 +20845,7 @@ function engineClient(o, org, breaker) {
20836
20845
  ...src,
20837
20846
  ...breaker ? { fetchFn: breaker.fetch } : {},
20838
20847
  timeoutMs: ENGINE_TIMEOUT_MS,
20839
- version: "0.1.68"
20848
+ version: "0.1.69"
20840
20849
  });
20841
20850
  const asked = org?.trim() || env.SLEDS_ORG?.trim();
20842
20851
  if (asked && !selectOrg(readConfig(o.home), org, env).seat)
@@ -20912,6 +20921,7 @@ function engineDeps(o, flags, source, runner, stateName) {
20912
20921
  const reposDirs = splitReposDirs(flags.reposDir).map((d) => resolve9(cwd, d));
20913
20922
  const { branch, prTitle } = flags;
20914
20923
  const hooksDir = join25(stateDir, "hooks");
20924
+ const pnpmStores = new Map;
20915
20925
  const permissionMark = (name) => join25(hooksDir, `${name}.permission.json`);
20916
20926
  const withHook = (name, settings) => applyPermissionHook(settings, [...o.sledsArgv ?? ["sleds"], "permission-event", "--mark", permissionMark(name)].map(shq2).join(" "));
20917
20927
  return {
@@ -20935,7 +20945,7 @@ function engineDeps(o, flags, source, runner, stateName) {
20935
20945
  ...flags.strictMcp ? { strictMcp: true } : {},
20936
20946
  ...flags.sandbox ? {
20937
20947
  sandbox: true,
20938
- writeSandboxSettings: o.writeSandboxSettings ?? ((name, cwd, allow) => {
20948
+ writeSandboxSettings: o.writeSandboxSettings ?? ((name, cwd, allow, readOnly) => {
20939
20949
  const gitCommonDir = gitCommonDirOf(exec, cwd);
20940
20950
  const dir = join25(stateDir, "sandbox");
20941
20951
  mkdirSync18(dir, { recursive: true, mode: 448 });
@@ -20947,6 +20957,12 @@ function engineDeps(o, flags, source, runner, stateName) {
20947
20957
  walls.permissions.allow = [
20948
20958
  ...new Set([...walls.permissions.allow, ...allow ?? []])
20949
20959
  ];
20960
+ walls.permissions.deny = [
20961
+ ...new Set([
20962
+ ...walls.permissions.deny,
20963
+ ...readOnlyDenyRules(readOnlyDirs(readOnly ?? [], cwd, [gitCommonDir]))
20964
+ ])
20965
+ ];
20950
20966
  const settings = withHook(name, { ...walls });
20951
20967
  writeFileSync16(p, `${JSON.stringify(settings, null, 2)}
20952
20968
  `, { mode: 384 });
@@ -20954,23 +20970,22 @@ function engineDeps(o, flags, source, runner, stateName) {
20954
20970
  return { settingsFile: p, gitCommonDir };
20955
20971
  })
20956
20972
  } : {},
20957
- writeHookSettings: (name, allow) => {
20973
+ writeHookSettings: (name, allow, readOnly) => {
20958
20974
  mkdirSync18(hooksDir, { recursive: true, mode: 448 });
20959
20975
  const p = join25(hooksDir, `${name}.json`);
20960
- const base = allow?.length ? { permissions: { allow: [...allow] } } : {};
20976
+ const deny = readOnlyDenyRules(readOnly ?? []);
20977
+ const permissions = {
20978
+ ...allow?.length ? { allow: [...allow] } : {},
20979
+ ...deny.length ? { deny } : {}
20980
+ };
20981
+ const base = Object.keys(permissions).length ? { permissions } : {};
20961
20982
  writeFileSync16(p, `${JSON.stringify(withHook(name, base), null, 2)}
20962
20983
  `, { mode: 384 });
20963
20984
  chmodSync5(p, 384);
20964
20985
  return p;
20965
20986
  },
20966
20987
  permissionMark,
20967
- mainCheckoutOf: o.mainCheckoutOf ?? ((cwd) => {
20968
- try {
20969
- return mainCheckoutOf(gitCommonDirOf(exec, cwd), cwd);
20970
- } catch {
20971
- return null;
20972
- }
20973
- }),
20988
+ readDirsOf: o.readDirsOf ?? ((dir) => engineReadDirs(exec, dir, exists, pnpmStores)),
20974
20989
  ...branch ? { branchOf: (claim) => branchFor(branch, claim) } : {},
20975
20990
  ...prTitle ? { prTitleOf: (claim) => prTitleFor(prTitle, claim) } : {},
20976
20991
  now: o.now ?? Date.now,
@@ -21072,6 +21087,52 @@ function gitCommonDirOf(exec, cwd) {
21072
21087
  throw new Error(`git has no common dir for ${cwd}, so the sandbox has nowhere to commit`);
21073
21088
  return resolve9(cwd, dir);
21074
21089
  }
21090
+ function worktreeListPaths(porcelain) {
21091
+ return porcelain.split(/\n\s*\n/).map((block) => block.split(`
21092
+ `).map((l) => l.trim())).filter((lines) => !lines.some((l) => l === "bare" || l.startsWith("prunable"))).flatMap((lines) => {
21093
+ const wt = lines.find((l) => l.startsWith("worktree "));
21094
+ return wt ? [wt.slice("worktree ".length)] : [];
21095
+ });
21096
+ }
21097
+ var PNPM_STORE_TIMEOUT_MS = 1e4;
21098
+ function engineReadDirs(exec, cwd, exists, stores) {
21099
+ let common = null;
21100
+ try {
21101
+ common = gitCommonDirOf(exec, cwd);
21102
+ } catch {}
21103
+ const worktrees = (() => {
21104
+ try {
21105
+ const r = exec("git", ["-C", cwd, "worktree", "list", "--porcelain"]);
21106
+ return r.status === 0 ? worktreeListPaths(r.stdout) : [];
21107
+ } catch {
21108
+ return [];
21109
+ }
21110
+ })();
21111
+ const pnpmStore = (() => {
21112
+ try {
21113
+ if (!exists(join25(cwd, "pnpm-lock.yaml")))
21114
+ return null;
21115
+ const key = common ?? cwd;
21116
+ const known = stores.get(key);
21117
+ if (known)
21118
+ return known;
21119
+ const r = exec("pnpm", ["store", "path"], { cwd, timeoutMs: PNPM_STORE_TIMEOUT_MS });
21120
+ const dir = r.status === 0 ? r.stdout.split(`
21121
+ `).map((l) => l.trim()).filter((l) => l.startsWith("/")).pop() : undefined;
21122
+ if (dir)
21123
+ stores.set(key, dir);
21124
+ return dir ?? null;
21125
+ } catch {
21126
+ return null;
21127
+ }
21128
+ })();
21129
+ return sessionReadDirs({
21130
+ mainCheckout: common ? mainCheckoutOf(common, cwd) : null,
21131
+ worktrees,
21132
+ pnpmStore,
21133
+ cwd
21134
+ });
21135
+ }
21075
21136
  var LENT_NEEDS_SANDBOX = "a lent engine runs every session sandboxed (spec 48 rule 10) — add --sandbox to --lent-by";
21076
21137
  function lenderHome(accountHome, lentBy) {
21077
21138
  return isAbsolute3(lentBy) ? resolve9(lentBy) : join25(dirname16(accountHome), lentBy);
@@ -21142,7 +21203,7 @@ async function driveEngine(o, flags, deps, until = {}) {
21142
21203
  runner: deps.runner.name,
21143
21204
  atOnce: flags.atOnce,
21144
21205
  interval: flags.interval,
21145
- cliVersion: "0.1.68"
21206
+ cliVersion: "0.1.69"
21146
21207
  };
21147
21208
  const beat = (checkedAt) => {
21148
21209
  const m = deps.machine;
@@ -23020,7 +23081,7 @@ function engineClient2(o, org, breaker) {
23020
23081
  ...src,
23021
23082
  ...breaker ? { fetchFn: breaker.fetch } : {},
23022
23083
  timeoutMs: ENGINE_TIMEOUT_MS2,
23023
- version: "0.1.68"
23084
+ version: "0.1.69"
23024
23085
  });
23025
23086
  const asked = org?.trim() || env.SLEDS_ORG?.trim();
23026
23087
  if (asked && !selectOrg(readConfig(o.home), org, env).seat)
@@ -23118,6 +23179,7 @@ function engineDeps2(o, flags, source, runner, stateName) {
23118
23179
  const reposDirs = splitReposDirs(flags.reposDir).map((d) => resolve11(cwd, d));
23119
23180
  const { branch, prTitle } = flags;
23120
23181
  const hooksDir = join28(stateDir, "hooks");
23182
+ const pnpmStores = new Map;
23121
23183
  const permissionMark = (name) => join28(hooksDir, `${name}.permission.json`);
23122
23184
  const withHook = (name, settings) => applyPermissionHook(settings, [...o.sledsArgv ?? ["sleds"], "permission-event", "--mark", permissionMark(name)].map(shq2).join(" "));
23123
23185
  return {
@@ -23141,7 +23203,7 @@ function engineDeps2(o, flags, source, runner, stateName) {
23141
23203
  ...flags.strictMcp ? { strictMcp: true } : {},
23142
23204
  ...flags.sandbox ? {
23143
23205
  sandbox: true,
23144
- writeSandboxSettings: o.writeSandboxSettings ?? ((name, cwd, allow) => {
23206
+ writeSandboxSettings: o.writeSandboxSettings ?? ((name, cwd, allow, readOnly) => {
23145
23207
  const gitCommonDir = gitCommonDirOf2(exec, cwd);
23146
23208
  const dir = join28(stateDir, "sandbox");
23147
23209
  mkdirSync21(dir, { recursive: true, mode: 448 });
@@ -23153,6 +23215,12 @@ function engineDeps2(o, flags, source, runner, stateName) {
23153
23215
  walls.permissions.allow = [
23154
23216
  ...new Set([...walls.permissions.allow, ...allow ?? []])
23155
23217
  ];
23218
+ walls.permissions.deny = [
23219
+ ...new Set([
23220
+ ...walls.permissions.deny,
23221
+ ...readOnlyDenyRules(readOnlyDirs(readOnly ?? [], cwd, [gitCommonDir]))
23222
+ ])
23223
+ ];
23156
23224
  const settings = withHook(name, { ...walls });
23157
23225
  writeFileSync20(p, `${JSON.stringify(settings, null, 2)}
23158
23226
  `, { mode: 384 });
@@ -23160,23 +23228,22 @@ function engineDeps2(o, flags, source, runner, stateName) {
23160
23228
  return { settingsFile: p, gitCommonDir };
23161
23229
  })
23162
23230
  } : {},
23163
- writeHookSettings: (name, allow) => {
23231
+ writeHookSettings: (name, allow, readOnly) => {
23164
23232
  mkdirSync21(hooksDir, { recursive: true, mode: 448 });
23165
23233
  const p = join28(hooksDir, `${name}.json`);
23166
- const base = allow?.length ? { permissions: { allow: [...allow] } } : {};
23234
+ const deny = readOnlyDenyRules(readOnly ?? []);
23235
+ const permissions = {
23236
+ ...allow?.length ? { allow: [...allow] } : {},
23237
+ ...deny.length ? { deny } : {}
23238
+ };
23239
+ const base = Object.keys(permissions).length ? { permissions } : {};
23167
23240
  writeFileSync20(p, `${JSON.stringify(withHook(name, base), null, 2)}
23168
23241
  `, { mode: 384 });
23169
23242
  chmodSync6(p, 384);
23170
23243
  return p;
23171
23244
  },
23172
23245
  permissionMark,
23173
- mainCheckoutOf: o.mainCheckoutOf ?? ((cwd) => {
23174
- try {
23175
- return mainCheckoutOf(gitCommonDirOf2(exec, cwd), cwd);
23176
- } catch {
23177
- return null;
23178
- }
23179
- }),
23246
+ readDirsOf: o.readDirsOf ?? ((dir) => engineReadDirs2(exec, dir, exists, pnpmStores)),
23180
23247
  ...branch ? { branchOf: (claim) => branchFor(branch, claim) } : {},
23181
23248
  ...prTitle ? { prTitleOf: (claim) => prTitleFor(prTitle, claim) } : {},
23182
23249
  now: o.now ?? Date.now,
@@ -23278,6 +23345,52 @@ function gitCommonDirOf2(exec, cwd) {
23278
23345
  throw new Error(`git has no common dir for ${cwd}, so the sandbox has nowhere to commit`);
23279
23346
  return resolve11(cwd, dir);
23280
23347
  }
23348
+ function worktreeListPaths2(porcelain) {
23349
+ return porcelain.split(/\n\s*\n/).map((block) => block.split(`
23350
+ `).map((l) => l.trim())).filter((lines) => !lines.some((l) => l === "bare" || l.startsWith("prunable"))).flatMap((lines) => {
23351
+ const wt = lines.find((l) => l.startsWith("worktree "));
23352
+ return wt ? [wt.slice("worktree ".length)] : [];
23353
+ });
23354
+ }
23355
+ var PNPM_STORE_TIMEOUT_MS2 = 1e4;
23356
+ function engineReadDirs2(exec, cwd, exists, stores) {
23357
+ let common = null;
23358
+ try {
23359
+ common = gitCommonDirOf2(exec, cwd);
23360
+ } catch {}
23361
+ const worktrees = (() => {
23362
+ try {
23363
+ const r = exec("git", ["-C", cwd, "worktree", "list", "--porcelain"]);
23364
+ return r.status === 0 ? worktreeListPaths2(r.stdout) : [];
23365
+ } catch {
23366
+ return [];
23367
+ }
23368
+ })();
23369
+ const pnpmStore = (() => {
23370
+ try {
23371
+ if (!exists(join28(cwd, "pnpm-lock.yaml")))
23372
+ return null;
23373
+ const key = common ?? cwd;
23374
+ const known = stores.get(key);
23375
+ if (known)
23376
+ return known;
23377
+ const r = exec("pnpm", ["store", "path"], { cwd, timeoutMs: PNPM_STORE_TIMEOUT_MS2 });
23378
+ const dir = r.status === 0 ? r.stdout.split(`
23379
+ `).map((l) => l.trim()).filter((l) => l.startsWith("/")).pop() : undefined;
23380
+ if (dir)
23381
+ stores.set(key, dir);
23382
+ return dir ?? null;
23383
+ } catch {
23384
+ return null;
23385
+ }
23386
+ })();
23387
+ return sessionReadDirs({
23388
+ mainCheckout: common ? mainCheckoutOf(common, cwd) : null,
23389
+ worktrees,
23390
+ pnpmStore,
23391
+ cwd
23392
+ });
23393
+ }
23281
23394
  function sandboxRefusal(flags) {
23282
23395
  if (flags.lentBy && !flags.sandbox)
23283
23396
  return LENT_NEEDS_SANDBOX2;
@@ -23361,7 +23474,7 @@ async function driveEngine2(o, flags, deps, until = {}) {
23361
23474
  runner: deps.runner.name,
23362
23475
  atOnce: flags.atOnce,
23363
23476
  interval: flags.interval,
23364
- cliVersion: "0.1.68"
23477
+ cliVersion: "0.1.69"
23365
23478
  };
23366
23479
  const beat = (checkedAt) => {
23367
23480
  const m = deps.machine;
@@ -25472,7 +25585,7 @@ function contextFor(deps) {
25472
25585
  ...src,
25473
25586
  fetchFn: deps.fetchFn,
25474
25587
  timeoutMs: deps.timeoutMs,
25475
- version: "0.1.68"
25588
+ version: "0.1.69"
25476
25589
  }), deps.home, now) : null;
25477
25590
  return {
25478
25591
  channel: "code",
@@ -32040,7 +32153,7 @@ var realPidAlive4 = (pid) => {
32040
32153
  };
32041
32154
  function machineClient(home, env) {
32042
32155
  const src = meterSource(home, undefined, { env });
32043
- return src ? fetchClient({ ...src, version: "0.1.68" }) : null;
32156
+ return src ? fetchClient({ ...src, version: "0.1.69" }) : null;
32044
32157
  }
32045
32158
  async function noteAnswer2(home, a, now) {
32046
32159
  try {
@@ -32991,7 +33104,7 @@ var main = async (argv) => {
32991
33104
  now: Date.now(),
32992
33105
  stderr: (line) => console.error(line),
32993
33106
  isTTY: !!process.stderr.isTTY,
32994
- version: "0.1.68"
33107
+ version: "0.1.69"
32995
33108
  });
32996
33109
  switch (cmd) {
32997
33110
  case "update":
@@ -33255,7 +33368,7 @@ ${renderHelpText(argv[1])}`);
33255
33368
  case "version":
33256
33369
  case "--version":
33257
33370
  case "-v":
33258
- console.log("sleds 0.1.68");
33371
+ console.log("sleds 0.1.69");
33259
33372
  return 0;
33260
33373
  default:
33261
33374
  console.error(`unknown command: ${cmd}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sleds/cli",
3
- "version": "0.1.68",
3
+ "version": "0.1.69",
4
4
  "description": "SLEDS CLI — the cost and limits of AI agent work, decided at the wall. Point Claude Code at a SLEDS proxy; estimate before you run; hold, switch model, or run overnight when you hit a limit.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",