@cavelang/cli 0.29.1 → 0.31.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/README.md +15 -1
- package/dist/internal/act/engine.d.ts +5 -1
- package/dist/internal/act/engine.d.ts.map +1 -1
- package/dist/internal/act/engine.js +39 -32
- package/dist/internal/act/engine.js.map +1 -1
- package/dist/internal/automate/engine.d.ts +4 -0
- package/dist/internal/automate/engine.d.ts.map +1 -1
- package/dist/internal/automate/engine.js +31 -25
- package/dist/internal/automate/engine.js.map +1 -1
- package/dist/internal/automate/main.d.ts.map +1 -1
- package/dist/internal/automate/main.js +7 -4
- package/dist/internal/automate/main.js.map +1 -1
- package/dist/internal/eval/loop.d.ts +1 -0
- package/dist/internal/eval/loop.d.ts.map +1 -1
- package/dist/internal/eval/loop.js +2 -1
- package/dist/internal/eval/loop.js.map +1 -1
- package/dist/internal/eval/main.d.ts.map +1 -1
- package/dist/internal/eval/main.js +2 -1
- package/dist/internal/eval/main.js.map +1 -1
- package/dist/internal/eval/run.d.ts +2 -0
- package/dist/internal/eval/run.d.ts.map +1 -1
- package/dist/internal/eval/run.js +6 -4
- package/dist/internal/eval/run.js.map +1 -1
- package/dist/internal/ingest/index.d.ts +1 -1
- package/dist/internal/ingest/index.d.ts.map +1 -1
- package/dist/internal/ingest/index.js.map +1 -1
- package/dist/internal/ingest/main.d.ts.map +1 -1
- package/dist/internal/ingest/main.js +4 -2
- package/dist/internal/ingest/main.js.map +1 -1
- package/dist/internal/ingest/run.d.ts +8 -1
- package/dist/internal/ingest/run.d.ts.map +1 -1
- package/dist/internal/ingest/run.js +17 -34
- package/dist/internal/ingest/run.js.map +1 -1
- package/dist/internal/loop/index.d.ts +2 -0
- package/dist/internal/loop/index.d.ts.map +1 -1
- package/dist/internal/loop/index.js +1 -0
- package/dist/internal/loop/index.js.map +1 -1
- package/dist/internal/loop/llm.d.ts +6 -0
- package/dist/internal/loop/llm.d.ts.map +1 -1
- package/dist/internal/loop/llm.js +22 -49
- package/dist/internal/loop/llm.js.map +1 -1
- package/dist/internal/loop/process-worker.d.ts +3 -0
- package/dist/internal/loop/process-worker.d.ts.map +1 -0
- package/dist/internal/loop/process-worker.js +32 -0
- package/dist/internal/loop/process-worker.js.map +1 -0
- package/dist/internal/loop/process.d.ts +61 -0
- package/dist/internal/loop/process.d.ts.map +1 -0
- package/dist/internal/loop/process.js +268 -0
- package/dist/internal/loop/process.js.map +1 -0
- package/dist/internal/mcp/guide.d.ts +12 -0
- package/dist/internal/mcp/guide.d.ts.map +1 -0
- package/dist/internal/mcp/guide.js +56 -0
- package/dist/internal/mcp/guide.js.map +1 -0
- package/dist/internal/mcp/index.d.ts +2 -2
- package/dist/internal/mcp/index.d.ts.map +1 -1
- package/dist/internal/mcp/index.js +2 -2
- package/dist/internal/mcp/index.js.map +1 -1
- package/dist/internal/mcp/server.d.ts +36 -36
- package/dist/internal/mcp/server.d.ts.map +1 -1
- package/dist/internal/mcp/server.js +90 -141
- package/dist/internal/mcp/server.js.map +1 -1
- package/dist/internal/mcp/tools.d.ts +5 -1
- package/dist/internal/mcp/tools.d.ts.map +1 -1
- package/dist/internal/mcp/tools.js +26 -1
- package/dist/internal/mcp/tools.js.map +1 -1
- package/dist/internal/view/scope.d.ts +19 -4
- package/dist/internal/view/scope.d.ts.map +1 -1
- package/dist/internal/view/scope.js +115 -31
- package/dist/internal/view/scope.js.map +1 -1
- package/dist/src/cli.d.ts +6 -2
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +12 -5
- package/dist/src/cli.js.map +1 -1
- package/dist/src/dispatch.d.ts.map +1 -1
- package/dist/src/dispatch.js +2 -2
- package/dist/src/dispatch.js.map +1 -1
- package/dist/src/doctor.d.ts.map +1 -1
- package/dist/src/doctor.js +19 -7
- package/dist/src/doctor.js.map +1 -1
- package/package.json +22 -21
- package/src/cli.ts +18 -5
- package/src/dispatch.ts +4 -2
- package/src/doctor.ts +18 -7
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
* `cave ingest` and `cave eval` use — into a `Complete`, so no LLM SDK
|
|
30
30
|
* ever becomes a dependency of this package.
|
|
31
31
|
*/
|
|
32
|
-
import { spawn } from 'node:child_process';
|
|
33
32
|
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
34
33
|
import { tmpdir } from 'node:os';
|
|
35
34
|
import { join } from 'node:path';
|
|
36
35
|
import { emitClaim } from '@cavelang/canonical';
|
|
36
|
+
import { runProcess, shellCommand } from "./process.js";
|
|
37
37
|
/** The reply that ends the reconstruction. */
|
|
38
38
|
export const stopToken = 'STOP';
|
|
39
39
|
const defaultMaxCues = 16;
|
|
@@ -172,60 +172,33 @@ export const llmPolicy = (complete, options = {}) => {
|
|
|
172
172
|
*/
|
|
173
173
|
export const shellComplete = (template, options = {}) => {
|
|
174
174
|
const timeoutSeconds = options.timeoutSeconds ?? 120;
|
|
175
|
-
return
|
|
175
|
+
return async (prompt) => {
|
|
176
176
|
let dir;
|
|
177
|
-
|
|
177
|
+
const substitutions = {};
|
|
178
178
|
if (template.includes('{prompt-file}')) {
|
|
179
179
|
dir = mkdtempSync(join(tmpdir(), 'cave-loop-'));
|
|
180
180
|
const file = join(dir, 'prompt.md');
|
|
181
181
|
writeFileSync(file, prompt);
|
|
182
|
-
|
|
183
|
-
command = template.replaceAll('{prompt-file}', `'${file.replaceAll("'", `'\\''`)}'`);
|
|
182
|
+
substitutions['prompt-file'] = file;
|
|
184
183
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
finish();
|
|
184
|
+
try {
|
|
185
|
+
const result = await runProcess(shellCommand(template, substitutions), {
|
|
186
|
+
input: prompt,
|
|
187
|
+
timeoutMs: timeoutSeconds * 1000,
|
|
188
|
+
...options.cwd === undefined ? {} : { cwd: options.cwd },
|
|
189
|
+
...options.signal === undefined ? {} : { signal: options.signal },
|
|
190
|
+
...options.maxStdoutBytes === undefined ? {} : { maxStdoutBytes: options.maxStdoutBytes },
|
|
191
|
+
...options.maxStderrBytes === undefined ? {} : { maxStderrBytes: options.maxStderrBytes }
|
|
192
|
+
});
|
|
193
|
+
if (result.code !== 0) {
|
|
194
|
+
throw new Error(`agent exited with ${result.code ?? `signal ${result.signal}`}`);
|
|
197
195
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
let stdout = '';
|
|
206
|
-
child.stdout.on('data', chunk => {
|
|
207
|
-
stdout += String(chunk);
|
|
208
|
-
});
|
|
209
|
-
child.on('error', error => settle(() => rejectPromise(new Error(`agent failed: ${error.message}`))));
|
|
210
|
-
// A killed shell can leave grandchildren holding the stdio pipes open,
|
|
211
|
-
// so the signal path settles on `exit` — waiting for `close` would wait
|
|
212
|
-
// for processes the timeout was meant to cut loose.
|
|
213
|
-
child.on('exit', (_code, signal) => {
|
|
214
|
-
if (signal !== null) {
|
|
215
|
-
settle(() => rejectPromise(new Error(`agent killed by ${signal} after ${timeoutSeconds}s`)));
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
child.on('close', code => settle(() => {
|
|
219
|
-
if (code === 0) {
|
|
220
|
-
resolvePromise(stdout);
|
|
221
|
-
}
|
|
222
|
-
else {
|
|
223
|
-
rejectPromise(new Error(`agent exited with ${code}`));
|
|
224
|
-
}
|
|
225
|
-
}));
|
|
226
|
-
child.stdin.on('error', () => { });
|
|
227
|
-
child.stdin.write(prompt);
|
|
228
|
-
child.stdin.end();
|
|
229
|
-
});
|
|
196
|
+
return result.stdout;
|
|
197
|
+
}
|
|
198
|
+
finally {
|
|
199
|
+
if (dir !== undefined)
|
|
200
|
+
rmSync(dir, { recursive: true, force: true });
|
|
201
|
+
}
|
|
202
|
+
};
|
|
230
203
|
};
|
|
231
204
|
//# sourceMappingURL=llm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../../src/llm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../../src/llm.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-worker.d.ts","sourceRoot":"","sources":["../../src/process-worker.ts"],"names":[],"mappings":"AAAA,yDAAyD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Internal synchronous-bridge worker for process.ts. */
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { ProcessFailure, runProcess } from "./process.js";
|
|
4
|
+
const request = JSON.parse(readFileSync(0, 'utf8'));
|
|
5
|
+
const controller = new AbortController();
|
|
6
|
+
const abort = () => controller.abort();
|
|
7
|
+
process.once('SIGINT', abort);
|
|
8
|
+
process.once('SIGTERM', abort);
|
|
9
|
+
try {
|
|
10
|
+
const result = await runProcess(request.command, { ...request.options, signal: controller.signal });
|
|
11
|
+
process.stdout.write(JSON.stringify({ ok: true, result }));
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
if (error instanceof ProcessFailure) {
|
|
15
|
+
process.stdout.write(JSON.stringify({ ok: false, failure: error.toJSON() }));
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
process.stdout.write(JSON.stringify({
|
|
19
|
+
ok: false,
|
|
20
|
+
failure: {
|
|
21
|
+
kind: 'spawn',
|
|
22
|
+
message: 'process failed to start',
|
|
23
|
+
result: { code: null, signal: null, stdout: '', stderr: '' }
|
|
24
|
+
}
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
process.removeListener('SIGINT', abort);
|
|
30
|
+
process.removeListener('SIGTERM', abort);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=process-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-worker.js","sourceRoot":"","sources":["../../src/process-worker.ts"],"names":[],"mappings":"AAAA,yDAAyD;AAEzD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EACL,cAAc,EACd,UAAU,EAGX,MAAM,cAAc,CAAA;AAOrB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAY,CAAA;AAC9D,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;AACxC,MAAM,KAAK,GAAG,GAAS,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,CAAA;AAC5C,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;AAC7B,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;AAC9B,IAAI,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAA;IACnG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;AAC5D,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;QACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAA;IAC9E,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAClC,EAAE,EAAE,KAAK;YACT,OAAO,EAAE;gBACP,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;aAC7D;SACF,CAAC,CAAC,CAAA;IACL,CAAC;AACH,CAAC;QAAS,CAAC;IACT,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IACvC,OAAO,CAAC,cAAc,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;AAC1C,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** Portable, bounded external-process execution for CAVE integrations. */
|
|
2
|
+
export type ProcessCommand = {
|
|
3
|
+
readonly executable: string;
|
|
4
|
+
readonly args: readonly string[];
|
|
5
|
+
};
|
|
6
|
+
export type ShellSyntax = 'posix' | 'powershell';
|
|
7
|
+
export type ProcessResult = {
|
|
8
|
+
readonly code: number | null;
|
|
9
|
+
readonly signal: NodeJS.Signals | null;
|
|
10
|
+
readonly stdout: string;
|
|
11
|
+
readonly stderr: string;
|
|
12
|
+
};
|
|
13
|
+
export type ProcessFailureKind = 'spawn' | 'timeout' | 'aborted' | 'stdout-limit' | 'stderr-limit';
|
|
14
|
+
export type ProcessFailureRecord = {
|
|
15
|
+
readonly kind: ProcessFailureKind;
|
|
16
|
+
readonly message: string;
|
|
17
|
+
readonly result: ProcessResult;
|
|
18
|
+
readonly limit?: number;
|
|
19
|
+
readonly errorCode?: string;
|
|
20
|
+
};
|
|
21
|
+
/** Typed, command-redacted failure for resource and lifecycle errors. */
|
|
22
|
+
export declare class ProcessFailure extends Error {
|
|
23
|
+
readonly name = "ProcessFailure";
|
|
24
|
+
readonly kind: ProcessFailureKind;
|
|
25
|
+
readonly result: ProcessResult;
|
|
26
|
+
readonly limit?: number;
|
|
27
|
+
readonly errorCode?: string;
|
|
28
|
+
constructor(record: ProcessFailureRecord);
|
|
29
|
+
toJSON(): ProcessFailureRecord;
|
|
30
|
+
}
|
|
31
|
+
export type ProcessOptions = {
|
|
32
|
+
readonly cwd?: string;
|
|
33
|
+
readonly input?: string;
|
|
34
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
35
|
+
readonly timeoutMs?: number;
|
|
36
|
+
readonly signal?: AbortSignal;
|
|
37
|
+
readonly maxStdoutBytes?: number;
|
|
38
|
+
readonly maxStderrBytes?: number;
|
|
39
|
+
};
|
|
40
|
+
export type SyncProcessOptions = Omit<ProcessOptions, 'signal'>;
|
|
41
|
+
export declare const defaultMaxStdoutBytes: number;
|
|
42
|
+
export declare const defaultMaxStderrBytes: number;
|
|
43
|
+
export declare const directCommand: (executable: string, args?: readonly string[]) => ProcessCommand;
|
|
44
|
+
export declare const shellSyntaxFor: (platform?: NodeJS.Platform) => ShellSyntax;
|
|
45
|
+
/** Quote one value as one argument for the selected intentional shell. */
|
|
46
|
+
export declare const quoteShellArgument: (value: string, syntax?: ShellSyntax) => string;
|
|
47
|
+
/** Substitute known placeholders once; unknown placeholders remain literal. */
|
|
48
|
+
export declare const substituteShell: (template: string, substitutions: Readonly<Record<string, string>>, syntax?: ShellSyntax) => string;
|
|
49
|
+
/**
|
|
50
|
+
* Make an intentional shell command explicit. POSIX uses `/bin/sh`; Windows
|
|
51
|
+
* uses PowerShell 7. The shell itself is still spawned with `shell:false`.
|
|
52
|
+
*/
|
|
53
|
+
export declare const shellCommand: (template: string, substitutions?: Readonly<Record<string, string>>, platform?: NodeJS.Platform) => ProcessCommand;
|
|
54
|
+
/** Run an executable plus argument array with bounded output and tree cleanup. */
|
|
55
|
+
export declare const runProcess: (command: ProcessCommand, options?: ProcessOptions) => Promise<ProcessResult>;
|
|
56
|
+
/**
|
|
57
|
+
* Synchronous bridge for compatibility-sensitive APIs. A short-lived Node
|
|
58
|
+
* worker owns the asynchronous tree cleanup, then returns one bounded result.
|
|
59
|
+
*/
|
|
60
|
+
export declare const runProcessSync: (command: ProcessCommand, options?: SyncProcessOptions) => ProcessResult;
|
|
61
|
+
//# sourceMappingURL=process.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/process.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/** Portable, bounded external-process execution for CAVE integrations. */
|
|
2
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
/** Typed, command-redacted failure for resource and lifecycle errors. */
|
|
5
|
+
export class ProcessFailure extends Error {
|
|
6
|
+
name = 'ProcessFailure';
|
|
7
|
+
kind;
|
|
8
|
+
result;
|
|
9
|
+
limit;
|
|
10
|
+
errorCode;
|
|
11
|
+
constructor(record) {
|
|
12
|
+
super(record.message);
|
|
13
|
+
this.kind = record.kind;
|
|
14
|
+
this.result = record.result;
|
|
15
|
+
this.limit = record.limit;
|
|
16
|
+
this.errorCode = record.errorCode;
|
|
17
|
+
}
|
|
18
|
+
toJSON() {
|
|
19
|
+
return {
|
|
20
|
+
kind: this.kind,
|
|
21
|
+
message: this.message,
|
|
22
|
+
result: this.result,
|
|
23
|
+
...this.limit === undefined ? {} : { limit: this.limit },
|
|
24
|
+
...this.errorCode === undefined ? {} : { errorCode: this.errorCode }
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export const defaultMaxStdoutBytes = 8 * 1024 * 1024;
|
|
29
|
+
export const defaultMaxStderrBytes = 1024 * 1024;
|
|
30
|
+
export const directCommand = (executable, args = []) => ({ executable, args });
|
|
31
|
+
export const shellSyntaxFor = (platform = process.platform) => platform === 'win32' ? 'powershell' : 'posix';
|
|
32
|
+
/** Quote one value as one argument for the selected intentional shell. */
|
|
33
|
+
export const quoteShellArgument = (value, syntax = shellSyntaxFor()) => syntax === 'powershell' ? `'${value.replaceAll("'", "''")}'` : `'${value.replaceAll("'", `'\\''`)}'`;
|
|
34
|
+
/** Substitute known placeholders once; unknown placeholders remain literal. */
|
|
35
|
+
export const substituteShell = (template, substitutions, syntax = shellSyntaxFor()) => template.replace(/\{([A-Za-z][A-Za-z0-9_-]*)\}/g, (whole, name) => Object.hasOwn(substitutions, name) ? quoteShellArgument(substitutions[name], syntax) : whole);
|
|
36
|
+
const powershellScript = (command) => [
|
|
37
|
+
'$global:LASTEXITCODE = $null',
|
|
38
|
+
command,
|
|
39
|
+
'$caveSucceeded = $?',
|
|
40
|
+
'$caveExitCode = $global:LASTEXITCODE',
|
|
41
|
+
'if ($caveSucceeded) { exit 0 }',
|
|
42
|
+
'if ($null -ne $caveExitCode) { exit $caveExitCode }',
|
|
43
|
+
'exit 1'
|
|
44
|
+
].join('\n');
|
|
45
|
+
/**
|
|
46
|
+
* Make an intentional shell command explicit. POSIX uses `/bin/sh`; Windows
|
|
47
|
+
* uses PowerShell 7. The shell itself is still spawned with `shell:false`.
|
|
48
|
+
*/
|
|
49
|
+
export const shellCommand = (template, substitutions = {}, platform = process.platform) => {
|
|
50
|
+
const syntax = shellSyntaxFor(platform);
|
|
51
|
+
const command = substituteShell(template, substitutions, syntax);
|
|
52
|
+
// EncodedCommand transports the exact UTF-16LE script without a native argv
|
|
53
|
+
// reparse. PowerShell 7 is required for standard native argument passing;
|
|
54
|
+
// Windows PowerShell 5.1 corrupts embedded quotes passed to executables. The
|
|
55
|
+
// wrapper preserves the last native command's exact non-zero exit code.
|
|
56
|
+
return platform === 'win32' ?
|
|
57
|
+
directCommand('pwsh.exe', [
|
|
58
|
+
'-NoLogo', '-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass',
|
|
59
|
+
'-EncodedCommand', Buffer.from(powershellScript(command), 'utf16le').toString('base64')
|
|
60
|
+
]) :
|
|
61
|
+
directCommand('/bin/sh', ['-c', command]);
|
|
62
|
+
};
|
|
63
|
+
const emptyResult = () => ({ code: null, signal: null, stdout: '', stderr: '' });
|
|
64
|
+
const positiveLimit = (value, fallback, name) => {
|
|
65
|
+
const result = value ?? fallback;
|
|
66
|
+
if (!Number.isSafeInteger(result) || result < 0) {
|
|
67
|
+
throw new TypeError(`${name} must be a non-negative safe integer`);
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
};
|
|
71
|
+
const killTree = (child) => {
|
|
72
|
+
const pid = child.pid;
|
|
73
|
+
if (pid === undefined)
|
|
74
|
+
return Promise.resolve();
|
|
75
|
+
if (process.platform !== 'win32') {
|
|
76
|
+
try {
|
|
77
|
+
process.kill(-pid, 'SIGKILL');
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
try {
|
|
81
|
+
child.kill('SIGKILL');
|
|
82
|
+
}
|
|
83
|
+
catch { /* already gone */ }
|
|
84
|
+
}
|
|
85
|
+
return Promise.resolve();
|
|
86
|
+
}
|
|
87
|
+
return new Promise(resolve => {
|
|
88
|
+
const killer = spawn('taskkill.exe', ['/pid', String(pid), '/t', '/f'], {
|
|
89
|
+
shell: false,
|
|
90
|
+
stdio: 'ignore',
|
|
91
|
+
windowsHide: true
|
|
92
|
+
});
|
|
93
|
+
killer.once('error', () => {
|
|
94
|
+
try {
|
|
95
|
+
child.kill('SIGKILL');
|
|
96
|
+
}
|
|
97
|
+
catch { /* already gone */ }
|
|
98
|
+
resolve();
|
|
99
|
+
});
|
|
100
|
+
killer.once('close', () => resolve());
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
const failureMessage = (kind, timeoutMs, limit) => {
|
|
104
|
+
switch (kind) {
|
|
105
|
+
case 'spawn': return 'process failed to start';
|
|
106
|
+
case 'timeout': return `process timed out after ${timeoutMs}ms`;
|
|
107
|
+
case 'aborted': return 'process was cancelled';
|
|
108
|
+
case 'stdout-limit': return `process stdout exceeded ${limit} bytes`;
|
|
109
|
+
case 'stderr-limit': return `process stderr exceeded ${limit} bytes`;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
/** Run an executable plus argument array with bounded output and tree cleanup. */
|
|
113
|
+
export const runProcess = (command, options = {}) => {
|
|
114
|
+
const stdoutLimit = positiveLimit(options.maxStdoutBytes, defaultMaxStdoutBytes, 'maxStdoutBytes');
|
|
115
|
+
const stderrLimit = positiveLimit(options.maxStderrBytes, defaultMaxStderrBytes, 'maxStderrBytes');
|
|
116
|
+
const timeoutMs = positiveLimit(options.timeoutMs, 0, 'timeoutMs');
|
|
117
|
+
if (options.signal?.aborted === true) {
|
|
118
|
+
return Promise.reject(new ProcessFailure({
|
|
119
|
+
kind: 'aborted', message: failureMessage('aborted', timeoutMs), result: emptyResult()
|
|
120
|
+
}));
|
|
121
|
+
}
|
|
122
|
+
return new Promise((resolve, reject) => {
|
|
123
|
+
const stdout = [];
|
|
124
|
+
const stderr = [];
|
|
125
|
+
let stdoutBytes = 0;
|
|
126
|
+
let stderrBytes = 0;
|
|
127
|
+
let code = null;
|
|
128
|
+
let exitSignal = null;
|
|
129
|
+
let settled = false;
|
|
130
|
+
let terminating = false;
|
|
131
|
+
let timer;
|
|
132
|
+
let spawnErrorCode;
|
|
133
|
+
const child = spawn(command.executable, [...command.args], {
|
|
134
|
+
shell: false,
|
|
135
|
+
detached: process.platform !== 'win32',
|
|
136
|
+
windowsHide: true,
|
|
137
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
138
|
+
...options.cwd === undefined ? {} : { cwd: options.cwd },
|
|
139
|
+
...options.env === undefined ? {} : { env: options.env }
|
|
140
|
+
});
|
|
141
|
+
const result = () => ({
|
|
142
|
+
code,
|
|
143
|
+
signal: exitSignal,
|
|
144
|
+
stdout: Buffer.concat(stdout).toString('utf8'),
|
|
145
|
+
stderr: Buffer.concat(stderr).toString('utf8')
|
|
146
|
+
});
|
|
147
|
+
const cleanup = () => {
|
|
148
|
+
if (timer !== undefined)
|
|
149
|
+
clearTimeout(timer);
|
|
150
|
+
options.signal?.removeEventListener('abort', abort);
|
|
151
|
+
};
|
|
152
|
+
const finish = (failure) => {
|
|
153
|
+
if (settled)
|
|
154
|
+
return;
|
|
155
|
+
settled = true;
|
|
156
|
+
cleanup();
|
|
157
|
+
child.stdin?.destroy();
|
|
158
|
+
child.stdout?.destroy();
|
|
159
|
+
child.stderr?.destroy();
|
|
160
|
+
if (failure === undefined)
|
|
161
|
+
resolve(result());
|
|
162
|
+
else
|
|
163
|
+
reject(failure);
|
|
164
|
+
};
|
|
165
|
+
const terminate = (kind, limit) => {
|
|
166
|
+
if (settled || terminating)
|
|
167
|
+
return;
|
|
168
|
+
terminating = true;
|
|
169
|
+
void killTree(child).finally(() => finish(new ProcessFailure({
|
|
170
|
+
kind,
|
|
171
|
+
message: failureMessage(kind, timeoutMs, limit),
|
|
172
|
+
result: result(),
|
|
173
|
+
...limit === undefined ? {} : { limit }
|
|
174
|
+
})));
|
|
175
|
+
};
|
|
176
|
+
const abort = () => terminate('aborted');
|
|
177
|
+
const collect = (stream, chunk) => {
|
|
178
|
+
if (terminating || settled)
|
|
179
|
+
return;
|
|
180
|
+
const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
181
|
+
const limit = stream === 'stdout' ? stdoutLimit : stderrLimit;
|
|
182
|
+
const used = stream === 'stdout' ? stdoutBytes : stderrBytes;
|
|
183
|
+
const remaining = Math.max(0, limit - used);
|
|
184
|
+
if (remaining > 0)
|
|
185
|
+
(stream === 'stdout' ? stdout : stderr).push(bytes.subarray(0, remaining));
|
|
186
|
+
if (stream === 'stdout')
|
|
187
|
+
stdoutBytes += Math.min(bytes.length, remaining);
|
|
188
|
+
else
|
|
189
|
+
stderrBytes += Math.min(bytes.length, remaining);
|
|
190
|
+
if (bytes.length > remaining)
|
|
191
|
+
terminate(stream === 'stdout' ? 'stdout-limit' : 'stderr-limit', limit);
|
|
192
|
+
};
|
|
193
|
+
child.stdout?.on('data', chunk => collect('stdout', chunk));
|
|
194
|
+
child.stderr?.on('data', chunk => collect('stderr', chunk));
|
|
195
|
+
child.on('error', (error) => {
|
|
196
|
+
if (terminating)
|
|
197
|
+
return;
|
|
198
|
+
spawnErrorCode = error.code;
|
|
199
|
+
finish(new ProcessFailure({
|
|
200
|
+
kind: 'spawn',
|
|
201
|
+
message: failureMessage('spawn', timeoutMs),
|
|
202
|
+
result: result(),
|
|
203
|
+
...spawnErrorCode === undefined ? {} : { errorCode: spawnErrorCode }
|
|
204
|
+
}));
|
|
205
|
+
});
|
|
206
|
+
child.on('exit', (observedCode, observedSignal) => {
|
|
207
|
+
code = observedCode;
|
|
208
|
+
exitSignal = observedSignal;
|
|
209
|
+
});
|
|
210
|
+
child.on('close', (observedCode, observedSignal) => {
|
|
211
|
+
code = observedCode;
|
|
212
|
+
exitSignal = observedSignal;
|
|
213
|
+
if (!terminating)
|
|
214
|
+
finish();
|
|
215
|
+
});
|
|
216
|
+
child.stdin?.on('error', () => { });
|
|
217
|
+
if (options.input !== undefined)
|
|
218
|
+
child.stdin?.end(options.input);
|
|
219
|
+
else
|
|
220
|
+
child.stdin?.end();
|
|
221
|
+
if (timeoutMs > 0)
|
|
222
|
+
timer = setTimeout(() => terminate('timeout'), timeoutMs);
|
|
223
|
+
options.signal?.addEventListener('abort', abort, { once: true });
|
|
224
|
+
// Close the check/listener race if cancellation landed during spawn setup.
|
|
225
|
+
if (options.signal?.aborted === true)
|
|
226
|
+
abort();
|
|
227
|
+
});
|
|
228
|
+
};
|
|
229
|
+
/**
|
|
230
|
+
* Synchronous bridge for compatibility-sensitive APIs. A short-lived Node
|
|
231
|
+
* worker owns the asynchronous tree cleanup, then returns one bounded result.
|
|
232
|
+
*/
|
|
233
|
+
export const runProcessSync = (command, options = {}) => {
|
|
234
|
+
const stdoutLimit = positiveLimit(options.maxStdoutBytes, defaultMaxStdoutBytes, 'maxStdoutBytes');
|
|
235
|
+
const stderrLimit = positiveLimit(options.maxStderrBytes, defaultMaxStderrBytes, 'maxStderrBytes');
|
|
236
|
+
const timeoutMs = positiveLimit(options.timeoutMs, 0, 'timeoutMs');
|
|
237
|
+
const extension = import.meta.url.endsWith('.ts') ? 'ts' : 'js';
|
|
238
|
+
const worker = fileURLToPath(new URL(`./process-worker.${extension}`, import.meta.url));
|
|
239
|
+
const result = spawnSync(process.execPath, ['--disable-warning=ExperimentalWarning', worker], {
|
|
240
|
+
shell: false,
|
|
241
|
+
windowsHide: true,
|
|
242
|
+
encoding: 'utf8',
|
|
243
|
+
input: JSON.stringify({ command, options: { ...options, maxStdoutBytes: stdoutLimit, maxStderrBytes: stderrLimit } }),
|
|
244
|
+
// JSON can expand a captured control byte to a six-byte `\\u00xx` escape.
|
|
245
|
+
maxBuffer: Math.max(1024 * 1024, (stdoutLimit + stderrLimit) * 7 + 1024 * 1024),
|
|
246
|
+
timeout: timeoutMs > 0 ? timeoutMs + 5_000 : undefined
|
|
247
|
+
});
|
|
248
|
+
if (result.status !== 0 || result.error !== undefined) {
|
|
249
|
+
const errorCode = result.error?.code;
|
|
250
|
+
throw new ProcessFailure({
|
|
251
|
+
kind: errorCode === 'ETIMEDOUT' ? 'timeout' : 'spawn',
|
|
252
|
+
message: failureMessage(errorCode === 'ETIMEDOUT' ? 'timeout' : 'spawn', timeoutMs),
|
|
253
|
+
result: emptyResult(),
|
|
254
|
+
...errorCode === undefined ? {} : { errorCode }
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
let response;
|
|
258
|
+
try {
|
|
259
|
+
response = JSON.parse(result.stdout);
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
throw new ProcessFailure({ kind: 'spawn', message: failureMessage('spawn', timeoutMs), result: emptyResult() });
|
|
263
|
+
}
|
|
264
|
+
if (!response.ok)
|
|
265
|
+
throw new ProcessFailure(response.failure);
|
|
266
|
+
return response.result;
|
|
267
|
+
};
|
|
268
|
+
//# sourceMappingURL=process.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/process.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact, version-matched operating guidance for agents using CAVE.
|
|
3
|
+
*
|
|
4
|
+
* Keep this task-oriented. The normative language specification lives in
|
|
5
|
+
* `.claude/skills/cave-*`; this guide answers the smaller question an MCP
|
|
6
|
+
* client has at the point of use: which tool should I call, and what must I
|
|
7
|
+
* preserve when I write or revise knowledge?
|
|
8
|
+
*/
|
|
9
|
+
export declare const guideTopics: readonly ["overview", "write", "find", "revise", "safety"];
|
|
10
|
+
export type GuideTopic = typeof guideTopics[number];
|
|
11
|
+
export declare const guideFor: (topic?: GuideTopic) => string;
|
|
12
|
+
//# sourceMappingURL=guide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guide.d.ts","sourceRoot":"","sources":["../../src/guide.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,WAAW,4DAA6D,CAAA;AACrF,MAAM,MAAM,UAAU,GAAG,OAAO,WAAW,CAAC,MAAM,CAAC,CAAA;AAoDnD,eAAO,MAAM,QAAQ,GAAI,QAAO,UAAuB,KAAG,MAAuB,CAAA"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact, version-matched operating guidance for agents using CAVE.
|
|
3
|
+
*
|
|
4
|
+
* Keep this task-oriented. The normative language specification lives in
|
|
5
|
+
* `.claude/skills/cave-*`; this guide answers the smaller question an MCP
|
|
6
|
+
* client has at the point of use: which tool should I call, and what must I
|
|
7
|
+
* preserve when I write or revise knowledge?
|
|
8
|
+
*/
|
|
9
|
+
export const guideTopics = ['overview', 'write', 'find', 'revise', 'safety'];
|
|
10
|
+
const guides = {
|
|
11
|
+
overview: `CAVE is durable, local agent memory: atomic claims in an append-only SQLite database.
|
|
12
|
+
|
|
13
|
+
Typical workflow:
|
|
14
|
+
1. Recall before reasoning: use cave_about for one entity, cave_query for a known relation, cave_search for unknown wording, or cave_reconstruct for multi-hop context.
|
|
15
|
+
2. Record durable facts, decisions, constraints and outcomes as one CAVE claim per line. Use cave_lint before cave_add when composing unfamiliar syntax.
|
|
16
|
+
3. Preserve uncertainty and provenance. Prefer a qualified claim over prose that hides who said it or how certain it is.
|
|
17
|
+
4. Revise by appending the same claim identity with a new confidence. Do not expect edits or current-only views to erase history.
|
|
18
|
+
|
|
19
|
+
Ask cave_help for one of these topics: write, find, revise, safety.`,
|
|
20
|
+
write: `Write one fact per line:
|
|
21
|
+
subject VERB [NOT] object [@context...] [#tag[:value]...] [@ N%] [!] [; comment]
|
|
22
|
+
subject HAS attribute: value [+/- delta] [@context...] [#tag[:value]...] [@ N%] [!] [; comment]
|
|
23
|
+
|
|
24
|
+
Examples:
|
|
25
|
+
auth/middleware USES jwt @ 90%
|
|
26
|
+
deploy/2026-07-25 YIELDS api/v2 @src:release-notes
|
|
27
|
+
checkout/errors CAUSE retry-storm @production @ 70% #topic:reliability
|
|
28
|
+
OpenAI HAS revenue: ~20B USD/yr +/- 2B USD/yr @2026-Q1 @ 90%
|
|
29
|
+
|
|
30
|
+
Use kebab-case entities with / for scope, UPPERCASE verbs, @ctx without a space for context, and @ 90% with a space for confidence. Keep source citations in @src: contexts. The MCP server stamps an agent source when cave_add receives no @src:. Use cave_lint, then cave_add.`,
|
|
31
|
+
find: `Choose the narrowest retrieval tool that fits:
|
|
32
|
+
- cave_about: all current claims mentioning a known entity, in either direction.
|
|
33
|
+
- cave_query: a known CAVE-Q shape, such as ?service USES redis or ?ancestor PARENT-OF+ me. Add WHERE conf >= 0.7 when confidence matters.
|
|
34
|
+
- cave_search: literal full-text discovery when entity or verb spelling is unknown.
|
|
35
|
+
- cave_neighbors: inspect named forward and inverse graph edges while walking manually.
|
|
36
|
+
- cave_reconstruct: collect bounded multi-hop context around one or more seed entities before broader reasoning.
|
|
37
|
+
- cave_export: portable canonical text; current=true omits superseded beliefs but does not erase history.
|
|
38
|
+
|
|
39
|
+
Set aliases=true only when equivalent names should match. Set resolve=true when the task needs the policy-selected winner rather than all coexisting sources. Use asOf for past belief time and at for valid time in the world.`,
|
|
40
|
+
revise: `CAVE is append-only. A claim's identity includes its subject, verb, object/value and non-source contexts; @src: distinguishes voices.
|
|
41
|
+
|
|
42
|
+
To update confidence, append the same claim and the same @src: with a new confidence:
|
|
43
|
+
api/gateway USES redis @src:architecture-review @ 90%
|
|
44
|
+
|
|
45
|
+
To retract that belief, append the same identity at zero confidence:
|
|
46
|
+
api/gateway USES redis @src:architecture-review @ 0% ; superseded by current design
|
|
47
|
+
|
|
48
|
+
Do not silently replace one source with another. Conflicting claims may coexist. Query with resolve=true only when a single policy-ranked answer is required. Run cave_derive after adding or changing premises when stored rules should materialize conclusions. Prefer generated act_<name> tools over free-form cave_add when a declared governed action fits.`,
|
|
49
|
+
safety: `CAVE preserves history. Retraction, current-only queries, resolution and sensitivity filters change what is shown or believed; they do not guarantee erasure from SQLite remnants, exports, sync peers or backups.
|
|
50
|
+
|
|
51
|
+
Never store credentials, private keys, tokens, or information whose retention policy requires selective deletion. If a secret is ingested, rotate it, stop propagation, inventory every database/export/backup, rebuild from reviewed safe input, and destroy or expire affected copies.
|
|
52
|
+
|
|
53
|
+
Use #sensitivity:public, internal, confidential or restricted where disclosure scope matters. Unlabelled claims default to internal on publication surfaces. Use maxSensitivity deliberately when exporting. Treat act_<name> tools as effect-capable even though their knowledge effects are governed and atomic.`
|
|
54
|
+
};
|
|
55
|
+
export const guideFor = (topic = 'overview') => guides[topic];
|
|
56
|
+
//# sourceMappingURL=guide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guide.js","sourceRoot":"","sources":["../../src/guide.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAU,CAAA;AAGrF,MAAM,MAAM,GAAyC;IACnD,QAAQ,EAAE;;;;;;;;oEAQwD;IAElE,KAAK,EAAE;;;;;;;;;;kRAUyQ;IAEhR,IAAI,EAAE;;;;;;;;gOAQwN;IAE9N,MAAM,EAAE;;;;;;;;kWAQwV;IAEhW,MAAM,EAAE;;;;mTAIyS;CAClT,CAAA;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,QAAoB,UAAU,EAAU,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* { "command": "cave", "args": ["mcp", "--db", "knowledge.db"] }
|
|
7
7
|
* ```
|
|
8
8
|
*
|
|
9
|
-
* Tools: cave_add, cave_query, cave_fuse, cave_search, cave_about,
|
|
9
|
+
* Tools: cave_help, cave_add, cave_query, cave_fuse, cave_search, cave_about,
|
|
10
10
|
* cave_neighbors, cave_reconstruct, cave_derive, cave_export, cave_lint —
|
|
11
11
|
* plus one generated `act_<name>` tool per action declared in the store
|
|
12
12
|
* (spec §25.5), the governed write vocabulary. `cave_fuse` and
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* `--tools <list>` narrow the served surface — the minimum viable agent
|
|
18
18
|
* permission boundary.
|
|
19
19
|
*/
|
|
20
|
-
export { agentSource, createServer, serve, instructions, instructionsFor, protocolVersion, serverInfo, specCard } from './server.ts';
|
|
20
|
+
export { agentSource, createServer, serve, instructions, instructionsFor, protocolVersion, protocolVersions, serverInfo, specCard } from './server.ts';
|
|
21
21
|
export type { ServerOptions } from './server.ts';
|
|
22
22
|
export { runMcp } from './main.ts';
|
|
23
23
|
export { actionTools, actToolName, actToolPrefix, allowsActions, permissions, scopedActionTools, scopedTools, tools } from './tools.ts';
|