@ccdd/project 2.0.1
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 +25 -0
- package/dist/monitor-ui/assets/GraphView-CYMJ1Nb7.css +1 -0
- package/dist/monitor-ui/assets/GraphView-UjtW4QRC.js +27 -0
- package/dist/monitor-ui/assets/ValidationView-CC1FvqUl.js +1 -0
- package/dist/monitor-ui/assets/ValidationView-DWl4b8Ug.css +1 -0
- package/dist/monitor-ui/assets/_plugin-vue_export-helper-BDNMzG2s.js +1 -0
- package/dist/monitor-ui/assets/elk-api-yRi2AOS6.js +1 -0
- package/dist/monitor-ui/assets/elk.bundled-CtLobQTy.js +24 -0
- package/dist/monitor-ui/assets/graph-layout-worker-CgfWoa9t.js +22 -0
- package/dist/monitor-ui/assets/index-CUzg-dht.css +1 -0
- package/dist/monitor-ui/assets/index-Cpm0fC0p.js +8 -0
- package/dist/monitor-ui/index.html +15 -0
- package/dist/scripts/prepare-demo.d.ts +26 -0
- package/dist/scripts/prepare-demo.js +121 -0
- package/dist/scripts/prepare-demo.js.map +1 -0
- package/dist/src/artifacts/groups.d.ts +9 -0
- package/dist/src/artifacts/groups.js +77 -0
- package/dist/src/artifacts/groups.js.map +1 -0
- package/dist/src/artifacts/human.d.ts +38 -0
- package/dist/src/artifacts/human.js +156 -0
- package/dist/src/artifacts/human.js.map +1 -0
- package/dist/src/artifacts/index.d.ts +149 -0
- package/dist/src/artifacts/index.js +354 -0
- package/dist/src/artifacts/index.js.map +1 -0
- package/dist/src/artifacts/instruction.d.ts +23 -0
- package/dist/src/artifacts/instruction.js +94 -0
- package/dist/src/artifacts/instruction.js.map +1 -0
- package/dist/src/artifacts/mcp-server.d.ts +6 -0
- package/dist/src/artifacts/mcp-server.js +96 -0
- package/dist/src/artifacts/mcp-server.js.map +1 -0
- package/dist/src/artifacts/tool-check.d.ts +40 -0
- package/dist/src/artifacts/tool-check.js +113 -0
- package/dist/src/artifacts/tool-check.js.map +1 -0
- package/dist/src/artifacts/types.d.ts +43 -0
- package/dist/src/artifacts/types.js +97 -0
- package/dist/src/artifacts/types.js.map +1 -0
- package/dist/src/broker/config.d.ts +11 -0
- package/dist/src/broker/config.js +141 -0
- package/dist/src/broker/config.js.map +1 -0
- package/dist/src/broker/graph.d.ts +69 -0
- package/dist/src/broker/graph.js +94 -0
- package/dist/src/broker/graph.js.map +1 -0
- package/dist/src/broker/index.d.ts +170 -0
- package/dist/src/broker/index.js +931 -0
- package/dist/src/broker/index.js.map +1 -0
- package/dist/src/cli.d.ts +24 -0
- package/dist/src/cli.js +340 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/contracts.d.ts +116 -0
- package/dist/src/contracts.js +2 -0
- package/dist/src/contracts.js.map +1 -0
- package/dist/src/definitions.d.ts +53 -0
- package/dist/src/definitions.js +2 -0
- package/dist/src/definitions.js.map +1 -0
- package/dist/src/doctor/index.d.ts +41 -0
- package/dist/src/doctor/index.js +189 -0
- package/dist/src/doctor/index.js.map +1 -0
- package/dist/src/executors/auth.d.ts +16 -0
- package/dist/src/executors/auth.js +150 -0
- package/dist/src/executors/auth.js.map +1 -0
- package/dist/src/executors/errors.d.ts +6 -0
- package/dist/src/executors/errors.js +10 -0
- package/dist/src/executors/errors.js.map +1 -0
- package/dist/src/executors/index.d.ts +20 -0
- package/dist/src/executors/index.js +262 -0
- package/dist/src/executors/index.js.map +1 -0
- package/dist/src/executors/pi.d.ts +32 -0
- package/dist/src/executors/pi.js +190 -0
- package/dist/src/executors/pi.js.map +1 -0
- package/dist/src/executors/process.d.ts +22 -0
- package/dist/src/executors/process.js +70 -0
- package/dist/src/executors/process.js.map +1 -0
- package/dist/src/local.d.ts +13 -0
- package/dist/src/local.js +20 -0
- package/dist/src/local.js.map +1 -0
- package/dist/src/monitor/actions.d.ts +12 -0
- package/dist/src/monitor/actions.js +74 -0
- package/dist/src/monitor/actions.js.map +1 -0
- package/dist/src/monitor/server.d.ts +8 -0
- package/dist/src/monitor/server.js +493 -0
- package/dist/src/monitor/server.js.map +1 -0
- package/dist/src/monitor/store.d.ts +22 -0
- package/dist/src/monitor/store.js +517 -0
- package/dist/src/monitor/store.js.map +1 -0
- package/dist/src/monitor/types.d.ts +143 -0
- package/dist/src/monitor/types.js +2 -0
- package/dist/src/monitor/types.js.map +1 -0
- package/dist/src/monitor/ui/api.d.ts +11 -0
- package/dist/src/monitor/ui/api.js +29 -0
- package/dist/src/monitor/ui/api.js.map +1 -0
- package/dist/src/monitor/ui/critic-presentation.d.ts +11 -0
- package/dist/src/monitor/ui/critic-presentation.js +60 -0
- package/dist/src/monitor/ui/critic-presentation.js.map +1 -0
- package/dist/src/monitor/ui/format.d.ts +9 -0
- package/dist/src/monitor/ui/format.js +22 -0
- package/dist/src/monitor/ui/format.js.map +1 -0
- package/dist/src/monitor/ui/graph-layout.d.ts +43 -0
- package/dist/src/monitor/ui/graph-layout.js +191 -0
- package/dist/src/monitor/ui/graph-layout.js.map +1 -0
- package/dist/src/monitor/ui/tool-content.d.ts +13 -0
- package/dist/src/monitor/ui/tool-content.js +22 -0
- package/dist/src/monitor/ui/tool-content.js.map +1 -0
- package/dist/src/monitor/ui/tool-input.d.ts +23 -0
- package/dist/src/monitor/ui/tool-input.js +112 -0
- package/dist/src/monitor/ui/tool-input.js.map +1 -0
- package/dist/src/project/cli.d.ts +9 -0
- package/dist/src/project/cli.js +306 -0
- package/dist/src/project/cli.js.map +1 -0
- package/dist/src/project/graph.d.ts +4 -0
- package/dist/src/project/graph.js +26 -0
- package/dist/src/project/graph.js.map +1 -0
- package/dist/src/project/identity.d.ts +5 -0
- package/dist/src/project/identity.js +87 -0
- package/dist/src/project/identity.js.map +1 -0
- package/dist/src/project/index.d.ts +19 -0
- package/dist/src/project/index.js +26 -0
- package/dist/src/project/index.js.map +1 -0
- package/dist/src/project/query.d.ts +9 -0
- package/dist/src/project/query.js +136 -0
- package/dist/src/project/query.js.map +1 -0
- package/dist/src/project/store.d.ts +15 -0
- package/dist/src/project/store.js +47 -0
- package/dist/src/project/store.js.map +1 -0
- package/dist/src/project/types.d.ts +106 -0
- package/dist/src/project/types.js +2 -0
- package/dist/src/project/types.js.map +1 -0
- package/dist/src/requester/index.d.ts +16 -0
- package/dist/src/requester/index.js +96 -0
- package/dist/src/requester/index.js.map +1 -0
- package/dist/src/runtime-paths.d.ts +1 -0
- package/dist/src/runtime-paths.js +4 -0
- package/dist/src/runtime-paths.js.map +1 -0
- package/dist/src/sdk.d.ts +9 -0
- package/dist/src/sdk.js +3 -0
- package/dist/src/sdk.js.map +1 -0
- package/dist/src/tools/contracts.d.ts +108 -0
- package/dist/src/tools/contracts.js +2 -0
- package/dist/src/tools/contracts.js.map +1 -0
- package/dist/src/tools/host.d.ts +7 -0
- package/dist/src/tools/host.js +98 -0
- package/dist/src/tools/host.js.map +1 -0
- package/dist/src/tools/paths.d.ts +2 -0
- package/dist/src/tools/paths.js +18 -0
- package/dist/src/tools/paths.js.map +1 -0
- package/dist/src/tools/runner.d.ts +54 -0
- package/dist/src/tools/runner.js +194 -0
- package/dist/src/tools/runner.js.map +1 -0
- package/dist/src/tools/runtime-host.d.ts +1 -0
- package/dist/src/tools/runtime-host.js +116 -0
- package/dist/src/tools/runtime-host.js.map +1 -0
- package/dist/src/tools/schema.d.ts +6 -0
- package/dist/src/tools/schema.js +106 -0
- package/dist/src/tools/schema.js.map +1 -0
- package/dist/src/worker-client.d.ts +27 -0
- package/dist/src/worker-client.js +96 -0
- package/dist/src/worker-client.js.map +1 -0
- package/dist/src/worker.d.ts +1 -0
- package/dist/src/worker.js +50 -0
- package/dist/src/worker.js.map +1 -0
- package/dist/src/workspaces/index.d.ts +33 -0
- package/dist/src/workspaces/index.js +394 -0
- package/dist/src/workspaces/index.js.map +1 -0
- package/package.json +26 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { registerHooks } from 'node:module';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { readFileSync, realpathSync, existsSync } from 'node:fs';
|
|
4
|
+
import { mkdir, lstat } from 'node:fs/promises';
|
|
5
|
+
import { join, relative, resolve } from 'node:path';
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
7
|
+
import { metadata, jsonCopy, object, validateArguments } from './schema.js';
|
|
8
|
+
import { scopedPath, within } from './paths.js';
|
|
9
|
+
const identifier = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
|
|
10
|
+
const registry = new Map();
|
|
11
|
+
let root = '', loaded;
|
|
12
|
+
const hash = (value) => createHash('sha256').update(value).digest('hex');
|
|
13
|
+
async function load(workspace) {
|
|
14
|
+
if (loaded)
|
|
15
|
+
return loaded;
|
|
16
|
+
root = realpathSync(workspace);
|
|
17
|
+
const modules = new Map();
|
|
18
|
+
const hooks = registerHooks({
|
|
19
|
+
resolve(specifier, context, next) {
|
|
20
|
+
let result;
|
|
21
|
+
try {
|
|
22
|
+
result = next(specifier, context);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
if (specifier.startsWith('.') && specifier.endsWith('.js') && context.parentURL?.startsWith('file:'))
|
|
26
|
+
result = next(specifier.slice(0, -3) + '.ts', context);
|
|
27
|
+
else
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
if (result.url.startsWith('file:')) {
|
|
31
|
+
const absolute = realpathSync(fileURLToPath(result.url));
|
|
32
|
+
if (!within(root, absolute))
|
|
33
|
+
throw new Error('Configuration imports must resolve inside the snapshot. Install dependencies in the reviewed project.');
|
|
34
|
+
modules.set(relative(root, absolute).split('\\').join('/'), hash(readFileSync(absolute)));
|
|
35
|
+
}
|
|
36
|
+
else if (!result.url.startsWith('node:'))
|
|
37
|
+
throw new Error('Only snapshot files and Node builtins may be imported.');
|
|
38
|
+
return result;
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
const path = join(root, 'ccdd.config.ts');
|
|
42
|
+
if (!existsSync(path))
|
|
43
|
+
throw new Error('Missing ccdd.config.ts');
|
|
44
|
+
const imported = await import(pathToFileURL(path).href);
|
|
45
|
+
const config = typeof imported.default === 'function' ? await imported.default() : imported.default;
|
|
46
|
+
if (!object(config) || !object(config.artifactTypes))
|
|
47
|
+
throw new Error('TS config must export a configuration or factory.');
|
|
48
|
+
const types = {};
|
|
49
|
+
for (const [type, definition] of Object.entries(config.artifactTypes)) {
|
|
50
|
+
if (!identifier.test(type) || !object(definition) || Object.keys(definition).some(key => !['agentTools', 'humanTools'].includes(key)))
|
|
51
|
+
throw new Error('TS Artifact types declare only agentTools and humanTools.');
|
|
52
|
+
types[type] = { agentTools: {}, humanTools: {} };
|
|
53
|
+
for (const audience of ['agentTools', 'humanTools']) {
|
|
54
|
+
const tools = definition[audience] ?? {};
|
|
55
|
+
if (!object(tools) || Object.keys(tools).length > 32)
|
|
56
|
+
throw new Error('Invalid Artifact tool map.');
|
|
57
|
+
for (const [key, tool] of Object.entries(tools)) {
|
|
58
|
+
if (!identifier.test(key) || !object(tool) || typeof tool.execute !== 'function' || (tool.preflight !== undefined && typeof tool.preflight !== 'function') || Object.keys(tool).some(key => !['metadata', 'execute', 'preflight'].includes(key)))
|
|
59
|
+
throw new Error(`Invalid tool definition: ${type}.${key}`);
|
|
60
|
+
types[type][audience][key] = metadata(tool.metadata);
|
|
61
|
+
registry.set(`${type}/${audience}/${key}`, tool);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const values = jsonCopy({ artifacts: config.artifacts, critics: config.critics });
|
|
66
|
+
const moduleList = [...modules].sort(([a], [b]) => a.localeCompare(b)).map(([path, hash]) => ({ path, hash }));
|
|
67
|
+
const manifest = { version: 1, configHash: hash(JSON.stringify({ values, types, modules: moduleList })), modules: moduleList, types };
|
|
68
|
+
loaded = { config: { ...values, artifactTypes: Object.fromEntries(Object.keys(types).map(type => [type, { custom: true }])), configManifest: manifest } };
|
|
69
|
+
// Keep hooks installed throughout execution so deferred imports cannot escape the snapshot.
|
|
70
|
+
void hooks;
|
|
71
|
+
return loaded;
|
|
72
|
+
}
|
|
73
|
+
process.on('message', async (message) => {
|
|
74
|
+
const { id, action } = message;
|
|
75
|
+
try {
|
|
76
|
+
if (action === 'load') {
|
|
77
|
+
process.send?.({ id, value: await load(message.root) });
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (!loaded)
|
|
81
|
+
throw new Error('Configuration is not loaded.');
|
|
82
|
+
const { artifact, type, audience, toolKey, args, outputDir, tmpDir } = message;
|
|
83
|
+
const definition = registry.get(`${type}/${audience === 'agent' ? 'agentTools' : 'humanTools'}/${toolKey}`);
|
|
84
|
+
if (!definition)
|
|
85
|
+
throw new Error('Unknown tool.');
|
|
86
|
+
const artifactPath = await scopedPath(root, artifact.path);
|
|
87
|
+
const info = await lstat(artifactPath);
|
|
88
|
+
if (!info.isFile() && !info.isDirectory())
|
|
89
|
+
throw new Error('Artifact requires a regular file or directory.');
|
|
90
|
+
if (definition.metadata.artifactKind === 'file' && !info.isFile() || definition.metadata.artifactKind === 'directory' && !info.isDirectory())
|
|
91
|
+
throw new Error('Tool does not support this Artifact shape.');
|
|
92
|
+
const controller = new AbortController();
|
|
93
|
+
const abort = () => controller.abort(new Error('Tool host interrupted.'));
|
|
94
|
+
process.once('SIGTERM', abort);
|
|
95
|
+
await mkdir(outputDir, { recursive: true });
|
|
96
|
+
await mkdir(tmpDir, { recursive: true });
|
|
97
|
+
const context = { artifactId: artifact.id, artifactPath, artifactDirectory: info.isDirectory(), outputDir, tmpDir, signal: controller.signal, resolvePath: async (path = '') => {
|
|
98
|
+
controller.signal.throwIfAborted();
|
|
99
|
+
if (!info.isDirectory() && path)
|
|
100
|
+
throw new Error('File Artifact does not accept an internal path.');
|
|
101
|
+
return path ? scopedPath(artifactPath, path) : artifactPath;
|
|
102
|
+
} };
|
|
103
|
+
try {
|
|
104
|
+
const value = action === 'preflight' ? (definition.preflight ? await definition.preflight(context) : { ok: true, message: 'Registered; no custom preflight, actual execution unverified.' }) : await definition.execute(context, validateArguments(definition.metadata.inputSchema, args));
|
|
105
|
+
process.send?.({ id, value: jsonCopy(value) });
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
process.off('SIGTERM', abort);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
process.send?.({ id, error: { message: error instanceof Error ? error.message : 'Tool host failed.', code: 'ARTIFACT_TOOL_FAILED' } });
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
process.on('disconnect', () => process.exit(0));
|
|
116
|
+
//# sourceMappingURL=runtime-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-host.js","sourceRoot":"","sources":["../../../src/tools/runtime-host.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { JsonSchema, ToolMetadata } from './contracts.js';
|
|
2
|
+
export declare const object: (value: unknown) => value is Record<string, any>;
|
|
3
|
+
export declare function jsonCopy<T>(value: T): T;
|
|
4
|
+
export declare function validateSchema(schema: unknown): asserts schema is JsonSchema;
|
|
5
|
+
export declare function validateArguments(schema: JsonSchema, args: unknown): Record<string, unknown>;
|
|
6
|
+
export declare function metadata(value: unknown): ToolMetadata;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { Type } from 'typebox';
|
|
2
|
+
import { Compile } from 'typebox/compile';
|
|
3
|
+
export const object = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
4
|
+
export function jsonCopy(value) {
|
|
5
|
+
const visit = (item) => {
|
|
6
|
+
if (item === null || typeof item === 'string' || typeof item === 'boolean')
|
|
7
|
+
return;
|
|
8
|
+
if (typeof item === 'number' && Number.isFinite(item))
|
|
9
|
+
return;
|
|
10
|
+
if (Array.isArray(item)) {
|
|
11
|
+
item.forEach(visit);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (object(item) && Object.getPrototypeOf(item) === Object.prototype) {
|
|
15
|
+
Object.values(item).forEach(visit);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
throw new Error('Tool declarations and results must contain only JSON values.');
|
|
19
|
+
};
|
|
20
|
+
visit(value);
|
|
21
|
+
if (Buffer.byteLength(JSON.stringify(value)) > 8 * 1024 * 1024)
|
|
22
|
+
throw new Error('Tool JSON exceeds the supported size.');
|
|
23
|
+
return JSON.parse(JSON.stringify(value));
|
|
24
|
+
}
|
|
25
|
+
const keywords = new Set(['type', 'description', 'title', 'default', 'examples', 'enum', 'const', 'properties', 'required', 'additionalProperties', 'items', 'minItems', 'maxItems', 'uniqueItems', 'minLength', 'maxLength', 'pattern', 'minimum', 'maximum', 'exclusiveMinimum', 'exclusiveMaximum', 'multipleOf', 'anyOf', 'oneOf', 'allOf', 'not']);
|
|
26
|
+
export function validateSchema(schema) {
|
|
27
|
+
if (!object(schema) || schema.type !== 'object')
|
|
28
|
+
throw new Error('A tool input schema must declare an object.');
|
|
29
|
+
const walk = (node, depth) => {
|
|
30
|
+
if (depth > 20 || !object(node))
|
|
31
|
+
throw new Error('Invalid or deeply nested tool schema.');
|
|
32
|
+
for (const key of Object.keys(node))
|
|
33
|
+
if (!keywords.has(key))
|
|
34
|
+
throw new Error(`Unsupported tool schema keyword: ${key}`);
|
|
35
|
+
if (node.type !== undefined && !['object', 'array', 'string', 'integer', 'number', 'boolean', 'null'].includes(node.type))
|
|
36
|
+
throw new Error('Unsupported schema type; use anyOf for unions.');
|
|
37
|
+
if (node.properties !== undefined) {
|
|
38
|
+
if (!object(node.properties))
|
|
39
|
+
throw new Error('Invalid schema properties');
|
|
40
|
+
for (const item of Object.values(node.properties))
|
|
41
|
+
walk(item, depth + 1);
|
|
42
|
+
}
|
|
43
|
+
if (node.items !== undefined)
|
|
44
|
+
walk(node.items, depth + 1);
|
|
45
|
+
if (object(node.additionalProperties))
|
|
46
|
+
walk(node.additionalProperties, depth + 1);
|
|
47
|
+
for (const key of ['anyOf', 'allOf', 'oneOf'])
|
|
48
|
+
if (node[key] !== undefined) {
|
|
49
|
+
if (!Array.isArray(node[key]) || !node[key].length)
|
|
50
|
+
throw new Error(`Invalid ${key}`);
|
|
51
|
+
node[key].forEach((item) => walk(item, depth + 1));
|
|
52
|
+
}
|
|
53
|
+
if (node.not !== undefined)
|
|
54
|
+
walk(node.not, depth + 1);
|
|
55
|
+
if (node.additionalProperties !== undefined && typeof node.additionalProperties !== 'boolean' && !object(node.additionalProperties))
|
|
56
|
+
throw new Error('Invalid schema additionalProperties');
|
|
57
|
+
for (const key of ['minItems', 'maxItems', 'minLength', 'maxLength'])
|
|
58
|
+
if (node[key] !== undefined && (!Number.isSafeInteger(node[key]) || node[key] < 0))
|
|
59
|
+
throw new Error(`Invalid schema ${key}`);
|
|
60
|
+
for (const key of ['minimum', 'maximum', 'exclusiveMinimum', 'exclusiveMaximum'])
|
|
61
|
+
if (node[key] !== undefined && (typeof node[key] !== 'number' || !Number.isFinite(node[key])))
|
|
62
|
+
throw new Error(`Invalid schema ${key}`);
|
|
63
|
+
if (node.multipleOf !== undefined && (typeof node.multipleOf !== 'number' || !Number.isFinite(node.multipleOf) || node.multipleOf <= 0))
|
|
64
|
+
throw new Error('Invalid schema multipleOf');
|
|
65
|
+
if (node.uniqueItems !== undefined && typeof node.uniqueItems !== 'boolean')
|
|
66
|
+
throw new Error('Invalid schema uniqueItems');
|
|
67
|
+
if (node.enum !== undefined && (!Array.isArray(node.enum) || !node.enum.length || new Set(node.enum.map((value) => JSON.stringify(value))).size !== node.enum.length))
|
|
68
|
+
throw new Error('Invalid schema enum');
|
|
69
|
+
if (node.examples !== undefined && !Array.isArray(node.examples))
|
|
70
|
+
throw new Error('Invalid schema examples');
|
|
71
|
+
for (const key of ['title', 'description'])
|
|
72
|
+
if (node[key] !== undefined && typeof node[key] !== 'string')
|
|
73
|
+
throw new Error(`Invalid schema ${key}`);
|
|
74
|
+
if (node.pattern !== undefined && (typeof node.pattern !== 'string' || node.pattern.length > 1000))
|
|
75
|
+
throw new Error('Invalid schema pattern');
|
|
76
|
+
if (node.required !== undefined && (!Array.isArray(node.required) || node.required.some((v) => typeof v !== 'string') || new Set(node.required).size !== node.required.length))
|
|
77
|
+
throw new Error('Invalid schema required');
|
|
78
|
+
};
|
|
79
|
+
jsonCopy(schema);
|
|
80
|
+
walk(schema, 0);
|
|
81
|
+
Compile(Type.Unsafe(schema));
|
|
82
|
+
}
|
|
83
|
+
export function validateArguments(schema, args) {
|
|
84
|
+
if (!object(args) || Buffer.byteLength(JSON.stringify(args)) > 65536)
|
|
85
|
+
throw new Error('Tool arguments must be an object of at most 64 KiB.');
|
|
86
|
+
const actual = jsonCopy(args);
|
|
87
|
+
if (!Compile(Type.Unsafe(schema)).Check(actual))
|
|
88
|
+
throw new Error('Tool arguments do not match the registered input schema.');
|
|
89
|
+
return actual;
|
|
90
|
+
}
|
|
91
|
+
export function metadata(value) {
|
|
92
|
+
const result = jsonCopy(value);
|
|
93
|
+
if (!object(result) || Object.keys(result).some(key => !['description', 'inputSchema', 'resultKinds', 'observation', 'artifactKind', 'timeoutMs'].includes(key)))
|
|
94
|
+
throw new Error('Invalid tool metadata.');
|
|
95
|
+
if (typeof result.description !== 'string' || !result.description.trim() || result.description.length > 4000 || /[{}]/.test(result.description.replaceAll('{artifactName}', '')))
|
|
96
|
+
throw new Error('Tool description requires text and supports only {artifactName}.');
|
|
97
|
+
validateSchema(result.inputSchema);
|
|
98
|
+
if (!Array.isArray(result.resultKinds) || !result.resultKinds.length || new Set(result.resultKinds).size !== result.resultKinds.length || result.resultKinds.some((v) => !['text', 'json', 'image', 'launch'].includes(v)))
|
|
99
|
+
throw new Error('Invalid tool resultKinds.');
|
|
100
|
+
if (!['content', 'none'].includes(result.observation) || (result.artifactKind !== undefined && !['file', 'directory', 'any'].includes(result.artifactKind)))
|
|
101
|
+
throw new Error('Invalid tool observation or artifact kind.');
|
|
102
|
+
if (result.timeoutMs !== undefined && (!Number.isSafeInteger(result.timeoutMs) || result.timeoutMs < 1 || result.timeoutMs > 900000))
|
|
103
|
+
throw new Error('Tool timeoutMs must be 1–900000.');
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/tools/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { PiOptions } from './executors/pi.js';
|
|
2
|
+
import type { createBroker } from './broker/index.js';
|
|
3
|
+
type Broker = ReturnType<typeof createBroker>;
|
|
4
|
+
type Run = NonNullable<ReturnType<Broker['getRun']>>;
|
|
5
|
+
export interface WorkerConfiguration {
|
|
6
|
+
piOptions?: PiOptions;
|
|
7
|
+
humanInbox: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface WorkerContext {
|
|
10
|
+
repoPath: string;
|
|
11
|
+
repoId: string;
|
|
12
|
+
stateDir: string;
|
|
13
|
+
}
|
|
14
|
+
export interface WorkerOptions extends WorkerContext, WorkerConfiguration {
|
|
15
|
+
runId: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function launchWorker({ runId, repoPath, repoId, stateDir, piOptions, humanInbox }: WorkerOptions): Promise<number | undefined>;
|
|
18
|
+
/** The worker accepts only saved execution settings, never arbitrary spread-in identity fields. */
|
|
19
|
+
export declare function readWorkerConfiguration(stateDir: string, runId: string): Promise<WorkerConfiguration>;
|
|
20
|
+
/** CLI and explicit monitor completion share durable, detached successor startup. */
|
|
21
|
+
export declare function ensureRunWorker({ broker, context, run, initialConfig }: {
|
|
22
|
+
broker: Broker;
|
|
23
|
+
context: WorkerContext;
|
|
24
|
+
run: Run;
|
|
25
|
+
initialConfig?: WorkerConfiguration;
|
|
26
|
+
}): Promise<Run>;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { fork } from 'node:child_process';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { isAbsolute, join } from 'node:path';
|
|
5
|
+
import { errorCode } from './executors/errors.js';
|
|
6
|
+
export async function launchWorker({ runId, repoPath, repoId, stateDir, piOptions, humanInbox }) {
|
|
7
|
+
const worker = fork(fileURLToPath(new URL('./worker.js', import.meta.url)), [JSON.stringify({ runId, repoPath, repoId, stateDir, piOptions, humanInbox })], {
|
|
8
|
+
detached: true, stdio: ['ignore', 'ignore', 'ignore', 'ipc'], execArgv: [],
|
|
9
|
+
env: Object.fromEntries(Object.entries(process.env).filter(([key]) => key !== 'NODE_TEST_CONTEXT')),
|
|
10
|
+
});
|
|
11
|
+
await new Promise((ok, no) => {
|
|
12
|
+
const timer = setTimeout(() => finish(new Error('Review worker startup timed out.')), 15000);
|
|
13
|
+
const finish = (error) => { clearTimeout(timer); worker.off('error', fail); worker.off('exit', exit); worker.off('message', message); if (error) {
|
|
14
|
+
worker.kill('SIGTERM');
|
|
15
|
+
no(error);
|
|
16
|
+
}
|
|
17
|
+
else
|
|
18
|
+
ok(); };
|
|
19
|
+
const fail = (error) => finish(error);
|
|
20
|
+
const exit = (code) => finish(new Error(`Review worker exited during startup (${code}).`));
|
|
21
|
+
const message = (value) => { if (value?.type === 'ready')
|
|
22
|
+
finish();
|
|
23
|
+
else if (value?.type === 'error')
|
|
24
|
+
finish(Object.assign(new Error(value.message), { code: value.code })); };
|
|
25
|
+
worker.once('error', fail);
|
|
26
|
+
worker.once('exit', exit);
|
|
27
|
+
worker.on('message', message);
|
|
28
|
+
});
|
|
29
|
+
worker.unref();
|
|
30
|
+
worker.channel?.unref();
|
|
31
|
+
return worker.pid;
|
|
32
|
+
}
|
|
33
|
+
/** The worker accepts only saved execution settings, never arbitrary spread-in identity fields. */
|
|
34
|
+
export async function readWorkerConfiguration(stateDir, runId) {
|
|
35
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/.test(runId))
|
|
36
|
+
throw new Error('Invalid Run identity.');
|
|
37
|
+
const input = JSON.parse(await readFile(join(stateDir, 'runs', runId, 'worker.json'), 'utf8'));
|
|
38
|
+
if (!input || typeof input !== 'object' || Array.isArray(input))
|
|
39
|
+
throw new Error('Invalid saved worker configuration.');
|
|
40
|
+
const value = input;
|
|
41
|
+
if (Object.keys(value).some(key => !['piOptions', 'humanInbox'].includes(key)) || typeof value.humanInbox !== 'boolean')
|
|
42
|
+
throw new Error('Invalid saved worker configuration.');
|
|
43
|
+
let piOptions;
|
|
44
|
+
if (value.piOptions !== undefined) {
|
|
45
|
+
if (!value.piOptions || typeof value.piOptions !== 'object' || Array.isArray(value.piOptions))
|
|
46
|
+
throw new Error('Invalid saved Provider settings.');
|
|
47
|
+
const settings = value.piOptions;
|
|
48
|
+
if (Object.keys(settings).some(key => !['authFile', 'codexAuthFile'].includes(key)))
|
|
49
|
+
throw new Error('Invalid saved Provider settings.');
|
|
50
|
+
piOptions = {};
|
|
51
|
+
for (const key of ['authFile', 'codexAuthFile']) {
|
|
52
|
+
if (settings[key] !== undefined) {
|
|
53
|
+
if (typeof settings[key] !== 'string' || !isAbsolute(settings[key]))
|
|
54
|
+
throw new Error('Saved credential paths must be absolute.');
|
|
55
|
+
piOptions[key] = settings[key];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return { humanInbox: value.humanInbox, ...(piOptions ? { piOptions } : {}) };
|
|
60
|
+
}
|
|
61
|
+
/** CLI and explicit monitor completion share durable, detached successor startup. */
|
|
62
|
+
export async function ensureRunWorker({ broker, context, run, initialConfig }) {
|
|
63
|
+
try {
|
|
64
|
+
if (initialConfig) {
|
|
65
|
+
const runDir = join(context.stateDir, 'runs', run.id);
|
|
66
|
+
await mkdir(runDir, { recursive: true, mode: 0o700 });
|
|
67
|
+
try {
|
|
68
|
+
await writeFile(join(runDir, 'worker.json'), JSON.stringify(initialConfig), { flag: 'wx', mode: 0o600 });
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (errorCode(error) !== 'EEXIST')
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const config = await readWorkerConfiguration(context.stateDir, run.id);
|
|
76
|
+
try {
|
|
77
|
+
await launchWorker({ ...context, ...config, runId: run.id });
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (errorCode(error) !== 'RUN_ALREADY_OWNED')
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
try {
|
|
86
|
+
await broker.failRun(run.id, error);
|
|
87
|
+
}
|
|
88
|
+
catch { }
|
|
89
|
+
throw Object.assign(error instanceof Error ? error : new Error(String(error)), { runId: run.id });
|
|
90
|
+
}
|
|
91
|
+
const current = broker.getRun(run.id);
|
|
92
|
+
if (!current)
|
|
93
|
+
throw new Error('Review handle not found.');
|
|
94
|
+
return current;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=worker-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-client.js","sourceRoot":"","sources":["../../src/worker-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createBroker } from './broker/index.js';
|
|
2
|
+
import { createExecutorRegistry } from './executors/index.js';
|
|
3
|
+
import { createLocalAlarmMethods } from './local.js';
|
|
4
|
+
import { errorMessage, errorCode } from './executors/errors.js';
|
|
5
|
+
// A single review owns this process; it never listens on a socket or accepts a queue.
|
|
6
|
+
const options = JSON.parse(process.argv[2]);
|
|
7
|
+
const { runId, piOptions, humanInbox, ...context } = options;
|
|
8
|
+
const executors = createExecutorRegistry({ piOptions, alarmMethods: createLocalAlarmMethods({ ...context, humanInbox }) });
|
|
9
|
+
const controller = new AbortController();
|
|
10
|
+
const stop = () => controller.abort(new Error('Review worker was stopped.'));
|
|
11
|
+
process.on('SIGINT', stop);
|
|
12
|
+
process.on('SIGTERM', stop);
|
|
13
|
+
let broker;
|
|
14
|
+
const notify = (message) => {
|
|
15
|
+
if (!process.connected)
|
|
16
|
+
return;
|
|
17
|
+
// The submitting client may disappear; IPC failure must not stop owned work.
|
|
18
|
+
try {
|
|
19
|
+
process.send?.(message, () => { if (process.connected) {
|
|
20
|
+
try {
|
|
21
|
+
process.disconnect();
|
|
22
|
+
}
|
|
23
|
+
catch { }
|
|
24
|
+
} });
|
|
25
|
+
}
|
|
26
|
+
catch { }
|
|
27
|
+
};
|
|
28
|
+
let notified = false;
|
|
29
|
+
try {
|
|
30
|
+
broker = await createBroker({ ...context, executors });
|
|
31
|
+
await broker.run(runId, { signal: controller.signal, onStarted: () => { notified = true; notify({ type: 'ready', runId }); } });
|
|
32
|
+
if (!notified)
|
|
33
|
+
notify({ type: 'ready', runId });
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
notify({ type: 'error', message: errorMessage(error), code: errorCode(error) });
|
|
37
|
+
if (errorCode(error) !== 'RUN_ALREADY_OWNED') {
|
|
38
|
+
try {
|
|
39
|
+
await broker?.failRun?.(runId, error);
|
|
40
|
+
}
|
|
41
|
+
catch { }
|
|
42
|
+
process.exitCode = 2;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
await broker?.close();
|
|
47
|
+
process.off('SIGINT', stop);
|
|
48
|
+
process.off('SIGTERM', stop);
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type WorkspaceMode = 'copy' | 'lock';
|
|
2
|
+
export interface WorkspaceDescriptor {
|
|
3
|
+
version: 1;
|
|
4
|
+
mode: WorkspaceMode;
|
|
5
|
+
sourcePath: string;
|
|
6
|
+
path: string;
|
|
7
|
+
hash: string;
|
|
8
|
+
stateDir: string;
|
|
9
|
+
baselineMetadataHash: string;
|
|
10
|
+
}
|
|
11
|
+
export interface WorkspaceHandle {
|
|
12
|
+
descriptor: Readonly<WorkspaceDescriptor>;
|
|
13
|
+
signal: AbortSignal;
|
|
14
|
+
assertUnchanged: () => Promise<unknown>;
|
|
15
|
+
close: () => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
/** State, events, caches and review outputs must never be part of the observed input. */
|
|
18
|
+
export declare function validateStateLocation(repoPath: unknown, stateDir: unknown): Promise<{
|
|
19
|
+
repoPath: string;
|
|
20
|
+
stateDir: string;
|
|
21
|
+
}>;
|
|
22
|
+
export declare function fingerprintWorkspace(workspacePath: string): Promise<string>;
|
|
23
|
+
/** Delete only caller-owned private scratch, never a shared cache or a source workspace. */
|
|
24
|
+
export declare function removeOwnedWorkspaceTree(directory: string): Promise<void>;
|
|
25
|
+
export declare function prepareWorkspace({ repoPath, stateDir, mode, signal }?: {
|
|
26
|
+
repoPath?: string;
|
|
27
|
+
stateDir?: string;
|
|
28
|
+
mode?: WorkspaceMode;
|
|
29
|
+
signal?: AbortSignal;
|
|
30
|
+
}): Promise<WorkspaceHandle>;
|
|
31
|
+
export declare function reopenWorkspace(descriptor: WorkspaceDescriptor, { signal }?: {
|
|
32
|
+
signal?: AbortSignal;
|
|
33
|
+
}): Promise<WorkspaceHandle>;
|