voratiq 0.1.0-beta.22 → 0.1.0-beta.24
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/README.md +1 -1
- package/dist/agents/runtime/harness.js +10 -1
- package/dist/agents/runtime/launcher.d.ts +2 -0
- package/dist/agents/runtime/launcher.js +2 -1
- package/dist/agents/runtime/operator-access.d.ts +68 -0
- package/dist/agents/runtime/operator-access.js +95 -0
- package/dist/agents/runtime/policy.d.ts +2 -1
- package/dist/agents/runtime/policy.js +16 -42
- package/dist/agents/runtime/registry.d.ts +4 -0
- package/dist/agents/runtime/registry.js +132 -0
- package/dist/auth/providers/utils.js +1 -1
- package/dist/bin.js +2 -71
- package/dist/cli/auto.js +3 -16
- package/dist/cli/contract.d.ts +2 -32
- package/dist/cli/contract.js +0 -54
- package/dist/cli/list.js +2 -1
- package/dist/cli/message.js +16 -11
- package/dist/cli/operator-envelope.d.ts +8 -8
- package/dist/cli/operator-envelope.js +34 -24
- package/dist/cli/option-parsers.d.ts +2 -0
- package/dist/cli/option-parsers.js +7 -0
- package/dist/cli/output.d.ts +1 -5
- package/dist/cli/reduce.js +5 -13
- package/dist/cli/run.js +3 -12
- package/dist/cli/spec.js +4 -10
- package/dist/cli/verify.js +8 -18
- package/dist/commands/apply/command.js +7 -1
- package/dist/commands/auto/command.js +0 -3
- package/dist/commands/auto/validation.js +3 -1
- package/dist/commands/doctor/agents.js +3 -1
- package/dist/commands/doctor/command.js +2 -1
- package/dist/commands/doctor/environment.js +3 -1
- package/dist/commands/doctor/fix.js +3 -1
- package/dist/commands/doctor/reconcile.js +3 -1
- package/dist/commands/fetch.d.ts +0 -1
- package/dist/commands/fetch.js +1 -5
- package/dist/commands/interactive/lifecycle.js +22 -0
- package/dist/commands/list/command.js +34 -16
- package/dist/commands/list/normalization.d.ts +2 -7
- package/dist/commands/list/normalization.js +11 -16
- package/dist/commands/list/records.d.ts +9 -0
- package/dist/commands/list/records.js +6 -0
- package/dist/commands/message/command.d.ts +0 -1
- package/dist/commands/message/command.js +42 -43
- package/dist/commands/message/lifecycle.d.ts +2 -0
- package/dist/commands/message/lifecycle.js +141 -36
- package/dist/commands/reduce/command.js +115 -62
- package/dist/commands/reduce/lifecycle.d.ts +16 -0
- package/dist/commands/reduce/lifecycle.js +219 -0
- package/dist/commands/reduce/targets.js +8 -11
- package/dist/commands/run/command.js +115 -25
- package/dist/commands/run/lifecycle.d.ts +4 -1
- package/dist/commands/run/lifecycle.js +183 -84
- package/dist/commands/run/record-init.js +6 -1
- package/dist/commands/shared/resolve-stage-competitors.js +2 -1
- package/dist/commands/shared/teardown-registry.d.ts +12 -0
- package/dist/commands/shared/teardown-registry.js +35 -0
- package/dist/commands/spec/command.js +155 -225
- package/dist/commands/spec/lifecycle.d.ts +16 -0
- package/dist/commands/spec/lifecycle.js +205 -0
- package/dist/commands/verify/command.js +40 -26
- package/dist/commands/verify/lifecycle.d.ts +2 -0
- package/dist/commands/verify/lifecycle.js +167 -45
- package/dist/commands/verify/targets.js +4 -7
- package/dist/competition/shared/prompt-helpers.d.ts +7 -3
- package/dist/competition/shared/prompt-helpers.js +41 -8
- package/dist/competition/shared/sandbox-policy.d.ts +13 -3
- package/dist/competition/shared/sandbox-policy.js +215 -4
- package/dist/competition/shared/teardown.d.ts +19 -0
- package/dist/competition/shared/teardown.js +66 -4
- package/dist/configs/agents/defaults.js +13 -44
- package/dist/configs/agents/loader.js +1 -1
- package/dist/configs/environment/loader.js +2 -1
- package/dist/configs/orchestration/loader.js +2 -1
- package/dist/configs/sandbox/loader.js +2 -1
- package/dist/configs/settings/loader.js +1 -1
- package/dist/configs/verification/loader.js +2 -1
- package/dist/domain/interactive/model/types.d.ts +2 -0
- package/dist/domain/interactive/model/types.js +16 -1
- package/dist/domain/interactive/persistence/adapter.js +25 -5
- package/dist/domain/interactive/prompt.d.ts +1 -1
- package/dist/domain/interactive/prompt.js +1 -1
- package/dist/domain/interactive/session-env.d.ts +10 -0
- package/dist/domain/interactive/session-env.js +25 -0
- package/dist/domain/message/competition/adapter.js +14 -10
- package/dist/domain/message/competition/prompt.js +3 -2
- package/dist/domain/message/model/mutators.js +11 -6
- package/dist/domain/message/model/types.d.ts +0 -1
- package/dist/domain/message/model/types.js +0 -1
- package/dist/domain/reduce/competition/adapter.d.ts +2 -0
- package/dist/domain/reduce/competition/adapter.js +25 -17
- package/dist/domain/reduce/competition/prompt.d.ts +1 -1
- package/dist/domain/reduce/competition/prompt.js +4 -3
- package/dist/domain/run/competition/agent-preparation.js +18 -10
- package/dist/domain/run/competition/agents/artifacts.js +27 -5
- package/dist/domain/run/competition/agents/lifecycle.js +13 -3
- package/dist/domain/run/competition/agents/preparation.js +2 -0
- package/dist/domain/run/competition/agents/types.d.ts +1 -0
- package/dist/domain/run/competition/agents/workspace.js +2 -1
- package/dist/domain/run/competition/prompt.d.ts +1 -0
- package/dist/domain/run/competition/prompt.js +4 -3
- package/dist/domain/run/competition/reports.js +2 -1
- package/dist/domain/run/model/enhanced.d.ts +1 -2
- package/dist/domain/run/model/enhanced.js +2 -4
- package/dist/domain/run/model/mutators.js +11 -9
- package/dist/domain/run/model/types.d.ts +8 -10
- package/dist/domain/run/model/types.js +5 -4
- package/dist/domain/run/persistence/adapter.d.ts +0 -1
- package/dist/domain/run/persistence/adapter.js +2 -2
- package/dist/domain/spec/competition/adapter.d.ts +2 -0
- package/dist/domain/spec/competition/adapter.js +23 -20
- package/dist/domain/spec/competition/prompt.js +3 -2
- package/dist/domain/spec/model/mutators.d.ts +20 -0
- package/dist/domain/spec/model/mutators.js +151 -0
- package/dist/domain/spec/persistence/adapter.d.ts +1 -0
- package/dist/domain/spec/persistence/adapter.js +7 -2
- package/dist/domain/verify/competition/adapter.d.ts +1 -1
- package/dist/domain/verify/competition/adapter.js +24 -25
- package/dist/domain/verify/competition/blinding.d.ts +4 -0
- package/dist/domain/verify/competition/blinding.js +7 -0
- package/dist/domain/verify/competition/programmatic.js +2 -1
- package/dist/domain/verify/competition/prompt.js +22 -3
- package/dist/domain/verify/competition/shared-layout.js +1 -1
- package/dist/interactive/providers/launch.d.ts +2 -0
- package/dist/interactive/providers/launch.js +19 -2
- package/dist/interactive/substrate.js +12 -2
- package/dist/mcp/server.d.ts +3 -2
- package/dist/mcp/server.js +311 -70
- package/dist/policy/auto.d.ts +0 -1
- package/dist/policy/auto.js +3 -14
- package/dist/preflight/index.js +2 -1
- package/dist/render/transcripts/apply.js +2 -1
- package/dist/render/transcripts/message.d.ts +1 -4
- package/dist/render/transcripts/message.js +10 -54
- package/dist/render/transcripts/reduce.d.ts +1 -4
- package/dist/render/transcripts/reduce.js +10 -54
- package/dist/render/transcripts/run.d.ts +4 -6
- package/dist/render/transcripts/run.js +8 -45
- package/dist/render/transcripts/spec.d.ts +1 -4
- package/dist/render/transcripts/spec.js +10 -54
- package/dist/render/transcripts/stage-progress.d.ts +1 -1
- package/dist/render/transcripts/verify.d.ts +1 -4
- package/dist/render/transcripts/verify.js +10 -54
- package/dist/render/utils/cli-writer.d.ts +4 -0
- package/dist/render/utils/progressive-render.d.ts +3 -0
- package/dist/render/utils/progressive-render.js +44 -0
- package/dist/render/utils/transcript-shell.js +3 -3
- package/dist/status/colors.js +0 -1
- package/dist/status/index.d.ts +1 -2
- package/dist/status/index.js +0 -1
- package/dist/utils/diff.d.ts +2 -0
- package/dist/utils/diff.js +1 -0
- package/dist/utils/git.d.ts +6 -0
- package/dist/utils/git.js +15 -0
- package/dist/utils/slug.d.ts +0 -1
- package/dist/utils/slug.js +0 -4
- package/dist/utils/swarm-session-ack.d.ts +9 -0
- package/dist/utils/swarm-session-ack.js +17 -0
- package/dist/workspace/agents.js +1 -0
- package/dist/workspace/artifact-paths.d.ts +55 -0
- package/dist/workspace/artifact-paths.js +106 -0
- package/dist/workspace/chat/artifacts.js +1 -1
- package/dist/workspace/chat/native-usage.js +1 -1
- package/dist/workspace/chat/sources.d.ts +2 -5
- package/dist/workspace/chat/sources.js +4 -4
- package/dist/workspace/cleanup.d.ts +8 -0
- package/dist/workspace/cleanup.js +28 -0
- package/dist/workspace/constants.d.ts +47 -0
- package/dist/workspace/constants.js +47 -0
- package/dist/workspace/dependencies.d.ts +11 -0
- package/dist/workspace/dependencies.js +150 -13
- package/dist/workspace/layout.js +3 -1
- package/dist/workspace/managed-state.js +2 -1
- package/dist/workspace/path-formatters.d.ts +9 -0
- package/dist/workspace/path-formatters.js +46 -0
- package/dist/workspace/path-resolvers.d.ts +1 -0
- package/dist/workspace/path-resolvers.js +5 -0
- package/dist/workspace/session-paths.d.ts +16 -0
- package/dist/workspace/session-paths.js +59 -0
- package/dist/workspace/setup.js +2 -1
- package/package.json +2 -1
- package/dist/cli/prune.d.ts +0 -18
- package/dist/cli/prune.js +0 -99
- package/dist/commands/prune/command.d.ts +0 -3
- package/dist/commands/prune/command.js +0 -388
- package/dist/commands/prune/errors.d.ts +0 -17
- package/dist/commands/prune/errors.js +0 -33
- package/dist/commands/prune/types.d.ts +0 -63
- package/dist/competition/shared/prune.d.ts +0 -1
- package/dist/competition/shared/prune.js +0 -4
- package/dist/render/transcripts/prune.d.ts +0 -21
- package/dist/render/transcripts/prune.js +0 -97
- package/dist/workspace/prune.d.ts +0 -8
- package/dist/workspace/prune.js +0 -29
- package/dist/workspace/structure.d.ts +0 -144
- package/dist/workspace/structure.js +0 -320
- /package/dist/{commands/prune/types.js → render/utils/cli-writer.js} +0 -0
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ npm install -g voratiq
|
|
|
15
15
|
|
|
16
16
|
- Node 20+
|
|
17
17
|
- git
|
|
18
|
-
- 1+ AI coding agent (Claude [>=2.1.
|
|
18
|
+
- 1+ AI coding agent (Claude [>=2.1.111](https://github.com/anthropics/claude-code?tab=readme-ov-file#get-started), Codex [>=0.122.0](https://github.com/openai/codex?tab=readme-ov-file#quickstart), or Gemini [>=0.31.0](https://github.com/google-gemini/gemini-cli?tab=readme-ov-file#quick-install))
|
|
19
19
|
- macOS: `ripgrep`
|
|
20
20
|
- Linux (Debian/Ubuntu): `bubblewrap`, `socat`, `ripgrep`
|
|
21
21
|
|
|
@@ -8,7 +8,7 @@ import { captureAgentChatArtifacts } from "./chat.js";
|
|
|
8
8
|
import { AgentRuntimeError, AgentRuntimeProcessError, AgentRuntimeSandboxError, } from "./errors.js";
|
|
9
9
|
import { configureSandboxSettings, runAgentProcess } from "./launcher.js";
|
|
10
10
|
import { writeAgentManifest } from "./manifest.js";
|
|
11
|
-
import { registerStagedAuthContext, teardownRegisteredAuthContext, } from "./registry.js";
|
|
11
|
+
import { registerSessionProcess, registerStagedAuthContext, teardownRegisteredAuthContext, unregisterSessionProcess, } from "./registry.js";
|
|
12
12
|
import { DEFAULT_DENIAL_BACKOFF } from "./sandbox.js";
|
|
13
13
|
export async function runSandboxedAgent(input) {
|
|
14
14
|
const { root, agent, prompt, environment, paths, sandboxStageId = "run", sessionId, sandboxProviderId, sandboxPolicyOverrides, extraWriteProtectedPaths, extraReadProtectedPaths, captureChat = true, teardownAuthOnExit = true, onWatchdogTrigger, } = input;
|
|
@@ -25,6 +25,7 @@ export async function runSandboxedAgent(input) {
|
|
|
25
25
|
prompt,
|
|
26
26
|
});
|
|
27
27
|
let authContext;
|
|
28
|
+
let spawnedProcess;
|
|
28
29
|
try {
|
|
29
30
|
const staged = await stageAgentAuth({
|
|
30
31
|
agent,
|
|
@@ -71,6 +72,10 @@ export async function runSandboxedAgent(input) {
|
|
|
71
72
|
providerId,
|
|
72
73
|
denialBackoff,
|
|
73
74
|
onWatchdogTrigger,
|
|
75
|
+
onSpawnedProcess: (child) => {
|
|
76
|
+
spawnedProcess = child;
|
|
77
|
+
registerSessionProcess(sessionId, child);
|
|
78
|
+
},
|
|
74
79
|
});
|
|
75
80
|
const chat = captureChat
|
|
76
81
|
? await captureAgentChatArtifacts({
|
|
@@ -96,6 +101,10 @@ export async function runSandboxedAgent(input) {
|
|
|
96
101
|
throw new AgentRuntimeProcessError(error instanceof Error ? error.message : toErrorMessage(error));
|
|
97
102
|
}
|
|
98
103
|
finally {
|
|
104
|
+
if (spawnedProcess &&
|
|
105
|
+
(spawnedProcess.exitCode !== null || spawnedProcess.signalCode !== null)) {
|
|
106
|
+
unregisterSessionProcess(sessionId, spawnedProcess);
|
|
107
|
+
}
|
|
99
108
|
await rm(promptPath, { force: true }).catch(() => { });
|
|
100
109
|
if (teardownAuthOnExit || !sessionId) {
|
|
101
110
|
await teardownRegisteredAuthContext(sessionId ?? "runtime", authContext).catch(() => { });
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ChildProcess } from "node:child_process";
|
|
1
2
|
import type { DenialBackoffConfig } from "../../configs/sandbox/types.js";
|
|
2
3
|
import type { WatchdogMetadata } from "../../domain/run/model/types.js";
|
|
3
4
|
import type { SandboxStageId } from "./policy.js";
|
|
@@ -16,6 +17,7 @@ export interface AgentProcessOptions {
|
|
|
16
17
|
providerId?: string;
|
|
17
18
|
/** Callback fired immediately when watchdog triggers, before process exits. */
|
|
18
19
|
onWatchdogTrigger?: (trigger: WatchdogTrigger, reason: string, failFast?: SandboxFailFastInfo) => void;
|
|
20
|
+
onSpawnedProcess?: (child: ChildProcess) => void;
|
|
19
21
|
}
|
|
20
22
|
export interface AgentProcessResult {
|
|
21
23
|
exitCode: number;
|
|
@@ -50,7 +50,7 @@ async function defaultResolveRunInvocation(context) {
|
|
|
50
50
|
return { command, args };
|
|
51
51
|
}
|
|
52
52
|
export async function runAgentProcess(options) {
|
|
53
|
-
const { runtimeManifestPath, agentRoot, stdoutPath, stderrPath, sandboxSettingsPath, denialBackoff, resolveRunInvocation, providerId = "", onWatchdogTrigger, } = options;
|
|
53
|
+
const { runtimeManifestPath, agentRoot, stdoutPath, stderrPath, sandboxSettingsPath, denialBackoff, resolveRunInvocation, providerId = "", onWatchdogTrigger, onSpawnedProcess, } = options;
|
|
54
54
|
const stdoutStream = createWriteStream(stdoutPath, { flags: "w" });
|
|
55
55
|
const stderrStream = createWriteStream(stderrPath, { flags: "w" });
|
|
56
56
|
const shimEntryPath = resolveShimEntryPath();
|
|
@@ -87,6 +87,7 @@ export async function runAgentProcess(options) {
|
|
|
87
87
|
stderr: { writable: stderrStream },
|
|
88
88
|
detached: true,
|
|
89
89
|
onSpawn: (child) => {
|
|
90
|
+
onSpawnedProcess?.(child);
|
|
90
91
|
watchdogController = createWatchdog(child, stderrStream, {
|
|
91
92
|
providerId,
|
|
92
93
|
onWatchdogTrigger,
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export declare const SANDBOX_STAGE_IDS: readonly ["spec", "run", "reduce", "verify", "message"];
|
|
2
|
+
export type SandboxStageId = (typeof SANDBOX_STAGE_IDS)[number];
|
|
3
|
+
export type SandboxGitAccessLevel = "deny-read" | "deny-read-write";
|
|
4
|
+
export type SandboxReadRoot = "repo-root" | "workspace-root";
|
|
5
|
+
export type SandboxWriteRoot = "workspace-root";
|
|
6
|
+
export type OperatorAccessProtectedOperatorDirKey = "spec-dir" | "run-dir" | "reduce-dir" | "verify-dir" | "message-dir";
|
|
7
|
+
export type OperatorAccessProtectedMetadataPathKey = "run-index" | "run-history-lock";
|
|
8
|
+
export type ReadonlyWorkspaceMountKey = "context" | "inputs" | "reference_repo";
|
|
9
|
+
export interface OperatorAccessProfile {
|
|
10
|
+
readonly readRoot: SandboxReadRoot;
|
|
11
|
+
readonly writeRoot: SandboxWriteRoot;
|
|
12
|
+
readonly gitAccess: SandboxGitAccessLevel;
|
|
13
|
+
readonly protectedOperatorDirs: readonly OperatorAccessProtectedOperatorDirKey[];
|
|
14
|
+
readonly protectedMetadataPaths: readonly OperatorAccessProtectedMetadataPathKey[];
|
|
15
|
+
readonly restrictRepositoryReads: boolean;
|
|
16
|
+
readonly readonlyWorkspaceMounts: readonly ReadonlyWorkspaceMountKey[];
|
|
17
|
+
}
|
|
18
|
+
export declare const OPERATOR_ACCESS_PROFILES: {
|
|
19
|
+
readonly spec: {
|
|
20
|
+
readonly readRoot: "repo-root";
|
|
21
|
+
readonly writeRoot: "workspace-root";
|
|
22
|
+
readonly gitAccess: "deny-read";
|
|
23
|
+
readonly protectedOperatorDirs: readonly ["run-dir", "reduce-dir", "verify-dir", "message-dir"];
|
|
24
|
+
readonly protectedMetadataPaths: readonly [];
|
|
25
|
+
readonly restrictRepositoryReads: false;
|
|
26
|
+
readonly readonlyWorkspaceMounts: readonly [];
|
|
27
|
+
};
|
|
28
|
+
readonly run: {
|
|
29
|
+
readonly readRoot: "workspace-root";
|
|
30
|
+
readonly writeRoot: "workspace-root";
|
|
31
|
+
readonly gitAccess: "deny-read-write";
|
|
32
|
+
readonly protectedOperatorDirs: readonly ["spec-dir", "reduce-dir", "verify-dir", "message-dir"];
|
|
33
|
+
readonly protectedMetadataPaths: readonly ["run-index", "run-history-lock"];
|
|
34
|
+
readonly restrictRepositoryReads: true;
|
|
35
|
+
readonly readonlyWorkspaceMounts: readonly [];
|
|
36
|
+
};
|
|
37
|
+
readonly reduce: {
|
|
38
|
+
readonly readRoot: "workspace-root";
|
|
39
|
+
readonly writeRoot: "workspace-root";
|
|
40
|
+
readonly gitAccess: "deny-read";
|
|
41
|
+
readonly protectedOperatorDirs: readonly ["spec-dir", "run-dir", "verify-dir", "message-dir"];
|
|
42
|
+
readonly protectedMetadataPaths: readonly [];
|
|
43
|
+
readonly restrictRepositoryReads: true;
|
|
44
|
+
readonly readonlyWorkspaceMounts: readonly [];
|
|
45
|
+
};
|
|
46
|
+
readonly verify: {
|
|
47
|
+
readonly readRoot: "workspace-root";
|
|
48
|
+
readonly writeRoot: "workspace-root";
|
|
49
|
+
readonly gitAccess: "deny-read";
|
|
50
|
+
readonly protectedOperatorDirs: readonly ["spec-dir", "run-dir", "reduce-dir", "message-dir"];
|
|
51
|
+
readonly protectedMetadataPaths: readonly [];
|
|
52
|
+
readonly restrictRepositoryReads: true;
|
|
53
|
+
readonly readonlyWorkspaceMounts: readonly ["context", "inputs", "reference_repo"];
|
|
54
|
+
};
|
|
55
|
+
readonly message: {
|
|
56
|
+
readonly readRoot: "repo-root";
|
|
57
|
+
readonly writeRoot: "workspace-root";
|
|
58
|
+
readonly gitAccess: "deny-read";
|
|
59
|
+
readonly protectedOperatorDirs: readonly ["spec-dir", "run-dir", "reduce-dir", "verify-dir"];
|
|
60
|
+
readonly protectedMetadataPaths: readonly [];
|
|
61
|
+
readonly restrictRepositoryReads: false;
|
|
62
|
+
readonly readonlyWorkspaceMounts: readonly [];
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
export declare function getOperatorAccessProfile(stageId: SandboxStageId): OperatorAccessProfile;
|
|
66
|
+
export declare function resolveProtectedOperatorDir(root: string, key: OperatorAccessProtectedOperatorDirKey): string;
|
|
67
|
+
export declare function resolveProtectedMetadataPath(root: string, key: OperatorAccessProtectedMetadataPathKey): string;
|
|
68
|
+
export declare function resolveRepositoryGitPath(root: string): string;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { resolve as resolveAbsolute } from "node:path";
|
|
2
|
+
import { VORATIQ_HISTORY_LOCK_FILENAME, VORATIQ_MESSAGE_DIR, VORATIQ_REDUCTION_DIR, VORATIQ_RUN_DIR, VORATIQ_RUN_FILE, VORATIQ_SPEC_DIR, VORATIQ_VERIFICATION_DIR, } from "../../workspace/constants.js";
|
|
3
|
+
import { resolveWorkspacePath } from "../../workspace/path-resolvers.js";
|
|
4
|
+
export const SANDBOX_STAGE_IDS = [
|
|
5
|
+
"spec",
|
|
6
|
+
"run",
|
|
7
|
+
"reduce",
|
|
8
|
+
"verify",
|
|
9
|
+
"message",
|
|
10
|
+
];
|
|
11
|
+
export const OPERATOR_ACCESS_PROFILES = {
|
|
12
|
+
spec: {
|
|
13
|
+
readRoot: "repo-root",
|
|
14
|
+
writeRoot: "workspace-root",
|
|
15
|
+
gitAccess: "deny-read",
|
|
16
|
+
protectedOperatorDirs: [
|
|
17
|
+
"run-dir",
|
|
18
|
+
"reduce-dir",
|
|
19
|
+
"verify-dir",
|
|
20
|
+
"message-dir",
|
|
21
|
+
],
|
|
22
|
+
protectedMetadataPaths: [],
|
|
23
|
+
restrictRepositoryReads: false,
|
|
24
|
+
readonlyWorkspaceMounts: [],
|
|
25
|
+
},
|
|
26
|
+
run: {
|
|
27
|
+
readRoot: "workspace-root",
|
|
28
|
+
writeRoot: "workspace-root",
|
|
29
|
+
gitAccess: "deny-read-write",
|
|
30
|
+
protectedOperatorDirs: [
|
|
31
|
+
"spec-dir",
|
|
32
|
+
"reduce-dir",
|
|
33
|
+
"verify-dir",
|
|
34
|
+
"message-dir",
|
|
35
|
+
],
|
|
36
|
+
protectedMetadataPaths: ["run-index", "run-history-lock"],
|
|
37
|
+
restrictRepositoryReads: true,
|
|
38
|
+
readonlyWorkspaceMounts: [],
|
|
39
|
+
},
|
|
40
|
+
reduce: {
|
|
41
|
+
readRoot: "workspace-root",
|
|
42
|
+
writeRoot: "workspace-root",
|
|
43
|
+
gitAccess: "deny-read",
|
|
44
|
+
protectedOperatorDirs: ["spec-dir", "run-dir", "verify-dir", "message-dir"],
|
|
45
|
+
protectedMetadataPaths: [],
|
|
46
|
+
restrictRepositoryReads: true,
|
|
47
|
+
readonlyWorkspaceMounts: [],
|
|
48
|
+
},
|
|
49
|
+
verify: {
|
|
50
|
+
readRoot: "workspace-root",
|
|
51
|
+
writeRoot: "workspace-root",
|
|
52
|
+
gitAccess: "deny-read",
|
|
53
|
+
protectedOperatorDirs: ["spec-dir", "run-dir", "reduce-dir", "message-dir"],
|
|
54
|
+
protectedMetadataPaths: [],
|
|
55
|
+
restrictRepositoryReads: true,
|
|
56
|
+
readonlyWorkspaceMounts: ["context", "inputs", "reference_repo"],
|
|
57
|
+
},
|
|
58
|
+
message: {
|
|
59
|
+
readRoot: "repo-root",
|
|
60
|
+
writeRoot: "workspace-root",
|
|
61
|
+
gitAccess: "deny-read",
|
|
62
|
+
protectedOperatorDirs: ["spec-dir", "run-dir", "reduce-dir", "verify-dir"],
|
|
63
|
+
protectedMetadataPaths: [],
|
|
64
|
+
restrictRepositoryReads: false,
|
|
65
|
+
readonlyWorkspaceMounts: [],
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
export function getOperatorAccessProfile(stageId) {
|
|
69
|
+
return OPERATOR_ACCESS_PROFILES[stageId];
|
|
70
|
+
}
|
|
71
|
+
export function resolveProtectedOperatorDir(root, key) {
|
|
72
|
+
switch (key) {
|
|
73
|
+
case "spec-dir":
|
|
74
|
+
return resolveWorkspacePath(root, VORATIQ_SPEC_DIR);
|
|
75
|
+
case "run-dir":
|
|
76
|
+
return resolveWorkspacePath(root, VORATIQ_RUN_DIR);
|
|
77
|
+
case "reduce-dir":
|
|
78
|
+
return resolveWorkspacePath(root, VORATIQ_REDUCTION_DIR);
|
|
79
|
+
case "verify-dir":
|
|
80
|
+
return resolveWorkspacePath(root, VORATIQ_VERIFICATION_DIR);
|
|
81
|
+
case "message-dir":
|
|
82
|
+
return resolveWorkspacePath(root, VORATIQ_MESSAGE_DIR);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export function resolveProtectedMetadataPath(root, key) {
|
|
86
|
+
switch (key) {
|
|
87
|
+
case "run-index":
|
|
88
|
+
return resolveWorkspacePath(root, VORATIQ_RUN_FILE);
|
|
89
|
+
case "run-history-lock":
|
|
90
|
+
return resolveWorkspacePath(root, VORATIQ_RUN_DIR, VORATIQ_HISTORY_LOCK_FILENAME);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export function resolveRepositoryGitPath(root) {
|
|
94
|
+
return resolveAbsolute(root, ".git");
|
|
95
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SandboxFilesystemConfig, SandboxNetworkConfig } from "../../configs/sandbox/types.js";
|
|
2
|
+
import { type SandboxStageId } from "./operator-access.js";
|
|
2
3
|
import type { SandboxPolicyOverrides } from "./types.js";
|
|
3
|
-
export type SandboxStageId
|
|
4
|
+
export type { SandboxStageId } from "./operator-access.js";
|
|
4
5
|
export interface BuildSandboxPolicyInput {
|
|
5
6
|
stageId: SandboxStageId;
|
|
6
7
|
root: string;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { isAbsolute, relative, resolve as resolveAbsolute } from "node:path";
|
|
2
|
-
import {
|
|
2
|
+
import { VORATIQ_AGENTS_FILE, VORATIQ_ENVIRONMENT_FILE, VORATIQ_ORCHESTRATION_FILE, VORATIQ_SANDBOX_FILE, } from "../../workspace/constants.js";
|
|
3
|
+
import { resolveWorkspacePath } from "../../workspace/path-resolvers.js";
|
|
4
|
+
import { getOperatorAccessProfile, resolveProtectedMetadataPath, resolveProtectedOperatorDir, resolveRepositoryGitPath, } from "./operator-access.js";
|
|
3
5
|
export function buildSandboxPolicy(input) {
|
|
4
6
|
const { stageId, root, workspacePath, sandboxHomePath, sandboxSettingsPath, runtimePath, artifactsPath, repoRootPath, providerFilesystem, providerNetwork, policyOverrides, stageDenyWritePaths = [], stageDenyReadPaths = [], } = input;
|
|
5
7
|
const baseline = buildBaselineFilesystemPolicy({
|
|
@@ -115,55 +117,27 @@ function buildBaselineFilesystemPolicy(options) {
|
|
|
115
117
|
resolveWorkspacePath(root, VORATIQ_ORCHESTRATION_FILE),
|
|
116
118
|
resolveWorkspacePath(root, VORATIQ_SANDBOX_FILE),
|
|
117
119
|
];
|
|
118
|
-
const
|
|
120
|
+
const stagePaths = resolveStageProtectedPaths(stageId, root);
|
|
119
121
|
// Default deny rules stay symmetric; read-only divergences are explicit.
|
|
120
|
-
const symmetricDeny = [...commonSensitivePaths, ...
|
|
122
|
+
const symmetricDeny = [...commonSensitivePaths, ...stagePaths.symmetric];
|
|
121
123
|
return {
|
|
122
124
|
allowWrite: [],
|
|
123
|
-
denyRead: [...symmetricDeny, ...
|
|
125
|
+
denyRead: [...symmetricDeny, ...stagePaths.readOnly],
|
|
124
126
|
denyWrite: [...symmetricDeny],
|
|
125
127
|
};
|
|
126
128
|
}
|
|
127
|
-
function
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
],
|
|
136
|
-
readOnly: [],
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
if (stageId === "spec") {
|
|
140
|
-
return {
|
|
141
|
-
symmetric: [
|
|
142
|
-
resolveWorkspacePath(root, VORATIQ_RUN_DIR),
|
|
143
|
-
resolveWorkspacePath(root, VORATIQ_VERIFICATION_DIR),
|
|
144
|
-
resolveWorkspacePath(root, VORATIQ_REDUCTION_DIR),
|
|
145
|
-
],
|
|
146
|
-
readOnly: [],
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
if (stageId === "verify") {
|
|
150
|
-
return {
|
|
151
|
-
symmetric: [
|
|
152
|
-
resolveWorkspacePath(root, VORATIQ_RUN_DIR),
|
|
153
|
-
resolveWorkspacePath(root, VORATIQ_SPEC_DIR),
|
|
154
|
-
resolveWorkspacePath(root, VORATIQ_REDUCTION_DIR),
|
|
155
|
-
],
|
|
156
|
-
// Verification agents should never inspect repository metadata during
|
|
157
|
-
// blinded review.
|
|
158
|
-
readOnly: [resolveAbsolute(root, ".git")],
|
|
159
|
-
};
|
|
129
|
+
function resolveStageProtectedPaths(stageId, root) {
|
|
130
|
+
const profile = getOperatorAccessProfile(stageId);
|
|
131
|
+
const symmetric = [
|
|
132
|
+
...profile.protectedOperatorDirs.map((key) => resolveProtectedOperatorDir(root, key)),
|
|
133
|
+
...profile.protectedMetadataPaths.map((key) => resolveProtectedMetadataPath(root, key)),
|
|
134
|
+
];
|
|
135
|
+
if (profile.gitAccess === "deny-read-write") {
|
|
136
|
+
symmetric.unshift(resolveRepositoryGitPath(root));
|
|
160
137
|
}
|
|
161
138
|
return {
|
|
162
|
-
symmetric
|
|
163
|
-
|
|
164
|
-
resolveWorkspacePath(root, VORATIQ_SPEC_DIR),
|
|
165
|
-
],
|
|
166
|
-
readOnly: [resolveAbsolute(root, ".git")],
|
|
139
|
+
symmetric,
|
|
140
|
+
readOnly: profile.gitAccess === "deny-read" ? [resolveRepositoryGitPath(root)] : [],
|
|
167
141
|
};
|
|
168
142
|
}
|
|
169
143
|
function resolveFilesystemOverrides(overrides, workspacePath) {
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import type { ChildProcess } from "node:child_process";
|
|
1
2
|
import type { StagedAuthContext } from "./auth.js";
|
|
2
3
|
export declare function registerStagedAuthContext(sessionId: string, context: StagedAuthContext): void;
|
|
3
4
|
export declare function teardownRegisteredAuthContext(sessionId: string, context: StagedAuthContext | undefined): Promise<void>;
|
|
4
5
|
export declare function teardownSessionAuth(sessionId: string | undefined): Promise<void>;
|
|
6
|
+
export declare function registerSessionProcess(sessionId: string | undefined, child: ChildProcess | undefined): void;
|
|
7
|
+
export declare function unregisterSessionProcess(sessionId: string | undefined, child: ChildProcess | undefined): void;
|
|
8
|
+
export declare function terminateSessionProcesses(sessionId: string | undefined): Promise<void>;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { teardownAuthContext } from "./auth.js";
|
|
2
2
|
const registry = new Map();
|
|
3
|
+
const processRegistry = new Map();
|
|
4
|
+
const PROCESS_EXIT_WAIT_MS = 2_000;
|
|
3
5
|
export function registerStagedAuthContext(sessionId, context) {
|
|
4
6
|
const existing = registry.get(sessionId);
|
|
5
7
|
if (existing) {
|
|
@@ -42,6 +44,48 @@ export async function teardownSessionAuth(sessionId) {
|
|
|
42
44
|
throw new AggregateError(failures, `Failed to teardown ${failures.length} auth contexts for session ${sessionId}`);
|
|
43
45
|
}
|
|
44
46
|
}
|
|
47
|
+
export function registerSessionProcess(sessionId, child) {
|
|
48
|
+
if (!sessionId || !child || child.pid === undefined) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const existing = processRegistry.get(sessionId);
|
|
52
|
+
if (existing) {
|
|
53
|
+
existing.add(child);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
processRegistry.set(sessionId, new Set([child]));
|
|
57
|
+
}
|
|
58
|
+
export function unregisterSessionProcess(sessionId, child) {
|
|
59
|
+
if (!sessionId || !child) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
removeProcess(sessionId, child);
|
|
63
|
+
}
|
|
64
|
+
export async function terminateSessionProcesses(sessionId) {
|
|
65
|
+
if (!sessionId) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const children = processRegistry.get(sessionId);
|
|
69
|
+
if (!children || children.size === 0) {
|
|
70
|
+
processRegistry.delete(sessionId);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const failures = [];
|
|
74
|
+
await Promise.all([...children].map(async (child) => {
|
|
75
|
+
try {
|
|
76
|
+
await terminateRegisteredProcess(sessionId, child);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
failures.push(error instanceof Error ? error : new Error(String(error)));
|
|
80
|
+
}
|
|
81
|
+
}));
|
|
82
|
+
if (failures.length === 1) {
|
|
83
|
+
throw failures[0];
|
|
84
|
+
}
|
|
85
|
+
if (failures.length > 1) {
|
|
86
|
+
throw new AggregateError(failures, `Failed to terminate ${failures.length} session processes for ${sessionId}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
45
89
|
function removeContext(sessionId, context) {
|
|
46
90
|
const contexts = registry.get(sessionId);
|
|
47
91
|
if (!contexts) {
|
|
@@ -52,3 +96,91 @@ function removeContext(sessionId, context) {
|
|
|
52
96
|
registry.delete(sessionId);
|
|
53
97
|
}
|
|
54
98
|
}
|
|
99
|
+
function removeProcess(sessionId, child) {
|
|
100
|
+
const children = processRegistry.get(sessionId);
|
|
101
|
+
if (!children) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
children.delete(child);
|
|
105
|
+
if (children.size === 0) {
|
|
106
|
+
processRegistry.delete(sessionId);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async function terminateRegisteredProcess(sessionId, child) {
|
|
110
|
+
if (hasExited(child) || child.pid === undefined) {
|
|
111
|
+
removeProcess(sessionId, child);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (tryTerminateProcessGroup(child.pid, "SIGTERM")) {
|
|
115
|
+
const exitedOnTerm = await waitForProcessExit(child, PROCESS_EXIT_WAIT_MS);
|
|
116
|
+
if (exitedOnTerm) {
|
|
117
|
+
removeProcess(sessionId, child);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
removeProcess(sessionId, child);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (tryTerminateProcessGroup(child.pid, "SIGKILL")) {
|
|
126
|
+
const exitedOnKill = await waitForProcessExit(child, PROCESS_EXIT_WAIT_MS);
|
|
127
|
+
if (exitedOnKill) {
|
|
128
|
+
removeProcess(sessionId, child);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
removeProcess(sessionId, child);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
throw new Error(`Detached agent process ${child.pid} did not exit after SIGTERM and SIGKILL.`);
|
|
137
|
+
}
|
|
138
|
+
function hasExited(child) {
|
|
139
|
+
return child.exitCode !== null || child.signalCode !== null;
|
|
140
|
+
}
|
|
141
|
+
function tryTerminateProcessGroup(pid, signal) {
|
|
142
|
+
try {
|
|
143
|
+
process.kill(-pid, signal);
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
try {
|
|
148
|
+
process.kill(pid, signal);
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
async function waitForProcessExit(child, timeoutMs) {
|
|
157
|
+
if (hasExited(child)) {
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
if (typeof child.once !== "function") {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
return await new Promise((resolve) => {
|
|
164
|
+
let settled = false;
|
|
165
|
+
const finish = (exited) => {
|
|
166
|
+
if (settled) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
settled = true;
|
|
170
|
+
if (typeof child.removeListener === "function") {
|
|
171
|
+
child.removeListener("exit", handleExit);
|
|
172
|
+
child.removeListener("close", handleExit);
|
|
173
|
+
}
|
|
174
|
+
clearTimeout(timer);
|
|
175
|
+
resolve(exited);
|
|
176
|
+
};
|
|
177
|
+
const handleExit = () => {
|
|
178
|
+
finish(true);
|
|
179
|
+
};
|
|
180
|
+
const timer = setTimeout(() => {
|
|
181
|
+
finish(hasExited(child));
|
|
182
|
+
}, timeoutMs);
|
|
183
|
+
child.once("exit", handleExit);
|
|
184
|
+
child.once("close", handleExit);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
@@ -2,7 +2,7 @@ import { constants as fsConstants } from "node:fs";
|
|
|
2
2
|
import { access, chmod, copyFile, mkdir, rm, stat, writeFile, } from "node:fs/promises";
|
|
3
3
|
import { isAbsolute, resolve as resolveNative } from "node:path";
|
|
4
4
|
import { isMissing } from "../../utils/fs.js";
|
|
5
|
-
import { SANDBOX_DIRNAME } from "../../workspace/
|
|
5
|
+
import { SANDBOX_DIRNAME } from "../../workspace/constants.js";
|
|
6
6
|
const STAGED_FILE_MODE = 0o600;
|
|
7
7
|
export function resolveProviderHome(runtime, envVar, defaultSubdir) {
|
|
8
8
|
const configured = runtime.env[envVar]?.trim();
|
package/dist/bin.js
CHANGED
|
@@ -108,73 +108,9 @@ async function flushPendingHistory() {
|
|
|
108
108
|
console.warn(`[voratiq] Failed to flush interactive history buffers: ${error.message}`);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
-
async function terminateActiveRunSafe(status, context) {
|
|
112
|
-
try {
|
|
113
|
-
const { terminateActiveRun } = await import("./commands/run/lifecycle.js");
|
|
114
|
-
await terminateActiveRun(status);
|
|
115
|
-
return null;
|
|
116
|
-
}
|
|
117
|
-
catch (error) {
|
|
118
|
-
const { toErrorMessage } = await import("./utils/errors.js");
|
|
119
|
-
const normalizedError = error instanceof Error ? error : new Error(toErrorMessage(error));
|
|
120
|
-
console.error(`[voratiq] Failed to teardown run after ${context}: ${toErrorMessage(error)}`);
|
|
121
|
-
return normalizedError;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
async function terminateActiveVerificationSafe(status, context) {
|
|
125
|
-
try {
|
|
126
|
-
const { terminateActiveVerification } = await import("./commands/verify/lifecycle.js");
|
|
127
|
-
await terminateActiveVerification(status);
|
|
128
|
-
return null;
|
|
129
|
-
}
|
|
130
|
-
catch (error) {
|
|
131
|
-
const { toErrorMessage } = await import("./utils/errors.js");
|
|
132
|
-
const normalizedError = error instanceof Error ? error : new Error(toErrorMessage(error));
|
|
133
|
-
console.error(`[voratiq] Failed to teardown verification after ${context}: ${toErrorMessage(error)}`);
|
|
134
|
-
return normalizedError;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
async function terminateActiveInteractiveSafe(status, context) {
|
|
138
|
-
try {
|
|
139
|
-
const { terminateActiveInteractive } = await import("./commands/interactive/lifecycle.js");
|
|
140
|
-
await terminateActiveInteractive(status, context);
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
catch (error) {
|
|
144
|
-
const { toErrorMessage } = await import("./utils/errors.js");
|
|
145
|
-
const normalizedError = error instanceof Error ? error : new Error(toErrorMessage(error));
|
|
146
|
-
console.error(`[voratiq] Failed to teardown interactive session after ${context}: ${toErrorMessage(error)}`);
|
|
147
|
-
return normalizedError;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
async function terminateActiveMessageSafe(status, context) {
|
|
151
|
-
try {
|
|
152
|
-
const { terminateActiveMessage } = await import("./commands/message/lifecycle.js");
|
|
153
|
-
await terminateActiveMessage(status);
|
|
154
|
-
return null;
|
|
155
|
-
}
|
|
156
|
-
catch (error) {
|
|
157
|
-
const { toErrorMessage } = await import("./utils/errors.js");
|
|
158
|
-
const normalizedError = error instanceof Error ? error : new Error(toErrorMessage(error));
|
|
159
|
-
console.error(`[voratiq] Failed to teardown message after ${context}: ${toErrorMessage(error)}`);
|
|
160
|
-
return normalizedError;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
111
|
async function terminateActiveSessionsSafe(status, context) {
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
const interactiveError = await terminateActiveInteractiveSafe(status, context);
|
|
167
|
-
const messageError = await terminateActiveMessageSafe(status, context);
|
|
168
|
-
const errors = [
|
|
169
|
-
runError,
|
|
170
|
-
verificationError,
|
|
171
|
-
interactiveError,
|
|
172
|
-
messageError,
|
|
173
|
-
].filter((error) => error instanceof Error);
|
|
174
|
-
if (errors.length > 1) {
|
|
175
|
-
return new AggregateError(errors, `Failed to teardown active sessions after ${context}`);
|
|
176
|
-
}
|
|
177
|
-
return errors[0] ?? null;
|
|
112
|
+
const { terminateRegisteredActiveSessions } = await import("./commands/shared/teardown-registry.js");
|
|
113
|
+
return await terminateRegisteredActiveSessions(status, context);
|
|
178
114
|
}
|
|
179
115
|
function renderRootLauncherGitGuidance(options) {
|
|
180
116
|
const lines = [];
|
|
@@ -359,7 +295,6 @@ async function registerCommands(program, argv) {
|
|
|
359
295
|
"auto",
|
|
360
296
|
"apply",
|
|
361
297
|
"list",
|
|
362
|
-
"prune",
|
|
363
298
|
"doctor",
|
|
364
299
|
"mcp",
|
|
365
300
|
]);
|
|
@@ -378,7 +313,6 @@ async function registerCommands(program, argv) {
|
|
|
378
313
|
program.addCommand((await import("./cli/auto.js")).createAutoCommand());
|
|
379
314
|
program.addCommand((await import("./cli/apply.js")).createApplyCommand());
|
|
380
315
|
program.addCommand((await import("./cli/list.js")).createListCommand());
|
|
381
|
-
program.addCommand((await import("./cli/prune.js")).createPruneCommand());
|
|
382
316
|
program.addCommand((await import("./cli/doctor.js")).createDoctorCommand());
|
|
383
317
|
program.addCommand((await import("./cli/mcp.js")).createMcpCommand());
|
|
384
318
|
return;
|
|
@@ -408,9 +342,6 @@ async function registerCommands(program, argv) {
|
|
|
408
342
|
case "list":
|
|
409
343
|
program.addCommand((await import("./cli/list.js")).createListCommand());
|
|
410
344
|
break;
|
|
411
|
-
case "prune":
|
|
412
|
-
program.addCommand((await import("./cli/prune.js")).createPruneCommand());
|
|
413
|
-
break;
|
|
414
345
|
case "doctor":
|
|
415
346
|
program.addCommand((await import("./cli/doctor.js")).createDoctorCommand());
|
|
416
347
|
break;
|
package/dist/cli/auto.js
CHANGED
|
@@ -9,22 +9,13 @@ import { renderWorkspaceAutoInitializedNotice } from "../render/transcripts/shar
|
|
|
9
9
|
import { renderCliError } from "../render/utils/errors.js";
|
|
10
10
|
import { HintedError } from "../utils/errors.js";
|
|
11
11
|
import { formatAlertMessage } from "../utils/output.js";
|
|
12
|
-
import { parsePositiveInteger } from "../utils/validators.js";
|
|
13
12
|
import { runApplyCommand } from "./apply.js";
|
|
14
13
|
import { toCliError } from "./errors.js";
|
|
14
|
+
import { collectRepeatedStringOption, parseMaxParallelOption, } from "./option-parsers.js";
|
|
15
15
|
import { beginChainedCommandOutput, writeCommandOutput } from "./output.js";
|
|
16
16
|
import { runRunCommand } from "./run.js";
|
|
17
17
|
import { runSpecCommand } from "./spec.js";
|
|
18
18
|
import { runVerifyCommand } from "./verify.js";
|
|
19
|
-
function parseMaxParallelOption(value) {
|
|
20
|
-
return parsePositiveInteger(value, "Expected positive integer after --max-parallel", "--max-parallel must be greater than 0");
|
|
21
|
-
}
|
|
22
|
-
function collectRunAgentOption(value, previous) {
|
|
23
|
-
return [...previous, value];
|
|
24
|
-
}
|
|
25
|
-
function collectVerifyAgentOption(value, previous) {
|
|
26
|
-
return [...previous, value];
|
|
27
|
-
}
|
|
28
19
|
function replayAutoCommandEvent(event) {
|
|
29
20
|
if (event.kind === "body") {
|
|
30
21
|
writeCommandOutput({
|
|
@@ -45,10 +36,6 @@ function replayAutoCommandEvent(event) {
|
|
|
45
36
|
writeCommandOutput({ body: renderCliError(toCliError(event.error)) });
|
|
46
37
|
return;
|
|
47
38
|
}
|
|
48
|
-
const warningBody = formatAlertMessage("Action required", "yellow", event.detail);
|
|
49
|
-
writeCommandOutput({
|
|
50
|
-
body: event.separateWithDivider ? `---\n\n${warningBody}` : warningBody,
|
|
51
|
-
});
|
|
52
39
|
}
|
|
53
40
|
async function persistAutoOutcome(options) {
|
|
54
41
|
const { runId, outcome } = options;
|
|
@@ -207,10 +194,10 @@ export function createAutoCommand() {
|
|
|
207
194
|
.option("--description <text>", "Generate a spec, then run and verify it")
|
|
208
195
|
.addOption(new Option("--run-agent <agent-id>", "Set run-stage agents directly (repeatable; order preserved)")
|
|
209
196
|
.default([], "")
|
|
210
|
-
.argParser(
|
|
197
|
+
.argParser(collectRepeatedStringOption))
|
|
211
198
|
.addOption(new Option("--verify-agent <agent-id>", "Set verify-stage agents directly (repeatable)")
|
|
212
199
|
.default([], "")
|
|
213
|
-
.argParser(
|
|
200
|
+
.argParser(collectRepeatedStringOption))
|
|
214
201
|
.option("--profile <name>", 'Orchestration profile (default: "default")')
|
|
215
202
|
.option("--max-parallel <count>", "Max concurrent agents/verifiers", parseMaxParallelOption)
|
|
216
203
|
.option("--branch", "Create or checkout a branch named after the spec")
|