svamp-cli 0.2.342 → 0.2.346

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 (67) hide show
  1. package/bin/skills/artifact/SKILL.md +1 -1
  2. package/bin/skills/crew/SKILL.md +21 -3
  3. package/dist/DefaultTransport-vfp78fug.mjs +47 -0
  4. package/dist/GeminiTransport-3OkhtFRO.mjs +130 -0
  5. package/dist/KimiTransport-D8n009Tr.mjs +141 -0
  6. package/dist/acpAgentConfig-CObOPlA8.mjs +48 -0
  7. package/dist/acpBackend-BZ1MJhQV.mjs +922 -0
  8. package/dist/{adminCommands-CRTBDZan.mjs → adminCommands-BvsYnRDA.mjs} +2 -18
  9. package/dist/{agentCommands-BuO988tJ.mjs → agentCommands-B2Nl7Fof.mjs} +6 -23
  10. package/dist/api-BHjyC0Ph.mjs +157 -0
  11. package/dist/{auth--WS0wezs.mjs → auth-CRz8TsEl.mjs} +1 -22
  12. package/dist/bootStatus-DqtNgJch.mjs +143 -0
  13. package/dist/claudeAuth-iAerdaMr.mjs +247 -0
  14. package/dist/cli.mjs +2939 -5
  15. package/dist/codexAppServerBackend-VGsYtbqg.mjs +786 -0
  16. package/dist/codexProvider-BtxYc5Rj.mjs +68 -0
  17. package/dist/{commands-DXM17M6n.mjs → commands-BB1Kcyt-.mjs} +13 -19
  18. package/dist/{commands-DU4B-4Gh.mjs → commands-BOpoVBOM.mjs} +55 -25
  19. package/dist/{commands-C0HQiu-S.mjs → commands-C2aODeVc.mjs} +58 -33
  20. package/dist/{commands-Cwxy-C5N.mjs → commands-CiRCwjkJ.mjs} +10 -32
  21. package/dist/{commands-DDuGBSsz.mjs → commands-D1pZq3d4.mjs} +103 -41
  22. package/dist/{commands-BKb1g8Gq.mjs → commands-D69mnkYu.mjs} +20 -30
  23. package/dist/{commands-BsKgZ5sQ.mjs → commands-DW5RnHZw.mjs} +2 -19
  24. package/dist/{commands-DXLOKJOj.mjs → commands-H4PsTGn8.mjs} +58 -26
  25. package/dist/cron-hHGdb5kU.mjs +132 -0
  26. package/dist/detectIsolation-CzoDCEnh.mjs +319 -0
  27. package/dist/envFlag-COOuJ3AH.mjs +11 -0
  28. package/dist/fileLock-BMPwCrB6.mjs +80 -0
  29. package/dist/{fleet-BHzlAvnu.mjs → fleet-DM_Q7w69.mjs} +85 -24
  30. package/dist/flushExit-C-i6SGjj.mjs +37 -0
  31. package/dist/friendlyName-1UZcyDhu.mjs +586 -0
  32. package/dist/{headlessCli-C2gvOpOt.mjs → headlessCli-C8HzQvis.mjs} +3 -21
  33. package/dist/hookSettings-DYMTUgVA.mjs +10399 -0
  34. package/dist/{httpServer-Be1Hcddr.mjs → httpServer-BzEDbOGn.mjs} +14 -5
  35. package/dist/hyphaClient-ybivOjZo.mjs +49 -0
  36. package/dist/index.mjs +40 -8
  37. package/dist/instance-CeHz5C8v.mjs +203 -0
  38. package/dist/kimiProvider-DbxODebR.mjs +69 -0
  39. package/dist/kimiSetup-NGsoYB5h.mjs +48 -0
  40. package/dist/loopVerify-B47sSjxe.mjs +444 -0
  41. package/dist/machineTools-DygM1jXW.mjs +580 -0
  42. package/dist/model-CUHojegn.mjs +66 -0
  43. package/dist/{notifyCommands-0aZUwKQK.mjs → notifyCommands-D-IKIxiq.mjs} +3 -18
  44. package/dist/package-DtuINqf5.mjs +64 -0
  45. package/dist/pinnedCodex-XW4qvOAe.mjs +11 -0
  46. package/dist/pinnedNono-5ZHb6328.mjs +15 -0
  47. package/dist/{rpc-rAQQ1q8t.mjs → rpc-BB6RF4-F.mjs} +38 -6
  48. package/dist/{rpc-B2Lc2BAB.mjs → rpc-Cf0grcru.mjs} +28 -20
  49. package/dist/{run-C7QVfyw4.mjs → run-ChdsgaSD.mjs} +17 -9
  50. package/dist/run-DkjwF-zA.mjs +9695 -0
  51. package/dist/sandboxDetect-Cdzsj5TC.mjs +19 -0
  52. package/dist/{scheduler-CzF4lOe_.mjs → scheduler-BY30ZrB9.mjs} +38 -6
  53. package/dist/securityContext-Cm5UTCuD.mjs +218 -0
  54. package/dist/serveAuth-DbVLRCRR.mjs +418 -0
  55. package/dist/{serveCommands-EIEqdaVu.mjs → serveCommands-CUHUiYnZ.mjs} +13 -34
  56. package/dist/sharingNotificationSync-qGIQ-3yf.mjs +359 -0
  57. package/dist/{sideband-BoutiRJi.mjs → sideband-68HhGT0i.mjs} +1 -21
  58. package/dist/store-Bn0ByYev.mjs +347 -0
  59. package/dist/store-fi0f-ff1.mjs +184 -0
  60. package/dist/types-57J3Re0n.mjs +17 -0
  61. package/dist/wantsHelp-6bMOeNUz.mjs +5 -0
  62. package/dist/wrapCommand-CdNawSaa.mjs +117 -0
  63. package/package.json +3 -3
  64. package/dist/cli-B24CmIli.mjs +0 -2780
  65. package/dist/package-CTbGYaJG.mjs +0 -64
  66. package/dist/run-CF4kAVPW.mjs +0 -26508
  67. package/dist/sandboxDetect-DNTcbgWD.mjs +0 -12
