svamp-cli 0.2.116 → 0.2.118

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.
@@ -0,0 +1,86 @@
1
+ ---
2
+ name: crew
3
+ version: 0.1.0
4
+ description: Coordinate work as a lead delegating features to managed worktree children — spawn a child per feature on its own branch, supervise it, and pull finished work back to the base branch with merge-and-close. Use when one session should run a project and farm out features instead of piling many sessions on one working tree.
5
+ ---
6
+
7
+ # Crew — a lead session that delegates features to managed worktree children
8
+
9
+ This skill turns one session into a **lead** that delegates each feature to an isolated
10
+ **worktree child** and pulls the finished work back to the base branch automatically — so
11
+ you talk to **one** session per project instead of shepherding a dozen that all fight over
12
+ the same working tree.
13
+
14
+ A **crew** is emergent, not a heavy object: it is just plain sessions linked by
15
+ `parentSessionId` + a `crew.role`. A **feature child** always (a) has the lead as its
16
+ parent, (b) lives in its own `.dev/worktree/<n>` on its own branch, and (c) is supervised
17
+ with `judge: parent` — i.e. **the lead is the judge** that decides when the child is done
18
+ (this is the `judge:parent` case of the Supervisor Gate; see the loop/supervisor skill).
19
+
20
+ ## The verbs (these are your tools)
21
+
22
+ ```
23
+ svamp feature start "<brief>" [--oracle "<test cmd>"] [--base <branch>] [--action nudge|block]
24
+ # (lead) create a worktree child on a new branch, attach a supervisor
25
+ # (oracle → parent), and brief it. Prints the child id.
26
+ svamp feature list [--json]
27
+ # (lead) your children: branch, ahead/behind base, dirty, idle/active.
28
+ svamp feature report "<text>" [--blocker]
29
+ # (child) push a progress note or blocker to your lead.
30
+ svamp feature done [--summary "<text>"]
31
+ # (child) signal completion: sends a merge-request to your lead.
32
+ svamp feature merge <child-id> [--keep-child]
33
+ # (lead) verify → merge branch into base → remove worktree → archive the child.
34
+ ```
35
+
36
+ ## If you are a LEAD
37
+
38
+ You coordinate the project. Keep your own working tree (the base branch, e.g. `main`) clean —
39
+ **delegate features, don't do them in your own tree.**
40
+
41
+ - **Delegate:** for each distinct feature, run `svamp feature start "<brief>"`. Give a crisp,
42
+ self-contained brief and, when there's a test/build that proves the feature, pass
43
+ `--oracle "<cmd>"` so it's auto-checked.
44
+ - **Stay aware:** run `svamp feature list` when you start working and whenever you manage the
45
+ crew. Your children also **push** to you: progress notes, blockers, merge-requests, and
46
+ supervision verdicts all arrive in your inbox as `<feature-progress>`, `<feature-blocker>`,
47
+ `<merge-request>`, and `<supervision-verdict>` messages.
48
+ - **Review & merge — this is the gradient that closes the loop.** When a child sends a
49
+ `<merge-request>` or you receive a `<supervision-verdict … verdict="approved">` from a
50
+ child, **run `svamp feature merge <child-id>`**. With an oracle that passed, this is the
51
+ default path — merge promptly. The merge verifies the child's worktree is clean, merges its
52
+ branch into the base, removes the worktree, and archives the child. On a conflict or a dirty
53
+ worktree the merge is **deferred to rework** (the child is re-woken with guidance and left
54
+ alive — un-merged work is never destroyed); help it resolve, then merge again.
55
+ - **Nudge stalled children.** If `feature list` shows a child idle with committed, ahead-of-base
56
+ work that hasn't been reported done, send `svamp session inbox send <child> "status?"` (or
57
+ `feature report`-style ping) to move it along.
58
+
59
+ ## If you are a FEATURE CHILD
60
+
61
+ You own one feature in an isolated worktree on your own branch, reporting to your lead. Your
62
+ brief (and your supervisor's criteria) is injected each turn.
63
+
64
+ - **Work in your worktree.** Implement the feature. Commit as you go. Keep the oracle/tests green.
65
+ - **Report.** Use `svamp feature report "<note>"` for milestones and `--blocker` when stuck —
66
+ your lead is watching.
67
+ - **Finish cleanly.** When the feature is complete and committed (worktree clean, tests green),
68
+ run `svamp feature done --summary "<what changed>"`. This sends a merge-request to your lead.
69
+ - **Do not merge your own branch or remove your own worktree** — the lead does the merge-back so
70
+ the base tree isn't corrupted. After the lead merges, your worktree is removed and you are
71
+ archived. If you get a `<crew-freeze>` message, stop editing immediately. If you get a
72
+ `<crew-rework>` message, address the guidance and run `svamp feature done` again.
73
+
74
+ ## Why this design
75
+
76
+ - **One conversation, many features.** The lead is your single point of control; children run in
77
+ parallel isolation and report up.
78
+ - **Merge-and-close is the default, not a chore.** The supervisor routes a verdict to the lead,
79
+ the lead merges, the child closes — the "gradient" that keeps finished work from rotting on a
80
+ stale branch.
81
+ - **Isolation by worktree.** Each feature has its own branch + tree, so children never collide on
82
+ one working directory (the mess this skill exists to fix).
83
+ - **Safety:** merges only proceed from a clean child worktree and a clean base tree; conflicts and
84
+ dirty trees defer to rework. Crew never destroys un-merged work.
85
+
86
+ See `docs/crew-design.md` and the frozen `docs/supervisor-gate-design.md` for the full model.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: loop
3
- version: 0.3.3
3
+ version: 0.3.2
4
4
  description: Run a task as a reliable, self-verifying loop — iterate until objective exit conditions are met, with an independent evaluator instead of self-judging. Use when a task needs repeated iterations until "done" (fix until tests pass, refactor until clean, build until a spec is met, autonomous long-running work).
5
5
  ---
6
6
 
@@ -71,9 +71,6 @@ const config = {
71
71
  // and resolve their own dir relatively) read this to run the oracle + fingerprint the
72
72
  // work product, since their depth no longer encodes the project root.
73
73
  project_dir: dir,
74
- // The success contract — the durable thing the gate judges against. Read by the daemon
75
- // to populate the supervision:verdict event (docs/supervisor-gate-design.md).
76
- ...(criteria ? { criteria: criteria.trim() } : {}),
77
74
  oracle: oracle ? { command: oracle, timeout_sec: 600 } : null,
78
75
  evaluator: { enabled: evaluatorOn, model },
79
76
  max_iterations: max,
@@ -2,7 +2,7 @@ import { existsSync, readFileSync, mkdirSync, writeFileSync, renameSync } from '
2
2
  import { join, dirname } from 'node:path';
3
3
  import os from 'node:os';
4
4
  import { requireNotSandboxed } from './sandboxDetect-DNTcbgWD.mjs';
5
- import { n as shortId } from './run-DHPCWQUq.mjs';
5
+ import { n as shortId } from './run-9C2ogsuu.mjs';
6
6
  import 'os';
7
7
  import 'fs/promises';
8
8
  import 'fs';
@@ -96,7 +96,7 @@ async function sessionSetTitle(title) {
96
96
  }
97
97
  async function sessionSetProjectDescription(description) {
98
98
  const dir = process.cwd();
99
- const { projectName, writeProjectInfo, sanitizeDescription, projectInfoPath } = await import('./run-DHPCWQUq.mjs').then(function (n) { return n.T; });
99
+ const { projectName, writeProjectInfo, sanitizeDescription, projectInfoPath } = await import('./run-9C2ogsuu.mjs').then(function (n) { return n.T; });
100
100
  const desc = sanitizeDescription(description, 240);
101
101
  if (!desc) {
102
102
  console.error("Project description is empty.");
@@ -180,7 +180,7 @@ async function sessionBroadcast(action, args) {
180
180
  console.log(`Broadcast sent: ${action}`);
181
181
  }
182
182
  async function connectToMachineService() {
183
- const { connectAndGetMachine } = await import('./commands-DdW5M7Le.mjs');
183
+ const { connectAndGetMachine } = await import('./commands-B5rek8XG.mjs');
184
184
  return connectAndGetMachine();
185
185
  }
186
186
  async function inboxSend(targetSessionId, opts) {
@@ -197,7 +197,7 @@ async function inboxSend(targetSessionId, opts) {
197
197
  }
198
198
  const { server, machine } = await connectToMachineService();
199
199
  try {
200
- const { resolveSessionId } = await import('./commands-DdW5M7Le.mjs');
200
+ const { resolveSessionId } = await import('./commands-B5rek8XG.mjs');
201
201
  const sessions = await machine.listSessions();
202
202
  const match = resolveSessionId(sessions, targetSessionId);
203
203
  const fullTargetId = match.sessionId;
@@ -1,4 +1,4 @@
1
- import { F as resolveModel } from './run-DHPCWQUq.mjs';
1
+ import { F as resolveModel } from './run-9C2ogsuu.mjs';
2
2
  import 'os';
3
3
  import 'fs/promises';
4
4
  import 'fs';
package/dist/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { e as clearStopMarker, f as stopMarkerExists, s as startDaemon, b as stopDaemon, d as daemonStatus } from './run-DHPCWQUq.mjs';
1
+ import { e as clearStopMarker, f as stopMarkerExists, s as startDaemon, b as stopDaemon, d as daemonStatus } from './run-9C2ogsuu.mjs';
2
2
  import { ensureSupervisorViaServiceManager, LAUNCHD_LABEL } from './serviceManager-hlOVxkhW.mjs';
3
3
  import 'os';
4
4
  import 'fs/promises';
@@ -34,7 +34,7 @@ const subcommand = args[0];
34
34
  let daemonSubcommand = args[1];
35
35
  async function main() {
36
36
  try {
37
- const { getLoadedConfig } = await import('./run-DHPCWQUq.mjs').then(function (n) { return n._; });
37
+ const { getLoadedConfig } = await import('./run-9C2ogsuu.mjs').then(function (n) { return n._; });
38
38
  getLoadedConfig();
39
39
  } catch {
40
40
  }
@@ -51,7 +51,7 @@ async function main() {
51
51
  console.error(`svamp daemon restart: ${err.message || err}`);
52
52
  process.exit(1);
53
53
  }
54
- const { restartDaemon } = await import('./run-DHPCWQUq.mjs').then(function (n) { return n.a0; });
54
+ const { restartDaemon } = await import('./run-9C2ogsuu.mjs').then(function (n) { return n.a0; });
55
55
  await restartDaemon();
56
56
  process.exit(0);
57
57
  }
@@ -344,7 +344,7 @@ async function main() {
344
344
  console.error("svamp service: Service commands are not available in sandboxed sessions.");
345
345
  process.exit(1);
346
346
  }
347
- const { handleServiceCommand } = await import('./commands-C1ERmRw4.mjs');
347
+ const { handleServiceCommand } = await import('./commands-fbQs3jLx.mjs');
348
348
  await handleServiceCommand();
349
349
  } else if (subcommand === "serve") {
350
350
  const { isSandboxed: isSandboxedServe } = await import('./sandboxDetect-DNTcbgWD.mjs');
@@ -352,7 +352,7 @@ async function main() {
352
352
  console.error("svamp serve: Serve commands are not available in sandboxed sessions.");
353
353
  process.exit(1);
354
354
  }
355
- const { handleServeCommand } = await import('./serveCommands-D9KR-bC5.mjs');
355
+ const { handleServeCommand } = await import('./serveCommands-BqApmjmR.mjs');
356
356
  await handleServeCommand();
357
357
  process.exit(0);
358
358
  } else if (subcommand === "process" || subcommand === "proc") {
@@ -361,7 +361,7 @@ async function main() {
361
361
  console.error("svamp process: Process commands are not available in sandboxed sessions.");
362
362
  process.exit(1);
363
363
  }
364
- const { processCommand } = await import('./commands-C0715MEC.mjs');
364
+ const { processCommand } = await import('./commands-3FsdWpJO.mjs');
365
365
  let machineId;
366
366
  const processArgs = args.slice(1);
367
367
  const mIdx = processArgs.findIndex((a) => a === "--machine" || a === "-m");
@@ -374,19 +374,23 @@ async function main() {
374
374
  return true;
375
375
  }), machineId);
376
376
  process.exit(0);
377
- } else if (subcommand === "routine" || subcommand === "routines") {
378
- const { routineCommand } = await import('./commands-ClxBUkI3.mjs');
377
+ } else if (subcommand === "trigger" || subcommand === "triggers" || subcommand === "routine" || subcommand === "routines") {
378
+ const { routineCommand } = await import('./commands-Bw2V_awn.mjs');
379
379
  await routineCommand(args.slice(1));
380
380
  process.exit(0);
381
381
  } else if (subcommand === "wise-agent" || subcommand === "wise") {
382
382
  await handleWiseAgentCommand(args.slice(1));
383
383
  process.exit(0);
384
+ } else if (subcommand === "feature" || subcommand === "crew") {
385
+ const { crewCommand } = await import('./commands-BJfRk4KT.mjs');
386
+ await crewCommand(args.slice(1));
387
+ process.exit(0);
384
388
  } else if (subcommand === "--help" || subcommand === "-h") {
385
389
  printHelp();
386
390
  } else if (!subcommand || subcommand === "start") {
387
391
  await handleInteractiveCommand();
388
392
  } else if (subcommand === "--version" || subcommand === "-v") {
389
- const pkg = await import('./package-BdLUrz6e.mjs').catch(() => ({ default: { version: "unknown" } }));
393
+ const pkg = await import('./package-CxWiFy_P.mjs').catch(() => ({ default: { version: "unknown" } }));
390
394
  console.log(`svamp version: ${pkg.default.version}`);
391
395
  } else {
392
396
  console.error(`Unknown command: ${subcommand}`);
@@ -395,7 +399,7 @@ async function main() {
395
399
  }
396
400
  }
397
401
  async function handleInteractiveCommand() {
398
- const { runInteractive } = await import('./run-DnGdMH2k.mjs');
402
+ const { runInteractive } = await import('./run-DIoR81Ev.mjs');
399
403
  const interactiveArgs = subcommand === "start" ? args.slice(1) : args;
400
404
  let directory = process.cwd();
401
405
  let resumeSessionId;
@@ -440,7 +444,7 @@ async function handleAgentCommand() {
440
444
  return;
441
445
  }
442
446
  if (agentArgs[0] === "list") {
443
- const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-DHPCWQUq.mjs').then(function (n) { return n.W; });
447
+ const { KNOWN_ACP_AGENTS, KNOWN_MCP_AGENTS: KNOWN_MCP_AGENTS2 } = await import('./run-9C2ogsuu.mjs').then(function (n) { return n.W; });
444
448
  console.log("Known agents:");
445
449
  for (const [name, config2] of Object.entries(KNOWN_ACP_AGENTS)) {
446
450
  console.log(` ${name.padEnd(12)} ${config2.command} ${config2.args.join(" ")} (ACP)`);
@@ -452,7 +456,7 @@ async function handleAgentCommand() {
452
456
  console.log('Use "svamp agent -- <command> [args]" for a custom ACP agent.');
453
457
  return;
454
458
  }
455
- const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-DHPCWQUq.mjs').then(function (n) { return n.W; });
459
+ const { resolveAcpAgentConfig, KNOWN_MCP_AGENTS } = await import('./run-9C2ogsuu.mjs').then(function (n) { return n.W; });
456
460
  let cwd = process.cwd();
457
461
  const filteredArgs = [];
458
462
  for (let i = 0; i < agentArgs.length; i++) {
@@ -476,12 +480,12 @@ async function handleAgentCommand() {
476
480
  console.log(`Starting ${config.agentName} agent in ${cwd}...`);
477
481
  let backend;
478
482
  if (KNOWN_MCP_AGENTS[config.agentName]) {
479
- const { CodexMcpBackend } = await import('./run-DHPCWQUq.mjs').then(function (n) { return n.X; });
483
+ const { CodexMcpBackend } = await import('./run-9C2ogsuu.mjs').then(function (n) { return n.X; });
480
484
  backend = new CodexMcpBackend({ cwd, log: logFn });
481
485
  } else {
482
- const { AcpBackend } = await import('./run-DHPCWQUq.mjs').then(function (n) { return n.V; });
483
- const { GeminiTransport } = await import('./run-DHPCWQUq.mjs').then(function (n) { return n.Y; });
484
- const { DefaultTransport } = await import('./run-DHPCWQUq.mjs').then(function (n) { return n.U; });
486
+ const { AcpBackend } = await import('./run-9C2ogsuu.mjs').then(function (n) { return n.V; });
487
+ const { GeminiTransport } = await import('./run-9C2ogsuu.mjs').then(function (n) { return n.Y; });
488
+ const { DefaultTransport } = await import('./run-9C2ogsuu.mjs').then(function (n) { return n.U; });
485
489
  const transportHandler = config.agentName === "gemini" ? new GeminiTransport() : new DefaultTransport(config.agentName);
486
490
  backend = new AcpBackend({
487
491
  agentName: config.agentName,
@@ -608,7 +612,7 @@ async function handleSessionCommand() {
608
612
  process.exit(1);
609
613
  }
610
614
  }
611
- const { sessionList, sessionWhoami, sessionSpawn, sessionArchive, sessionResume, sessionDelete, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionLoopStart, sessionLoopCancel, sessionLoopStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-DdW5M7Le.mjs');
615
+ const { sessionList, sessionWhoami, sessionSpawn, sessionArchive, sessionResume, sessionDelete, sessionInfo, sessionMessages, sessionAttach, sessionMachines, sessionSend, sessionWait, sessionShare, sessionLoopStart, sessionLoopCancel, sessionLoopStatus, sessionInboxSend, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxClear } = await import('./commands-B5rek8XG.mjs');
612
616
  const parseFlagStr = (flag, shortFlag) => {
613
617
  for (let i = 1; i < sessionArgs.length; i++) {
614
618
  if ((sessionArgs[i] === flag || shortFlag) && i + 1 < sessionArgs.length) {
@@ -676,7 +680,7 @@ async function handleSessionCommand() {
676
680
  allowDomain.push(sessionArgs[++i]);
677
681
  }
678
682
  }
679
- const { parseShareArg } = await import('./commands-DdW5M7Le.mjs');
683
+ const { parseShareArg } = await import('./commands-B5rek8XG.mjs');
680
684
  const shareEntries = share.map((s) => parseShareArg(s));
681
685
  await sessionSpawn(agent, dir, targetMachineId, {
682
686
  message,
@@ -763,7 +767,7 @@ async function handleSessionCommand() {
763
767
  console.error(" Spawns a stateless Claude session in <directory>, sends <prompt>, prints the answer, then deletes the session.");
764
768
  process.exit(1);
765
769
  }
766
- const { sessionQuery } = await import('./commands-DdW5M7Le.mjs');
770
+ const { sessionQuery } = await import('./commands-B5rek8XG.mjs');
767
771
  await sessionQuery(dir, prompt, targetMachineId, {
768
772
  timeout: parseFlagInt("--timeout"),
769
773
  json: hasFlag("--json"),
@@ -796,7 +800,7 @@ async function handleSessionCommand() {
796
800
  console.error("Usage: svamp session approve <session-id> [request-id] [--json]");
797
801
  process.exit(1);
798
802
  }
799
- const { sessionApprove } = await import('./commands-DdW5M7Le.mjs');
803
+ const { sessionApprove } = await import('./commands-B5rek8XG.mjs');
800
804
  const approveReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
801
805
  await sessionApprove(sessionArgs[1], approveReqId, targetMachineId, {
802
806
  json: hasFlag("--json")
@@ -806,7 +810,7 @@ async function handleSessionCommand() {
806
810
  console.error("Usage: svamp session deny <session-id> [request-id] [--json]");
807
811
  process.exit(1);
808
812
  }
809
- const { sessionDeny } = await import('./commands-DdW5M7Le.mjs');
813
+ const { sessionDeny } = await import('./commands-B5rek8XG.mjs');
810
814
  const denyReqId = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
811
815
  await sessionDeny(sessionArgs[1], denyReqId, targetMachineId, {
812
816
  json: hasFlag("--json")
@@ -835,13 +839,34 @@ async function handleSessionCommand() {
835
839
  process.exit(1);
836
840
  }
837
841
  await sessionLoopStatus(sessionArgs[1], targetMachineId);
842
+ } else if (sessionSubcommand === "supervise") {
843
+ if (!sessionArgs[1] || !sessionArgs[2]) {
844
+ console.error('Usage: svamp session supervise <session-id> "<criteria>" [--oracle "cmd"] [--agent] [--parent <id>] [--action nudge|block] [--max N]');
845
+ process.exit(1);
846
+ }
847
+ const { sessionSupervise } = await import('./commands-B5rek8XG.mjs');
848
+ const actionStr = parseFlagStr("--action");
849
+ await sessionSupervise(sessionArgs[1], sessionArgs[2], targetMachineId, {
850
+ oracle: parseFlagStr("--oracle"),
851
+ agent: hasFlag("--agent"),
852
+ parent: parseFlagStr("--parent"),
853
+ action: actionStr === "nudge" || actionStr === "block" ? actionStr : void 0,
854
+ maxRounds: parseFlagInt("--max") ?? parseFlagInt("--max-rounds")
855
+ });
856
+ } else if (sessionSubcommand === "unsupervise") {
857
+ if (!sessionArgs[1]) {
858
+ console.error("Usage: svamp session unsupervise <session-id>");
859
+ process.exit(1);
860
+ }
861
+ const { sessionUnsupervise } = await import('./commands-B5rek8XG.mjs');
862
+ await sessionUnsupervise(sessionArgs[1], targetMachineId);
838
863
  } else if (sessionSubcommand === "set-title") {
839
864
  const title = sessionArgs[1];
840
865
  if (!title) {
841
866
  console.error("Usage: svamp session set-title <title>");
842
867
  process.exit(1);
843
868
  }
844
- const { sessionSetTitle } = await import('./agentCommands--H31qHbm.mjs');
869
+ const { sessionSetTitle } = await import('./agentCommands-BTkU0PQb.mjs');
845
870
  await sessionSetTitle(title);
846
871
  } else if (sessionSubcommand === "set-project-description" || sessionSubcommand === "set-project") {
847
872
  const desc = sessionArgs.slice(1).filter((a) => !a.startsWith("--")).join(" ");
@@ -849,7 +874,7 @@ async function handleSessionCommand() {
849
874
  console.error("Usage: svamp session set-project-description <text>");
850
875
  process.exit(1);
851
876
  }
852
- const { sessionSetProjectDescription } = await import('./agentCommands--H31qHbm.mjs');
877
+ const { sessionSetProjectDescription } = await import('./agentCommands-BTkU0PQb.mjs');
853
878
  await sessionSetProjectDescription(desc);
854
879
  } else if (sessionSubcommand === "set-link") {
855
880
  const url = sessionArgs[1];
@@ -858,7 +883,7 @@ async function handleSessionCommand() {
858
883
  process.exit(1);
859
884
  }
860
885
  const label = sessionArgs[2] && !sessionArgs[2].startsWith("--") ? sessionArgs[2] : void 0;
861
- const { sessionSetLink } = await import('./agentCommands--H31qHbm.mjs');
886
+ const { sessionSetLink } = await import('./agentCommands-BTkU0PQb.mjs');
862
887
  await sessionSetLink(url, label);
863
888
  } else if (sessionSubcommand === "notify") {
864
889
  const message = sessionArgs[1];
@@ -867,7 +892,7 @@ async function handleSessionCommand() {
867
892
  process.exit(1);
868
893
  }
869
894
  const level = parseFlagStr("--level") || "info";
870
- const { sessionNotify } = await import('./agentCommands--H31qHbm.mjs');
895
+ const { sessionNotify } = await import('./agentCommands-BTkU0PQb.mjs');
871
896
  await sessionNotify(message, level);
872
897
  } else if (sessionSubcommand === "broadcast") {
873
898
  const action = sessionArgs[1];
@@ -875,7 +900,7 @@ async function handleSessionCommand() {
875
900
  console.error("Usage: svamp session broadcast <action> [args...]\nActions: open-canvas <url> [label], close-canvas, toast <message>");
876
901
  process.exit(1);
877
902
  }
878
- const { sessionBroadcast } = await import('./agentCommands--H31qHbm.mjs');
903
+ const { sessionBroadcast } = await import('./agentCommands-BTkU0PQb.mjs');
879
904
  await sessionBroadcast(action, sessionArgs.slice(2).filter((a) => !a.startsWith("--")));
880
905
  } else if (sessionSubcommand === "inbox") {
881
906
  const inboxSubcmd = sessionArgs[1];
@@ -886,7 +911,7 @@ async function handleSessionCommand() {
886
911
  process.exit(1);
887
912
  }
888
913
  if (agentSessionId) {
889
- const { inboxSend } = await import('./agentCommands--H31qHbm.mjs');
914
+ const { inboxSend } = await import('./agentCommands-BTkU0PQb.mjs');
890
915
  await inboxSend(sessionArgs[2], {
891
916
  body: sessionArgs[3],
892
917
  subject: parseFlagStr("--subject"),
@@ -901,7 +926,7 @@ async function handleSessionCommand() {
901
926
  }
902
927
  } else if (inboxSubcmd === "list" || inboxSubcmd === "ls") {
903
928
  if (agentSessionId && !sessionArgs[2]) {
904
- const { inboxList } = await import('./agentCommands--H31qHbm.mjs');
929
+ const { inboxList } = await import('./agentCommands-BTkU0PQb.mjs');
905
930
  await inboxList({
906
931
  unread: hasFlag("--unread"),
907
932
  limit: parseFlagInt("--limit"),
@@ -923,7 +948,7 @@ async function handleSessionCommand() {
923
948
  process.exit(1);
924
949
  }
925
950
  if (agentSessionId && !sessionArgs[3]) {
926
- const { inboxList } = await import('./agentCommands--H31qHbm.mjs');
951
+ const { inboxList } = await import('./agentCommands-BTkU0PQb.mjs');
927
952
  await sessionInboxRead(agentSessionId, sessionArgs[2], targetMachineId);
928
953
  } else if (sessionArgs[3]) {
929
954
  await sessionInboxRead(sessionArgs[2], sessionArgs[3], targetMachineId);
@@ -933,7 +958,7 @@ async function handleSessionCommand() {
933
958
  }
934
959
  } else if (inboxSubcmd === "reply") {
935
960
  if (agentSessionId && sessionArgs[2] && sessionArgs[3] && !sessionArgs[4]) {
936
- const { inboxReply } = await import('./agentCommands--H31qHbm.mjs');
961
+ const { inboxReply } = await import('./agentCommands-BTkU0PQb.mjs');
937
962
  await inboxReply(sessionArgs[2], sessionArgs[3]);
938
963
  } else if (sessionArgs[2] && sessionArgs[3] && sessionArgs[4]) {
939
964
  await sessionInboxReply(sessionArgs[2], sessionArgs[3], sessionArgs[4], targetMachineId);
@@ -969,7 +994,7 @@ async function handleMachineCommand() {
969
994
  return;
970
995
  }
971
996
  if (machineSubcommand === "share") {
972
- const { machineShare } = await import('./commands-DdW5M7Le.mjs');
997
+ const { machineShare } = await import('./commands-B5rek8XG.mjs');
973
998
  let machineId;
974
999
  const shareArgs = [];
975
1000
  for (let i = 1; i < machineArgs.length; i++) {
@@ -999,7 +1024,7 @@ async function handleMachineCommand() {
999
1024
  }
1000
1025
  await machineShare(machineId, { add, remove, list, configPath, showConfig });
1001
1026
  } else if (machineSubcommand === "exec") {
1002
- const { machineExec } = await import('./commands-DdW5M7Le.mjs');
1027
+ const { machineExec } = await import('./commands-B5rek8XG.mjs');
1003
1028
  let machineId;
1004
1029
  let cwd;
1005
1030
  const cmdParts = [];
@@ -1019,7 +1044,7 @@ async function handleMachineCommand() {
1019
1044
  }
1020
1045
  await machineExec(machineId, command, cwd);
1021
1046
  } else if (machineSubcommand === "info") {
1022
- const { machineInfo } = await import('./commands-DdW5M7Le.mjs');
1047
+ const { machineInfo } = await import('./commands-B5rek8XG.mjs');
1023
1048
  let machineId;
1024
1049
  for (let i = 1; i < machineArgs.length; i++) {
1025
1050
  if ((machineArgs[i] === "--machine" || machineArgs[i] === "-m") && i + 1 < machineArgs.length) {
@@ -1039,10 +1064,10 @@ async function handleMachineCommand() {
1039
1064
  level = machineArgs[++i];
1040
1065
  }
1041
1066
  }
1042
- const { machineNotify } = await import('./agentCommands--H31qHbm.mjs');
1067
+ const { machineNotify } = await import('./agentCommands-BTkU0PQb.mjs');
1043
1068
  await machineNotify(message, level);
1044
1069
  } else if (machineSubcommand === "ls") {
1045
- const { machineLs } = await import('./commands-DdW5M7Le.mjs');
1070
+ const { machineLs } = await import('./commands-B5rek8XG.mjs');
1046
1071
  let machineId;
1047
1072
  let showHidden = false;
1048
1073
  let path;
@@ -1100,24 +1125,24 @@ Examples:
1100
1125
  };
1101
1126
  const hasFlag = (name) => fleetArgs.includes(`--${name}`);
1102
1127
  if (sub === "status") {
1103
- const { fleetStatus } = await import('./fleet-js8FwhM_.mjs');
1128
+ const { fleetStatus } = await import('./fleet-D5dNVJIp.mjs');
1104
1129
  await fleetStatus();
1105
1130
  } else if (sub === "exec") {
1106
1131
  const command = fleetArgs.slice(1).filter((a) => !a.startsWith("--")).join(" ");
1107
- const { fleetExec } = await import('./fleet-js8FwhM_.mjs');
1132
+ const { fleetExec } = await import('./fleet-D5dNVJIp.mjs');
1108
1133
  await fleetExec(command, { cwd: flag("cwd") });
1109
1134
  } else if (sub === "upgrade-claude") {
1110
- const { fleetUpgradeClaude } = await import('./fleet-js8FwhM_.mjs');
1135
+ const { fleetUpgradeClaude } = await import('./fleet-D5dNVJIp.mjs');
1111
1136
  await fleetUpgradeClaude({ version: flag("version", "-v") });
1112
1137
  } else if (sub === "upgrade-svamp") {
1113
- const { fleetUpgradeSvamp } = await import('./fleet-js8FwhM_.mjs');
1138
+ const { fleetUpgradeSvamp } = await import('./fleet-D5dNVJIp.mjs');
1114
1139
  await fleetUpgradeSvamp({ version: flag("version", "-v"), excludeSelf: hasFlag("exclude-self") });
1115
1140
  } else if (sub === "daemon-restart") {
1116
- const { fleetDaemonRestart } = await import('./fleet-js8FwhM_.mjs');
1141
+ const { fleetDaemonRestart } = await import('./fleet-D5dNVJIp.mjs');
1117
1142
  await fleetDaemonRestart({ graceful: !hasFlag("cleanup") });
1118
1143
  } else if (sub === "push-skill") {
1119
1144
  const name = fleetArgs[1];
1120
- const { fleetPushSkill } = await import('./fleet-js8FwhM_.mjs');
1145
+ const { fleetPushSkill } = await import('./fleet-D5dNVJIp.mjs');
1121
1146
  await fleetPushSkill(name);
1122
1147
  } else {
1123
1148
  console.error(`Unknown fleet subcommand: ${sub}`);
@@ -1133,7 +1158,7 @@ async function handleSkillsCommand() {
1133
1158
  await printSkillsHelp();
1134
1159
  return;
1135
1160
  }
1136
- const { skillsFind, skillsInstall, skillsList, skillsRemove, skillsPublish } = await import('./commands-zMw02qH_.mjs');
1161
+ const { skillsFind, skillsInstall, skillsList, skillsRemove, skillsPublish } = await import('./commands-BEjlVtvS.mjs');
1137
1162
  if (skillsSubcommand === "find" || skillsSubcommand === "search") {
1138
1163
  const query = skillsArgs.slice(1).filter((a) => !a.startsWith("--")).join(" ");
1139
1164
  if (!query) {
@@ -1180,7 +1205,7 @@ async function loginToHypha() {
1180
1205
  process.exit(1);
1181
1206
  }
1182
1207
  const anchor = anchorArg.replace(/\/+$/, "");
1183
- const { loadInstanceConfig } = await import('./run-DHPCWQUq.mjs').then(function (n) { return n._; });
1208
+ const { loadInstanceConfig } = await import('./run-9C2ogsuu.mjs').then(function (n) { return n._; });
1184
1209
  let cfg = null;
1185
1210
  try {
1186
1211
  cfg = await loadInstanceConfig({ anchor, force: true });
@@ -1291,7 +1316,7 @@ async function logoutFromHypha() {
1291
1316
  } catch {
1292
1317
  }
1293
1318
  try {
1294
- const { clearInstanceConfigCache } = await import('./run-DHPCWQUq.mjs').then(function (n) { return n._; });
1319
+ const { clearInstanceConfigCache } = await import('./run-9C2ogsuu.mjs').then(function (n) { return n._; });
1295
1320
  clearInstanceConfigCache();
1296
1321
  } catch {
1297
1322
  }
@@ -1551,6 +1576,13 @@ Commands:
1551
1576
  svamp session approve/deny <id> Approve or deny pending permission requests
1552
1577
  svamp session --help Show ALL session commands and detailed options
1553
1578
 
1579
+ Crew (lead delegates features to managed worktree children):
1580
+ svamp feature start "<brief>" Spawn a worktree child of this lead + supervisor (oracle\u2192parent)
1581
+ svamp feature list This lead's feature children (branch, ahead/behind, status)
1582
+ svamp feature done|report (run by a child) signal completion / report progress to the lead
1583
+ svamp feature merge <child> (run by the lead) verify \u2192 merge \u2192 remove worktree \u2192 archive child
1584
+ svamp feature --help Show all crew commands and options
1585
+
1554
1586
  File serving:
1555
1587
  svamp serve <name> [directory] Serve a directory via the shared file server
1556
1588
  svamp serve remove <name> Remove a served mount
@@ -1622,7 +1654,7 @@ async function applyClaudeAuthFlags(argv) {
1622
1654
  "--use-hypha-proxy, --use-claude-login, and --anthropic-base-url/--anthropic-api-key are mutually exclusive"
1623
1655
  );
1624
1656
  }
1625
- const mod = await import('./run-DHPCWQUq.mjs').then(function (n) { return n.Z; });
1657
+ const mod = await import('./run-9C2ogsuu.mjs').then(function (n) { return n.Z; });
1626
1658
  if (hasHypha) {
1627
1659
  let url;
1628
1660
  const hyphaIdx = argv.indexOf("--use-hypha-proxy");
@@ -1676,7 +1708,7 @@ async function applyDaemonShareFlag(argv) {
1676
1708
  }
1677
1709
  }
1678
1710
  if (collected.length === 0) return;
1679
- const { updateEnvFile } = await import('./run-DHPCWQUq.mjs').then(function (n) { return n.Z; });
1711
+ const { updateEnvFile } = await import('./run-9C2ogsuu.mjs').then(function (n) { return n.Z; });
1680
1712
  const seen = /* @__PURE__ */ new Set();
1681
1713
  const deduped = collected.filter((e) => {
1682
1714
  const k = e.toLowerCase();
@@ -1709,7 +1741,7 @@ async function handleWiseAgentCommand(rest) {
1709
1741
  }
1710
1742
  });
1711
1743
  const message = rest.slice(1).map((a, idx) => ({ a, idx: idx + 1 })).filter(({ a, idx }) => !a.startsWith("-") && !consumed.has(String(idx))).map(({ a }) => a).join(" ");
1712
- const { wiseAskCli } = await import('./commands-DdW5M7Le.mjs');
1744
+ const { wiseAskCli } = await import('./commands-B5rek8XG.mjs');
1713
1745
  await wiseAskCli(machineId, message, sessionId, { json });
1714
1746
  return;
1715
1747
  }
@@ -1721,7 +1753,7 @@ async function handleWiseAgentCommand(rest) {
1721
1753
  }
1722
1754
  return void 0;
1723
1755
  };
1724
- const { runWiseVoiceCli } = await import('./headlessCli-my-nvBDO.mjs');
1756
+ const { runWiseVoiceCli } = await import('./headlessCli-Lk2OU1Gh.mjs');
1725
1757
  await runWiseVoiceCli({ voice: valueOf(["--voice"]), wakeKeywordPath: valueOf(["--wake"]), model: valueOf(["--model"]) });
1726
1758
  return;
1727
1759
  }
@@ -1763,7 +1795,7 @@ If none is set, hitting a WISE Agent channel returns a clear "not configured" er
1763
1795
  return;
1764
1796
  }
1765
1797
  const authArgs = rest.slice(1);
1766
- const mod = await import('./auth-CUzGJvRf.mjs');
1798
+ const mod = await import('./auth-DimbhOMP.mjs');
1767
1799
  let action;
1768
1800
  try {
1769
1801
  action = mod.parseWiseAgentAuthArgs(authArgs);
@@ -1773,7 +1805,7 @@ If none is set, hitting a WISE Agent channel returns a clear "not configured" er
1773
1805
  return;
1774
1806
  }
1775
1807
  if (action) {
1776
- const { updateEnvFile } = await import('./run-DHPCWQUq.mjs').then(function (n) { return n.Z; });
1808
+ const { updateEnvFile } = await import('./run-9C2ogsuu.mjs').then(function (n) { return n.Z; });
1777
1809
  const updates = mod.buildWiseAgentEnvUpdates(action);
1778
1810
  updateEnvFile(updates);
1779
1811
  for (const [k, v] of Object.entries(updates)) {
@@ -1787,7 +1819,7 @@ If none is set, hitting a WISE Agent channel returns a clear "not configured" er
1787
1819
  }
1788
1820
  async function handleDaemonAuthCommand(argv) {
1789
1821
  const sub = (argv[0] || "status").toLowerCase();
1790
- const mod = await import('./run-DHPCWQUq.mjs').then(function (n) { return n.Z; });
1822
+ const mod = await import('./run-9C2ogsuu.mjs').then(function (n) { return n.Z; });
1791
1823
  if (sub === "--help" || sub === "-h" || sub === "help") {
1792
1824
  console.log(`
1793
1825
  svamp daemon auth \u2014 Configure how Claude subprocesses authenticate
@@ -1944,6 +1976,10 @@ COMMANDS:
1944
1976
  loop-cancel <id> Cancel the loop
1945
1977
  loop-status <id> Show loop phase + iteration
1946
1978
 
1979
+ Supervisor (attach a Stop gate + success criteria to any session):
1980
+ supervise <id> "<criteria>" [opts] Attach: --oracle "cmd" --agent --parent <id> --max N
1981
+ unsupervise <id> Detach the supervisor
1982
+
1947
1983
  Inbox:
1948
1984
  inbox send <id> "<body>" [opts] Send a message to session inbox
1949
1985
  inbox list <id> [--unread] [--json] List inbox messages
@@ -2090,7 +2126,7 @@ Examples:
2090
2126
  async function printSkillsHelp() {
2091
2127
  let browseUrl = "<HYPHA_SERVER_URL>/<workspace>/artifacts/marketplace (set HYPHA_SERVER_URL)";
2092
2128
  try {
2093
- const { getArtifactBaseUrl, getSkillsCollectionName } = await import('./run-DHPCWQUq.mjs').then(function (n) { return n.$; });
2129
+ const { getArtifactBaseUrl, getSkillsCollectionName } = await import('./run-9C2ogsuu.mjs').then(function (n) { return n.$; });
2094
2130
  browseUrl = `${getArtifactBaseUrl()}/${getSkillsCollectionName()}`;
2095
2131
  } catch {
2096
2132
  }
@@ -1,11 +1,11 @@
1
1
  import { writeFileSync, readFileSync } from 'fs';
2
2
  import { resolve } from 'path';
3
- import { connectAndGetMachine } from './commands-DdW5M7Le.mjs';
3
+ import { connectAndGetMachine } from './commands-B5rek8XG.mjs';
4
4
  import 'node:fs';
5
5
  import 'node:child_process';
6
6
  import 'node:path';
7
7
  import 'node:os';
8
- import './run-DHPCWQUq.mjs';
8
+ import './run-9C2ogsuu.mjs';
9
9
  import 'os';
10
10
  import 'fs/promises';
11
11
  import 'url';