@mcoda/codali 0.1.134 → 0.1.135-codali.4
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/CHANGELOG.md +42 -0
- package/ORCHESTRATION.md +387 -0
- package/README.md +103 -1
- package/config/alternate-local.example.json +49 -0
- package/config/docdex-runtime.json +21 -0
- package/config/orchestration.schema.json +548 -0
- package/config/raijin-suku.example.json +172 -0
- package/config/terminal-long-scenarios.v1.json +70 -0
- package/dist/agents/RoleResolution.d.ts.map +1 -1
- package/dist/agents/RoleResolution.js +4 -4
- package/dist/api/CodaliApi.d.ts +16 -0
- package/dist/api/CodaliApi.d.ts.map +1 -1
- package/dist/api/CodaliApi.js +39 -10
- package/dist/cli/AskCommand.d.ts +3 -0
- package/dist/cli/AskCommand.d.ts.map +1 -1
- package/dist/cli/AskCommand.js +76 -13
- package/dist/cli/RunCommand.d.ts +4 -0
- package/dist/cli/RunCommand.d.ts.map +1 -1
- package/dist/cli/RunCommand.js +110 -24
- package/dist/cli/TerminalCommand.d.ts +35 -0
- package/dist/cli/TerminalCommand.d.ts.map +1 -0
- package/dist/cli/TerminalCommand.js +616 -0
- package/dist/cli/TerminalCredentials.d.ts +3 -0
- package/dist/cli/TerminalCredentials.d.ts.map +1 -0
- package/dist/cli/TerminalCredentials.js +89 -0
- package/dist/cli/TerminalInput.d.ts +24 -0
- package/dist/cli/TerminalInput.d.ts.map +1 -0
- package/dist/cli/TerminalInput.js +98 -0
- package/dist/cli/TerminalText.d.ts +10 -0
- package/dist/cli/TerminalText.d.ts.map +1 -0
- package/dist/cli/TerminalText.js +53 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +33 -4
- package/dist/cognitive/ConfiguredPipeline.d.ts +34 -0
- package/dist/cognitive/ConfiguredPipeline.d.ts.map +1 -0
- package/dist/cognitive/ConfiguredPipeline.js +50 -0
- package/dist/cognitive/ValidationRunner.d.ts +4 -0
- package/dist/cognitive/ValidationRunner.d.ts.map +1 -1
- package/dist/cognitive/ValidationRunner.js +18 -41
- package/dist/config/NodeOrchestration.d.ts +21 -0
- package/dist/config/NodeOrchestration.d.ts.map +1 -0
- package/dist/config/NodeOrchestration.js +54 -0
- package/dist/config/OrchestrationConfig.d.ts +100 -0
- package/dist/config/OrchestrationConfig.d.ts.map +1 -0
- package/dist/config/OrchestrationConfig.js +245 -0
- package/dist/connectors/mcp/McpClient.d.ts +3 -1
- package/dist/connectors/mcp/McpClient.d.ts.map +1 -1
- package/dist/connectors/mcp/McpClient.js +3 -2
- package/dist/connectors/mcp/McpServerRegistry.d.ts +2 -2
- package/dist/connectors/mcp/McpServerRegistry.d.ts.map +1 -1
- package/dist/connectors/mcp/McpServerRegistry.js +39 -16
- package/dist/connectors/mcp/McpToolAdapter.js +2 -2
- package/dist/connectors/media/ConfiguredMediaTools.d.ts +6 -0
- package/dist/connectors/media/ConfiguredMediaTools.d.ts.map +1 -0
- package/dist/connectors/media/ConfiguredMediaTools.js +41 -0
- package/dist/connectors/media/ImageGenerationTool.js +3 -3
- package/dist/connectors/media/MediaArtifactReceipt.d.ts +5 -0
- package/dist/connectors/media/MediaArtifactReceipt.d.ts.map +1 -0
- package/dist/connectors/media/MediaArtifactReceipt.js +65 -0
- package/dist/connectors/media/MediaJobStore.d.ts +68 -0
- package/dist/connectors/media/MediaJobStore.d.ts.map +1 -0
- package/dist/connectors/media/MediaJobStore.js +199 -0
- package/dist/connectors/media/MediaJobWorker.d.ts +2 -0
- package/dist/connectors/media/MediaJobWorker.d.ts.map +1 -0
- package/dist/connectors/media/MediaJobWorker.js +65 -0
- package/dist/connectors/media/RemoteMediaJob.d.ts +6 -0
- package/dist/connectors/media/RemoteMediaJob.d.ts.map +1 -0
- package/dist/connectors/media/RemoteMediaJob.js +80 -0
- package/dist/docdex/DocdexClient.d.ts +18 -1
- package/dist/docdex/DocdexClient.d.ts.map +1 -1
- package/dist/docdex/DocdexClient.js +135 -19
- package/dist/docdex/ManagedDocdex.d.ts +29 -0
- package/dist/docdex/ManagedDocdex.d.ts.map +1 -0
- package/dist/docdex/ManagedDocdex.js +215 -0
- package/dist/docdex/ManagedRuntime.d.ts +28 -0
- package/dist/docdex/ManagedRuntime.d.ts.map +1 -0
- package/dist/docdex/ManagedRuntime.js +212 -0
- package/dist/eval/EvaluationProcess.d.ts +13 -0
- package/dist/eval/EvaluationProcess.d.ts.map +1 -0
- package/dist/eval/EvaluationProcess.js +76 -0
- package/dist/eval/LongWorkflowJourney.d.ts +34 -0
- package/dist/eval/LongWorkflowJourney.d.ts.map +1 -0
- package/dist/eval/LongWorkflowJourney.js +243 -0
- package/dist/eval/PlanningCorpus.d.ts +45 -0
- package/dist/eval/PlanningCorpus.d.ts.map +1 -0
- package/dist/eval/PlanningCorpus.js +189 -0
- package/dist/eval/PlanningCorpusRunner.d.ts +13 -0
- package/dist/eval/PlanningCorpusRunner.d.ts.map +1 -0
- package/dist/eval/PlanningCorpusRunner.js +89 -0
- package/dist/eval/TerminalCorpusRunner.d.ts +36 -0
- package/dist/eval/TerminalCorpusRunner.d.ts.map +1 -0
- package/dist/eval/TerminalCorpusRunner.js +222 -0
- package/dist/eval/TerminalTaskCorpus.d.ts +26 -0
- package/dist/eval/TerminalTaskCorpus.d.ts.map +1 -0
- package/dist/eval/TerminalTaskCorpus.js +105 -0
- package/dist/eval/TerminalWorkflowCorpus.d.ts +11 -0
- package/dist/eval/TerminalWorkflowCorpus.d.ts.map +1 -0
- package/dist/eval/TerminalWorkflowCorpus.js +116 -0
- package/dist/eval/fixtures/TerminalRecoveryJourney.d.ts +4 -0
- package/dist/eval/fixtures/TerminalRecoveryJourney.d.ts.map +1 -0
- package/dist/eval/fixtures/TerminalRecoveryJourney.js +132 -0
- package/dist/gateway/CodaliGateway.d.ts +2 -0
- package/dist/gateway/CodaliGateway.d.ts.map +1 -1
- package/dist/gateway/CodaliGateway.js +11 -1
- package/dist/gateway/ConfiguredGateway.d.ts +23 -0
- package/dist/gateway/ConfiguredGateway.d.ts.map +1 -0
- package/dist/gateway/ConfiguredGateway.js +44 -0
- package/dist/gateway/GatewayTracer.d.ts +1 -1
- package/dist/gateway/GatewayTracer.d.ts.map +1 -1
- package/dist/gateway/GatewayTracer.js +2 -27
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/permissions/PermissionGate.d.ts +44 -0
- package/dist/permissions/PermissionGate.d.ts.map +1 -0
- package/dist/permissions/PermissionGate.js +97 -0
- package/dist/providers/ConfiguredEmbeddings.d.ts +43 -0
- package/dist/providers/ConfiguredEmbeddings.d.ts.map +1 -0
- package/dist/providers/ConfiguredEmbeddings.js +87 -0
- package/dist/providers/ConfiguredModelScope.d.ts +69 -0
- package/dist/providers/ConfiguredModelScope.d.ts.map +1 -0
- package/dist/providers/ConfiguredModelScope.js +113 -0
- package/dist/providers/ConfiguredProvider.d.ts +79 -0
- package/dist/providers/ConfiguredProvider.d.ts.map +1 -0
- package/dist/providers/ConfiguredProvider.js +238 -0
- package/dist/providers/ModelServiceError.d.ts +10 -0
- package/dist/providers/ModelServiceError.d.ts.map +1 -0
- package/dist/providers/ModelServiceError.js +45 -0
- package/dist/providers/MswarmWorkerProvider.d.ts.map +1 -1
- package/dist/providers/MswarmWorkerProvider.js +4 -0
- package/dist/providers/OpenAiCompatibleProvider.d.ts.map +1 -1
- package/dist/providers/OpenAiCompatibleProvider.js +91 -50
- package/dist/providers/ProviderTypes.d.ts +12 -0
- package/dist/providers/ProviderTypes.d.ts.map +1 -1
- package/dist/runtime/CodaliJobRuntime.d.ts +6 -0
- package/dist/runtime/CodaliJobRuntime.d.ts.map +1 -1
- package/dist/runtime/CodaliJobRuntime.js +36 -1
- package/dist/runtime/CodaliRuntime.d.ts +28 -0
- package/dist/runtime/CodaliRuntime.d.ts.map +1 -1
- package/dist/runtime/CodaliRuntime.js +69 -1
- package/dist/runtime/CompletionReport.d.ts +5 -0
- package/dist/runtime/CompletionReport.d.ts.map +1 -0
- package/dist/runtime/CompletionReport.js +12 -0
- package/dist/runtime/ProgressTracker.d.ts +17 -0
- package/dist/runtime/ProgressTracker.d.ts.map +1 -0
- package/dist/runtime/ProgressTracker.js +27 -0
- package/dist/runtime/RequestedTestEvidence.d.ts +12 -0
- package/dist/runtime/RequestedTestEvidence.d.ts.map +1 -0
- package/dist/runtime/RequestedTestEvidence.js +16 -0
- package/dist/runtime/RequiredRetrieval.d.ts +13 -0
- package/dist/runtime/RequiredRetrieval.d.ts.map +1 -0
- package/dist/runtime/RequiredRetrieval.js +25 -0
- package/dist/runtime/ReviewSource.d.ts +6 -0
- package/dist/runtime/ReviewSource.d.ts.map +1 -0
- package/dist/runtime/ReviewSource.js +38 -0
- package/dist/runtime/Runner.d.ts +7 -0
- package/dist/runtime/Runner.d.ts.map +1 -1
- package/dist/runtime/Runner.js +215 -171
- package/dist/runtime/SecretRedaction.d.ts +11 -0
- package/dist/runtime/SecretRedaction.d.ts.map +1 -0
- package/dist/runtime/SecretRedaction.js +85 -0
- package/dist/runtime/SessionController.d.ts +148 -0
- package/dist/runtime/SessionController.d.ts.map +1 -0
- package/dist/runtime/SessionController.js +1357 -0
- package/dist/runtime/StructuralEvidence.d.ts +22 -0
- package/dist/runtime/StructuralEvidence.d.ts.map +1 -0
- package/dist/runtime/StructuralEvidence.js +87 -0
- package/dist/runtime/TaskReviewContext.d.ts +34 -0
- package/dist/runtime/TaskReviewContext.d.ts.map +1 -0
- package/dist/runtime/TaskReviewContext.js +34 -0
- package/dist/runtime/ValidationOutput.d.ts +5 -0
- package/dist/runtime/ValidationOutput.d.ts.map +1 -0
- package/dist/runtime/ValidationOutput.js +32 -0
- package/dist/runtime/VerificationCommand.d.ts +5 -0
- package/dist/runtime/VerificationCommand.d.ts.map +1 -0
- package/dist/runtime/VerificationCommand.js +76 -0
- package/dist/runtime/WorkStatusPage.d.ts +15 -0
- package/dist/runtime/WorkStatusPage.d.ts.map +1 -0
- package/dist/runtime/WorkStatusPage.js +58 -0
- package/dist/runtime/WorkspaceLedger.d.ts +13 -0
- package/dist/runtime/WorkspaceLedger.d.ts.map +1 -0
- package/dist/runtime/WorkspaceLedger.js +145 -0
- package/dist/runtime/WorkspaceLock.d.ts.map +1 -1
- package/dist/runtime/WorkspaceLock.js +20 -17
- package/dist/runtime/WorkspaceSnapshot.d.ts +13 -0
- package/dist/runtime/WorkspaceSnapshot.d.ts.map +1 -0
- package/dist/runtime/WorkspaceSnapshot.js +88 -0
- package/dist/session/AtomicState.d.ts +13 -0
- package/dist/session/AtomicState.d.ts.map +1 -0
- package/dist/session/AtomicState.js +123 -0
- package/dist/session/SessionStoragePath.d.ts +15 -0
- package/dist/session/SessionStoragePath.d.ts.map +1 -0
- package/dist/session/SessionStoragePath.js +89 -0
- package/dist/session/SessionStore.d.ts +9 -0
- package/dist/session/SessionStore.d.ts.map +1 -1
- package/dist/session/SessionStore.js +181 -47
- package/dist/session/WorkState.d.ts +23 -0
- package/dist/session/WorkState.d.ts.map +1 -0
- package/dist/session/WorkState.js +367 -0
- package/dist/session/WorkTypes.d.ts +94 -0
- package/dist/session/WorkTypes.d.ts.map +1 -0
- package/dist/session/WorkTypes.js +1 -0
- package/dist/tools/ToolRegistry.d.ts +2 -0
- package/dist/tools/ToolRegistry.d.ts.map +1 -1
- package/dist/tools/ToolRegistry.js +12 -2
- package/dist/tools/ToolTypes.d.ts +16 -0
- package/dist/tools/ToolTypes.d.ts.map +1 -1
- package/dist/tools/docdex/DocdexTools.d.ts +2 -0
- package/dist/tools/docdex/DocdexTools.d.ts.map +1 -1
- package/dist/tools/docdex/DocdexTools.js +17 -2
- package/dist/tools/filesystem/FileTools.d.ts.map +1 -1
- package/dist/tools/filesystem/FileTools.js +30 -10
- package/dist/tools/shell/AsyncProcess.d.ts +19 -0
- package/dist/tools/shell/AsyncProcess.d.ts.map +1 -0
- package/dist/tools/shell/AsyncProcess.js +94 -0
- package/dist/tools/shell/DarwinRuntimeLibraries.d.ts +13 -0
- package/dist/tools/shell/DarwinRuntimeLibraries.d.ts.map +1 -0
- package/dist/tools/shell/DarwinRuntimeLibraries.js +130 -0
- package/dist/tools/shell/HostToolchain.d.ts +19 -0
- package/dist/tools/shell/HostToolchain.d.ts.map +1 -0
- package/dist/tools/shell/HostToolchain.js +266 -0
- package/dist/tools/shell/IsolatedExecutor.d.ts +15 -0
- package/dist/tools/shell/IsolatedExecutor.d.ts.map +1 -0
- package/dist/tools/shell/IsolatedExecutor.js +138 -0
- package/dist/tools/shell/ShellTool.d.ts.map +1 -1
- package/dist/tools/shell/ShellTool.js +9 -29
- package/dist/tools/shell/ShellWorkingDirectory.d.ts +3 -0
- package/dist/tools/shell/ShellWorkingDirectory.d.ts.map +1 -0
- package/dist/tools/shell/ShellWorkingDirectory.js +30 -0
- package/package.json +27 -24
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ToolContext, type ToolHandlerResult } from "../ToolTypes.js";
|
|
2
|
+
import { type HostRuntime } from "./HostToolchain.js";
|
|
3
|
+
export interface ExecutorStatus {
|
|
4
|
+
available: boolean;
|
|
5
|
+
backend: "bubblewrap" | "sandbox-exec" | "unavailable";
|
|
6
|
+
reason?: string;
|
|
7
|
+
}
|
|
8
|
+
/** All paths have been canonicalized by the host, before launching the sandbox. */
|
|
9
|
+
export declare const darwinSandboxProfile: (root: string, scratch: string, writePaths: string[], runtimes: HostRuntime[], network?: boolean) => string;
|
|
10
|
+
export declare const executorStatus: () => ExecutorStatus;
|
|
11
|
+
export declare const createIsolatedExecutor: (options?: {
|
|
12
|
+
network?: boolean;
|
|
13
|
+
status?: ExecutorStatus;
|
|
14
|
+
}) => ((command: string, args: string[], context: ToolContext) => Promise<ToolHandlerResult>);
|
|
15
|
+
//# sourceMappingURL=IsolatedExecutor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IsolatedExecutor.d.ts","sourceRoot":"","sources":["../../../src/tools/shell/IsolatedExecutor.ts"],"names":[],"mappings":"AAMA,OAAO,EAAsB,KAAK,WAAW,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAA6C,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjG,MAAM,WAAW,cAAc;IAAG,SAAS,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,YAAY,GAAG,cAAc,GAAG,aAAa,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAAE;AAEhI,mFAAmF;AACnF,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,EAAE,SAAS,MAAM,EAAE,YAAY,MAAM,EAAE,EAAE,UAAU,WAAW,EAAE,EAAE,iBAAe,KAAG,MA2BpI,CAAC;AAQF,eAAO,MAAM,cAAc,QAAO,cAcjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,UAAS;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,cAAc,CAAA;CAAO,KAAG,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAoD3L,CAAC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { existsSync, realpathSync, mkdtempSync, rmSync, promises as fs } from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { spawnSync } from "node:child_process";
|
|
5
|
+
import { runProcess } from "./AsyncProcess.js";
|
|
6
|
+
import { resolveShellWorkingDirectory } from "./ShellWorkingDirectory.js";
|
|
7
|
+
import { ToolExecutionError } from "../ToolTypes.js";
|
|
8
|
+
import { discoverHostToolchain, extraRuntimeMounts } from "./HostToolchain.js";
|
|
9
|
+
/** All paths have been canonicalized by the host, before launching the sandbox. */
|
|
10
|
+
export const darwinSandboxProfile = (root, scratch, writePaths, runtimes, network = false) => {
|
|
11
|
+
const quoted = (value) => JSON.stringify(value);
|
|
12
|
+
const ancestors = new Set();
|
|
13
|
+
for (const target of [root, scratch, ...extraRuntimeMounts(runtimes).map(runtime => runtime.readOnlyRoot)]) {
|
|
14
|
+
for (let parent = path.dirname(target); parent !== path.dirname(parent); parent = path.dirname(parent))
|
|
15
|
+
ancestors.add(parent);
|
|
16
|
+
}
|
|
17
|
+
return [
|
|
18
|
+
"(version 1)", "(deny default)", "(allow process*)", "(allow sysctl-read)",
|
|
19
|
+
// dyld opens the root directory when locating its shared cache. This literal
|
|
20
|
+
// permits the directory itself, never a recursive read of the filesystem.
|
|
21
|
+
'(allow file-read* (literal "/"))',
|
|
22
|
+
// realpath/lstat needs ancestor metadata, not directory contents or sibling files.
|
|
23
|
+
...[...ancestors].map(parent => `(allow file-read-metadata (literal ${quoted(parent)}))`),
|
|
24
|
+
'(allow file-read* (subpath "/usr") (subpath "/bin") (subpath "/sbin") (subpath "/System") (subpath "/Library") (subpath "/private/etc") (subpath "/dev"))',
|
|
25
|
+
// Git and other native tools open the null device read/write for discarded IO.
|
|
26
|
+
'(allow file-write-data (literal "/dev/null"))',
|
|
27
|
+
// Apple's /bin/sh reads this system selector before starting npm scripts.
|
|
28
|
+
// Permit only that selector, not other private /var files or directories.
|
|
29
|
+
'(allow file-read* (literal "/private/var/select/sh") (literal "/var/select/sh"))',
|
|
30
|
+
'(allow file-read-metadata (literal "/private/var/select") (literal "/var/select"))',
|
|
31
|
+
`(allow file-read* (subpath ${quoted(root)}))`,
|
|
32
|
+
...extraRuntimeMounts(runtimes).map(runtime => `(allow file-read* (${runtime.directory ? "subpath" : "literal"} ${quoted(runtime.readOnlyRoot)}))`),
|
|
33
|
+
`(allow file-read* file-write* (subpath ${quoted(scratch)}))`,
|
|
34
|
+
...writePaths.map(file => `(allow file-write* (subpath ${quoted(file)}))`),
|
|
35
|
+
...[".git", ".mcoda"].map(dir => `(deny file-write* (subpath ${quoted(path.join(root, dir))}))`),
|
|
36
|
+
network ? "(allow network*)" : "(deny network*)",
|
|
37
|
+
].join("\n");
|
|
38
|
+
};
|
|
39
|
+
const bubblewrapRoot = () => {
|
|
40
|
+
const args = ["--die-with-parent", "--new-session", "--unshare-all", "--ro-bind", "/usr", "/usr", "--dev", "/dev", "--proc", "/proc", "--tmpfs", "/tmp"];
|
|
41
|
+
for (const dir of ["/bin", "/sbin", "/lib", "/lib64"])
|
|
42
|
+
if (existsSync(dir))
|
|
43
|
+
args.push("--ro-bind", realpathSync(dir), dir);
|
|
44
|
+
return args;
|
|
45
|
+
};
|
|
46
|
+
export const executorStatus = () => {
|
|
47
|
+
if (process.platform === "linux") {
|
|
48
|
+
if (!existsSync("/usr/bin/bwrap"))
|
|
49
|
+
return { available: false, backend: "unavailable", reason: "Install bubblewrap to enable isolated shell execution" };
|
|
50
|
+
const probe = spawnSync("/usr/bin/bwrap", [...bubblewrapRoot(), "--", "/usr/bin/true"], { timeout: 3000, stdio: "ignore" });
|
|
51
|
+
return probe.status === 0 ? { available: true, backend: "bubblewrap" } : { available: false, backend: "unavailable", reason: "bubblewrap user namespaces are unavailable" };
|
|
52
|
+
}
|
|
53
|
+
if (process.platform === "darwin" && existsSync("/usr/bin/sandbox-exec")) {
|
|
54
|
+
const scratch = realpathSync(mkdtempSync(path.join(os.tmpdir(), "codali-isolation-probe-")));
|
|
55
|
+
try {
|
|
56
|
+
const probe = spawnSync("/usr/bin/sandbox-exec", ["-p", darwinSandboxProfile(scratch, scratch, [], []), "/usr/bin/true"], { timeout: 3000, stdio: "ignore" });
|
|
57
|
+
if (probe.status === 0)
|
|
58
|
+
return { available: true, backend: "sandbox-exec" };
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
rmSync(scratch, { recursive: true, force: true });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return { available: false, backend: "unavailable", reason: "No supported isolation backend on this platform" };
|
|
65
|
+
};
|
|
66
|
+
export const createIsolatedExecutor = (options = {}) => {
|
|
67
|
+
const status = options.status ?? executorStatus();
|
|
68
|
+
return async (command, args, context) => {
|
|
69
|
+
if (!status.available)
|
|
70
|
+
throw new ToolExecutionError("tool_permission_denied", status.reason ?? "Isolation unavailable");
|
|
71
|
+
const root = realpathSync(context.workspaceRoot);
|
|
72
|
+
const cwd = resolveShellWorkingDirectory(root, context.shellWorkingDirectory);
|
|
73
|
+
if (root === path.parse(root).root)
|
|
74
|
+
throw new ToolExecutionError("tool_permission_denied", "Filesystem root cannot be an isolated workspace");
|
|
75
|
+
const runtimes = discoverHostToolchain(root);
|
|
76
|
+
const writePaths = (context.allowedWritePaths ?? ["."]).map(file => {
|
|
77
|
+
const requested = path.resolve(root, file);
|
|
78
|
+
if (requested !== root && !requested.startsWith(`${root}${path.sep}`))
|
|
79
|
+
throw new ToolExecutionError("tool_permission_denied", "Shell write scope escapes workspace");
|
|
80
|
+
if (!existsSync(requested))
|
|
81
|
+
throw new ToolExecutionError("tool_permission_denied", "Create the scoped directory/file with write_file before shell execution");
|
|
82
|
+
const real = realpathSync(requested);
|
|
83
|
+
if (real !== root && !real.startsWith(`${root}${path.sep}`))
|
|
84
|
+
throw new ToolExecutionError("tool_permission_denied", "Shell write scope resolves outside workspace");
|
|
85
|
+
if ([".git", ".mcoda"].some(dir => real === path.join(root, dir) || real.startsWith(`${root}/${dir}/`)))
|
|
86
|
+
throw new ToolExecutionError("tool_permission_denied", "Repository control metadata cannot be a write scope");
|
|
87
|
+
return real;
|
|
88
|
+
});
|
|
89
|
+
if (status.backend === "bubblewrap") {
|
|
90
|
+
const launch = bubblewrapRoot();
|
|
91
|
+
if (options.network) {
|
|
92
|
+
launch.push("--share-net");
|
|
93
|
+
for (const file of ["/etc/resolv.conf", "/etc/hosts", "/etc/nsswitch.conf", "/etc/ssl/certs"])
|
|
94
|
+
if (existsSync(file))
|
|
95
|
+
launch.push("--ro-bind", realpathSync(file), file);
|
|
96
|
+
}
|
|
97
|
+
launch.push("--dir", path.dirname(root), "--ro-bind", root, root);
|
|
98
|
+
for (const runtime of extraRuntimeMounts(runtimes))
|
|
99
|
+
launch.push("--dir", path.dirname(runtime.readOnlyRoot), "--ro-bind", runtime.readOnlyRoot, runtime.readOnlyRoot);
|
|
100
|
+
launch.push("--dir", "/tmp/codali-bin");
|
|
101
|
+
for (const runtime of runtimes)
|
|
102
|
+
launch.push("--symlink", runtime.executable, `/tmp/codali-bin/${runtime.name}`);
|
|
103
|
+
for (const file of writePaths)
|
|
104
|
+
launch.push("--bind", file, file);
|
|
105
|
+
launch.push("--chdir", cwd, "--dir", "/tmp/home", "--setenv", "HOME", "/tmp/home", "--setenv", "TMPDIR", "/tmp", "--setenv", "PATH", "/tmp/codali-bin:/usr/local/bin:/usr/bin:/bin");
|
|
106
|
+
for (const [key, value] of Object.entries({ CARGO_HOME: "/tmp/home/cargo", XDG_CACHE_HOME: "/tmp/home/cache", PYTHONPYCACHEPREFIX: "/tmp/home/pycache", PYTHONUSERBASE: "/tmp/home/python", GIT_CONFIG_NOSYSTEM: "1", GIT_CONFIG_GLOBAL: "/dev/null", GIT_ATTR_NOSYSTEM: "1" }))
|
|
107
|
+
launch.push("--setenv", key, value);
|
|
108
|
+
// Git hooks/config and private session state are not part of executable workspace access.
|
|
109
|
+
for (const dir of [".git", ".mcoda"])
|
|
110
|
+
if (existsSync(path.join(root, dir)))
|
|
111
|
+
launch.push("--ro-bind", path.join(root, dir), path.join(root, dir));
|
|
112
|
+
launch.push("--", command, ...args);
|
|
113
|
+
return runProcess("/usr/bin/bwrap", launch, context);
|
|
114
|
+
}
|
|
115
|
+
const scratch = realpathSync(await fs.mkdtemp(path.join(os.tmpdir(), "codali-shell-")));
|
|
116
|
+
try {
|
|
117
|
+
await fs.chmod(scratch, 0o700);
|
|
118
|
+
const privateHome = path.join(scratch, "home");
|
|
119
|
+
const privateBin = path.join(scratch, "bin");
|
|
120
|
+
await fs.mkdir(privateHome, { mode: 0o700 });
|
|
121
|
+
await fs.mkdir(privateBin, { mode: 0o700 });
|
|
122
|
+
for (const runtime of runtimes)
|
|
123
|
+
await fs.symlink(runtime.executable, path.join(privateBin, runtime.name));
|
|
124
|
+
const profile = darwinSandboxProfile(root, scratch, writePaths, runtimes, options.network);
|
|
125
|
+
return await runProcess("/usr/bin/sandbox-exec", ["-p", profile, runtimes.find(runtime => runtime.name === command)?.executable ?? command, ...args], context, {
|
|
126
|
+
...runtimes.find(runtime => runtime.name === "cc")?.environment,
|
|
127
|
+
HOME: privateHome, TMPDIR: scratch, PATH: `${privateBin}:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin`,
|
|
128
|
+
CARGO_HOME: path.join(privateHome, "cargo"), XDG_CACHE_HOME: path.join(privateHome, "cache"),
|
|
129
|
+
PYTHONPYCACHEPREFIX: path.join(privateHome, "pycache"), PYTHONUSERBASE: path.join(privateHome, "python"),
|
|
130
|
+
// Host Git settings can invoke external helpers or read private paths.
|
|
131
|
+
GIT_CONFIG_NOSYSTEM: "1", GIT_CONFIG_GLOBAL: "/dev/null", GIT_ATTR_NOSYSTEM: "1",
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
finally {
|
|
135
|
+
await fs.rm(scratch, { recursive: true, force: true });
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShellTool.d.ts","sourceRoot":"","sources":["../../../src/tools/shell/ShellTool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ShellTool.d.ts","sourceRoot":"","sources":["../../../src/tools/shell/ShellTool.ts"],"names":[],"mappings":"AACA,OAAO,EAAwC,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AA6C5F,eAAO,MAAM,eAAe,QAAO,cAmDjC,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { spawnSync } from "node:child_process";
|
|
2
1
|
import path from "node:path";
|
|
3
2
|
import { ToolExecutionError } from "../ToolTypes.js";
|
|
3
|
+
import { runProcess } from "./AsyncProcess.js";
|
|
4
|
+
import { resolveShellWorkingDirectory } from "./ShellWorkingDirectory.js";
|
|
4
5
|
const resolveAllowlist = (context) => {
|
|
5
6
|
return context.shellAllowlist ?? [];
|
|
6
7
|
};
|
|
@@ -40,15 +41,17 @@ const isDestructiveShellAction = (command, args) => {
|
|
|
40
41
|
};
|
|
41
42
|
export const createShellTool = () => ({
|
|
42
43
|
name: "run_shell",
|
|
43
|
-
description:
|
|
44
|
+
description: 'Run an allowlisted executable. Default cwd is the workspace root; set cwd for a module-local command, e.g. {"command":"npm","args":["test"],"cwd":"packages/app"}. In terminal mode the workspace is read-only unless writePaths names root-relative paths inside the claimed task. Existing source files in those paths require current reads and structural analysis.',
|
|
44
45
|
readOnly: false,
|
|
45
46
|
capability: "shell",
|
|
46
47
|
inputSchema: {
|
|
47
48
|
type: "object",
|
|
48
49
|
required: ["command"],
|
|
49
50
|
properties: {
|
|
50
|
-
command: { type: "string" },
|
|
51
|
+
command: { type: "string", description: "One executable name, without arguments or shell syntax." },
|
|
51
52
|
args: { type: "array", items: { type: "string" } },
|
|
53
|
+
cwd: { type: "string", description: "Existing working directory inside the workspace, relative to its root. Default: workspace root. Does not change the base of writePaths." },
|
|
54
|
+
writePaths: { type: "array", items: { type: "string" }, description: "Terminal mode: root-relative existing files/directories to make writable, regardless of cwd. Default: no workspace writes. Must fit the claimed task scope." },
|
|
52
55
|
},
|
|
53
56
|
},
|
|
54
57
|
handler: async (args, context) => {
|
|
@@ -57,7 +60,7 @@ export const createShellTool = () => ({
|
|
|
57
60
|
retryable: false,
|
|
58
61
|
});
|
|
59
62
|
}
|
|
60
|
-
const { command, args: commandArgs = [] } = args;
|
|
63
|
+
const { command, args: commandArgs = [], cwd } = args;
|
|
61
64
|
if (!context.allowDestructiveOperations
|
|
62
65
|
&& isDestructiveShellAction(command, commandArgs)) {
|
|
63
66
|
throw new ToolExecutionError("tool_permission_denied", "Destructive operation blocked by policy", {
|
|
@@ -77,30 +80,7 @@ export const createShellTool = () => ({
|
|
|
77
80
|
details: { command },
|
|
78
81
|
});
|
|
79
82
|
}
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
encoding: "utf8",
|
|
83
|
-
});
|
|
84
|
-
if (result.error) {
|
|
85
|
-
throw result.error;
|
|
86
|
-
}
|
|
87
|
-
const stdout = result.stdout ?? "";
|
|
88
|
-
const stderr = result.stderr ?? "";
|
|
89
|
-
const exitCode = result.status ?? 0;
|
|
90
|
-
if (exitCode !== 0) {
|
|
91
|
-
const message = stderr || stdout || `Command failed with exit code ${exitCode}`;
|
|
92
|
-
throw new ToolExecutionError("tool_execution_failed", message, {
|
|
93
|
-
retryable: false,
|
|
94
|
-
details: { command, exitCode },
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
return {
|
|
98
|
-
output: stdout || stderr,
|
|
99
|
-
data: {
|
|
100
|
-
stdout,
|
|
101
|
-
stderr,
|
|
102
|
-
exitCode,
|
|
103
|
-
},
|
|
104
|
-
};
|
|
83
|
+
const shellWorkingDirectory = resolveShellWorkingDirectory(context.workspaceRoot, cwd);
|
|
84
|
+
return (context.shellExecutor ?? runProcess)(command, commandArgs, { ...context, shellWorkingDirectory });
|
|
105
85
|
},
|
|
106
86
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShellWorkingDirectory.d.ts","sourceRoot":"","sources":["../../../src/tools/shell/ShellWorkingDirectory.ts"],"names":[],"mappings":"AAIA,gFAAgF;AAChF,eAAO,MAAM,4BAA4B,GAAI,eAAe,MAAM,EAAE,YAAY,MAAM,KAAG,MAoBxF,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { realpathSync, statSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { ToolExecutionError } from "../ToolTypes.js";
|
|
4
|
+
/** Resolve only the process directory; write scopes still use workspaceRoot. */
|
|
5
|
+
export const resolveShellWorkingDirectory = (workspaceRoot, requested) => {
|
|
6
|
+
if (requested !== undefined && (typeof requested !== "string" || !requested.trim())) {
|
|
7
|
+
throw new ToolExecutionError("tool_invalid_args", "cwd must be a non-empty directory path inside the workspace");
|
|
8
|
+
}
|
|
9
|
+
const root = realpathSync.native(workspaceRoot);
|
|
10
|
+
const inside = (candidate) => {
|
|
11
|
+
const relative = path.relative(root, candidate);
|
|
12
|
+
return relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
|
|
13
|
+
};
|
|
14
|
+
const candidate = path.resolve(root, requested ?? ".");
|
|
15
|
+
if (!inside(candidate))
|
|
16
|
+
throw new ToolExecutionError("tool_permission_denied", "Shell cwd escapes the workspace");
|
|
17
|
+
try {
|
|
18
|
+
const resolved = realpathSync.native(candidate);
|
|
19
|
+
if (!inside(resolved))
|
|
20
|
+
throw new ToolExecutionError("tool_permission_denied", "Shell cwd resolves outside the workspace");
|
|
21
|
+
if (!statSync(resolved).isDirectory())
|
|
22
|
+
throw new ToolExecutionError("tool_invalid_args", "Shell cwd must be an existing directory");
|
|
23
|
+
return resolved;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (error instanceof ToolExecutionError)
|
|
27
|
+
throw error;
|
|
28
|
+
throw new ToolExecutionError("tool_invalid_args", "Shell cwd is not an accessible existing directory");
|
|
29
|
+
}
|
|
30
|
+
};
|
package/package.json
CHANGED
|
@@ -1,46 +1,49 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"version": "0.1.134",
|
|
4
|
-
"description": "Standalone tool-runner adapter for mcoda.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "dist/index.js",
|
|
7
|
-
"types": "dist/index.d.ts",
|
|
2
|
+
"author": "bekir dag",
|
|
8
3
|
"bin": {
|
|
9
4
|
"codali": "dist/cli.js",
|
|
10
5
|
"dataset": "dist/dataset-cli.js"
|
|
11
6
|
},
|
|
7
|
+
"bugs": {
|
|
8
|
+
"url": "https://github.com/bekirdag/mcoda/issues"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@mcoda/db": "0.1.135-codali.4",
|
|
12
|
+
"@mcoda/shared": "0.1.135-codali.4",
|
|
13
|
+
"@modelcontextprotocol/sdk": "1.30.0",
|
|
14
|
+
"zod": "4.5.2"
|
|
15
|
+
},
|
|
16
|
+
"description": "Standalone tool-runner adapter for mcoda.",
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=20"
|
|
19
|
+
},
|
|
12
20
|
"files": [
|
|
13
21
|
"dist",
|
|
14
22
|
"!dist/**/__tests__/**",
|
|
15
23
|
"!dist/**/*.test.*",
|
|
16
24
|
"README.md",
|
|
17
25
|
"CHANGELOG.md",
|
|
18
|
-
"LICENSE"
|
|
26
|
+
"LICENSE",
|
|
27
|
+
"ORCHESTRATION.md",
|
|
28
|
+
"config"
|
|
19
29
|
],
|
|
20
|
-
"engines": {
|
|
21
|
-
"node": ">=20"
|
|
22
|
-
},
|
|
23
|
-
"repository": {
|
|
24
|
-
"type": "git",
|
|
25
|
-
"url": "git+https://github.com/bekirdag/mcoda.git"
|
|
26
|
-
},
|
|
27
|
-
"bugs": {
|
|
28
|
-
"url": "https://github.com/bekirdag/mcoda/issues"
|
|
29
|
-
},
|
|
30
30
|
"homepage": "https://github.com/bekirdag/mcoda#readme",
|
|
31
31
|
"license": "MIT",
|
|
32
|
-
"
|
|
32
|
+
"main": "dist/index.js",
|
|
33
|
+
"name": "@mcoda/codali",
|
|
33
34
|
"publishConfig": {
|
|
34
35
|
"access": "public"
|
|
35
36
|
},
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"@mcoda/shared": "0.1.134"
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/bekirdag/mcoda.git"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build": "tsc -p tsconfig.json",
|
|
43
43
|
"lint": "echo \"lint not configured\"",
|
|
44
44
|
"test": "pnpm run build && node ../../scripts/run-node-tests.js dist"
|
|
45
|
-
}
|
|
46
|
-
|
|
45
|
+
},
|
|
46
|
+
"type": "module",
|
|
47
|
+
"types": "dist/index.d.ts",
|
|
48
|
+
"version": "0.1.135-codali.4"
|
|
49
|
+
}
|