@@ -0,0 +1,68 @@
1
+ function codexPermissionSettings(mode) {
2
+ switch (mode) {
3
+ case "yolo":
4
+ case "bypassPermissions":
5
+ case "danger-full-access":
6
+ return { approvalPolicy: "never", sandbox: "danger-full-access" };
7
+ case "safe-yolo":
8
+ case "acceptEdits":
9
+ return { approvalPolicy: "on-failure", sandbox: "workspace-write" };
10
+ case "read-only":
11
+ case "plan":
12
+ return { approvalPolicy: "on-request", sandbox: "read-only" };
13
+ case "default":
14
+ default:
15
+ return { approvalPolicy: "on-request", sandbox: "workspace-write" };
16
+ }
17
+ }
18
+ const CODEX_PROVIDER_KEY_ENV = "SVAMP_CODEX_API_KEY";
19
+ const PROVIDER_NAME = "svamp";
20
+ function resolveCodexProvider(env = process.env) {
21
+ return {
22
+ apiBase: env.SVAMP_CODEX_API_BASE || env.LLM_API_BASE || void 0,
23
+ apiKey: env.SVAMP_CODEX_API_KEY || env.LLM_API_KEY || void 0,
24
+ model: env.SVAMP_CODEX_MODEL || env.LLM_MODEL || void 0
25
+ };
26
+ }
27
+ function hasCustomProvider(cfg) {
28
+ return !!(cfg.apiBase && cfg.apiKey);
29
+ }
30
+ function buildCodexProviderArgs(cfg) {
31
+ if (!hasCustomProvider(cfg)) {
32
+ return { configArgs: cfg.model ? ["-c", `model=${JSON.stringify(cfg.model)}`] : [], env: {}, model: cfg.model };
33
+ }
34
+ const configArgs = [
35
+ "-c",
36
+ `model_provider=${JSON.stringify(PROVIDER_NAME)}`,
37
+ "-c",
38
+ `model_providers.${PROVIDER_NAME}.name=${JSON.stringify(PROVIDER_NAME)}`,
39
+ "-c",
40
+ `model_providers.${PROVIDER_NAME}.base_url=${JSON.stringify(cfg.apiBase)}`,
41
+ "-c",
42
+ `model_providers.${PROVIDER_NAME}.env_key=${JSON.stringify(CODEX_PROVIDER_KEY_ENV)}`,
43
+ "-c",
44
+ `model_providers.${PROVIDER_NAME}.wire_api=${JSON.stringify("responses")}`
45
+ ];
46
+ if (cfg.model) configArgs.push("-c", `model=${JSON.stringify(cfg.model)}`);
47
+ return { configArgs, env: { [CODEX_PROVIDER_KEY_ENV]: cfg.apiKey }, model: cfg.model };
48
+ }
49
+ function codexForcedModel(env = process.env) {
50
+ const f = (env.SVAMP_CODEX_FORCE_MODEL || "").toLowerCase();
51
+ if (!f || f === "0" || f === "false" || f === "no" || f === "off") return void 0;
52
+ return env.SVAMP_CODEX_MODEL || env.LLM_MODEL || void 0;
53
+ }
54
+ function codexModelMenu(env = process.env) {
55
+ return (env.SVAMP_CODEX_MODELS || "").split(",").map((s) => s.trim()).filter(Boolean).filter((m, i, a) => a.indexOf(m) === i);
56
+ }
57
+ function codexDefaultModel(env = process.env) {
58
+ const menu = codexModelMenu(env);
59
+ return env.SVAMP_CODEX_MODEL || env.LLM_MODEL || menu[0] || void 0;
60
+ }
61
+ function codexClampModel(requested, env = process.env) {
62
+ const menu = codexModelMenu(env);
63
+ if (!menu.length) return requested;
64
+ if (requested && menu.includes(requested)) return requested;
65
+ return codexDefaultModel(env);
66
+ }
67
+
68
+ export { CODEX_PROVIDER_KEY_ENV, buildCodexProviderArgs, codexClampModel, codexDefaultModel, codexForcedModel, codexModelMenu, codexPermissionSettings, hasCustomProvider, resolveCodexProvider };
@@ -1,28 +1,22 @@
1
- import { connectAndResolveSession } from './commands-DDuGBSsz.mjs';
2
- import { w as wantsHelp } from './cli-B24CmIli.mjs';
1
+ import { connectAndResolveSession } from './commands-D1pZq3d4.mjs';
2
+ import { w as wantsHelp } from './wantsHelp-6bMOeNUz.mjs';
3
3
  import 'node:fs';
