@sleds/cli 0.1.34 → 0.1.35

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 +51 -12
  2. package/package.json +1 -1
package/dist/sleds.mjs CHANGED
@@ -3285,6 +3285,12 @@ ${draft ? str5(draft.pack) ?? "" : ""}`,
3285
3285
  }
3286
3286
  };
3287
3287
  }
3288
+ function forPersonOf(v) {
3289
+ const rel = isObject4(v) && isObject4(v.relation) ? v.relation : null;
3290
+ const key = str5(rel?.key)?.trim();
3291
+ const how = str5(rel?.how);
3292
+ return key && how && RELATION_HOWS.includes(how) ? { forPerson: { relation: { key, how } } } : {};
3293
+ }
3288
3294
  async function runTool(ctx, args) {
3289
3295
  if (!ctx.client)
3290
3296
  return NOT_SET_UP;
@@ -3316,7 +3322,8 @@ async function runTool(ctx, args) {
3316
3322
  why: str5(e.why),
3317
3323
  ...str5(e.suggested) ? { suggested: str5(e.suggested) } : {},
3318
3324
  ...strList(e.cites) ? { cites: strList(e.cites) } : {},
3319
- ...typeof e.irreversible === "boolean" ? { irreversible: e.irreversible } : {}
3325
+ ...typeof e.irreversible === "boolean" ? { irreversible: e.irreversible } : {},
3326
+ ...forPersonOf(e.forPerson)
3320
3327
  } : null;
3321
3328
  const res = await postSaying(ctx, "/proxy/run", {
3322
3329
  runId,
@@ -4242,7 +4249,7 @@ async function handleLine(line, ctx) {
4242
4249
  return isNotification ? null : errorResponse(id, -32601, `method not found: ${method}`);
4243
4250
  }
4244
4251
  }
4245
- var PROTOCOL_VERSION = "2025-06-18", SERVER_INFO, SERVER_INSTRUCTIONS, MCP_TIMEOUT_MS = 5000, sourceSchema, specSchema, TOOLS, VIEW_TOOLS, NOT_SET_UP, UNREACHABLE, isObject4 = (v) => typeof v === "object" && v !== null && !Array.isArray(v), num3 = (v) => typeof v === "number" && Number.isFinite(v) ? v : undefined, str5 = (v) => typeof v === "string" ? v : undefined, errorMessage = (j) => isObject4(j?.error) ? str5(j.error.message) : str5(j?.error), proposalText = (t) => (t ?? "").replace(/\n*Nothing runs until a person says yes:[^\n]*$/, ""), PROPOSED_NEXT = (key) => `Nothing runs until a person approves it: Approve in the SLEDS app or on the item page, or \`sleds route approve ${key}\`. If you are a drafting session, stop here.`, strList = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string") : undefined, UI_RESOURCES, response = (id, result) => JSON.stringify({ jsonrpc: "2.0", id, result }), errorResponse = (id, code, message) => JSON.stringify({ jsonrpc: "2.0", id, error: { code, message } });
4252
+ var PROTOCOL_VERSION = "2025-06-18", SERVER_INFO, SERVER_INSTRUCTIONS, MCP_TIMEOUT_MS = 5000, sourceSchema, specSchema, TOOLS, VIEW_TOOLS, NOT_SET_UP, UNREACHABLE, isObject4 = (v) => typeof v === "object" && v !== null && !Array.isArray(v), num3 = (v) => typeof v === "number" && Number.isFinite(v) ? v : undefined, str5 = (v) => typeof v === "string" ? v : undefined, errorMessage = (j) => isObject4(j?.error) ? str5(j.error.message) : str5(j?.error), proposalText = (t) => (t ?? "").replace(/\n*Nothing runs until a person says yes:[^\n]*$/, ""), PROPOSED_NEXT = (key) => `Nothing runs until a person approves it: Approve in the SLEDS app or on the item page, or \`sleds route approve ${key}\`. If you are a drafting session, stop here.`, strList = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string") : undefined, RELATION_HOWS, UI_RESOURCES, response = (id, result) => JSON.stringify({ jsonrpc: "2.0", id, result }), errorResponse = (id, code, message) => JSON.stringify({ jsonrpc: "2.0", id, error: { code, message } });
4246
4253
  var init_server = __esm(() => {
4247
4254
  init_worth();
4248
4255
  init_intake();
@@ -4609,7 +4616,7 @@ var init_server = __esm(() => {
4609
4616
  },
4610
4617
  {
4611
4618
  name: "run",
4612
- description: "An engine's word on a run it holds (spec 26): with nothing but `runId`, a heartbeat that renews the lease (every few minutes while the session runs; a lapsed lease returns the node to ready). `park: {question}` when the session needs a person — the node parks with the question, the seat is free, the engine takes the next node. `fail: {log}` when the session exited without a PR — back to ready once, parked the second time. `watch` updates where to watch it. On a decider's (answerer's) run: `answer: {md, cites}` when the record settles the question, `release: {why, waitsOn, cites}` when the record says the node must wait on other items (its session stops, the node goes back to ready without a seat, and it is not taken again until those land), `escalate: {why, suggested?}` when it does not — SLEDS may refuse an answer and escalate it, and says why. When the PR opens: `actual` (or `land`) with `node` and state `pr`; the merge lands the node from the PR body's `SLEDS-Node:` line.",
4619
+ description: "An engine's word on a run it holds (spec 26): with nothing but `runId`, a heartbeat that renews the lease (every few minutes while the session runs; a lapsed lease returns the node to ready). `park: {question}` when the session needs a person — the node parks with the question, the seat is free, the engine takes the next node. `fail: {log}` when the session exited without a PR — back to ready once, parked the second time. `watch` updates where to watch it. On a decider's (answerer's) run: `answer: {md, cites}` when the record settles the question, `release: {why, waitsOn, cites}` when the record says the node must wait on other items (its session stops, the node goes back to ready without a seat, and it is not taken again until those land), `escalate: {why, suggested?, forPerson?}` when it does not — `forPerson: {relation: {key, how}}` when the fix is a relation only a person can set (`blockedBy SL-1474`), which the person's card then sets in one press — SLEDS may refuse an answer and escalate it, and says why. When the PR opens: `actual` (or `land`) with `node` and state `pr`; the merge lands the node from the PR body's `SLEDS-Node:` line.",
4613
4620
  inputSchema: {
4614
4621
  type: "object",
4615
4622
  properties: {
@@ -4669,7 +4676,26 @@ var init_server = __esm(() => {
4669
4676
  why: { type: "string", description: "One line for the person." },
4670
4677
  suggested: { type: "string", description: "Your best answer, when you have one." },
4671
4678
  cites: { type: "array", items: { type: "string" } },
4672
- irreversible: { type: "boolean" }
4679
+ irreversible: { type: "boolean" },
4680
+ forPerson: {
4681
+ type: "object",
4682
+ description: "SL-1499: what only a person can set, for their card's one press — a relation on the item. Put it here, not in `suggested`: the session cannot set it.",
4683
+ properties: {
4684
+ relation: {
4685
+ type: "object",
4686
+ properties: {
4687
+ key: { type: "string", description: "The other item's key (SL-1474)." },
4688
+ how: {
4689
+ type: "string",
4690
+ enum: ["blockedBy", "blocks", "relates", "duplicates"],
4691
+ description: "How this item stands to it: blockedBy when it waits on it."
4692
+ }
4693
+ },
4694
+ required: ["key", "how"]
4695
+ }
4696
+ },
4697
+ required: ["relation"]
4698
+ }
4673
4699
  },
4674
4700
  required: ["why"]
4675
4701
  },
@@ -5176,6 +5202,7 @@ var init_server = __esm(() => {
5176
5202
  text: "Control plane unreachable. Nothing was recorded → try again in a moment.",
5177
5203
  isError: true
5178
5204
  };
5205
+ RELATION_HOWS = ["blockedBy", "blocks", "relates", "duplicates"];
5179
5206
  UI_RESOURCES = [
5180
5207
  {
5181
5208
  uri: INTAKE_VIEW_URI,
@@ -10300,7 +10327,7 @@ function beatBody(state, flags, host = {}) {
10300
10327
  name: flags.name,
10301
10328
  os: host.os ?? process.platform,
10302
10329
  runner: flags.runner,
10303
- version: host.version ?? "0.1.34" ?? "dev",
10330
+ version: host.version ?? "0.1.35" ?? "dev",
10304
10331
  running: live.length,
10305
10332
  items: live.slice(0, BEAT_ITEMS).map((r) => `${r.item}/${r.node}`)
10306
10333
  };
@@ -11147,6 +11174,7 @@ function answerPrompt(o) {
11147
11174
  `- Settled by the record: the SLEDS \`${run}\` tool with \`{runId: "${c.runId}", answer: {md, cites}}\` — \`md\` is the answer as you would tell the session, \`cites\` the list of pointers.`,
11148
11175
  `- The record says node ${c.node} must wait for another item to land ("build nothing until #123 merges") and that item is on the board: \`${run}\` with \`{runId: "${c.runId}", release: {why, waitsOn, cites}}\` — \`waitsOn\` the keys of the items it waits on (\`SL-123\`). It frees the seat: node ${c.node}'s session is closed, and the node is retaken fresh once they land. Release rather than answer "stay parked", which only parks it again.`,
11149
11176
  `- Not settled, irreversible, or unsure: \`${run}\` with \`{runId: "${c.runId}", escalate: {why, suggested?, cites?, irreversible?}}\` — \`why\` in one line for the person (with any action only a person can take), \`suggested\` your best answer as the session would be told it, when you have one. Mark \`irreversible: true\` when it is, even if the session did not.`,
11177
+ `- When the fix is a relation on the item only a person can set (node ${c.node} looks like it waits on SL-1474, but the record does not settle it, so it is not a release), escalate with \`forPerson: {relation: {key, how}}\` — \`{key: "SL-1474", how: "blockedBy"}\` — so the person's card sets it in one press. Never tell the session to set it: a session cannot set relations.`,
11150
11178
  ...VERDICT_SHAPE,
11151
11179
  "- Read what the tool answers: an answer can come back `escalated` with `refused` (irreversible, no cites, or the autonomy is ask). That is SLEDS's call, not a failure; do not post again.",
11152
11180
  "- Once the verdict is posted, stop. The engine ends this session; the node's session picks up from the answer."
@@ -21285,13 +21313,13 @@ init_src();
21285
21313
  import { readFileSync as readFileSync24 } from "node:fs";
21286
21314
  import { hostname as hostname12 } from "node:os";
21287
21315
  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>]";
21288
- 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 | --overrule --stdin | 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]";
21316
+ 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 | 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]";
21289
21317
  var ANSWER_USAGE = "usage: sleds route answer <key>/<node> <answer…> | sleds route answer <key>/<node> --stdin [--json]";
21290
21318
  var PROPOSE_USAGE = "usage: sleds route propose <key> (--file <nodes.json> | --stdin) [--name <engine>] [--json]";
21291
21319
  var APPROVE_USAGE = "usage: sleds route approve <key> [--file <nodes.json>] [--json]";
21292
21320
  var REDRAFT_USAGE = "usage: sleds route redraft <key> [--json]";
21293
21321
  var SINGLE_USAGE = "usage: sleds route single <key> [--json]";
21294
- var DECISION_USAGE = "usage: sleds route decision <key> <id> --seen | sleds route decision <key> <id> (--answer | --overrule) (<answer…> | --stdin) | sleds route decision <key> <id> [--answer (<answer…> | --stdin)] --route accept|keep|redraft | sleds route decision <key> <id> --keep-route [--json]";
21322
+ var DECISION_USAGE = "usage: sleds route decision <key> <id> --seen | sleds route decision <key> <id> (--answer | --overrule) (<answer…> | --stdin) | sleds route decision <key> <id> [--answer (<answer…> | --stdin)] --route accept|keep|redraft | sleds route decision <key> <id> --keep-route | sleds route decision <key> <id> --apply [--answer (<answer…> | --stdin)] [--json]";
21295
21323
  var ROUTE_VERDICTS = ["accept", "keep", "redraft"];
21296
21324
  function nodesFromJson(text) {
21297
21325
  let parsed;
@@ -21611,6 +21639,14 @@ function answeredLine(key, route, held) {
21611
21639
  return `${key}: route kept as filed — what it held is released`;
21612
21640
  return `${key}: answered — what it held is released`;
21613
21641
  }
21642
+ function appliedLine(key, applied) {
21643
+ const a = applied && typeof applied === "object" ? applied : {};
21644
+ const rel = a.relation && typeof a.relation === "object" ? a.relation : {};
21645
+ const what = typeof rel.how === "string" && typeof rel.key === "string" ? `${rel.how} ${rel.key}` : "";
21646
+ if (!what)
21647
+ return `${key}: set and answered`;
21648
+ return a.changed === false ? `${key}: ${what} was already set — answered` : `${key}: set ${what} — answered`;
21649
+ }
21614
21650
  async function decisionCmd(o, argv) {
21615
21651
  const log = o.log ?? console.log;
21616
21652
  const error = o.error ?? console.error;
@@ -21620,6 +21656,7 @@ async function decisionCmd(o, argv) {
21620
21656
  const answer = argv.includes("--answer");
21621
21657
  const fromStdin = argv.includes("--stdin");
21622
21658
  const keepRoute = argv.includes("--keep-route");
21659
+ const apply = argv.includes("--apply");
21623
21660
  const at = argv.indexOf("--route");
21624
21661
  const routeArg = at >= 0 ? argv[at + 1] : undefined;
21625
21662
  const words = argv.filter((a, i) => ![
@@ -21629,14 +21666,15 @@ async function decisionCmd(o, argv) {
21629
21666
  "--answer",
21630
21667
  "--stdin",
21631
21668
  "--keep-route",
21669
+ "--apply",
21632
21670
  "--route"
21633
21671
  ].includes(a) && !(at >= 0 && i === at + 1));
21634
21672
  const [key, id, ...rest] = words;
21635
21673
  const badRoute = at >= 0 && !ROUTE_VERDICTS.includes(routeArg) || at >= 0 && keepRoute;
21636
21674
  const route = keepRoute ? "keep" : at >= 0 ? routeArg : undefined;
21637
21675
  const verbs = [seen, overrule, answer].filter(Boolean).length;
21638
- const routeAlone = Boolean(route) && verbs === 0;
21639
- if (!key || !id || badRoute || route && (seen || overrule) || !routeAlone && verbs !== 1 || (seen || routeAlone) && (fromStdin || rest.length > 0)) {
21676
+ const routeAlone = (Boolean(route) || apply) && verbs === 0;
21677
+ if (!key || !id || badRoute || (route || apply) && (seen || overrule) || route && apply || !routeAlone && verbs !== 1 || (seen || routeAlone) && (fromStdin || rest.length > 0)) {
21640
21678
  error(DECISION_USAGE);
21641
21679
  return 2;
21642
21680
  }
@@ -21654,13 +21692,14 @@ async function decisionCmd(o, argv) {
21654
21692
  project: key,
21655
21693
  id,
21656
21694
  ...seen ? { seen: true } : answer ? { answer: md } : overrule ? { overrule: md } : {},
21657
- ...route ? { route } : {}
21695
+ ...route ? { route } : {},
21696
+ ...apply ? { apply: true } : {}
21658
21697
  });
21659
21698
  if (!r) {
21660
21699
  error(`${key}: SLEDS unreachable — nothing marked`);
21661
21700
  return 1;
21662
21701
  }
21663
- return said(o, key, json, r, () => log(seen ? `${key}: marked seen` : overrule ? `${key}: overruled — your answer stands in the log` : answeredLine(key, r.json?.route ?? route, r.json?.held)));
21702
+ return said(o, key, json, r, () => log(seen ? `${key}: marked seen` : overrule ? `${key}: overruled — your answer stands in the log` : apply ? appliedLine(key, r.json?.applied) : answeredLine(key, r.json?.route ?? route, r.json?.held)));
21664
21703
  }
21665
21704
  var DECISIONS_USAGE = "usage: sleds route decisions [<key>] [--flagged] [--json]";
21666
21705
  function decisionsLines(raw) {
@@ -24108,7 +24147,7 @@ ${renderHelpText(argv[1])}`);
24108
24147
  case "version":
24109
24148
  case "--version":
24110
24149
  case "-v":
24111
- console.log("sleds 0.1.34");
24150
+ console.log("sleds 0.1.35");
24112
24151
  return 0;
24113
24152
  default:
24114
24153
  console.error(`unknown command: ${cmd}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sleds/cli",
3
- "version": "0.1.34",
3
+ "version": "0.1.35",
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",