@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,13 @@
|
|
|
1
|
+
export interface WorkspaceSnapshot {
|
|
2
|
+
git: boolean;
|
|
3
|
+
head?: string;
|
|
4
|
+
hashes: Record<string, string>;
|
|
5
|
+
dirtyPaths: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare const workspaceGit: (root: string, args: string[]) => Promise<string>;
|
|
8
|
+
export declare const workspaceHash: (value: string | Buffer) => string;
|
|
9
|
+
/** The same content identity is used by baselines, validation and completion. */
|
|
10
|
+
export declare const hashWorkspacePath: (root: string, relative: string) => Promise<string>;
|
|
11
|
+
export declare const captureWorkspace: (root: string) => Promise<WorkspaceSnapshot>;
|
|
12
|
+
export declare const changedWorkspacePaths: (before: WorkspaceSnapshot, after: WorkspaceSnapshot) => string[];
|
|
13
|
+
//# sourceMappingURL=WorkspaceSnapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkspaceSnapshot.d.ts","sourceRoot":"","sources":["../../src/runtime/WorkspaceSnapshot.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAAG,GAAG,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAC;CAAE;AACzH,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,EAAE,MAAM,MAAM,EAAE,KAAG,OAAO,CAAC,MAAM,CAKxE,CAAC;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,GAAG,MAAM,KAAG,MAA0D,CAAC;AAClH,iFAAiF;AACjF,eAAO,MAAM,iBAAiB,GAAU,MAAM,MAAM,EAAE,UAAU,MAAM,KAAG,OAAO,CAAC,MAAM,CAuBtF,CAAC;AACF,eAAO,MAAM,gBAAgB,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,iBAAiB,CA+B9E,CAAC;AACF,eAAO,MAAM,qBAAqB,GAAI,QAAQ,iBAAiB,EAAE,OAAO,iBAAiB,KAAG,MAAM,EACsC,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { constants, promises as fs } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { execFile } from "node:child_process";
|
|
5
|
+
export const workspaceGit = (root, args) => new Promise((resolve, reject) => {
|
|
6
|
+
execFile("git", ["--no-optional-locks", "-c", "core.fsmonitor=false", ...args], {
|
|
7
|
+
cwd: root, timeout: 15000, maxBuffer: 8 * 1024 * 1024,
|
|
8
|
+
env: { PATH: process.env.PATH, LANG: "C", GIT_CONFIG_NOSYSTEM: "1", GIT_CONFIG_GLOBAL: "/dev/null", GIT_TERMINAL_PROMPT: "0" },
|
|
9
|
+
}, (error, output) => error ? reject(new Error(`Git inspection failed (${error.code ?? "unknown"})`)) : resolve(output));
|
|
10
|
+
});
|
|
11
|
+
export const workspaceHash = (value) => createHash("sha256").update(value).digest("hex");
|
|
12
|
+
/** The same content identity is used by baselines, validation and completion. */
|
|
13
|
+
export const hashWorkspacePath = async (root, relative) => {
|
|
14
|
+
root = await fs.realpath(root);
|
|
15
|
+
const file = path.resolve(root, relative);
|
|
16
|
+
if (!file.startsWith(`${root}${path.sep}`))
|
|
17
|
+
throw new Error("Unsafe workspace inventory path");
|
|
18
|
+
try {
|
|
19
|
+
const parent = await fs.realpath(path.dirname(file));
|
|
20
|
+
if (parent !== root && !parent.startsWith(`${root}${path.sep}`))
|
|
21
|
+
throw new Error("Workspace parent symlink escapes the repository");
|
|
22
|
+
const stat = await fs.lstat(file);
|
|
23
|
+
if (stat.isSymbolicLink())
|
|
24
|
+
return `symlink:${await fs.readlink(file)}`;
|
|
25
|
+
if (!stat.isFile())
|
|
26
|
+
return `directory:${stat.ino}`;
|
|
27
|
+
const handle = await fs.open(file, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
28
|
+
try {
|
|
29
|
+
const before = await handle.stat();
|
|
30
|
+
const digest = createHash("sha256");
|
|
31
|
+
for await (const chunk of handle.createReadStream({ autoClose: false }))
|
|
32
|
+
digest.update(chunk);
|
|
33
|
+
const after = await handle.stat();
|
|
34
|
+
if (before.ino !== stat.ino || before.size !== after.size || before.mtimeMs !== after.mtimeMs || before.ctimeMs !== after.ctimeMs)
|
|
35
|
+
throw new Error(`Workspace file changed during inspection: ${relative}`);
|
|
36
|
+
return digest.digest("hex");
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
await handle.close();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error.code === "ENOENT")
|
|
44
|
+
return "missing";
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
export const captureWorkspace = async (root) => {
|
|
49
|
+
root = await fs.realpath(root);
|
|
50
|
+
const snapshot = { git: true, hashes: {}, dirtyPaths: [] };
|
|
51
|
+
let files;
|
|
52
|
+
try {
|
|
53
|
+
files = (await workspaceGit(root, ["ls-files", "-z", "--cached", "--others", "--exclude-standard"])).split("\0").filter(Boolean);
|
|
54
|
+
snapshot.head = await workspaceGit(root, ["rev-parse", "HEAD"]).then(v => v.trim()).catch(() => "unborn");
|
|
55
|
+
const dirty = await Promise.all([
|
|
56
|
+
workspaceGit(root, ["diff", "--relative", "--no-ext-diff", "--no-textconv", "--name-only", "-z"]),
|
|
57
|
+
workspaceGit(root, ["diff", "--cached", "--relative", "--no-ext-diff", "--no-textconv", "--name-only", "-z"]),
|
|
58
|
+
workspaceGit(root, ["ls-files", "--others", "--exclude-standard", "-z"]),
|
|
59
|
+
]);
|
|
60
|
+
snapshot.dirtyPaths = [...new Set(dirty.flatMap(value => value.split("\0").filter(Boolean)))].sort();
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
snapshot.git = false;
|
|
64
|
+
files = [];
|
|
65
|
+
const walk = async (directory) => {
|
|
66
|
+
for (const entry of await fs.readdir(path.join(root, directory), { withFileTypes: true })) {
|
|
67
|
+
if ([".git", "node_modules", ".docdex", ".mcoda", ".codali", "dist", "build"].includes(entry.name))
|
|
68
|
+
continue;
|
|
69
|
+
const relative = path.join(directory, entry.name);
|
|
70
|
+
if (entry.isDirectory())
|
|
71
|
+
await walk(relative);
|
|
72
|
+
else
|
|
73
|
+
files.push(relative);
|
|
74
|
+
if (files.length > 20000)
|
|
75
|
+
throw new Error("Workspace inventory exceeds 20000 files; narrow the workspace");
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
await walk("");
|
|
79
|
+
}
|
|
80
|
+
files = [...new Set(files)].filter(file => !/^(?:\.docdex|\.mcoda|\.codali)\//.test(file));
|
|
81
|
+
if (files.length > 20000)
|
|
82
|
+
throw new Error("Workspace inventory exceeds 20000 files; narrow the workspace");
|
|
83
|
+
for (const relative of files) {
|
|
84
|
+
snapshot.hashes[relative] = await hashWorkspacePath(root, relative);
|
|
85
|
+
}
|
|
86
|
+
return snapshot;
|
|
87
|
+
};
|
|
88
|
+
export const changedWorkspacePaths = (before, after) => [...new Set([...Object.keys(before.hashes), ...Object.keys(after.hashes)])].filter(file => before.hashes[file] !== after.hashes[file]);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Windows cannot flush a directory handle through Node's fsync. File contents
|
|
2
|
+
* are still flushed before publication; POSIX directory durability is retained. */
|
|
3
|
+
export declare const syncStateDirectory: (directory: string) => Promise<void>;
|
|
4
|
+
export declare const atomicWriteJson: (file: string, value: unknown) => Promise<void>;
|
|
5
|
+
/** Probe an execution lock without relying on process IDs or waiting behind a live owner. */
|
|
6
|
+
export declare const tryStateLock: <T>(file: string, operation: () => Promise<T>) => Promise<{
|
|
7
|
+
acquired: false;
|
|
8
|
+
} | {
|
|
9
|
+
acquired: true;
|
|
10
|
+
value: T;
|
|
11
|
+
}>;
|
|
12
|
+
export declare const withStateLock: <T>(file: string, operation: () => Promise<T>, timeoutMs?: number) => Promise<T>;
|
|
13
|
+
//# sourceMappingURL=AtomicState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AtomicState.d.ts","sourceRoot":"","sources":["../../src/session/AtomicState.ts"],"names":[],"mappings":"AAMA;mFACmF;AACnF,eAAO,MAAM,kBAAkB,GAAU,WAAW,MAAM,KAAG,OAAO,CAAC,IAAI,CAOxE,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,MAAM,MAAM,EAAE,OAAO,OAAO,KAAG,OAAO,CAAC,IAAI,CAyBhF,CAAC;AAIF,6FAA6F;AAC7F,eAAO,MAAM,YAAY,GAAU,CAAC,EAAE,MAAM,MAAM,EAAE,WAAW,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAK3I,CAAC;AACF,eAAO,MAAM,aAAa,GAAU,CAAC,EAAE,MAAM,MAAM,EAAE,WAAW,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,kBAAkB,KAAG,OAAO,CAAC,CAAC,CAS/G,CAAC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { promises as fs } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { Connection } from "@mcoda/db";
|
|
5
|
+
import { assertRegularStateFile } from "./SessionStoragePath.js";
|
|
6
|
+
/** Windows cannot flush a directory handle through Node's fsync. File contents
|
|
7
|
+
* are still flushed before publication; POSIX directory durability is retained. */
|
|
8
|
+
export const syncStateDirectory = async (directory) => {
|
|
9
|
+
const handle = await fs.open(directory, "r");
|
|
10
|
+
try {
|
|
11
|
+
await handle.sync();
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
const code = error.code ?? "";
|
|
15
|
+
if (!["EINVAL", "ENOTSUP"].includes(code) && !(process.platform === "win32" && code === "EPERM"))
|
|
16
|
+
throw error;
|
|
17
|
+
}
|
|
18
|
+
finally {
|
|
19
|
+
await handle.close();
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
export const atomicWriteJson = async (file, value) => {
|
|
23
|
+
await assertRegularStateFile(file);
|
|
24
|
+
await fs.mkdir(path.dirname(file), { recursive: true, mode: 0o700 });
|
|
25
|
+
const temporary = `${file}.${randomUUID()}.tmp`;
|
|
26
|
+
const handle = await fs.open(temporary, "wx", 0o600);
|
|
27
|
+
try {
|
|
28
|
+
await handle.writeFile(`${JSON.stringify(value, null, 2)}\n`, "utf8");
|
|
29
|
+
await handle.sync();
|
|
30
|
+
await handle.close();
|
|
31
|
+
// A concurrent Windows reader or scanner can briefly deny replacement.
|
|
32
|
+
// Retry the same atomic rename; never remove the previous durable state.
|
|
33
|
+
for (let attempt = 0;; attempt++) {
|
|
34
|
+
try {
|
|
35
|
+
await fs.rename(temporary, file);
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
const code = error.code ?? "";
|
|
40
|
+
if (process.platform !== "win32" || !["EPERM", "EACCES", "EBUSY"].includes(code) || attempt >= 7)
|
|
41
|
+
throw error;
|
|
42
|
+
await assertRegularStateFile(file);
|
|
43
|
+
await new Promise(resolve => setTimeout(resolve, Math.min(20 * 2 ** attempt, 160)));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
await syncStateDirectory(path.dirname(file));
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
await handle.close().catch(() => undefined);
|
|
50
|
+
await fs.unlink(temporary).catch(() => undefined);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
/** Short storage transaction lock. Never hold across inference or tool execution. */
|
|
54
|
+
const localTransactions = new Map();
|
|
55
|
+
/** Probe an execution lock without relying on process IDs or waiting behind a live owner. */
|
|
56
|
+
export const tryStateLock = async (file, operation) => {
|
|
57
|
+
if (localTransactions.has(file))
|
|
58
|
+
return { acquired: false };
|
|
59
|
+
let entered = false;
|
|
60
|
+
try {
|
|
61
|
+
return { acquired: true, value: await withStateLock(file, async () => { entered = true; return operation(); }, 0) };
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (!entered && error.code === "SQLITE_BUSY")
|
|
65
|
+
return { acquired: false };
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
export const withStateLock = async (file, operation, timeoutMs = 10000) => {
|
|
70
|
+
const previous = localTransactions.get(file) ?? Promise.resolve();
|
|
71
|
+
let release;
|
|
72
|
+
const next = new Promise(resolve => { release = resolve; });
|
|
73
|
+
const tail = previous.then(() => next);
|
|
74
|
+
localTransactions.set(file, tail);
|
|
75
|
+
await previous;
|
|
76
|
+
try {
|
|
77
|
+
return await transact(file, operation, timeoutMs);
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
release();
|
|
81
|
+
if (localTransactions.get(file) === tail)
|
|
82
|
+
localTransactions.delete(file);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const transact = async (file, operation, timeoutMs) => {
|
|
86
|
+
await fs.mkdir(path.dirname(file), { recursive: true, mode: 0o700 });
|
|
87
|
+
// Reuse mcoda's SQLite dependency for an OS-owned transaction lock. A killed
|
|
88
|
+
// process releases it automatically, without PID reuse or stale recovery files.
|
|
89
|
+
const databasePath = `${file}.transactions.sqlite`;
|
|
90
|
+
for (const suffix of ["", "-wal", "-shm", "-journal"])
|
|
91
|
+
await assertRegularStateFile(databasePath + suffix);
|
|
92
|
+
const connection = await Connection.open(databasePath);
|
|
93
|
+
try {
|
|
94
|
+
await fs.chmod(databasePath, 0o600);
|
|
95
|
+
// Do not park SQLite busy handlers on libuv threads needed by the owner to
|
|
96
|
+
// finish its filesystem transaction. Retry asynchronously across processes.
|
|
97
|
+
await connection.db.exec("PRAGMA busy_timeout = 0;");
|
|
98
|
+
const deadline = Date.now() + timeoutMs;
|
|
99
|
+
while (true) {
|
|
100
|
+
try {
|
|
101
|
+
await connection.db.exec("BEGIN IMMEDIATE;");
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
if (error.code !== "SQLITE_BUSY" || Date.now() >= deadline)
|
|
106
|
+
throw error;
|
|
107
|
+
await new Promise(resolve => setTimeout(resolve, 20));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
const result = await operation();
|
|
112
|
+
await connection.db.exec("COMMIT;");
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
await connection.db.exec("ROLLBACK;").catch(() => undefined);
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
finally {
|
|
121
|
+
await connection.close();
|
|
122
|
+
}
|
|
123
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Existing state files must not alias another file or an external endpoint. */
|
|
2
|
+
export declare function assertRegularStateFile(file: string): Promise<void>;
|
|
3
|
+
/** Resolve trusted outer aliases (e.g. macOS /var) once, then reject symlinks
|
|
4
|
+
* beneath the storage boundary. The terminal sandbox prevents model processes
|
|
5
|
+
* from replacing these parents; this is not isolation from a hostile OS user. */
|
|
6
|
+
export declare function sessionStoragePath(options: {
|
|
7
|
+
workspaceRoot: string;
|
|
8
|
+
storageRoot: string;
|
|
9
|
+
file: string;
|
|
10
|
+
allowExternal: boolean;
|
|
11
|
+
createParents?: boolean;
|
|
12
|
+
directory?: boolean;
|
|
13
|
+
}): Promise<string>;
|
|
14
|
+
export declare function readStateFile(file: string): Promise<string>;
|
|
15
|
+
//# sourceMappingURL=SessionStoragePath.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionStoragePath.d.ts","sourceRoot":"","sources":["../../src/session/SessionStoragePath.ts"],"names":[],"mappings":"AAGA,gFAAgF;AAChF,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKxE;AAED;;iFAEiF;AACjF,wBAAsB,kBAAkB,CAAC,OAAO,EAAE;IAChD,aAAa,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAChI,GAAG,OAAO,CAAC,MAAM,CAAC,CAuClB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOjE"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { constants, promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
/** Existing state files must not alias another file or an external endpoint. */
|
|
4
|
+
export async function assertRegularStateFile(file) {
|
|
5
|
+
try {
|
|
6
|
+
const stat = await fs.lstat(file);
|
|
7
|
+
if (!stat.isFile() || stat.isSymbolicLink() || stat.nlink !== 1)
|
|
8
|
+
throw new Error(`Unsafe session state file: ${path.basename(file)}`);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
if (error.code !== "ENOENT")
|
|
12
|
+
throw error;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/** Resolve trusted outer aliases (e.g. macOS /var) once, then reject symlinks
|
|
16
|
+
* beneath the storage boundary. The terminal sandbox prevents model processes
|
|
17
|
+
* from replacing these parents; this is not isolation from a hostile OS user. */
|
|
18
|
+
export async function sessionStoragePath(options) {
|
|
19
|
+
const workspace = path.resolve(options.workspaceRoot);
|
|
20
|
+
const root = path.resolve(options.storageRoot);
|
|
21
|
+
const file = path.resolve(options.file);
|
|
22
|
+
const inside = (base, target) => target === base || target.startsWith(`${base}${path.sep}`);
|
|
23
|
+
if (!inside(root, file))
|
|
24
|
+
throw new Error("Session state path escapes its storage root");
|
|
25
|
+
let anchor;
|
|
26
|
+
if (inside(workspace, root))
|
|
27
|
+
anchor = workspace;
|
|
28
|
+
else {
|
|
29
|
+
if (!options.allowExternal)
|
|
30
|
+
throw new Error("Session storage path is outside workspace root");
|
|
31
|
+
// Only the host can select this external boundary. Existing outer aliases
|
|
32
|
+
// are trusted, while the root and all descendants must be real directories.
|
|
33
|
+
anchor = path.dirname(root);
|
|
34
|
+
while (true) {
|
|
35
|
+
try {
|
|
36
|
+
await fs.realpath(anchor);
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (error.code !== "ENOENT" || path.dirname(anchor) === anchor)
|
|
41
|
+
throw error;
|
|
42
|
+
anchor = path.dirname(anchor);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
let canonical = await fs.realpath(anchor);
|
|
47
|
+
const directory = options.directory ? file : path.dirname(file);
|
|
48
|
+
const relative = path.relative(anchor, directory);
|
|
49
|
+
if (relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative))
|
|
50
|
+
throw new Error("Invalid session storage boundary");
|
|
51
|
+
for (const component of relative.split(path.sep).filter(Boolean)) {
|
|
52
|
+
canonical = path.join(canonical, component);
|
|
53
|
+
let stat;
|
|
54
|
+
try {
|
|
55
|
+
stat = await fs.lstat(canonical);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
if (error.code !== "ENOENT" || !options.createParents)
|
|
59
|
+
throw error;
|
|
60
|
+
try {
|
|
61
|
+
await fs.mkdir(canonical, { mode: 0o700 });
|
|
62
|
+
}
|
|
63
|
+
catch (creation) {
|
|
64
|
+
if (creation.code !== "EEXIST")
|
|
65
|
+
throw creation;
|
|
66
|
+
}
|
|
67
|
+
stat = await fs.lstat(canonical);
|
|
68
|
+
}
|
|
69
|
+
if (!stat.isDirectory() || stat.isSymbolicLink())
|
|
70
|
+
throw new Error("Unsafe session storage directory");
|
|
71
|
+
}
|
|
72
|
+
if (options.directory)
|
|
73
|
+
return canonical;
|
|
74
|
+
const resolved = path.join(canonical, path.basename(file));
|
|
75
|
+
await assertRegularStateFile(resolved);
|
|
76
|
+
return resolved;
|
|
77
|
+
}
|
|
78
|
+
export async function readStateFile(file) {
|
|
79
|
+
const handle = await fs.open(file, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
80
|
+
try {
|
|
81
|
+
const stat = await handle.stat();
|
|
82
|
+
if (!stat.isFile() || stat.nlink !== 1)
|
|
83
|
+
throw new Error("Unsafe session state file");
|
|
84
|
+
return await handle.readFile("utf8");
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
await handle.close();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { WorkState } from "./WorkTypes.js";
|
|
1
2
|
export type CodaliSessionStatus = "active" | "paused" | "completed" | "failed";
|
|
2
3
|
export interface CodaliSessionMetadata {
|
|
3
4
|
schemaVersion: 1;
|
|
@@ -40,6 +41,8 @@ export interface CodaliResumeBundle {
|
|
|
40
41
|
export interface SessionStoreOptions {
|
|
41
42
|
workspaceRoot: string;
|
|
42
43
|
storageDir?: string;
|
|
44
|
+
/** Trusted host-only option. Repository configuration must never set this. */
|
|
45
|
+
allowExternalStorage?: boolean;
|
|
43
46
|
}
|
|
44
47
|
export interface CreateSessionInput {
|
|
45
48
|
sessionId?: string;
|
|
@@ -55,8 +58,10 @@ export declare class SessionStore {
|
|
|
55
58
|
readonly workspaceRoot: string;
|
|
56
59
|
readonly storageDir: string;
|
|
57
60
|
private lastTimestampMs;
|
|
61
|
+
private readonly allowExternalStorage;
|
|
58
62
|
constructor(options: SessionStoreOptions);
|
|
59
63
|
private rootDir;
|
|
64
|
+
private checkedPath;
|
|
60
65
|
private sessionDir;
|
|
61
66
|
private metadataPath;
|
|
62
67
|
private transcriptPath;
|
|
@@ -66,6 +71,7 @@ export declare class SessionStore {
|
|
|
66
71
|
readSession(sessionId: string): Promise<CodaliSessionMetadata>;
|
|
67
72
|
getOrCreateSession(input: CreateSessionInput): Promise<CodaliSessionMetadata>;
|
|
68
73
|
updateSession(sessionId: string, patch: Partial<Omit<CodaliSessionMetadata, "schemaVersion" | "sessionId" | "createdAt">>): Promise<CodaliSessionMetadata>;
|
|
74
|
+
private mutateSession;
|
|
69
75
|
addRun(sessionId: string, runId: string): Promise<CodaliSessionMetadata>;
|
|
70
76
|
appendTranscript(sessionId: string, event: Omit<CodaliSessionTranscriptEvent, "schemaVersion" | "sessionId" | "timestamp"> & {
|
|
71
77
|
timestamp?: string;
|
|
@@ -77,5 +83,8 @@ export declare class SessionStore {
|
|
|
77
83
|
buildResumeBundle(sessionId: string, options?: {
|
|
78
84
|
recentEvents?: number;
|
|
79
85
|
}): Promise<CodaliResumeBundle>;
|
|
86
|
+
initializeWork(sessionId: string, objective: string): Promise<WorkState>;
|
|
87
|
+
readWork(sessionId: string): Promise<WorkState>;
|
|
88
|
+
updateWork(sessionId: string, expectedRevision: number, mutate: (state: WorkState) => void): Promise<WorkState>;
|
|
80
89
|
}
|
|
81
90
|
//# sourceMappingURL=SessionStore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionStore.d.ts","sourceRoot":"","sources":["../../src/session/SessionStore.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SessionStore.d.ts","sourceRoot":"","sources":["../../src/session/SessionStore.ts"],"names":[],"mappings":"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"}
|