4
4
  import 'node:child_process';
5
5
  import 'node:path';
6
6
  import 'node:os';
7
- import './run-CF4kAVPW.mjs';
8
- import 'os';
9
- import 'fs/promises';
7
+ import './hyphaClient-ybivOjZo.mjs';
8
+ import './friendlyName-1UZcyDhu.mjs';
9
+ import 'node:crypto';
10
+ import './types-57J3Re0n.mjs';
11
+ import './securityContext-Cm5UTCuD.mjs';
12
+ import './loopVerify-B47sSjxe.mjs';
13
+ import './instance-CeHz5C8v.mjs';
10
14
  import 'fs';
11
15
  import 'path';
12
- import 'url';
13
- import 'child_process';
14
- import 'crypto';
15
- import 'node:crypto';
16
- import 'util';
17
- import 'http';
18
- import 'net';
19
- import 'node:events';
20
- import '@agentclientprotocol/sdk';
21
- import 'node:util';
22
- import 'node:readline';
23
- import 'node:fs/promises';
24
- import 'yaml';
25
- import './serviceManager-hlOVxkhW.mjs';
16
+ import 'os';
17
+ import './store-Bn0ByYev.mjs';
18
+ import './fileLock-BMPwCrB6.mjs';
19
+ import './flushExit-C-i6SGjj.mjs';
26
20
 
