@sleds/cli 0.1.14 → 0.1.15

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 +58 -28
  2. package/package.json +1 -1
package/dist/sleds.mjs CHANGED
@@ -24,7 +24,7 @@ import { dirname, join, resolve } from "node:path";
24
24
  var BASE_URL_KEY = "ANTHROPIC_BASE_URL", AUTH_TOKEN_KEY = "ANTHROPIC_AUTH_TOKEN", claudeDir = (home, env = process.env) => {
25
25
  const o = env.CLAUDE_CONFIG_DIR?.trim();
26
26
  return o ? resolve(home, o) : join(home, ".claude");
27
- }, hasHomeOverride = (env = process.env) => Boolean(env.SLEDS_HOME?.trim() || env.CLAUDE_CONFIG_DIR?.trim()), settingsPath = (home) => join(claudeDir(home), "settings.json"), sledsCommand = (sub, home, env = process.env) => {
27
+ }, hasHomeOverride = (env = process.env) => Boolean(env.SLEDS_HOME?.trim() || env.CLAUDE_CONFIG_DIR?.trim()), settingsPath = (home) => join(claudeDir(home), "settings.json"), sledsCommand = (sub, home, env = process.env) => withSeatEnv(`sleds ${sub}`, home, env), withSeatEnv = (command, home, env = process.env) => {
28
28
  const parts = [];
29
29
  const sh = env.SLEDS_HOME?.trim();
30
30
  const cc = env.CLAUDE_CONFIG_DIR?.trim();
@@ -32,7 +32,7 @@ var BASE_URL_KEY = "ANTHROPIC_BASE_URL", AUTH_TOKEN_KEY = "ANTHROPIC_AUTH_TOKEN"
32
32
  parts.push(`SLEDS_HOME=${shellWord(resolve(home, sh))}`);
33
33
  if (cc)
34
34
  parts.push(`CLAUDE_CONFIG_DIR=${shellWord(resolve(home, cc))}`);
35
- parts.push(`sleds ${sub}`);
35
+ parts.push(command);
36
36
  return parts.join(" ");
37
37
  }, sledsCommandsIn = (settings) => {
38
38
  const out = [];
@@ -531,7 +531,7 @@ __export(exports_seat, {
531
531
  writeSeatState: () => writeSeatState2
532
532
  });
533
533
  import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync10, renameSync as renameSync5, writeFileSync as writeFileSync10 } from "node:fs";
