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.
- package/bin/skills/artifact/SKILL.md +1 -1
- package/bin/skills/crew/SKILL.md +21 -3
- package/dist/DefaultTransport-vfp78fug.mjs +47 -0
- package/dist/GeminiTransport-3OkhtFRO.mjs +130 -0
- package/dist/KimiTransport-D8n009Tr.mjs +141 -0
- package/dist/acpAgentConfig-CObOPlA8.mjs +48 -0
- package/dist/acpBackend-BZ1MJhQV.mjs +922 -0
- package/dist/{adminCommands-CRTBDZan.mjs → adminCommands-BvsYnRDA.mjs} +2 -18
- package/dist/{agentCommands-BuO988tJ.mjs → agentCommands-B2Nl7Fof.mjs} +6 -23
- package/dist/api-BHjyC0Ph.mjs +157 -0
- package/dist/{auth--WS0wezs.mjs → auth-CRz8TsEl.mjs} +1 -22
- package/dist/bootStatus-DqtNgJch.mjs +143 -0
- package/dist/claudeAuth-iAerdaMr.mjs +247 -0
- package/dist/cli.mjs +2939 -5
- package/dist/codexAppServerBackend-VGsYtbqg.mjs +786 -0
- package/dist/codexProvider-BtxYc5Rj.mjs +68 -0
- package/dist/{commands-DXM17M6n.mjs → commands-BB1Kcyt-.mjs} +13 -19
- package/dist/{commands-DU4B-4Gh.mjs → commands-BOpoVBOM.mjs} +55 -25
- package/dist/{commands-C0HQiu-S.mjs → commands-C2aODeVc.mjs} +58 -33
- package/dist/{commands-Cwxy-C5N.mjs → commands-CiRCwjkJ.mjs} +10 -32
- package/dist/{commands-DDuGBSsz.mjs → commands-D1pZq3d4.mjs} +103 -41
- package/dist/{commands-BKb1g8Gq.mjs → commands-D69mnkYu.mjs} +20 -30
- package/dist/{commands-BsKgZ5sQ.mjs → commands-DW5RnHZw.mjs} +2 -19
- package/dist/{commands-DXLOKJOj.mjs → commands-H4PsTGn8.mjs} +58 -26
- package/dist/cron-hHGdb5kU.mjs +132 -0
- package/dist/detectIsolation-CzoDCEnh.mjs +319 -0
- package/dist/envFlag-COOuJ3AH.mjs +11 -0
- package/dist/fileLock-BMPwCrB6.mjs +80 -0
- package/dist/{fleet-BHzlAvnu.mjs → fleet-DM_Q7w69.mjs} +85 -24
- package/dist/flushExit-C-i6SGjj.mjs +37 -0
- package/dist/friendlyName-1UZcyDhu.mjs +586 -0
- package/dist/{headlessCli-C2gvOpOt.mjs → headlessCli-C8HzQvis.mjs} +3 -21
- package/dist/hookSettings-DYMTUgVA.mjs +10399 -0
- package/dist/{httpServer-Be1Hcddr.mjs → httpServer-BzEDbOGn.mjs} +14 -5
- package/dist/hyphaClient-ybivOjZo.mjs +49 -0
- package/dist/index.mjs +40 -8
- package/dist/instance-CeHz5C8v.mjs +203 -0
- package/dist/kimiProvider-DbxODebR.mjs +69 -0
- package/dist/kimiSetup-NGsoYB5h.mjs +48 -0
- package/dist/loopVerify-B47sSjxe.mjs +444 -0
- package/dist/machineTools-DygM1jXW.mjs +580 -0
- package/dist/model-CUHojegn.mjs +66 -0
- package/dist/{notifyCommands-0aZUwKQK.mjs → notifyCommands-D-IKIxiq.mjs} +3 -18
- package/dist/package-DtuINqf5.mjs +64 -0
- package/dist/pinnedCodex-XW4qvOAe.mjs +11 -0
- package/dist/pinnedNono-5ZHb6328.mjs +15 -0
- package/dist/{rpc-rAQQ1q8t.mjs → rpc-BB6RF4-F.mjs} +38 -6
- package/dist/{rpc-B2Lc2BAB.mjs → rpc-Cf0grcru.mjs} +28 -20
- package/dist/{run-C7QVfyw4.mjs → run-ChdsgaSD.mjs} +17 -9
- package/dist/run-DkjwF-zA.mjs +9695 -0
- package/dist/sandboxDetect-Cdzsj5TC.mjs +19 -0
- package/dist/{scheduler-CzF4lOe_.mjs → scheduler-BY30ZrB9.mjs} +38 -6
- package/dist/securityContext-Cm5UTCuD.mjs +218 -0
- package/dist/serveAuth-DbVLRCRR.mjs +418 -0
- package/dist/{serveCommands-EIEqdaVu.mjs → serveCommands-CUHUiYnZ.mjs} +13 -34
- package/dist/sharingNotificationSync-qGIQ-3yf.mjs +359 -0
- package/dist/{sideband-BoutiRJi.mjs → sideband-68HhGT0i.mjs} +1 -21
- package/dist/store-Bn0ByYev.mjs +347 -0
- package/dist/store-fi0f-ff1.mjs +184 -0
- package/dist/types-57J3Re0n.mjs +17 -0
- package/dist/wantsHelp-6bMOeNUz.mjs +5 -0
- package/dist/wrapCommand-CdNawSaa.mjs +117 -0
- package/package.json +3 -3
- package/dist/cli-B24CmIli.mjs +0 -2780
- package/dist/package-CTbGYaJG.mjs +0 -64
- package/dist/run-CF4kAVPW.mjs +0 -26508
- 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-
|
|
2
|
-
import { w as wantsHelp } from './
|
|
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 './
|
|
8
|
-
import '
|
|
9
|
-
import '
|
|
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 '
|
|
13
|
-
import '
|
|
14
|
-
import '
|
|
15
|
-
import '
|
|
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-
|
|
4
|
-
import { w as wantsHelp } from './
|
|
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 './
|
|
10
|
-
import '
|
|
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 '
|
|
17
|
-
import '
|
|
18
|
-
import '
|
|
19
|
-
import '
|
|
20
|
-
import '
|
|
21
|
-
import '
|
|
22
|
-
import '
|
|
23
|
-
import '
|
|
24
|
-
|
|
25
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
3
|
+
import { connectAndGetMachine, resolveSessionId, createWorktree, connectAndResolveSession } from './commands-D1pZq3d4.mjs';
|
|
4
4
|
import { execFileSync } from 'node:child_process';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
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 '
|
|
9
|
-
import '
|
|
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 '
|
|
13
|
-
import '
|
|
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
|
|
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
|
|
323
|
-
if (!
|
|
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:
|
|
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
|
|
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 './
|
|
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('./
|
|
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-
|
|
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-
|
|
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('./
|
|
155
|
-
const { getFreePort } = await import('./
|
|
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('./
|
|
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-
|
|
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-
|
|
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-
|
|
210
|
+
const { removeSessionLinkByService } = await import('./agentCommands-B2Nl7Fof.mjs');
|
|
233
211
|
removeSessionLinkByService("tunnel", name);
|
|
234
212
|
console.log(`Stopped tunnel '${name}'.`);
|
|
235
213
|
} catch (err) {
|