27
21
  function argVal(args, name) {
28
22
  const i = args.indexOf(name);
@@ -1,29 +1,59 @@
1
1
  import { writeFileSync, readFileSync } from 'fs';
2
2
  import { resolve } from 'path';
3
- import { connectAndGetMachine } from './commands-DDuGBSsz.mjs';
4
- import { w as wantsHelp } from './cli-B24CmIli.mjs';
3
+ import { connectAndGetMachine } from './commands-D1pZq3d4.mjs';
4
+ import { w as wantsHelp } from './wantsHelp-6bMOeNUz.mjs';
5
5
  import 'node:fs';
6
6
  import 'node:child_process';
7
7
  import 'node:path';
8
8
  import 'node:os';
9
- import './run-CF4kAVPW.mjs';
10
- import 'os';
11
- import 'fs/promises';
12
- import 'url';
13
- import 'child_process';
14
- import 'crypto';
9
+ import './hyphaClient-ybivOjZo.mjs';
10
+ import './friendlyName-1UZcyDhu.mjs';
15
11
  import 'node:crypto';
16
- import 'util';
17
- import 'http';
18
- import 'net';
19
- import 'node:events';
20
- import '@agentclientprotocol/sdk';
21
- import 'node:util';
22
- import 'node:readline';
23
- import 'node:fs/promises';
24
- import 'yaml';
25
- import './serviceManager-hlOVxkhW.mjs';
12
+ import './types-57J3Re0n.mjs';
13
+ import './securityContext-Cm5UTCuD.mjs';
14
+ import './loopVerify-B47sSjxe.mjs';
15
+ import './instance-CeHz5C8v.mjs';
16
+ import 'os';
17
+ import './store-Bn0ByYev.mjs';
18
+ import './fileLock-BMPwCrB6.mjs';
19
+ import './flushExit-C-i6SGjj.mjs';
20
+
21
+ function positionalArgs(args, valueFlags) {
22
+ const out = [];
23
+ for (let i = 0; i < args.length; i++) {
24
+ const a = args[i];
25
+ if (a === "--") break;
26
+ if (a.startsWith("-") && a !== "-") {
27
+ if (!a.includes("=") && valueFlags.has(a)) i++;
28
+ continue;
29
+ }
30
+ out.push(a);
31
+ }
32
+ return out;
33
+ }
34
+ function firstPositional(args, valueFlags) {
35
+ return positionalArgs(args, valueFlags)[0];
36
+ }
26
37
 
38
+ const PROCESS_VALUE_FLAGS = /* @__PURE__ */ new Set([
39
+ "-o",
40
+ "--output",
41
+ "--save",
42
+ "--last",
43
+ "--env",
44
+ "--ttl",
45
+ "--workdir",
46
+ "--max-restarts",
47
+ "--restart-delay",
48
+ "--probe-port",
49
+ "--probe-path",
50
+ "--probe-interval",
51
+ "--probe-timeout",
52
+ "--probe-failures",
53
+ // pre-stripped by cli.ts today, listed so this set stays correct if that ever changes
54
+ "-m",
55
+ "--machine"
56
+ ]);
27
57
  function getFlag(args, flag) {
28
58
  const idx = args.indexOf(flag);
29
59
  return idx !== -1 && idx + 1 < args.length ? args[idx + 1] : void 0;
@@ -308,7 +338,7 @@ async function processCommand(args, machineId) {
308
338
  }
309
339
  }
310
340
  async function applyCommand(args, machineId) {
311
- const filePath = args.find((a) => !a.startsWith("-"));
341
+ const filePath = firstPositional(args, PROCESS_VALUE_FLAGS);
312
342
  if (!filePath) {
313
343
  console.error("Error: spec file required");
314
344
  console.error("Usage: svamp process apply <file.yaml>");
@@ -353,7 +383,7 @@ async function listCommand(args, machineId) {
353
383
  }
354
384
  }
355
385
  async function getCommand(args, machineId) {
356
- const idOrName = args.find((a) => !a.startsWith("-"));
386
+ const idOrName = firstPositional(args, PROCESS_VALUE_FLAGS);
357
387
  if (!idOrName) {
358
388
  console.error("Error: process name or id required");
359
389
  process.exit(1);
@@ -394,7 +424,7 @@ ${content}`, "utf-8");
394
424
  }
395
425
  async function startCommand(args, machineId) {
396
426
  const { flagArgs, cmdArgs } = splitOnDoubleDash(args);
397
- const idOrName = flagArgs.find((a) => !a.startsWith("-"));
427
+ const idOrName = firstPositional(flagArgs, PROCESS_VALUE_FLAGS);
398
428
  if (!idOrName) {
399
429
  console.error("Error: process name or id required");
400
430
  process.exit(1);
@@ -477,7 +507,7 @@ async function startCommand(args, machineId) {
477
507
  }
478
508
  }
479
509
  async function stopCommand(args, machineId) {
480
- const idOrName = args.find((a) => !a.startsWith("-"));
510
+ const idOrName = firstPositional(args, PROCESS_VALUE_FLAGS);
481
511
  if (!idOrName) {
482
512
  console.error("Error: process name or id required");
483
513
  process.exit(1);
@@ -491,7 +521,7 @@ async function stopCommand(args, machineId) {
491
521
  }
492
522
  }
493
523
  async function restartCommand(args, machineId) {
494
- const idOrName = args.find((a) => !a.startsWith("-"));
524
+ const idOrName = firstPositional(args, PROCESS_VALUE_FLAGS);
495
525
  if (!idOrName) {
496
526
  console.error("Error: process name or id required");
497
527
  process.exit(1);
@@ -505,7 +535,7 @@ async function restartCommand(args, machineId) {
505
535
  }
506
536
  }
507
537
  async function deleteCommand(args, machineId) {
508
- const idOrName = args.find((a) => !a.startsWith("-"));
538
+ const idOrName = firstPositional(args, PROCESS_VALUE_FLAGS);
509
539
  if (!idOrName) {
510
540
  console.error("Error: process name or id required");
511
541
  process.exit(1);
@@ -519,7 +549,7 @@ async function deleteCommand(args, machineId) {
519
549
  }
520
550
  }
521
551
  async function logsCommand(args, machineId) {
522
- const idOrName = args.find((a) => !a.startsWith("-"));
552
+ const idOrName = firstPositional(args, PROCESS_VALUE_FLAGS);
523
553
  if (!idOrName) {
524
554
  console.error("Error: process name or id required");
525
555
  process.exit(1);
@@ -1,28 +1,22 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import { join, resolve } from 'node:path';
3
- import { connectAndGetMachine, resolveSessionId, createWorktree, connectAndResolveSession } from './commands-DDuGBSsz.mjs';
3
+ import { connectAndGetMachine, resolveSessionId, createWorktree, connectAndResolveSession } from './commands-D1pZq3d4.mjs';
4
4
  import { execFileSync } from 'node:child_process';
5
- import { ak as withFileLock, u as updateIssue, k as addComment, l as addIssue, e as shortId } from './run-CF4kAVPW.mjs';
6
- import { w as wantsHelp } from './cli-B24CmIli.mjs';
5
+ import { w as withFileLock } from './fileLock-BMPwCrB6.mjs';
6
+ import { u as updateIssue, f as addComment, h as addIssue, n as resolveCrewIssueOnMerge } from './store-Bn0ByYev.mjs';
7
+ import { s as shortId } from './friendlyName-1UZcyDhu.mjs';
8
+ import { w as wantsHelp } from './wantsHelp-6bMOeNUz.mjs';
7
9
  import 'node:os';
8
- import 'os';
9
- import 'fs/promises';
10
+ import './hyphaClient-ybivOjZo.mjs';
11
+ import './types-57J3Re0n.mjs';
12
+ import './securityContext-Cm5UTCuD.mjs';
13
+ import './loopVerify-B47sSjxe.mjs';
14
+ import './instance-CeHz5C8v.mjs';
10
15
  import 'fs';
11
16
  import 'path';
12
- import 'url';
13
- import 'child_process';
14
- import 'crypto';
17
+ import 'os';
18
+ import './flushExit-C-i6SGjj.mjs';
15
19
  import 'node:crypto';
16
- import 'util';
17
- import 'http';
18
- import 'net';
19
- import 'node:events';
20
- import '@agentclientprotocol/sdk';
21
- import 'node:util';
22
- import 'node:readline';
23
- import 'node:fs/promises';
24
- import 'yaml';
25
- import './serviceManager-hlOVxkhW.mjs';
26
20
 
27
21
  function git(cwd, args) {
28
22
  return execFileSync("git", args, { cwd, stdio: "pipe", encoding: "utf-8" }).toString();
@@ -187,6 +181,9 @@ function projectRootFromWorktree(worktreePath) {
187
181
  if (idx === -1) return null;
188
182
  return worktreePath.slice(0, idx);
189
183
  }
184
+ function canonicalProjectRoot(anyPathInProject) {
185
+ return projectRootFromWorktree(anyPathInProject) ?? anyPathInProject;
186
+ }
190
187
  function removeWorktree(worktreePath) {
191
188
  const projectRoot = projectRootFromWorktree(worktreePath);
192
189
  if (!projectRoot) return;
@@ -214,14 +211,17 @@ function resolveNotifyLead(leadId, childParentSessionId, childId) {
214
211
  return leadId || childParentSessionId || childId;
215
212
  }
216
213
 
214
+ function crewReportUrgency(crew) {
215
+ return crew?.action === "block" ? "urgent" : "normal";
216
+ }
217
217
  function isStandaloneChild(crew) {
218
218
  return !!crew && crew.standalone === true;
219
219
  }
220
- function worktreeCrewMeta(feature, branch, worktreePath, baseBranch) {
221
- return { role: "feature", feature, branch, worktreePath, baseBranch };
220
+ function worktreeCrewMeta(feature, branch, worktreePath, baseBranch, action) {
221
+ return { role: "feature", feature, branch, worktreePath, baseBranch, ...action ? { action } : {} };
222
222
  }
223
- function standaloneCrewMeta(feature, directory) {
224
- return { role: "feature", feature, standalone: true, directory };
223
+ function standaloneCrewMeta(feature, directory, action) {
224
+ return { role: "feature", feature, standalone: true, directory, ...action ? { action } : {} };
225
225
  }
226
226
  function childDirectory(crew, sessionDir) {
227
227
  return crew?.worktreePath || crew?.directory || sessionDir || "";
@@ -277,7 +277,7 @@ async function waitForChildIdle(machine, childId, timeoutMs = 2e4) {
277
277
  }
278
278
  return false;
279
279
  }
280
- async function inbox(machine, fromId, toId, body, subject) {
280
+ async function inbox(machine, fromId, toId, body, subject, urgency = "normal") {
281
281
  await rpc(machine, toId, "sendInboxMessage", {
282
282
  message: {
283
283
  messageId: shortId(),
@@ -288,7 +288,7 @@ async function inbox(machine, fromId, toId, body, subject) {
288
288
  fromSession: fromId,
289
289
  to: toId,
290
290
  subject,
291
- urgency: "normal"
291
+ urgency
292
292
  }
293
293
  });
294
294
  }
@@ -319,11 +319,12 @@ async function featureStart(brief, opts = {}) {
319
319
  }
320
320
  console.log(`Standalone child folder: ${childDir} (no worktree)`);
321
321
  } else {
322
- const projectRoot2 = opts.directory || lead.directory;
323
- if (!projectRoot2) {
322
+ const leadDir = opts.directory || lead.directory;
323
+ if (!leadDir) {
324
324
  console.error("Could not determine the lead project directory.");
325
325
  process.exit(1);
326
326
  }
327
+ const projectRoot2 = canonicalProjectRoot(leadDir);
327
328
  base = opts.baseBranch || currentBranch(projectRoot2) || "main";
328
329
  try {
329
330
  wt = createWorktree(projectRoot2);
@@ -334,7 +335,7 @@ async function featureStart(brief, opts = {}) {
334
335
  childDir = wt.path;
335
336
  console.log(`Worktree: ${wt.branch} \u2192 ${wt.path}`);
336
337
  }
337
- const projectRoot = lead.directory || opts.directory || childDir;
338
+ const projectRoot = canonicalProjectRoot(lead.directory || opts.directory || childDir);
338
339
  const result = await machine.spawnSession({
339
340
  directory: childDir,
340
341
  agent: "claude",
@@ -395,8 +396,9 @@ async function featureStart(brief, opts = {}) {
395
396
  }
396
397
  const oracle = opts.oracle?.trim();
397
398
  const patch = {
398
- crew: standalone ? standaloneCrewMeta(brief.trim(), childDir) : worktreeCrewMeta(brief.trim(), wt.branch, wt.path, base)
399
+ crew: standalone ? standaloneCrewMeta(brief.trim(), childDir, opts.action) : worktreeCrewMeta(brief.trim(), wt.branch, wt.path, base, opts.action)
399
400
  };
401
+ const childMaxIterations = opts.maxRounds ?? 20;
400
402
  let judges = [];
401
403
  if (oracle) {
402
404
  judges = [{ type: "oracle", cmd: oracle, on_fail: "escalate" }, { type: "parent", parent: lead.sessionId }];
@@ -404,8 +406,10 @@ async function featureStart(brief, opts = {}) {
404
406
  until: brief.trim(),
405
407
  oracle,
406
408
  parent: lead.sessionId,
407
- max_iterations: opts.maxRounds ?? 20
409
+ max_iterations: childMaxIterations
408
410
  };
411
+ } else if (opts.maxRounds != null) {
412
+ patch.loop = { max_iterations: childMaxIterations };
409
413
  }
410
414
  try {
411
415
  await rpc(machine, childId, "updateConfig", { patch });
@@ -527,9 +531,10 @@ async function featureReport(text, opts = {}) {
527
531
  process.exit(1);
528
532
  }
529
533
  const kind = opts.blocker ? "blocker" : "progress";
534
+ const urgency = opts.blocker ? "urgent" : crewReportUrgency(meta?.crew);
530
535
  await inbox(machine, selfId, parent, `<feature-${kind} from="${selfId}">
531
536
  ${text.trim()}
532
- </feature-${kind}>`, `feature ${kind}`);
537
+ </feature-${kind}>`, `feature ${kind}`, urgency);
533
538
  console.log(`Reported ${kind} to lead ${parent.slice(0, 8)}.`);
534
539
  } finally {
535
540
  await server.disconnect();
@@ -555,7 +560,7 @@ async function featureDone(opts = {}) {
555
560
  `No branch to merge (standalone folder). Detach & close with: svamp feature merge ${selfId.slice(0, 8)}`,
556
561
  `</done-request>`
557
562
  ].filter(Boolean).join("\n");
558
- await inbox(machine, selfId, parent, body2, `done-request (standalone)`);
563
+ await inbox(machine, selfId, parent, body2, `done-request (standalone)`, crewReportUrgency(crew));
559
564
  console.log(`Sent done-request to lead ${parent.slice(0, 8)} (standalone folder ${dir2 || "?"}; no branch to merge).`);
560
565
  return;
561
566
  }
@@ -576,7 +581,7 @@ async function featureDone(opts = {}) {
576
581
  `Review & merge with: svamp feature merge ${selfId.slice(0, 8)}`,
577
582
  `</merge-request>`
578
583
  ].filter(Boolean).join("\n");
579
- await inbox(machine, selfId, parent, body, `merge-request (${branch || "feature"})`);
584
+ await inbox(machine, selfId, parent, body, `merge-request (${branch || "feature"})`, crewReportUrgency(crew));
580
585
  console.log(`Sent merge-request to lead ${parent.slice(0, 8)} (branch ${branch || "?"}, +${ab.ahead} commits).`);
581
586
  if (dirty) console.log(" \u26A0 Worktree is dirty \u2014 commit your work or the merge will be rejected.");
582
587
  } finally {
@@ -676,6 +681,12 @@ Stop editing and hold \u2014 do not keep working. Once the blocker is resolved,
676
681
  console.warn(`Merged, but could not archive child: ${e.message}`);
677
682
  }
678
683
  }