534
- import { join as join10 } from "node:path";
534
+ import { join as join11 } from "node:path";
535
535
  var SEAT_POST_MIN_DELTA_PCT2 = 1, SEAT_POST_MIN_INTERVAL_MS2, SEAT_POST_TIMEOUT_MS2 = 1500, STDIN_TIMEOUT_MS2 = 300, isObject9 = (v) => typeof v === "object" && v !== null && !Array.isArray(v), num5 = (v) => typeof v === "number" && Number.isFinite(v) ? v : undefined, EPOCH_MS_THRESHOLD2 = 100000000000, parseResetsAt2 = (v) => {
536
536
  const n = num5(v);
537
537
  if (n !== undefined) {
@@ -604,7 +604,7 @@ var SEAT_POST_MIN_DELTA_PCT2 = 1, SEAT_POST_MIN_INTERVAL_MS2, SEAT_POST_TIMEOUT_
604
604
  if (parts.length === 0)
605
605
  return null;
606
606
  return `seat ${parts.join(SEP)}`;
607
- }, seatStatePath2 = (home) => join10(configDir(home), "seat.json"), parseWindowStored2 = (v) => {
607
+ }, seatStatePath2 = (home) => join11(configDir(home), "seat.json"), parseWindowStored2 = (v) => {
608
608
  if (!isObject9(v))
609
609
  return;
610
610
  const capturedAt = num5(v.capturedAt);
@@ -750,9 +750,9 @@ var SEAT_POST_MIN_DELTA_PCT2 = 1, SEAT_POST_MIN_INTERVAL_MS2, SEAT_POST_TIMEOUT_
750
750
  } catch {
751
751
  return false;
752
752
  }
753
- }, postSeatWindow2 = (o, w) => postJson2(o, "/proxy/seat", seatWindowBody2(w)), postSeatWall2 = (o, input) => postJson2(o, "/proxy/seat-wall", input), SEAT_WALL_LINE2 = "Seat limit hit. sleds on --until-reset to continue on the org key, or sleds defer to resume here at the reset.", SEAT_WALL_LINE_NO_KEY2 = "Seat limit hit. sleds defer resumes this session on this Mac at the reset; /sled 5 to hand off — this org has no platform key to switch to.", seatWallLine2 = (hasUpstreamKey) => hasUpstreamKey ? SEAT_WALL_LINE2 : SEAT_WALL_LINE_NO_KEY2, readStdin2 = (timeoutMs, stdin = process.stdin) => new Promise((resolve4) => {
753
+ }, postSeatWindow2 = (o, w) => postJson2(o, "/proxy/seat", seatWindowBody2(w)), postSeatWall2 = (o, input) => postJson2(o, "/proxy/seat-wall", input), SEAT_WALL_LINE2 = "Seat limit hit. sleds on --until-reset to continue on the org key, or sleds defer to resume here at the reset.", SEAT_WALL_LINE_NO_KEY2 = "Seat limit hit. sleds defer resumes this session on this Mac at the reset; /sled 5 to hand off — this org has no platform key to switch to.", seatWallLine2 = (hasUpstreamKey) => hasUpstreamKey ? SEAT_WALL_LINE2 : SEAT_WALL_LINE_NO_KEY2, readStdin2 = (timeoutMs, stdin = process.stdin) => new Promise((resolve5) => {
754
754
  if (stdin.isTTY) {
755
- resolve4("");
755
+ resolve5("");
756
756
  return;
757
757
  }
758
758
  let data = "";
@@ -762,7 +762,7 @@ var SEAT_POST_MIN_DELTA_PCT2 = 1, SEAT_POST_MIN_INTERVAL_MS2, SEAT_POST_TIMEOUT_
762
762
  return;
763
763
  settled = true;
764
764
  clearTimeout(timer);
765
- resolve4(data);
765
+ resolve5(data);
766
766
  };
767
767
  const timer = setTimeout(finish, timeoutMs);
768
768
  stdin.setEncoding("utf8");
@@ -793,13 +793,20 @@ import { hostname } from "node:os";
793
793
  // src/musher.ts
794
794
  import { spawnSync } from "node:child_process";
795
795
  import { createPublicKey, verify as cryptoVerify } from "node:crypto";
796
- import { dirname as dirname2, join as join4 } from "node:path";
796
+ import { basename, dirname as dirname2, join as join4 } from "node:path";
797
797
  var MUSHER_LABEL = "ai.sleds.musher";
798
798
  var MUSHER_INTERVAL_S = 300;
799
799
  var DEFAULT_PERMISSION_MODE = "acceptEdits";
800
800
  var DEFAULT_TIMEOUT_MINUTES = 90;
801
801
  var SUMMARY_MAX = 2000;
802
- var musherPlistPath = (home) => join4(home, "Library", "LaunchAgents", `${MUSHER_LABEL}.plist`);
802
+ var musherLabel = (env = process.env) => {
803
+ const sh = env.SLEDS_HOME?.trim();
804
+ if (!sh)
805
+ return MUSHER_LABEL;
806
+ const tag = basename(sh).replace(/^\.+/, "").replace(/[^A-Za-z0-9_-]+/g, "-") || "seat";
807
+ return `${MUSHER_LABEL}.${tag}`;
808
+ };
809
+ var musherPlistPath = (home, env = process.env) => join4(home, "Library", "LaunchAgents", `${musherLabel(env)}.plist`);
803
810
  var musherLogPath = (configDir2) => join4(configDir2, "musher.log");
804
811
  var xmlEscape = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
805
812
  var musherPath = (home, execPath, currentPath = "") => {
@@ -817,6 +824,7 @@ var musherPath = (home, execPath, currentPath = "") => {
817
824
  return [...new Set(parts)].join(":");
818
825
  };
819
826
  var buildMusherPlist = (o) => {
827
+ const label = o.label ?? MUSHER_LABEL;
820
828
  const args = [...o.sledsArgv, "musher", "tick"].map((a) => ` <string>${xmlEscape(a)}</string>`).join(`
821
829
  `);
822
830
  const env = Object.entries(o.env).filter(([, v]) => v !== "").map(([k, v]) => ` <key>${xmlEscape(k)}</key>
@@ -827,7 +835,7 @@ var buildMusherPlist = (o) => {
827
835
  <plist version="1.0">
828
836
  <dict>
829
837
  <key>Label</key>
830
- <string>${MUSHER_LABEL}</string>
838
+ <string>${label}</string>
831
839
  <key>ProgramArguments</key>
832
840
  <array>
833
841
  ${args}
@@ -1500,7 +1508,7 @@ var findClaude = (home, configured, which) => {
1500
1508
  return null;
1501
1509
  };
1502
1510
  var musherAgentState = (home, env = process.env) => {
1503
- const plist = musherPlistPath(home);
1511
+ const plist = musherPlistPath(home, env);
1504
1512
  if (!existsSync6(plist))
1505
1513
  return { installed: false, thisSeat: false };
1506
1514
  try {
@@ -1696,7 +1704,11 @@ async function runDoctor(o) {
1696
1704
  name: "musher",
1697
1705
  detail: "agent installed for a different seat (SLEDS_HOME differs)",
1698
1706
  fix: "sleds musher --install"
1699
- } : { level: "ok", name: "musher", detail: `launchd agent ${MUSHER_LABEL}, every 5 min` });
1707
+ } : {
1708
+ level: "ok",
1709
+ name: "musher",
1710
+ detail: `launchd agent ${musherLabel(env)}, every 5 min`
1711
+ });
1700
1712
  const claude = findClaude(home, readConfig(home).musher?.claudePath, (c) => (o.which ?? defaultWhich2)(c)[0] ?? null);
1701
1713
  checks.push(claude ? { level: "ok", name: "claude cli", detail: claude } : {
1702
1714
  level: "warn",
@@ -2770,7 +2782,8 @@ var musherInstall = (o) => {
2770
2782
  return 1;
2771
2783
  }
2772
2784
  const env = o.env ?? process.env;
2773
- const plist = musherPlistPath(o.home);
2785
+ const plist = musherPlistPath(o.home, env);
2786
+ const label = musherLabel(env);
2774
2787
  const dir = configDir(o.home, env);
2775
2788
  mkdirSync7(dirname3(plist), { recursive: true });
2776
2789
  mkdirSync7(dir, { recursive: true, mode: 448 });
@@ -2784,7 +2797,7 @@ var musherInstall = (o) => {
2784
2797
  const exec = o.exec ?? defaultExecSync;
2785
2798
  if (existsSync8(plist))
2786
2799
  exec("launchctl", ["unload", plist]);
2787
- writeFileSync7(plist, buildMusherPlist({ sledsArgv: o.sledsArgv, env: agentEnv, logPath: musherLogPath(dir) }));
2800
+ writeFileSync7(plist, buildMusherPlist({ sledsArgv: o.sledsArgv, env: agentEnv, logPath: musherLogPath(dir), label }));
2788
2801
  const r = exec("launchctl", ["load", plist]);
2789
2802
  if (!r.ok) {
2790
2803
  error(`launchctl load failed: ${r.stderr.trim() || "unknown"}`);
@@ -2793,19 +2806,20 @@ var musherInstall = (o) => {
2793
2806
  const cfg = readConfig(o.home);
2794
2807
  writeConfig(o.home, { ...cfg, musher: { ...cfg.musher ?? {}, agent: "launchd" } });
2795
2808
  const claude = findClaude2(o.home, cfg.musher?.claudePath, o.which ?? defaultWhich3);
2796
- log(`musher installed: launchd agent ${MUSHER_LABEL}, every ${5} min · log ${musherLogPath(dir)}`);
2809
+ log(`musher installed: launchd agent ${label}, every 5 min · log ${musherLogPath(dir)}`);
2797
2810
  if (!claude)
2798
2811
  log("warn: `claude` not found on PATH — set it with `sleds musher --claude /path/to/claude`");
2799
2812
  return 0;
2800
2813
  };
2801
2814
  var musherUninstall = (o) => {
2802
2815
  const log = o.log ?? console.log;
2803
- const plist = musherPlistPath(o.home);
2816
+ const env = o.env ?? process.env;
2817
+ const plist = musherPlistPath(o.home, env);
2804
2818
  const exec = o.exec ?? defaultExecSync;
2805
2819
  if (existsSync8(plist)) {
2806
2820
  exec("launchctl", ["unload", plist]);
2807
2821
  rmSync2(plist, { force: true });
2808
- log(`musher removed: ${MUSHER_LABEL}`);
2822
+ log(`musher removed: ${musherLabel(env)}`);
2809
2823
  } else
2810
2824
  log("musher was not installed.");
2811
2825
  const cfg = readConfig(o.home);
@@ -2834,9 +2848,10 @@ var clientFor = (o) => {
2834
2848
  var musherStatus = async (o) => {
2835
2849
  const log = o.log ?? console.log;
2836
2850
  const now = (o.now ?? Date.now)();
2837
- const plist = musherPlistPath(o.home);
2851
+ const env = o.env ?? process.env;
2852
+ const plist = musherPlistPath(o.home, env);
2838
2853
  const cfg = readConfig(o.home);
2839
- log(existsSync8(plist) ? `agent ${MUSHER_LABEL} installed (${plist})` : "agent not installed — sleds musher --install");
2854
+ log(existsSync8(plist) ? `agent ${musherLabel(env)} installed (${plist})` : "agent not installed — sleds musher --install");
2840
2855
  const claude = findClaude2(o.home, cfg.musher?.claudePath, o.which ?? defaultWhich3);
2841
2856
  log(`claude ${claude ?? "not found — sleds musher --claude /path/to/claude"}`);
2842
2857
  log(`mode ${cfg.musher?.permissionMode ?? DEFAULT_PERMISSION_MODE} · timeout ${cfg.musher?.timeoutMinutes ?? DEFAULT_TIMEOUT_MINUTES} min`);
@@ -3797,7 +3812,7 @@ async function postSeat(proxyUrl, token, body, fetchFn) {
3797
3812
  // src/commands/specEvent.ts
3798
3813
  init_meter();
3799
3814
  import { readFileSync as readFileSync9, statSync } from "node:fs";
3800
- import { basename, isAbsolute, relative } from "node:path";
3815
+ import { basename as basename2, isAbsolute, relative } from "node:path";
3801
3816
  var HOOK_STDIN_TIMEOUT_MS2 = 1000;
3802
3817
  var ESTIMATE_TIMEOUT_MS = 4000;
3803
3818
  var MIN_SPEC_CHARS = 200;
@@ -3810,12 +3825,12 @@ function isSpecPath(path) {
3810
3825
  return false;
3811
3826
  if (NOT_SPEC.test(path))
3812
3827
  return false;
3813
- return SPEC_DIRS.test(path) || SPEC_NAMES.test(basename(path));
3828
+ return SPEC_DIRS.test(path) || SPEC_NAMES.test(basename2(path));
3814
3829
  }
3815
3830
  function specTitle(body, path) {
3816
3831
  const m = /^#\s+(.+?)\s*$/m.exec(body);
3817
3832
  const t = m?.[1]?.trim();
3818
- return (t && t.length > 0 ? t : basename(path).replace(/\.(md|mdx)$/i, "")).slice(0, 120);
3833
+ return (t && t.length > 0 ? t : basename2(path).replace(/\.(md|mdx)$/i, "")).slice(0, 120);
3819
3834
  }
3820
3835
  function looksLikeSpec(body) {
3821
3836
  if (body.trim().length < MIN_SPEC_CHARS)
@@ -3873,7 +3888,7 @@ var specEvent = async (o) => {
3873
3888
  const spec = {
3874
3889
  title: specTitle(body, input.filePath),
3875
3890
  body: body.slice(0, MAX_SPEC_CHARS),
3876
- repoHint: input.cwd ? basename(input.cwd) : undefined
3891
+ repoHint: input.cwd ? basename2(input.cwd) : undefined
3877
3892
  };
3878
3893
  try {
3879
3894
  const res = await (o.fetchFn ?? fetch)(`${src.proxyUrl}/proxy/estimate`, {
@@ -4136,7 +4151,7 @@ var uninstall2 = (o) => {
4136
4151
  if (existsSync12(plist)) {
4137
4152
  (o.unloadAgent ?? defaultUnload)(plist);
4138
4153
  rmSync5(plist, { force: true });
4139
- removed.push(`launchd agent ${MUSHER_LABEL}`);
4154
+ removed.push(`launchd agent ${musherLabel()}`);
4140
4155
  }
4141
4156
  if (removed.length === 0) {
4142
4157
  log("Nothing to remove; SLEDS was not installed.");
@@ -4212,6 +4227,21 @@ var defaultExec = (cmd, args) => {
4212
4227
  return { ok: r.status === 0, stderr: r.stderr ?? "" };
4213
4228
  };
4214
4229
 
4230
+ // src/settings.ts
4231
+ import { dirname as dirname4, join as join10, resolve as resolve4 } from "node:path";
4232
+ var withSeatEnv2 = (command, home, env = process.env) => {
4233
+ const parts = [];
4234
+ const sh = env.SLEDS_HOME?.trim();
4235
+ const cc = env.CLAUDE_CONFIG_DIR?.trim();
4236
+ if (sh)
4237
+ parts.push(`SLEDS_HOME=${shellWord2(resolve4(home, sh))}`);
4238
+ if (cc)
4239
+ parts.push(`CLAUDE_CONFIG_DIR=${shellWord2(resolve4(home, cc))}`);
4240
+ parts.push(command);
4241
+ return parts.join(" ");
4242
+ };
4243
+ var shellWord2 = (v) => /^[\w./~-]+$/.test(v) ? v : `'${v.replace(/'/g, "'\\''")}'`;
4244
+
4215
4245
  // src/index.ts
4216
4246
  var USAGE = `usage: sleds <command> [options]
4217
4247
 
@@ -4309,9 +4339,9 @@ var sledsArgv = () => {
4309
4339
  return script ? [process.execPath, script] : [process.execPath];
4310
4340
  };
4311
4341
  var shellQuote = (s) => /^[\w./-]+$/.test(s) ? s : `'${s.replace(/'/g, "'\\''")}'`;
4312
- var statusLineCommand = (argv) => [...argv, "statusline"].map(shellQuote).join(" ");
4313
- var seatEventCommand = (argv) => [...argv, "seat-event"].map(shellQuote).join(" ");
4314
- var specEventCommand = (argv) => [...argv, "spec-event"].map(shellQuote).join(" ");
4342
+ var statusLineCommand = (argv, home = homedir()) => withSeatEnv2([...argv, "statusline"].map(shellQuote).join(" "), home);
4343
+ var seatEventCommand = (argv, home = homedir()) => withSeatEnv2([...argv, "seat-event"].map(shellQuote).join(" "), home);
4344
+ var specEventCommand = (argv, home = homedir()) => withSeatEnv2([...argv, "spec-event"].map(shellQuote).join(" "), home);
4315
4345
  var main = async (argv) => {
4316
4346
  const { cmd, flags } = parseArgs(argv);
4317
4347
  const home = homedir();
@@ -4403,7 +4433,7 @@ var main = async (argv) => {
4403
4433
  case "version":
4404
4434
  case "--version":
4405
4435
  case "-v":
4406
- console.log("sleds 0.1.14");
4436
+ console.log("sleds 0.1.15");
4407
4437
  return 0;
4408
4438
  default:
4409
4439
  console.error(`unknown command: ${cmd}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sleds/cli",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
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",