@sleds/cli 0.1.34 → 0.1.36

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 +59 -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,
@@ -5205,6 +5232,12 @@ var init_recommend = __esm(() => {
5205
5232
  var init_profile2 = __esm(() => {
5206
5233
  init_profile();
5207
5234
  });
5235
+ // ../../packages/shared/src/item/outcome.ts
5236
+ var OUTCOME_WINDOW_DAYS = 14, OUTCOME_WINDOW_MS;
5237
+ var init_outcome = __esm(() => {
5238
+ OUTCOME_WINDOW_MS = OUTCOME_WINDOW_DAYS * 86400000;
5239
+ });
5240
+
5208
5241
  // ../../packages/shared/src/slack/mention.ts
5209
5242
  var init_mention = __esm(() => {
5210
5243
  init_intake();
@@ -7467,6 +7500,7 @@ var init_src = __esm(() => {
7467
7500
  init_recommend();
7468
7501
  init_due();
7469
7502
  init_profile2();
7503
+ init_outcome();
7470
7504
  init_mention();
7471
7505
  init_productHits();
7472
7506
  init_model();
@@ -8154,6 +8188,7 @@ init_plan3();
8154
8188
  init_recommend();
8155
8189
  init_due();
8156
8190
  init_profile2();
8191
+ init_outcome();
8157
8192
  init_mention();
8158
8193
  init_productHits();
8159
8194
  init_model();
@@ -10300,7 +10335,7 @@ function beatBody(state, flags, host = {}) {
10300
10335
  name: flags.name,
10301
10336
  os: host.os ?? process.platform,
10302
10337
  runner: flags.runner,
10303
- version: host.version ?? "0.1.34" ?? "dev",
10338
+ version: host.version ?? "0.1.36" ?? "dev",
10304
10339
  running: live.length,
10305
10340
  items: live.slice(0, BEAT_ITEMS).map((r) => `${r.item}/${r.node}`)
10306
10341
  };
@@ -11147,6 +11182,7 @@ function answerPrompt(o) {
11147
11182
  `- 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
11183
  `- 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
11184
  `- 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.`,
11185
+ `- 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
11186
  ...VERDICT_SHAPE,
11151
11187
  "- 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
11188
  "- Once the verdict is posted, stop. The engine ends this session; the node's session picks up from the answer."
@@ -21285,13 +21321,13 @@ init_src();
21285
21321
  import { readFileSync as readFileSync24 } from "node:fs";
21286
21322
  import { hostname as hostname12 } from "node:os";
21287
21323
  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]";
21324
+ 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
21325
  var ANSWER_USAGE = "usage: sleds route answer <key>/<node> <answer…> | sleds route answer <key>/<node> --stdin [--json]";
21290
21326
  var PROPOSE_USAGE = "usage: sleds route propose <key> (--file <nodes.json> | --stdin) [--name <engine>] [--json]";
21291
21327
  var APPROVE_USAGE = "usage: sleds route approve <key> [--file <nodes.json>] [--json]";
21292
21328
  var REDRAFT_USAGE = "usage: sleds route redraft <key> [--json]";
21293
21329
  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]";
21330
+ 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
21331
  var ROUTE_VERDICTS = ["accept", "keep", "redraft"];
21296
21332
  function nodesFromJson(text) {
21297
21333
  let parsed;
@@ -21611,6 +21647,14 @@ function answeredLine(key, route, held) {
21611
21647
  return `${key}: route kept as filed — what it held is released`;
21612
21648
  return `${key}: answered — what it held is released`;
21613
21649
  }
21650
+ function appliedLine(key, applied) {
21651
+ const a = applied && typeof applied === "object" ? applied : {};
21652
+ const rel = a.relation && typeof a.relation === "object" ? a.relation : {};
21653
+ const what = typeof rel.how === "string" && typeof rel.key === "string" ? `${rel.how} ${rel.key}` : "";
21654
+ if (!what)
21655
+ return `${key}: set and answered`;
21656
+ return a.changed === false ? `${key}: ${what} was already set — answered` : `${key}: set ${what} — answered`;
21657
+ }
21614
21658
  async function decisionCmd(o, argv) {
21615
21659
  const log = o.log ?? console.log;
21616
21660
  const error = o.error ?? console.error;
@@ -21620,6 +21664,7 @@ async function decisionCmd(o, argv) {
21620
21664
  const answer = argv.includes("--answer");
21621
21665
  const fromStdin = argv.includes("--stdin");
21622
21666
  const keepRoute = argv.includes("--keep-route");
21667
+ const apply = argv.includes("--apply");
21623
21668
  const at = argv.indexOf("--route");
21624
21669
  const routeArg = at >= 0 ? argv[at + 1] : undefined;
21625
21670
  const words = argv.filter((a, i) => ![
@@ -21629,14 +21674,15 @@ async function decisionCmd(o, argv) {
21629
21674
  "--answer",
21630
21675
  "--stdin",
21631
21676
  "--keep-route",
21677
+ "--apply",
21632
21678
  "--route"
21633
21679
  ].includes(a) && !(at >= 0 && i === at + 1));
21634
21680
  const [key, id, ...rest] = words;
21635
21681
  const badRoute = at >= 0 && !ROUTE_VERDICTS.includes(routeArg) || at >= 0 && keepRoute;
21636
21682
  const route = keepRoute ? "keep" : at >= 0 ? routeArg : undefined;
21637
21683
  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)) {
21684
+ const routeAlone = (Boolean(route) || apply) && verbs === 0;
21685
+ if (!key || !id || badRoute || (route || apply) && (seen || overrule) || route && apply || !routeAlone && verbs !== 1 || (seen || routeAlone) && (fromStdin || rest.length > 0)) {
21640
21686
  error(DECISION_USAGE);
21641
21687
  return 2;
21642
21688
  }
@@ -21654,13 +21700,14 @@ async function decisionCmd(o, argv) {
21654
21700
  project: key,
21655
21701
  id,
21656
21702
  ...seen ? { seen: true } : answer ? { answer: md } : overrule ? { overrule: md } : {},
21657
- ...route ? { route } : {}
21703
+ ...route ? { route } : {},
21704
+ ...apply ? { apply: true } : {}
21658
21705
  });
21659
21706
  if (!r) {
21660
21707
  error(`${key}: SLEDS unreachable — nothing marked`);
21661
21708
  return 1;
21662
21709
  }
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)));
21710
+ 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
21711
  }
21665
21712
  var DECISIONS_USAGE = "usage: sleds route decisions [<key>] [--flagged] [--json]";
21666
21713
  function decisionsLines(raw) {
@@ -24108,7 +24155,7 @@ ${renderHelpText(argv[1])}`);
24108
24155
  case "version":
24109
24156
  case "--version":
24110
24157
  case "-v":
24111
- console.log("sleds 0.1.34");
24158
+ console.log("sleds 0.1.36");
24112
24159
  return 0;
24113
24160
  default:
24114
24161
  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.36",
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",