684
+ try {
685
+ const resolved = resolveCrewIssueOnMerge(projectRoot, childId, { branch, base });
686
+ if (resolved) console.log(` issue: #${resolved.id} closed (merged).`);
687
+ } catch (e) {
688
+ console.warn(`Merged, but could not close the crew tracking issue: ${e.message}`);
689
+ }
679
690
  const cleanup = r.cleanupWarning ? "worktree NOT removed (see warning)" : isMainWorkingTree(projectRoot, worktreePath) ? "ran in the lead tree (no worktree to remove)" : "worktree removed";
680
691
  if (r.cleanupWarning) console.warn(`\u26A0\uFE0F ${r.cleanupWarning}`);
681
692
  console.log(`\u2705 Merged ${branch} \u2192 ${base}; ${cleanup}; child ${childId.slice(0, 8)} ${opts.keepChild ? "kept" : "archived"}.`);
@@ -711,6 +722,10 @@ const FEATURE_HELP = `Usage: svamp feature <command>
711
722
  [--max N] [--dir <path>] [--no-worktree] [--model <id>] [--lead <id>] [-m <machine>]
712
723
  Spawn a managed child of the lead + attach a loop gate (oracle\u2192parent).
713
724
  --model sets the child's model (e.g. claude-fable-5, claude-opus-4-8).
725
+ --action nudge|block controls how the lead is notified when the child reports or
726
+ finishes: 'nudge' (default) sends at normal urgency, which the lead picks up on its
727
+ next idle turn; 'block' sends urgent, which WAKES the lead. An explicit
728
+ 'crew report --blocker' is always urgent regardless.
714
729
  --issue <id> links the child to an existing backlog issue: the child's verdict
715
730
  routes ONTO that issue \u2014 the seam that joins crew to the backlog that
716
731
  'svamp issue pending' (the loop oracle) reads.
@@ -737,6 +752,16 @@ async function crewCommand(args) {
737
752
  const valueFlags = ["--oracle", "--base", "--action", "--max", "--dir", "-d", "--lead", "-m", "--machine", "--issue", "--model"];
738
753
  const brief = positionals(rest, valueFlags).join(" ");
739
754
  const maxStr = flag(rest, "--max");
755
+ let maxRounds;
756
+ if (maxStr !== void 0) {
757
+ const n = Number(maxStr);
758
+ if (!Number.isInteger(n) || n <= 0) {
759
+ console.error(`Error: --max must be a positive integer (got "${maxStr}").`);
760
+ console.error(" Omit it to use the default round cap; it is a HARD stop for the child.");
761
+ process.exit(1);
762
+ }
763
+ maxRounds = n;
764
+ }
740
765
  const action = flag(rest, "--action");
741
766
  await featureStart(brief, {
742
767
  leadId: lead,
@@ -748,7 +773,7 @@ async function crewCommand(args) {
748
773
  issueId: flag(rest, "--issue"),
749
774
  model: flag(rest, "--model"),
750
775
  action: action === "block" ? "block" : action === "nudge" ? "nudge" : void 0,
751
- maxRounds: maxStr ? parseInt(maxStr, 10) : void 0
776
+ maxRounds
752
777
  });
753
778
  } else if (sub === "list" || sub === "ls") {
754
779
  await featureList({ leadId: lead, machineId, json: has(rest, "--json") });
@@ -1,27 +1,5 @@
1
1
  import * as path from 'path';
2
- import { w as wantsHelp } from './cli-B24CmIli.mjs';
3
- import './run-CF4kAVPW.mjs';
4
- import 'os';
5
- import 'fs/promises';
6
- import 'fs';
7
- import 'url';
8
- import 'child_process';
9
- import 'crypto';
10
- import 'node:fs';
11
- import 'node:path';
12
- import 'node:crypto';
13
- import 'node:child_process';
14
- import 'util';
15
- import 'http';
16
- import 'net';
17
- import 'node:os';
18
- import 'node:events';
19
- import '@agentclientprotocol/sdk';
20
- import 'node:util';
21
- import 'node:readline';
22
- import 'node:fs/promises';
23
- import 'yaml';
24
- import './serviceManager-hlOVxkhW.mjs';
2
+ import { w as wantsHelp } from './wantsHelp-6bMOeNUz.mjs';
25
3
 
26
4
  function getFlag(args, flag) {
27
5
  const idx = args.indexOf(flag);
@@ -83,7 +61,7 @@ async function serviceExpose(args) {
83
61
  process.exit(1);
84
62
  }
85
63
  if (foreground) {
86
- const { runFrpcTunnel } = await import('./run-CF4kAVPW.mjs').then(function (n) { return n.as; });
64
+ const { runFrpcTunnel } = await import('./hookSettings-DYMTUgVA.mjs').then(function (n) { return n.w; });
87
65
  await runFrpcTunnel(name, ports, void 0, {
88
66
  group,
89
67
  groupKey,
@@ -93,7 +71,7 @@ async function serviceExpose(args) {
93
71
  });
94
72
  return;
95
73
  }
96
- const { connectAndGetMachine } = await import('./commands-DDuGBSsz.mjs');
74
+ const { connectAndGetMachine } = await import('./commands-D1pZq3d4.mjs');
97
75
  const { server, machine } = await connectAndGetMachine();
98
76
  try {
99
77
  const status = await machine.tunnelStart({
@@ -115,7 +93,7 @@ async function serviceExpose(args) {
115
93
  console.log(` port ${port}: ${url}`);
116
94
  }
117
95
  if (process.env.SVAMP_SESSION_ID) {
118
- const { autoAddSessionLink } = await import('./agentCommands-BuO988tJ.mjs');
96
+ const { autoAddSessionLink } = await import('./agentCommands-B2Nl7Fof.mjs');
119
97
  let added = 0;
120
98
  for (const [port, url] of urlEntries) {
121
99
  const label = urlEntries.length > 1 ? `${name}:${port}` : name;
@@ -151,8 +129,8 @@ async function serviceServe(args) {
151
129
  const resolvedDir = path.resolve(directory);
152
130
  console.log(`Serving ${resolvedDir}`);
153
131
  const http = await import('http');
154
- const { serveStaticMount } = await import('./run-CF4kAVPW.mjs').then(function (n) { return n.at; });
155
- const { getFreePort } = await import('./run-CF4kAVPW.mjs').then(function (n) { return n.as; });
132
+ const { serveStaticMount } = await import('./hookSettings-DYMTUgVA.mjs').then(function (n) { return n.x; });
133
+ const { getFreePort } = await import('./hookSettings-DYMTUgVA.mjs').then(function (n) { return n.w; });
156
134
  const server = http.createServer((req, res) => {
157
135
  const u = new URL(req.url || "/", "http://127.0.0.1");
158
136
  let rel = u.pathname;
@@ -175,7 +153,7 @@ async function serviceServe(args) {
175
153
  resolve(18080);
176
154
  });
177
155
  });
178
- const { runFrpcTunnel } = await import('./run-CF4kAVPW.mjs').then(function (n) { return n.as; });
156
+ const { runFrpcTunnel } = await import('./hookSettings-DYMTUgVA.mjs').then(function (n) { return n.w; });
179
157
  void server;
180
158
  await runFrpcTunnel(name, [servePort]);
181
159
  } catch (err) {
@@ -185,7 +163,7 @@ async function serviceServe(args) {
185
163
  }
186
164
  async function serviceList(_args) {
187
165
  try {
188
- const { connectAndGetMachine } = await import('./commands-DDuGBSsz.mjs');
166
+ const { connectAndGetMachine } = await import('./commands-D1pZq3d4.mjs');
189
167
  const { server, machine } = await connectAndGetMachine();
190
168
  try {
191
169
  const tunnels = await machine.tunnelList({});
@@ -225,11 +203,11 @@ async function serviceDelete(args) {
225
203
  process.exit(1);
226
204
  }
227
205
  try {
228
- const { connectAndGetMachine } = await import('./commands-DDuGBSsz.mjs');
206
+ const { connectAndGetMachine } = await import('./commands-D1pZq3d4.mjs');
229
207
  const { server, machine } = await connectAndGetMachine();
230
208
  try {
231
209
  await machine.tunnelStop({ name });
232
- const { removeSessionLinkByService } = await import('./agentCommands-BuO988tJ.mjs');
210
+ const { removeSessionLinkByService } = await import('./agentCommands-B2Nl7Fof.mjs');
233
211
  removeSessionLinkByService("tunnel", name);
234
212
  console.log(`Stopped tunnel '${name}'.`);
235
213
  } catch (err) {