voratiq 0.1.0-beta.0
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/LICENSE +21 -0
- package/README.md +59 -0
- package/dist/auth/providers/claude/constants.d.ts +7 -0
- package/dist/auth/providers/claude/constants.js +9 -0
- package/dist/auth/providers/claude/credentials.d.ts +5 -0
- package/dist/auth/providers/claude/credentials.js +112 -0
- package/dist/auth/providers/claude/error.d.ts +5 -0
- package/dist/auth/providers/claude/error.js +6 -0
- package/dist/auth/providers/claude/keychain.d.ts +4 -0
- package/dist/auth/providers/claude/keychain.js +158 -0
- package/dist/auth/providers/claude.d.ts +2 -0
- package/dist/auth/providers/claude.js +124 -0
- package/dist/auth/providers/codex.d.ts +2 -0
- package/dist/auth/providers/codex.js +93 -0
- package/dist/auth/providers/gemini.d.ts +2 -0
- package/dist/auth/providers/gemini.js +159 -0
- package/dist/auth/providers/index.d.ts +2 -0
- package/dist/auth/providers/index.js +16 -0
- package/dist/auth/providers/messages.d.ts +1 -0
- package/dist/auth/providers/messages.js +3 -0
- package/dist/auth/providers/secret-staging.d.ts +14 -0
- package/dist/auth/providers/secret-staging.js +72 -0
- package/dist/auth/providers/teardown.d.ts +2 -0
- package/dist/auth/providers/teardown.js +6 -0
- package/dist/auth/providers/types.d.ts +31 -0
- package/dist/auth/providers/types.js +1 -0
- package/dist/auth/providers/utils.d.ts +20 -0
- package/dist/auth/providers/utils.js +148 -0
- package/dist/auth/runtime.d.ts +2 -0
- package/dist/auth/runtime.js +17 -0
- package/dist/auth/staging.d.ts +8 -0
- package/dist/auth/staging.js +7 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +142 -0
- package/dist/cli/apply.d.ts +14 -0
- package/dist/cli/apply.js +38 -0
- package/dist/cli/commander-utils.d.ts +3 -0
- package/dist/cli/commander-utils.js +27 -0
- package/dist/cli/confirmation.d.ts +14 -0
- package/dist/cli/confirmation.js +16 -0
- package/dist/cli/errors.d.ts +5 -0
- package/dist/cli/errors.js +16 -0
- package/dist/cli/init.d.ts +10 -0
- package/dist/cli/init.js +41 -0
- package/dist/cli/list.d.ts +14 -0
- package/dist/cli/list.js +48 -0
- package/dist/cli/output.d.ts +14 -0
- package/dist/cli/output.js +62 -0
- package/dist/cli/prune.d.ts +14 -0
- package/dist/cli/prune.js +54 -0
- package/dist/cli/review.d.ts +12 -0
- package/dist/cli/review.js +33 -0
- package/dist/cli/run.d.ts +13 -0
- package/dist/cli/run.js +51 -0
- package/dist/commands/apply/command.d.ts +9 -0
- package/dist/commands/apply/command.js +135 -0
- package/dist/commands/apply/errors.d.ts +35 -0
- package/dist/commands/apply/errors.js +73 -0
- package/dist/commands/apply/types.d.ts +13 -0
- package/dist/commands/apply/types.js +1 -0
- package/dist/commands/errors.d.ts +4 -0
- package/dist/commands/errors.js +7 -0
- package/dist/commands/fetch.d.ts +8 -0
- package/dist/commands/fetch.js +25 -0
- package/dist/commands/init/agents.d.ts +3 -0
- package/dist/commands/init/agents.js +159 -0
- package/dist/commands/init/command.d.ts +2 -0
- package/dist/commands/init/command.js +40 -0
- package/dist/commands/init/environment.d.ts +2 -0
- package/dist/commands/init/environment.js +76 -0
- package/dist/commands/init/evals.d.ts +4 -0
- package/dist/commands/init/evals.js +219 -0
- package/dist/commands/init/types.d.ts +48 -0
- package/dist/commands/init/types.js +1 -0
- package/dist/commands/list/command.d.ts +13 -0
- package/dist/commands/list/command.js +60 -0
- package/dist/commands/prune/command.d.ts +2 -0
- package/dist/commands/prune/command.js +336 -0
- package/dist/commands/prune/errors.d.ts +20 -0
- package/dist/commands/prune/errors.js +39 -0
- package/dist/commands/prune/types.d.ts +42 -0
- package/dist/commands/prune/types.js +1 -0
- package/dist/commands/review/command.d.ts +10 -0
- package/dist/commands/review/command.js +26 -0
- package/dist/commands/run/agent-execution.d.ts +19 -0
- package/dist/commands/run/agent-execution.js +63 -0
- package/dist/commands/run/agents/auth-stage.d.ts +23 -0
- package/dist/commands/run/agents/auth-stage.js +108 -0
- package/dist/commands/run/agents/chat-preserver.d.ts +9 -0
- package/dist/commands/run/agents/chat-preserver.js +35 -0
- package/dist/commands/run/agents/eval-runner.d.ts +19 -0
- package/dist/commands/run/agents/eval-runner.js +27 -0
- package/dist/commands/run/agents/failures.d.ts +7 -0
- package/dist/commands/run/agents/failures.js +32 -0
- package/dist/commands/run/agents/lifecycle.d.ts +9 -0
- package/dist/commands/run/agents/lifecycle.js +157 -0
- package/dist/commands/run/agents/preparation.d.ts +2 -0
- package/dist/commands/run/agents/preparation.js +123 -0
- package/dist/commands/run/agents/run-context.d.ts +46 -0
- package/dist/commands/run/agents/run-context.js +193 -0
- package/dist/commands/run/agents/sandbox-launcher.d.ts +44 -0
- package/dist/commands/run/agents/sandbox-launcher.js +211 -0
- package/dist/commands/run/agents/types.d.ts +47 -0
- package/dist/commands/run/agents/types.js +1 -0
- package/dist/commands/run/agents/watchdog.d.ts +39 -0
- package/dist/commands/run/agents/watchdog.js +172 -0
- package/dist/commands/run/agents/workspace-prep.d.ts +17 -0
- package/dist/commands/run/agents/workspace-prep.js +78 -0
- package/dist/commands/run/agents.d.ts +14 -0
- package/dist/commands/run/agents.js +47 -0
- package/dist/commands/run/argv.d.ts +1 -0
- package/dist/commands/run/argv.js +19 -0
- package/dist/commands/run/command.d.ts +14 -0
- package/dist/commands/run/command.js +170 -0
- package/dist/commands/run/errors.d.ts +61 -0
- package/dist/commands/run/errors.js +86 -0
- package/dist/commands/run/id.d.ts +1 -0
- package/dist/commands/run/id.js +22 -0
- package/dist/commands/run/lifecycle.d.ts +19 -0
- package/dist/commands/run/lifecycle.js +186 -0
- package/dist/commands/run/phases.d.ts +11 -0
- package/dist/commands/run/phases.js +1 -0
- package/dist/commands/run/prompts.d.ts +4 -0
- package/dist/commands/run/prompts.js +16 -0
- package/dist/commands/run/record-init.d.ts +15 -0
- package/dist/commands/run/record-init.js +29 -0
- package/dist/commands/run/reports.d.ts +14 -0
- package/dist/commands/run/reports.js +63 -0
- package/dist/commands/run/sandbox-registry.d.ts +4 -0
- package/dist/commands/run/sandbox-registry.js +54 -0
- package/dist/commands/run/sandbox.d.ts +16 -0
- package/dist/commands/run/sandbox.js +96 -0
- package/dist/commands/run/shim/agent-manifest.d.ts +7 -0
- package/dist/commands/run/shim/agent-manifest.js +1 -0
- package/dist/commands/run/shim/run-agent-shim.d.ts +1 -0
- package/dist/commands/run/shim/run-agent-shim.js +232 -0
- package/dist/commands/run/shim/run-agent-shim.mjs +10 -0
- package/dist/commands/run/validation.d.ts +20 -0
- package/dist/commands/run/validation.js +60 -0
- package/dist/configs/agents/defaults.d.ts +9 -0
- package/dist/configs/agents/defaults.js +55 -0
- package/dist/configs/agents/errors.d.ts +40 -0
- package/dist/configs/agents/errors.js +78 -0
- package/dist/configs/agents/loader.d.ts +8 -0
- package/dist/configs/agents/loader.js +137 -0
- package/dist/configs/agents/types.d.ts +39 -0
- package/dist/configs/agents/types.js +31 -0
- package/dist/configs/environment/detect.d.ts +17 -0
- package/dist/configs/environment/detect.js +79 -0
- package/dist/configs/environment/errors.d.ts +12 -0
- package/dist/configs/environment/errors.js +26 -0
- package/dist/configs/environment/loader.d.ts +10 -0
- package/dist/configs/environment/loader.js +80 -0
- package/dist/configs/environment/types.d.ts +21 -0
- package/dist/configs/environment/types.js +98 -0
- package/dist/configs/evals/defaults.d.ts +8 -0
- package/dist/configs/evals/defaults.js +28 -0
- package/dist/configs/evals/detect.d.ts +10 -0
- package/dist/configs/evals/detect.js +224 -0
- package/dist/configs/evals/errors.d.ts +16 -0
- package/dist/configs/evals/errors.js +29 -0
- package/dist/configs/evals/loader.d.ts +9 -0
- package/dist/configs/evals/loader.js +46 -0
- package/dist/configs/evals/types.d.ts +42 -0
- package/dist/configs/evals/types.js +74 -0
- package/dist/configs/sandbox/defaults.d.ts +14 -0
- package/dist/configs/sandbox/defaults.js +54 -0
- package/dist/configs/sandbox/errors.d.ts +5 -0
- package/dist/configs/sandbox/errors.js +8 -0
- package/dist/configs/sandbox/loader.d.ts +6 -0
- package/dist/configs/sandbox/loader.js +192 -0
- package/dist/configs/sandbox/merge.d.ts +9 -0
- package/dist/configs/sandbox/merge.js +94 -0
- package/dist/configs/sandbox/schemas.d.ts +58 -0
- package/dist/configs/sandbox/schemas.js +72 -0
- package/dist/configs/sandbox/types.d.ts +34 -0
- package/dist/configs/sandbox/types.js +1 -0
- package/dist/configs/shared/loader-factory.d.ts +19 -0
- package/dist/configs/shared/loader-factory.js +33 -0
- package/dist/configs/shared/yaml-error-formatter.d.ts +40 -0
- package/dist/configs/shared/yaml-error-formatter.js +41 -0
- package/dist/evals/runner.d.ts +16 -0
- package/dist/evals/runner.js +132 -0
- package/dist/preflight/errors.d.ts +10 -0
- package/dist/preflight/errors.js +21 -0
- package/dist/preflight/index.d.ts +30 -0
- package/dist/preflight/index.js +157 -0
- package/dist/records/enhanced.d.ts +38 -0
- package/dist/records/enhanced.js +139 -0
- package/dist/records/errors.d.ts +23 -0
- package/dist/records/errors.js +43 -0
- package/dist/records/history-lock.d.ts +27 -0
- package/dist/records/history-lock.js +184 -0
- package/dist/records/mutators.d.ts +17 -0
- package/dist/records/mutators.js +144 -0
- package/dist/records/persistence.d.ts +95 -0
- package/dist/records/persistence.js +459 -0
- package/dist/records/types.d.ts +238 -0
- package/dist/records/types.js +131 -0
- package/dist/render/interactions/confirmation.d.ts +19 -0
- package/dist/render/interactions/confirmation.js +63 -0
- package/dist/render/transcripts/apply.d.ts +2 -0
- package/dist/render/transcripts/apply.js +52 -0
- package/dist/render/transcripts/init.d.ts +18 -0
- package/dist/render/transcripts/init.js +84 -0
- package/dist/render/transcripts/list.d.ts +3 -0
- package/dist/render/transcripts/list.js +44 -0
- package/dist/render/transcripts/prune.d.ts +16 -0
- package/dist/render/transcripts/prune.js +50 -0
- package/dist/render/transcripts/review.d.ts +2 -0
- package/dist/render/transcripts/review.js +36 -0
- package/dist/render/transcripts/run.d.ts +25 -0
- package/dist/render/transcripts/run.js +295 -0
- package/dist/render/transcripts/shared.d.ts +12 -0
- package/dist/render/transcripts/shared.js +41 -0
- package/dist/render/utils/agents.d.ts +28 -0
- package/dist/render/utils/agents.js +261 -0
- package/dist/render/utils/badges.d.ts +20 -0
- package/dist/render/utils/badges.js +37 -0
- package/dist/render/utils/errors.d.ts +2 -0
- package/dist/render/utils/errors.js +14 -0
- package/dist/render/utils/records.d.ts +1 -0
- package/dist/render/utils/records.js +32 -0
- package/dist/render/utils/runs.d.ts +16 -0
- package/dist/render/utils/runs.js +50 -0
- package/dist/render/utils/table.d.ts +12 -0
- package/dist/render/utils/table.js +32 -0
- package/dist/render/utils/transcript.d.ts +14 -0
- package/dist/render/utils/transcript.js +44 -0
- package/dist/status/colors.d.ts +10 -0
- package/dist/status/colors.js +33 -0
- package/dist/status/index.d.ts +37 -0
- package/dist/status/index.js +30 -0
- package/dist/testing/test-hooks.d.ts +7 -0
- package/dist/testing/test-hooks.js +16 -0
- package/dist/utils/binaries.d.ts +1 -0
- package/dist/utils/binaries.js +13 -0
- package/dist/utils/cli-root.d.ts +2 -0
- package/dist/utils/cli-root.js +42 -0
- package/dist/utils/colors.d.ts +2 -0
- package/dist/utils/colors.js +23 -0
- package/dist/utils/diff.d.ts +9 -0
- package/dist/utils/diff.js +61 -0
- package/dist/utils/env.d.ts +10 -0
- package/dist/utils/env.js +56 -0
- package/dist/utils/errors.d.ts +31 -0
- package/dist/utils/errors.js +53 -0
- package/dist/utils/fs.d.ts +13 -0
- package/dist/utils/fs.js +70 -0
- package/dist/utils/git.d.ts +40 -0
- package/dist/utils/git.js +126 -0
- package/dist/utils/output.d.ts +4 -0
- package/dist/utils/output.js +12 -0
- package/dist/utils/path.d.ts +11 -0
- package/dist/utils/path.js +84 -0
- package/dist/utils/process.d.ts +37 -0
- package/dist/utils/process.js +152 -0
- package/dist/utils/terminal.d.ts +5 -0
- package/dist/utils/terminal.js +5 -0
- package/dist/utils/validators.d.ts +1 -0
- package/dist/utils/validators.js +15 -0
- package/dist/utils/version.d.ts +1 -0
- package/dist/utils/version.js +25 -0
- package/dist/utils/yaml-reader.d.ts +14 -0
- package/dist/utils/yaml-reader.js +41 -0
- package/dist/utils/yaml.d.ts +33 -0
- package/dist/utils/yaml.js +75 -0
- package/dist/workspace/agents.d.ts +33 -0
- package/dist/workspace/agents.js +189 -0
- package/dist/workspace/chat/artifacts.d.ts +14 -0
- package/dist/workspace/chat/artifacts.js +157 -0
- package/dist/workspace/chat/sources.d.ts +5 -0
- package/dist/workspace/chat/sources.js +80 -0
- package/dist/workspace/chat/types.d.ts +1 -0
- package/dist/workspace/chat/types.js +1 -0
- package/dist/workspace/cleanup.d.ts +4 -0
- package/dist/workspace/cleanup.js +12 -0
- package/dist/workspace/credential-guard.d.ts +4 -0
- package/dist/workspace/credential-guard.js +71 -0
- package/dist/workspace/dependencies.d.ts +23 -0
- package/dist/workspace/dependencies.js +190 -0
- package/dist/workspace/errors.d.ts +16 -0
- package/dist/workspace/errors.js +43 -0
- package/dist/workspace/layout.d.ts +30 -0
- package/dist/workspace/layout.js +124 -0
- package/dist/workspace/prune.d.ts +8 -0
- package/dist/workspace/prune.js +29 -0
- package/dist/workspace/run.d.ts +14 -0
- package/dist/workspace/run.js +28 -0
- package/dist/workspace/sandbox-requirements.d.ts +17 -0
- package/dist/workspace/sandbox-requirements.js +69 -0
- package/dist/workspace/setup.d.ts +3 -0
- package/dist/workspace/setup.js +81 -0
- package/dist/workspace/shim.d.ts +4 -0
- package/dist/workspace/shim.js +65 -0
- package/dist/workspace/structure.d.ts +77 -0
- package/dist/workspace/structure.js +134 -0
- package/dist/workspace/templates.d.ts +9 -0
- package/dist/workspace/templates.js +66 -0
- package/dist/workspace/types.d.ts +4 -0
- package/dist/workspace/types.js +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { assertSandboxDestination } from "../staging.js";
|
|
3
|
+
import { buildAuthFailedMessage } from "./messages.js";
|
|
4
|
+
import { disposeHandles, registerSandboxSecrets, stageSecretFile, } from "./secret-staging.js";
|
|
5
|
+
import { teardownAuthProvider } from "./teardown.js";
|
|
6
|
+
import { assertReadableFileOrThrow, composeSandboxEnvResult, copyOptionalDirectoryWithPermissions, copyOptionalFileWithPermissions, createSandboxPaths, ensureDirectories, resolveChildPath, } from "./utils.js";
|
|
7
|
+
const GEMINI_PROVIDER_ID = "gemini";
|
|
8
|
+
const GEMINI_LOGIN_HINT = buildAuthFailedMessage("Gemini");
|
|
9
|
+
const GEMINI_REQUIRED_FILES = [
|
|
10
|
+
"oauth_creds.json",
|
|
11
|
+
"google_accounts.json",
|
|
12
|
+
"settings.json",
|
|
13
|
+
"state.json",
|
|
14
|
+
];
|
|
15
|
+
const GEMINI_OPTIONAL_FILES = ["installation_id", "GEMINI.md"];
|
|
16
|
+
const GEMINI_API_KEY_ENV_VARS = ["GEMINI_API_KEY", "GOOGLE_API_KEY"];
|
|
17
|
+
class GeminiAuthProviderError extends Error {
|
|
18
|
+
constructor(message, options) {
|
|
19
|
+
super(message, options);
|
|
20
|
+
this.name = "GeminiAuthProviderError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export const geminiAuthProvider = {
|
|
24
|
+
id: GEMINI_PROVIDER_ID,
|
|
25
|
+
async verify(options) {
|
|
26
|
+
const apiKey = resolveGeminiApiKey(options.runtime.env);
|
|
27
|
+
if (apiKey) {
|
|
28
|
+
return { status: "ok" };
|
|
29
|
+
}
|
|
30
|
+
const homeDir = options.runtime.homeDir;
|
|
31
|
+
if (!homeDir) {
|
|
32
|
+
throw new GeminiAuthProviderError(GEMINI_LOGIN_HINT);
|
|
33
|
+
}
|
|
34
|
+
const geminiHome = resolveChildPath(homeDir, ".gemini");
|
|
35
|
+
for (const filename of GEMINI_REQUIRED_FILES) {
|
|
36
|
+
const target = resolveChildPath(geminiHome, filename);
|
|
37
|
+
await assertReadableFileOrThrow(target, (cause) => new GeminiAuthProviderError(GEMINI_LOGIN_HINT, { cause }));
|
|
38
|
+
}
|
|
39
|
+
const settingsPath = resolveChildPath(geminiHome, "settings.json");
|
|
40
|
+
await validateSettingsFile(settingsPath);
|
|
41
|
+
return { status: "ok" };
|
|
42
|
+
},
|
|
43
|
+
async stage(options) {
|
|
44
|
+
const apiKey = resolveGeminiApiKey(options.runtime.env);
|
|
45
|
+
if (apiKey) {
|
|
46
|
+
return composeSandboxEnvResult(options.agentRoot, {
|
|
47
|
+
GEMINI_API_KEY: apiKey,
|
|
48
|
+
GOOGLE_API_KEY: apiKey,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
const homeDir = options.runtime.homeDir;
|
|
52
|
+
if (!homeDir) {
|
|
53
|
+
throw new GeminiAuthProviderError(GEMINI_LOGIN_HINT);
|
|
54
|
+
}
|
|
55
|
+
const geminiHome = resolveChildPath(homeDir, ".gemini");
|
|
56
|
+
for (const filename of GEMINI_REQUIRED_FILES) {
|
|
57
|
+
const source = resolveChildPath(geminiHome, filename);
|
|
58
|
+
await assertReadableFileOrThrow(source, (cause) => new GeminiAuthProviderError(GEMINI_LOGIN_HINT, { cause }));
|
|
59
|
+
}
|
|
60
|
+
const sandboxPaths = createSandboxPaths(options.agentRoot, {
|
|
61
|
+
gemini: [".gemini"],
|
|
62
|
+
});
|
|
63
|
+
await ensureDirectories([...Object.values(sandboxPaths)]);
|
|
64
|
+
const secretHandles = await stageRequiredFiles(geminiHome, sandboxPaths.gemini, sandboxPaths.home);
|
|
65
|
+
try {
|
|
66
|
+
await stageOptionalFiles(geminiHome, sandboxPaths.gemini, sandboxPaths.home);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
await disposeHandles(secretHandles);
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
registerSandboxSecrets(sandboxPaths.home, secretHandles);
|
|
73
|
+
return composeSandboxEnvResult(sandboxPaths.home, {});
|
|
74
|
+
},
|
|
75
|
+
async teardown(options) {
|
|
76
|
+
await teardownAuthProvider(options);
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
function resolveGeminiApiKey(env) {
|
|
80
|
+
for (const key of GEMINI_API_KEY_ENV_VARS) {
|
|
81
|
+
const value = env[key];
|
|
82
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
83
|
+
return value.trim();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
async function stageRequiredFiles(geminiHome, sandboxGeminiDir, sandboxHome) {
|
|
89
|
+
const handles = [];
|
|
90
|
+
try {
|
|
91
|
+
for (const filename of GEMINI_REQUIRED_FILES) {
|
|
92
|
+
const source = resolveChildPath(geminiHome, filename);
|
|
93
|
+
const bytes = await readFile(source);
|
|
94
|
+
if (filename === "settings.json") {
|
|
95
|
+
validateSettingsContent(bytes.toString("utf8"));
|
|
96
|
+
}
|
|
97
|
+
const destination = resolveChildPath(sandboxGeminiDir, filename);
|
|
98
|
+
const handle = await stageSecretFile(sandboxHome, {
|
|
99
|
+
destinationPath: destination,
|
|
100
|
+
sourceBytes: bytes,
|
|
101
|
+
providerId: GEMINI_PROVIDER_ID,
|
|
102
|
+
fileLabel: filename,
|
|
103
|
+
});
|
|
104
|
+
handles.push(handle);
|
|
105
|
+
}
|
|
106
|
+
return handles;
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
await disposeHandles(handles);
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async function stageOptionalFiles(geminiHome, sandboxGeminiDir, sandboxHome) {
|
|
114
|
+
for (const filename of GEMINI_OPTIONAL_FILES) {
|
|
115
|
+
const source = resolveChildPath(geminiHome, filename);
|
|
116
|
+
const destination = resolveChildPath(sandboxGeminiDir, filename);
|
|
117
|
+
assertSandboxDestination({
|
|
118
|
+
sandboxHome,
|
|
119
|
+
destinationPath: destination,
|
|
120
|
+
providerId: GEMINI_PROVIDER_ID,
|
|
121
|
+
fileLabel: filename,
|
|
122
|
+
});
|
|
123
|
+
await copyOptionalFileWithPermissions(source, destination, (cause) => {
|
|
124
|
+
return new GeminiAuthProviderError(GEMINI_LOGIN_HINT, { cause });
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
const tmpSource = resolveChildPath(geminiHome, "tmp");
|
|
128
|
+
const sandboxTmpDestination = resolveChildPath(sandboxGeminiDir, "tmp");
|
|
129
|
+
assertSandboxDestination({
|
|
130
|
+
sandboxHome,
|
|
131
|
+
destinationPath: sandboxTmpDestination,
|
|
132
|
+
providerId: GEMINI_PROVIDER_ID,
|
|
133
|
+
fileLabel: "tmp",
|
|
134
|
+
});
|
|
135
|
+
await copyOptionalDirectoryWithPermissions(tmpSource, sandboxTmpDestination, (cause) => new GeminiAuthProviderError(GEMINI_LOGIN_HINT, { cause }));
|
|
136
|
+
}
|
|
137
|
+
async function validateSettingsFile(settingsPath) {
|
|
138
|
+
let raw;
|
|
139
|
+
try {
|
|
140
|
+
raw = await readFile(settingsPath, "utf8");
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
throw new GeminiAuthProviderError(GEMINI_LOGIN_HINT, { cause: error });
|
|
144
|
+
}
|
|
145
|
+
validateSettingsContent(raw);
|
|
146
|
+
}
|
|
147
|
+
function validateSettingsContent(raw) {
|
|
148
|
+
let parsed;
|
|
149
|
+
try {
|
|
150
|
+
parsed = JSON.parse(raw);
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
throw new GeminiAuthProviderError(GEMINI_LOGIN_HINT, { cause: error });
|
|
154
|
+
}
|
|
155
|
+
const selectedType = parsed?.security?.auth?.selectedType;
|
|
156
|
+
if (typeof selectedType !== "string" || selectedType.trim().length === 0) {
|
|
157
|
+
throw new GeminiAuthProviderError(GEMINI_LOGIN_HINT);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { claudeAuthProvider } from "./claude.js";
|
|
2
|
+
import { codexAuthProvider } from "./codex.js";
|
|
3
|
+
import { geminiAuthProvider } from "./gemini.js";
|
|
4
|
+
const REGISTRY = new Map();
|
|
5
|
+
registerAuthProvider(claudeAuthProvider);
|
|
6
|
+
registerAuthProvider(codexAuthProvider);
|
|
7
|
+
registerAuthProvider(geminiAuthProvider);
|
|
8
|
+
function registerAuthProvider(provider) {
|
|
9
|
+
if (REGISTRY.has(provider.id)) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
REGISTRY.set(provider.id, provider);
|
|
13
|
+
}
|
|
14
|
+
export function resolveAuthProvider(id) {
|
|
15
|
+
return REGISTRY.get(id);
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function buildAuthFailedMessage(label: string): string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface SecretHandle {
|
|
2
|
+
abort(): void;
|
|
3
|
+
cleanup(): Promise<void>;
|
|
4
|
+
}
|
|
5
|
+
export interface StageSecretFileOptions {
|
|
6
|
+
destinationPath: string;
|
|
7
|
+
sourceBytes: Buffer;
|
|
8
|
+
providerId: string;
|
|
9
|
+
fileLabel: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function stageSecretFile(sandboxPath: string, options: StageSecretFileOptions): Promise<SecretHandle>;
|
|
12
|
+
export declare function registerSandboxSecrets(sandboxPath: string, handles: SecretHandle[]): void;
|
|
13
|
+
export declare function cleanupSandbox(sandboxPath: string): Promise<void>;
|
|
14
|
+
export declare function disposeHandles(handles: readonly SecretHandle[]): Promise<void>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { mkdir } from "node:fs/promises";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { safeUnlink } from "../../utils/fs.js";
|
|
4
|
+
import { assertSandboxDestination } from "../staging.js";
|
|
5
|
+
import { writeFileWithPermissions } from "./utils.js";
|
|
6
|
+
const SECRET_FILE_MODE = 0o600;
|
|
7
|
+
const sandboxSecretRegistry = new Map();
|
|
8
|
+
export async function stageSecretFile(sandboxPath, options) {
|
|
9
|
+
assertSandboxDestination({
|
|
10
|
+
sandboxHome: sandboxPath,
|
|
11
|
+
destinationPath: options.destinationPath,
|
|
12
|
+
providerId: options.providerId,
|
|
13
|
+
fileLabel: options.fileLabel,
|
|
14
|
+
});
|
|
15
|
+
await mkdir(dirname(options.destinationPath), { recursive: true });
|
|
16
|
+
try {
|
|
17
|
+
await writeFileWithPermissions(options.destinationPath, options.sourceBytes, { mode: SECRET_FILE_MODE, flag: "w" }, SECRET_FILE_MODE);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
throw new Error(`Failed to stage secret file for ${options.providerId}:${options.fileLabel} at ${options.destinationPath}.`, { cause: error });
|
|
21
|
+
}
|
|
22
|
+
return new SecretFileHandle(options.destinationPath);
|
|
23
|
+
}
|
|
24
|
+
export function registerSandboxSecrets(sandboxPath, handles) {
|
|
25
|
+
if (handles.length === 0) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
sandboxSecretRegistry.set(sandboxPath, handles);
|
|
29
|
+
}
|
|
30
|
+
export async function cleanupSandbox(sandboxPath) {
|
|
31
|
+
const handles = sandboxSecretRegistry.get(sandboxPath);
|
|
32
|
+
if (!handles) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
sandboxSecretRegistry.delete(sandboxPath);
|
|
36
|
+
await disposeHandles(handles);
|
|
37
|
+
}
|
|
38
|
+
export async function disposeHandles(handles) {
|
|
39
|
+
const uniqueHandles = [...new Set(handles)];
|
|
40
|
+
const errors = [];
|
|
41
|
+
for (const handle of uniqueHandles) {
|
|
42
|
+
try {
|
|
43
|
+
handle.abort();
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
errors.push(error);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
for (const handle of uniqueHandles) {
|
|
50
|
+
try {
|
|
51
|
+
await handle.cleanup();
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
errors.push(error);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (errors.length > 0) {
|
|
58
|
+
throw errors[0];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
class SecretFileHandle {
|
|
62
|
+
path;
|
|
63
|
+
constructor(path) {
|
|
64
|
+
this.path = path;
|
|
65
|
+
}
|
|
66
|
+
abort() {
|
|
67
|
+
// No-op for regular files
|
|
68
|
+
}
|
|
69
|
+
async cleanup() {
|
|
70
|
+
await safeUnlink(this.path);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface AuthRuntimeContext {
|
|
2
|
+
platform: NodeJS.Platform;
|
|
3
|
+
env: NodeJS.ProcessEnv;
|
|
4
|
+
homeDir: string;
|
|
5
|
+
username: string;
|
|
6
|
+
}
|
|
7
|
+
export interface VerifyOptions {
|
|
8
|
+
agentId: string;
|
|
9
|
+
runtime: AuthRuntimeContext;
|
|
10
|
+
}
|
|
11
|
+
export interface VerifyResult {
|
|
12
|
+
status: "ok";
|
|
13
|
+
}
|
|
14
|
+
export interface StageOptions extends VerifyOptions {
|
|
15
|
+
agentRoot: string;
|
|
16
|
+
runId?: string;
|
|
17
|
+
root?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface StageResult {
|
|
20
|
+
sandboxPath: string;
|
|
21
|
+
env: Record<string, string>;
|
|
22
|
+
}
|
|
23
|
+
export interface TeardownOptions {
|
|
24
|
+
sandboxPath: string;
|
|
25
|
+
}
|
|
26
|
+
export interface AuthProvider {
|
|
27
|
+
readonly id: string;
|
|
28
|
+
verify(options: VerifyOptions): Promise<VerifyResult>;
|
|
29
|
+
stage(options: StageOptions): Promise<StageResult>;
|
|
30
|
+
teardown?(options: TeardownOptions): Promise<void>;
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { writeFile } from "node:fs/promises";
|
|
2
|
+
import { isMissing } from "../../utils/fs.js";
|
|
3
|
+
import type { AuthRuntimeContext, StageResult, TeardownOptions } from "./types.js";
|
|
4
|
+
export declare function resolveProviderHome(runtime: AuthRuntimeContext, envVar: string, defaultSubdir: string): string | undefined;
|
|
5
|
+
export declare function resolveChildPath(root: string, ...segments: string[]): string;
|
|
6
|
+
export interface SandboxPaths extends Record<string, string> {
|
|
7
|
+
home: string;
|
|
8
|
+
}
|
|
9
|
+
export type SandboxLayout = Record<string, readonly string[]>;
|
|
10
|
+
export { isMissing };
|
|
11
|
+
export declare function createSandboxPaths(agentRoot: string, layout: SandboxLayout): SandboxPaths;
|
|
12
|
+
export declare function ensureDirectories(directories: readonly string[]): Promise<void>;
|
|
13
|
+
export type ErrorFactory = (cause?: unknown) => Error;
|
|
14
|
+
export declare function assertReadableFileOrThrow(path: string, createError: ErrorFactory): Promise<void>;
|
|
15
|
+
export declare function copyFileWithPermissions(source: string, destination: string, mode?: number): Promise<void>;
|
|
16
|
+
export declare function writeFileWithPermissions(destination: string, data: string | NodeJS.ArrayBufferView, options?: Parameters<typeof writeFile>[2], mode?: number): Promise<void>;
|
|
17
|
+
export declare function copyOptionalFileWithPermissions(source: string, destination: string, createError?: ErrorFactory): Promise<void>;
|
|
18
|
+
export declare function copyOptionalDirectoryWithPermissions(source: string, destination: string, createError?: ErrorFactory, fileMode?: number, dirMode?: number): Promise<void>;
|
|
19
|
+
export declare function composeSandboxEnvResult(sandboxPath: string, env: Record<string, string>): StageResult;
|
|
20
|
+
export declare function teardownSandbox({ sandboxPath, }: TeardownOptions): Promise<void>;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { constants as fsConstants } from "node:fs";
|
|
2
|
+
import { access, chmod, copyFile, mkdir, readdir, rm, stat, writeFile, } from "node:fs/promises";
|
|
3
|
+
import { isAbsolute, resolve as resolveNative } from "node:path";
|
|
4
|
+
import { isMissing } from "../../utils/fs.js";
|
|
5
|
+
import { SANDBOX_DIRNAME } from "../../workspace/structure.js";
|
|
6
|
+
const STAGED_FILE_MODE = 0o600;
|
|
7
|
+
export function resolveProviderHome(runtime, envVar, defaultSubdir) {
|
|
8
|
+
const configured = runtime.env[envVar]?.trim();
|
|
9
|
+
if (configured) {
|
|
10
|
+
if (isAbsolute(configured)) {
|
|
11
|
+
return configured;
|
|
12
|
+
}
|
|
13
|
+
const base = runtime.homeDir ?? process.cwd();
|
|
14
|
+
return resolveNative(base, configured);
|
|
15
|
+
}
|
|
16
|
+
if (runtime.homeDir) {
|
|
17
|
+
return resolveNative(runtime.homeDir, defaultSubdir);
|
|
18
|
+
}
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
export function resolveChildPath(root, ...segments) {
|
|
22
|
+
return resolveNative(root, ...segments);
|
|
23
|
+
}
|
|
24
|
+
export { isMissing };
|
|
25
|
+
export function createSandboxPaths(agentRoot, layout) {
|
|
26
|
+
const home = resolveChildPath(agentRoot, SANDBOX_DIRNAME);
|
|
27
|
+
const paths = { home };
|
|
28
|
+
for (const [name, segments] of Object.entries(layout)) {
|
|
29
|
+
paths[name] = resolveChildPath(home, ...segments);
|
|
30
|
+
}
|
|
31
|
+
return paths;
|
|
32
|
+
}
|
|
33
|
+
export async function ensureDirectories(directories) {
|
|
34
|
+
const unique = [...new Set(directories)];
|
|
35
|
+
await Promise.all(unique.map(async (directory) => {
|
|
36
|
+
await mkdir(directory, { recursive: true });
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
const { F_OK } = fsConstants;
|
|
40
|
+
export async function assertReadableFileOrThrow(path, createError) {
|
|
41
|
+
try {
|
|
42
|
+
const stats = await stat(path);
|
|
43
|
+
if (!stats.isFile()) {
|
|
44
|
+
throw createError();
|
|
45
|
+
}
|
|
46
|
+
await access(path, F_OK);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (isMissing(error)) {
|
|
50
|
+
throw createError(error);
|
|
51
|
+
}
|
|
52
|
+
throw createError(error);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export async function copyFileWithPermissions(source, destination, mode = STAGED_FILE_MODE) {
|
|
56
|
+
await copyFile(source, destination);
|
|
57
|
+
await chmod(destination, mode);
|
|
58
|
+
}
|
|
59
|
+
export async function writeFileWithPermissions(destination, data, options = { encoding: "utf8" }, mode = STAGED_FILE_MODE) {
|
|
60
|
+
await writeFile(destination, data, options);
|
|
61
|
+
await chmod(destination, mode);
|
|
62
|
+
}
|
|
63
|
+
export async function copyOptionalFileWithPermissions(source, destination, createError) {
|
|
64
|
+
try {
|
|
65
|
+
await access(source, F_OK);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
if (isMissing(error)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (createError) {
|
|
72
|
+
throw createError(error);
|
|
73
|
+
}
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
await copyFileWithPermissions(source, destination);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (isMissing(error)) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (createError) {
|
|
84
|
+
throw createError(error);
|
|
85
|
+
}
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export async function copyOptionalDirectoryWithPermissions(source, destination, createError, fileMode = STAGED_FILE_MODE, dirMode = 0o700) {
|
|
90
|
+
try {
|
|
91
|
+
const sourceStats = await stat(source);
|
|
92
|
+
if (!sourceStats.isDirectory()) {
|
|
93
|
+
if (createError) {
|
|
94
|
+
throw createError();
|
|
95
|
+
}
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
if (isMissing(error)) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (createError) {
|
|
104
|
+
throw createError(error);
|
|
105
|
+
}
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
await copyDirectoryRecursive(source, destination, fileMode, dirMode);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
if (isMissing(error)) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (createError) {
|
|
116
|
+
throw createError(error);
|
|
117
|
+
}
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async function copyDirectoryRecursive(source, destination, fileMode, dirMode) {
|
|
122
|
+
await mkdir(destination, { recursive: true, mode: dirMode });
|
|
123
|
+
await chmod(destination, dirMode).catch(() => { });
|
|
124
|
+
const entries = await readdir(source, { withFileTypes: true });
|
|
125
|
+
for (const entry of entries) {
|
|
126
|
+
const sourcePath = resolveChildPath(source, entry.name);
|
|
127
|
+
const destinationPath = resolveChildPath(destination, entry.name);
|
|
128
|
+
if (entry.isDirectory()) {
|
|
129
|
+
await copyDirectoryRecursive(sourcePath, destinationPath, fileMode, dirMode);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (entry.isFile()) {
|
|
133
|
+
await copyFileWithPermissions(sourcePath, destinationPath, fileMode);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export function composeSandboxEnvResult(sandboxPath, env) {
|
|
138
|
+
return {
|
|
139
|
+
sandboxPath,
|
|
140
|
+
env: {
|
|
141
|
+
HOME: sandboxPath,
|
|
142
|
+
...env,
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
export async function teardownSandbox({ sandboxPath, }) {
|
|
147
|
+
await rm(sandboxPath, { recursive: true, force: true });
|
|
148
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { homedir, userInfo } from "node:os";
|
|
2
|
+
function resolveHomeDir() {
|
|
3
|
+
const envHome = process.env.HOME;
|
|
4
|
+
if (envHome && envHome.trim().length > 0) {
|
|
5
|
+
return envHome;
|
|
6
|
+
}
|
|
7
|
+
return homedir();
|
|
8
|
+
}
|
|
9
|
+
export function buildAuthRuntimeContext() {
|
|
10
|
+
const { username } = userInfo();
|
|
11
|
+
return {
|
|
12
|
+
platform: process.platform,
|
|
13
|
+
env: process.env,
|
|
14
|
+
homeDir: resolveHomeDir(),
|
|
15
|
+
username,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { assertPathWithinRoot } from "../utils/path.js";
|
|
2
|
+
export function assertSandboxDestination(options) {
|
|
3
|
+
const { sandboxHome, destinationPath, providerId, fileLabel } = options;
|
|
4
|
+
assertPathWithinRoot(sandboxHome, destinationPath, {
|
|
5
|
+
message: `Secret staging for ${providerId}:${fileLabel} must target the sandbox home (${sandboxHome}). Received ${destinationPath}.`,
|
|
6
|
+
});
|
|
7
|
+
}
|
package/dist/bin.d.ts
ADDED
package/dist/bin.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { realpathSync } from "node:fs";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { Command, CommanderError } from "commander";
|
|
7
|
+
import { createApplyCommand } from "./cli/apply.js";
|
|
8
|
+
import { commanderAlreadyRendered } from "./cli/commander-utils.js";
|
|
9
|
+
import { CliError, toCliError } from "./cli/errors.js";
|
|
10
|
+
import { createInitCommand } from "./cli/init.js";
|
|
11
|
+
import { createListCommand } from "./cli/list.js";
|
|
12
|
+
import { writeCommandOutput } from "./cli/output.js";
|
|
13
|
+
import { createPruneCommand } from "./cli/prune.js";
|
|
14
|
+
import { createReviewCommand } from "./cli/review.js";
|
|
15
|
+
import { createRunCommand } from "./cli/run.js";
|
|
16
|
+
import { terminateActiveRun } from "./commands/run/lifecycle.js";
|
|
17
|
+
import { flushAllRunRecordBuffers } from "./records/persistence.js";
|
|
18
|
+
import { renderCliError } from "./render/utils/errors.js";
|
|
19
|
+
import { toErrorMessage } from "./utils/errors.js";
|
|
20
|
+
import { getVoratiqVersion } from "./utils/version.js";
|
|
21
|
+
const SIGNAL_EXIT_CODES = {
|
|
22
|
+
SIGINT: 130,
|
|
23
|
+
SIGTERM: 143,
|
|
24
|
+
};
|
|
25
|
+
function installProcessGuards() {
|
|
26
|
+
process.once("SIGINT", () => {
|
|
27
|
+
void handleSignal("SIGINT");
|
|
28
|
+
});
|
|
29
|
+
process.once("SIGTERM", () => {
|
|
30
|
+
void handleSignal("SIGTERM");
|
|
31
|
+
});
|
|
32
|
+
process.on("uncaughtException", (error) => {
|
|
33
|
+
void terminateActiveRun("failed")
|
|
34
|
+
.catch((teardownError) => {
|
|
35
|
+
console.error(`[voratiq] Failed to teardown run after uncaught exception: ${toErrorMessage(teardownError)}`);
|
|
36
|
+
})
|
|
37
|
+
.finally(async () => {
|
|
38
|
+
await flushPendingHistory();
|
|
39
|
+
console.error(error);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
process.on("unhandledRejection", (reason) => {
|
|
44
|
+
void terminateActiveRun("failed")
|
|
45
|
+
.catch((teardownError) => {
|
|
46
|
+
console.error(`[voratiq] Failed to teardown run after unhandled rejection: ${toErrorMessage(teardownError)}`);
|
|
47
|
+
})
|
|
48
|
+
.finally(async () => {
|
|
49
|
+
await flushPendingHistory();
|
|
50
|
+
console.error(reason);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async function handleSignal(signal) {
|
|
56
|
+
const exitCode = SIGNAL_EXIT_CODES[signal] ?? 1;
|
|
57
|
+
try {
|
|
58
|
+
await terminateActiveRun("aborted");
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
console.error(`[voratiq] Failed to teardown run after ${signal}: ${toErrorMessage(error)}`);
|
|
62
|
+
await flushPendingHistory();
|
|
63
|
+
process.exit(1);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
await flushPendingHistory();
|
|
67
|
+
process.exit(exitCode);
|
|
68
|
+
}
|
|
69
|
+
async function flushPendingHistory() {
|
|
70
|
+
try {
|
|
71
|
+
await flushAllRunRecordBuffers();
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.warn(`[voratiq] Failed to flush run history buffers: ${error.message}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
installProcessGuards();
|
|
78
|
+
export async function runCli(argv = process.argv) {
|
|
79
|
+
const program = new Command();
|
|
80
|
+
program
|
|
81
|
+
.name("voratiq")
|
|
82
|
+
.description("Voratiq CLI")
|
|
83
|
+
.version(getVoratiqVersion(), "-v, --version", "print the Voratiq version")
|
|
84
|
+
.exitOverride()
|
|
85
|
+
.showHelpAfterError();
|
|
86
|
+
program.addCommand(createInitCommand());
|
|
87
|
+
program.addCommand(createListCommand());
|
|
88
|
+
program.addCommand(createRunCommand());
|
|
89
|
+
program.addCommand(createReviewCommand());
|
|
90
|
+
program.addCommand(createApplyCommand());
|
|
91
|
+
program.addCommand(createPruneCommand());
|
|
92
|
+
if (argv.length <= 2) {
|
|
93
|
+
writeCommandOutput({ body: program.helpInformation() });
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
await program.parseAsync(argv);
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
if (error instanceof CommanderError) {
|
|
101
|
+
if (commanderAlreadyRendered(error)) {
|
|
102
|
+
process.exitCode = error.exitCode ?? 0;
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
writeCommandOutput({
|
|
106
|
+
body: renderCliError(new CliError(toErrorMessage(error))),
|
|
107
|
+
exitCode: error.exitCode ?? 1,
|
|
108
|
+
});
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const cliError = toCliError(error);
|
|
112
|
+
const body = renderCliError(cliError);
|
|
113
|
+
writeCommandOutput({
|
|
114
|
+
body,
|
|
115
|
+
exitCode: 1,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function shouldAutorun() {
|
|
120
|
+
if (process.env.VORATIQ_CLI_SKIP_AUTORUN === "1") {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
const modulePath = safeRealpath(fileURLToPath(import.meta.url));
|
|
124
|
+
const invokedPath = process.argv[1] !== undefined
|
|
125
|
+
? safeRealpath(resolve(process.argv[1]))
|
|
126
|
+
: undefined;
|
|
127
|
+
if (!invokedPath) {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
return modulePath === invokedPath;
|
|
131
|
+
}
|
|
132
|
+
function safeRealpath(path) {
|
|
133
|
+
try {
|
|
134
|
+
return realpathSync(path);
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return path;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (shouldAutorun()) {
|
|
141
|
+
void runCli();
|
|
142
|
+
}
|