@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,40 @@
|
|
|
1
|
+
import { type WorkspaceMode } from '../workspaces/index.js';
|
|
2
|
+
import type { HumanToolResult } from './human.js';
|
|
3
|
+
import { type ReviewToolDefinition } from '../tools/runner.js';
|
|
4
|
+
import type { ToolResult } from '../tools/contracts.js';
|
|
5
|
+
import { type ArtifactAudience } from './types.js';
|
|
6
|
+
export interface ArtifactToolCheck {
|
|
7
|
+
artifactId?: string;
|
|
8
|
+
audience?: ArtifactAudience;
|
|
9
|
+
toolName?: string;
|
|
10
|
+
ok: boolean;
|
|
11
|
+
message: string;
|
|
12
|
+
code?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ArtifactToolCheckReport {
|
|
15
|
+
ok: boolean;
|
|
16
|
+
status: 'READY' | 'NOT_READY';
|
|
17
|
+
mode: WorkspaceMode;
|
|
18
|
+
checkedAt: string;
|
|
19
|
+
snapshotHash?: string;
|
|
20
|
+
workspacePath?: string;
|
|
21
|
+
checks: ArtifactToolCheck[];
|
|
22
|
+
tools: Array<ReviewToolDefinition & {
|
|
23
|
+
audience: ArtifactAudience;
|
|
24
|
+
}>;
|
|
25
|
+
result?: HumanToolResult | ToolResult;
|
|
26
|
+
}
|
|
27
|
+
export interface DiagnoseArtifactToolsOptions {
|
|
28
|
+
repoPath: string;
|
|
29
|
+
repoId?: string;
|
|
30
|
+
mode?: WorkspaceMode;
|
|
31
|
+
stateDir?: string;
|
|
32
|
+
artifactId?: string;
|
|
33
|
+
audience?: ArtifactAudience;
|
|
34
|
+
toolName?: string;
|
|
35
|
+
arguments?: unknown;
|
|
36
|
+
execute?: boolean;
|
|
37
|
+
signal?: AbortSignal;
|
|
38
|
+
}
|
|
39
|
+
/** Diagnose registered tools without creating a Broker, Run, request, alarm, Agent session or verdict. */
|
|
40
|
+
export declare function diagnoseArtifactTools({ repoPath, mode, stateDir, artifactId, audience, toolName, arguments: args, execute, signal }: DiagnoseArtifactToolsOptions): Promise<ArtifactToolCheckReport>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { localContext } from '../local.js';
|
|
4
|
+
import { readWorkspaceConfig } from '../broker/config.js';
|
|
5
|
+
import { prepareWorkspace } from '../workspaces/index.js';
|
|
6
|
+
import { createReviewTools } from '../tools/runner.js';
|
|
7
|
+
import { assertArtifactAudience } from './types.js';
|
|
8
|
+
import { isArtifactGroup, resolveArtifactScope } from './groups.js';
|
|
9
|
+
function safeFailure(error, aborted) {
|
|
10
|
+
const code = error && typeof error === 'object' && 'code' in error ? error.code : undefined;
|
|
11
|
+
if (aborted || code === 'ABORTED')
|
|
12
|
+
return { code: 'ABORTED', message: 'Artifact tool diagnosis was cancelled.' };
|
|
13
|
+
if (code === 'WORKSPACE_CHANGED' || code === 'WORKSPACE_CACHE_TAMPERED')
|
|
14
|
+
return { code, message: 'The workspace changed during Artifact tool diagnosis.' };
|
|
15
|
+
if (code === 'ARTIFACT_TOOLS_UNAVAILABLE')
|
|
16
|
+
return { code, message: 'A Critic references an Artifact with no tools for its reviewer kind. Register the corresponding agentTools or humanTools.' };
|
|
17
|
+
if (code === 'HUMAN_TOOL_TIMEOUT')
|
|
18
|
+
return { code, message: 'The registered Human tool exceeded its configured time limit.' };
|
|
19
|
+
if (code === 'HUMAN_TOOL_UNAVAILABLE')
|
|
20
|
+
return { code, message: 'The registered Human tool executable is unavailable.' };
|
|
21
|
+
if (code === 'HUMAN_TOOL_FAILED')
|
|
22
|
+
return { code, message: 'The registered Human tool did not finish successfully.' };
|
|
23
|
+
return { code: 'ARTIFACT_TOOL_CHECK_FAILED', message: 'Artifact tool diagnosis failed. Check the configuration, selected tool, scoped arguments and workspace access.' };
|
|
24
|
+
}
|
|
25
|
+
/** Diagnose registered tools without creating a Broker, Run, request, alarm, Agent session or verdict. */
|
|
26
|
+
export async function diagnoseArtifactTools({ repoPath, mode = 'copy', stateDir, artifactId, audience, toolName, arguments: args, execute = false, signal }) {
|
|
27
|
+
const report = { ok: false, status: 'NOT_READY', mode, checkedAt: new Date().toISOString(), checks: [], tools: [] };
|
|
28
|
+
let workspace;
|
|
29
|
+
try {
|
|
30
|
+
if ((audience !== undefined && audience !== 'agent' && audience !== 'human') || (execute && (!artifactId || !audience || !toolName)) || (!execute && args !== undefined))
|
|
31
|
+
throw new Error('Actual tool execution requires explicit Artifact, audience and tool selection.');
|
|
32
|
+
signal?.throwIfAborted();
|
|
33
|
+
const context = await localContext({ repoPath, stateDir });
|
|
34
|
+
workspace = await prepareWorkspace({ repoPath: context.repoPath, stateDir: context.stateDir, mode, signal });
|
|
35
|
+
const worktreePath = workspace.descriptor.path;
|
|
36
|
+
report.snapshotHash = workspace.descriptor.hash;
|
|
37
|
+
// Cached copies are retained: a desktop viewer can continue reading after its launcher exits.
|
|
38
|
+
report.workspacePath = worktreePath;
|
|
39
|
+
const { config } = await readWorkspaceConfig(worktreePath);
|
|
40
|
+
const { configManifest } = config;
|
|
41
|
+
if (artifactId !== undefined && !Object.hasOwn(config.artifacts, artifactId))
|
|
42
|
+
throw new Error('Unknown selected Artifact.');
|
|
43
|
+
if (execute && artifactId !== undefined && isArtifactGroup(config.artifacts[artifactId])) {
|
|
44
|
+
report.checks.push({ artifactId, ok: false, message: 'Groups collect member tools. Select a leaf Artifact with --artifact to execute its tool.' });
|
|
45
|
+
return report;
|
|
46
|
+
}
|
|
47
|
+
const selectedScope = resolveArtifactScope(config.artifacts, artifactId === undefined ? Object.keys(config.artifacts) : [artifactId]);
|
|
48
|
+
const selected = selectedScope.artifacts;
|
|
49
|
+
if (!selected.length)
|
|
50
|
+
throw new Error('Unknown selected Artifact.');
|
|
51
|
+
if (!artifactId && !audience && !toolName) {
|
|
52
|
+
for (const critic of config.critics) {
|
|
53
|
+
try {
|
|
54
|
+
assertArtifactAudience({ profile: critic.profile, ...resolveArtifactScope(config.artifacts, [critic.target, ...critic.deps]), artifactTypes: config.artifactTypes, configManifest });
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
report.checks.push({ ok: false, ...safeFailure(error, false) });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
for (const targetAudience of audience ? [audience] : ['agent', 'human']) {
|
|
62
|
+
const registry = await createReviewTools({ worktreePath, ...selectedScope, artifactTypes: config.artifactTypes, configManifest, audience: targetAudience, runDir: join(context.stateDir, 'tool-check', randomUUID()), signal: workspace.signal });
|
|
63
|
+
try {
|
|
64
|
+
// Explicit Artifact selection makes the short operation name unambiguous; published names win.
|
|
65
|
+
const resolvedToolName = toolName === undefined || registry.tools.some(tool => tool.name === toolName) || artifactId === undefined ? toolName : `${toolName}_${artifactId}`;
|
|
66
|
+
const definitions = registry.tools.filter(tool => resolvedToolName === undefined || tool.name === resolvedToolName);
|
|
67
|
+
if (toolName !== undefined && !definitions.length) {
|
|
68
|
+
report.checks.push({ artifactId, audience: targetAudience, toolName, ok: false, message: 'The selected tool is not registered for this Artifact and reviewer kind.' });
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
report.tools.push(...definitions.map(tool => ({ ...tool, audience: targetAudience })));
|
|
72
|
+
for (const artifact of selected) {
|
|
73
|
+
if (definitions.some(tool => tool.artifactId === artifact.id))
|
|
74
|
+
continue;
|
|
75
|
+
const required = audience !== undefined || config.critics.some(critic => critic.profile.kind === targetAudience && resolveArtifactScope(config.artifacts, [critic.target, ...critic.deps]).artifacts.some(leaf => leaf.id === artifact.id));
|
|
76
|
+
report.checks.push({ artifactId: artifact.id, audience: targetAudience, ok: !required, message: `No ${targetAudience} tools are available for this Artifact. It cannot be used by a ${targetAudience} Critic.` });
|
|
77
|
+
}
|
|
78
|
+
report.checks.push(...(await registry.preflight({ toolName: resolvedToolName })).map(check => ({ ...check, audience: targetAudience })));
|
|
79
|
+
if (execute && targetAudience === audience && definitions.length === 1 && report.checks.every(check => check.ok)) {
|
|
80
|
+
await workspace.assertUnchanged();
|
|
81
|
+
const result = await registry.call(definitions[0].name, args ?? {});
|
|
82
|
+
await workspace.assertUnchanged();
|
|
83
|
+
report.result = result;
|
|
84
|
+
report.checks.push({ artifactId, audience, toolName: definitions[0].name, ok: true, message: 'The selected registered tool completed successfully. No review result was created.' });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
await registry.close();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
await workspace.assertUnchanged();
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
delete report.result;
|
|
95
|
+
// A mutated workspace can abort a running program before its boundary check resumes.
|
|
96
|
+
// Preserve that integrity failure instead of relabeling it as an ordinary cancellation.
|
|
97
|
+
const reason = workspace?.signal.aborted && !signal?.aborted ? workspace.signal.reason : error;
|
|
98
|
+
report.checks.push({ artifactId, audience, toolName, ok: false, ...safeFailure(reason, signal?.aborted ?? false) });
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
try {
|
|
102
|
+
await workspace?.close();
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
report.checks.push({ ok: false, code: 'WORKSPACE_CLEANUP_FAILED', message: 'Could not finish workspace observation cleanup.' });
|
|
106
|
+
}
|
|
107
|
+
report.ok = report.checks.length > 0 && report.checks.every(check => check.ok);
|
|
108
|
+
report.status = report.ok ? 'READY' : 'NOT_READY';
|
|
109
|
+
report.checkedAt = new Date().toISOString();
|
|
110
|
+
}
|
|
111
|
+
return report;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=tool-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-check.js","sourceRoot":"","sources":["../../../src/artifacts/tool-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAA4C,MAAM,wBAAwB,CAAC;AAEpG,OAAO,EAAE,iBAAiB,EAA6B,MAAM,oBAAoB,CAAC;AAElF,OAAO,EAAE,sBAAsB,EAAyB,MAAM,YAAY,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAkCpE,SAAS,WAAW,CAAC,KAAc,EAAE,OAAgB;IACnD,MAAM,IAAI,GAAG,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5F,IAAI,OAAO,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,wCAAwC,EAAE,CAAC;IACjH,IAAI,IAAI,KAAK,mBAAmB,IAAI,IAAI,KAAK,0BAA0B;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,uDAAuD,EAAE,CAAC;IAC3J,IAAI,IAAI,KAAK,4BAA4B;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,2HAA2H,EAAE,CAAC;IACjM,IAAI,IAAI,KAAK,oBAAoB;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,+DAA+D,EAAE,CAAC;IAC7H,IAAI,IAAI,KAAK,wBAAwB;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,sDAAsD,EAAE,CAAC;IACxH,IAAI,IAAI,KAAK,mBAAmB;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,wDAAwD,EAAE,CAAC;IACrH,OAAO,EAAE,IAAI,EAAE,4BAA4B,EAAE,OAAO,EAAE,gHAAgH,EAAE,CAAC;AAC3K,CAAC;AAED,0GAA0G;AAC1G,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,EAAE,QAAQ,EAAE,IAAI,GAAG,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,GAAG,KAAK,EAAE,MAAM,EAAgC;IACvL,MAAM,MAAM,GAA4B,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAC7I,IAAI,SAAsC,CAAC;IAC3C,IAAI,CAAC;QACH,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,IAAI,KAAK,SAAS,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAC;QAC5Q,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC3D,SAAS,GAAG,MAAM,gBAAgB,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7G,MAAM,YAAY,GAAG,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC;QAC/C,MAAM,CAAC,YAAY,GAAG,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC;QAChD,8FAA8F;QAC9F,MAAM,CAAC,aAAa,GAAG,YAAY,CAAC;QACpC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,mBAAmB,CAAC,YAAY,CAAC,CAAC;QAC3D,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,CAAC;QAClC,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAC5H,IAAI,OAAO,IAAI,UAAU,KAAK,SAAS,IAAI,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;YACzF,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,0FAA0F,EAAE,CAAC,CAAC;YACnJ,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,aAAa,GAAG,oBAAoB,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;QACtI,MAAM,QAAQ,GAAG,aAAa,CAAC,SAAS,CAAC;QACzC,IAAI,CAAC,QAAQ,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QACpE,IAAI,CAAC,UAAU,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1C,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpC,IAAI,CAAC;oBACH,sBAAsB,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,oBAAoB,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,cAAc,EAAE,CAAC,CAAC;gBACvL,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;gBAClE,CAAC;YACH,CAAC;QACH,CAAC;QACD,KAAK,MAAM,cAAc,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAU,EAAE,CAAC;YACjF,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,EAAE,YAAY,EAAE,GAAG,aAAa,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;YAClP,IAAI,CAAC;gBACH,+FAA+F;gBAC/F,MAAM,gBAAgB,GAAG,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,UAAU,EAAE,CAAC;gBAC5K,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,gBAAgB,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,gBAAgB,CAAC,CAAC;gBACpH,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;oBAClD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,0EAA0E,EAAE,CAAC,CAAC;oBACvK,SAAS;gBACX,CAAC;gBACD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC;gBACvF,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;oBAChC,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,EAAE,CAAC;wBAAE,SAAS;oBACxE,MAAM,QAAQ,GAAG,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,cAAc,IAAI,oBAAoB,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;oBAC5O,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,cAAc,kEAAkE,cAAc,UAAU,EAAE,CAAC,CAAC;gBACpN,CAAC;gBACD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC;gBACzI,IAAI,OAAO,IAAI,cAAc,KAAK,QAAQ,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;oBACjH,MAAM,SAAS,CAAC,eAAe,EAAE,CAAC;oBAClC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;oBACpE,MAAM,SAAS,CAAC,eAAe,EAAE,CAAC;oBAClC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;oBACvB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,oFAAoF,EAAE,CAAC,CAAC;gBACvL,CAAC;YACH,CAAC;oBAAS,CAAC;gBAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;YAAC,CAAC;QACvC,CAAC;QACD,MAAM,SAAS,CAAC,eAAe,EAAE,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,MAAM,CAAC,MAAM,CAAC;QACrB,qFAAqF;QACrF,wFAAwF;QACxF,MAAM,MAAM,GAAG,SAAS,EAAE,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QAC/F,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC;IACtH,CAAC;YAAS,CAAC;QACT,IAAI,CAAC;YAAC,MAAM,SAAS,EAAE,KAAK,EAAE,CAAC;QAAC,CAAC;QACjC,MAAM,CAAC;YAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,0BAA0B,EAAE,OAAO,EAAE,iDAAiD,EAAE,CAAC,CAAC;QAAC,CAAC;QAC1I,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC/E,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC;QAClD,MAAM,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ConfigManifest } from '../tools/contracts.js';
|
|
2
|
+
export type ArtifactOperation = 'read' | 'list';
|
|
3
|
+
export type ArtifactViewerKind = 'text' | 'files';
|
|
4
|
+
export type ArtifactAudience = 'agent' | 'human';
|
|
5
|
+
export interface BuiltinArtifactTool {
|
|
6
|
+
description?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface HumanCommandTool {
|
|
9
|
+
description: string;
|
|
10
|
+
command: string;
|
|
11
|
+
args: string[];
|
|
12
|
+
timeoutMs?: number;
|
|
13
|
+
}
|
|
14
|
+
export type HumanArtifactToolConfig = BuiltinArtifactTool | HumanCommandTool;
|
|
15
|
+
export interface ArtifactTypeDefinition {
|
|
16
|
+
viewer?: ArtifactViewerKind;
|
|
17
|
+
/** Serialized marker for a type whose tools are in the recorded TS manifest. */
|
|
18
|
+
custom?: true;
|
|
19
|
+
tools?: Partial<Record<ArtifactOperation, {
|
|
20
|
+
description: string;
|
|
21
|
+
}>>;
|
|
22
|
+
agentTools?: Partial<Record<ArtifactOperation, BuiltinArtifactTool>>;
|
|
23
|
+
humanTools?: Record<string, HumanArtifactToolConfig>;
|
|
24
|
+
}
|
|
25
|
+
export declare function validateArtifactType(typeName: unknown, definition: unknown): ArtifactTypeDefinition;
|
|
26
|
+
/** Legacy defaults are available only if neither audience was explicitly declared. */
|
|
27
|
+
export declare function artifactAudienceTools(typeDefinition: ArtifactTypeDefinition, audience: ArtifactAudience, { allowLegacy }?: {
|
|
28
|
+
allowLegacy?: boolean;
|
|
29
|
+
}): Record<string, HumanArtifactToolConfig>;
|
|
30
|
+
export declare function assertArtifactAudience(request: {
|
|
31
|
+
profile: {
|
|
32
|
+
kind: string;
|
|
33
|
+
};
|
|
34
|
+
artifacts: readonly {
|
|
35
|
+
id: string;
|
|
36
|
+
type: string;
|
|
37
|
+
}[];
|
|
38
|
+
artifactTypes: Readonly<Record<string, unknown>>;
|
|
39
|
+
configManifest?: ConfigManifest;
|
|
40
|
+
}, { allowLegacy }?: {
|
|
41
|
+
allowLegacy?: boolean;
|
|
42
|
+
}): void;
|
|
43
|
+
export declare function toolDescription(typeDefinition: unknown, toolName: string, artifactName: unknown, audience?: ArtifactAudience): string;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
const identifier = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
|
|
2
|
+
const object = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
3
|
+
const operations = { text: ['read'], files: ['list', 'read'] };
|
|
4
|
+
const defaults = {
|
|
5
|
+
read: 'Read text from {artifactName} using 1-based line ranges.',
|
|
6
|
+
list: 'List files within {artifactName}.',
|
|
7
|
+
};
|
|
8
|
+
export function validateArtifactType(typeName, definition) {
|
|
9
|
+
if (typeof typeName === 'string' && identifier.test(typeName) && object(definition) && definition.custom === true && Object.keys(definition).length === 1)
|
|
10
|
+
return { custom: true };
|
|
11
|
+
if (typeof typeName !== 'string' || !identifier.test(typeName) || !object(definition) ||
|
|
12
|
+
(definition.viewer !== 'text' && definition.viewer !== 'files')) {
|
|
13
|
+
throw new Error(`Invalid artifact type/viewer: ${String(typeName)}`);
|
|
14
|
+
}
|
|
15
|
+
for (const key of Object.keys(definition)) {
|
|
16
|
+
if (!['viewer', 'tools', 'agentTools', 'humanTools'].includes(key))
|
|
17
|
+
throw new Error(`Unknown artifact type field: ${typeName}.${key}`);
|
|
18
|
+
}
|
|
19
|
+
for (const audience of ['tools', 'agentTools', 'humanTools']) {
|
|
20
|
+
if (!Object.hasOwn(definition, audience))
|
|
21
|
+
continue;
|
|
22
|
+
const configured = definition[audience];
|
|
23
|
+
if (!object(configured))
|
|
24
|
+
throw new Error(`Artifact type ${audience} must be an object: ${typeName}`);
|
|
25
|
+
if (Object.keys(configured).length > 32)
|
|
26
|
+
throw new Error(`Too many artifact tools: ${typeName}.${audience}`);
|
|
27
|
+
for (const [operation, tool] of Object.entries(configured)) {
|
|
28
|
+
if (!identifier.test(operation) || !object(tool))
|
|
29
|
+
throw new Error(`Invalid artifact tool: ${typeName}.${operation}`);
|
|
30
|
+
const builtin = operation === 'read' || operation === 'list';
|
|
31
|
+
if (builtin && !operations[definition.viewer].includes(operation)) {
|
|
32
|
+
throw new Error(`Unsupported artifact tool for ${definition.viewer} viewer: ${typeName}.${operation}`);
|
|
33
|
+
}
|
|
34
|
+
if (!builtin && (audience !== 'humanTools' || !Object.hasOwn(tool, 'command'))) {
|
|
35
|
+
throw new Error(`Unsupported artifact tool: ${typeName}.${operation}`);
|
|
36
|
+
}
|
|
37
|
+
if (builtin) {
|
|
38
|
+
if (Object.keys(tool).some(key => key !== 'description'))
|
|
39
|
+
throw new Error(`Artifact builtin tool allows only description: ${typeName}.${operation}`);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
if (Object.keys(tool).some(key => !['description', 'command', 'args', 'timeoutMs'].includes(key)))
|
|
43
|
+
throw new Error(`Unknown Human command field: ${typeName}.${operation}`);
|
|
44
|
+
if (typeof tool.command !== 'string' || !tool.command.trim() || tool.command.length > 4096 || /[\0\r\n{}]/.test(tool.command) || (!tool.command.startsWith('/') && /[/\\]/.test(tool.command)))
|
|
45
|
+
throw new Error(`Human command must be an executable name or absolute path: ${typeName}.${operation}`);
|
|
46
|
+
if (!Array.isArray(tool.args) || tool.args.length > 64 || !tool.args.includes('{artifactPath}') || tool.args.some(arg => typeof arg !== 'string' || arg.length > 4096 || arg.includes('\0') || (arg !== '{artifactPath}' && /[{}]/.test(arg))))
|
|
47
|
+
throw new Error(`Human command args must include standalone {artifactPath} and fixed string arguments: ${typeName}.${operation}`);
|
|
48
|
+
if (tool.timeoutMs !== undefined && (typeof tool.timeoutMs !== 'number' || !Number.isInteger(tool.timeoutMs) || tool.timeoutMs < 1 || tool.timeoutMs > 120_000))
|
|
49
|
+
throw new Error(`Human command timeoutMs must be 1–120000: ${typeName}.${operation}`);
|
|
50
|
+
}
|
|
51
|
+
if (tool.description === undefined && audience !== 'tools' && builtin)
|
|
52
|
+
continue;
|
|
53
|
+
if (typeof tool.description !== 'string' || !tool.description.trim() || tool.description.length > 4000)
|
|
54
|
+
throw new Error(`Artifact tool description must contain 1–4000 characters: ${typeName}.${operation}`);
|
|
55
|
+
if (/[{}]/.test(tool.description.replaceAll('{artifactName}', '')))
|
|
56
|
+
throw new Error(`Artifact tool description supports only the {artifactName} placeholder: ${typeName}.${operation}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return definition;
|
|
60
|
+
}
|
|
61
|
+
/** Legacy defaults are available only if neither audience was explicitly declared. */
|
|
62
|
+
export function artifactAudienceTools(typeDefinition, audience, { allowLegacy = false } = {}) {
|
|
63
|
+
const definition = validateArtifactType('artifact', typeDefinition);
|
|
64
|
+
if (Object.hasOwn(definition, 'agentTools') || Object.hasOwn(definition, 'humanTools'))
|
|
65
|
+
return structuredClone(definition[audience === 'agent' ? 'agentTools' : 'humanTools'] ?? {});
|
|
66
|
+
if (!allowLegacy)
|
|
67
|
+
return {};
|
|
68
|
+
if (definition.custom)
|
|
69
|
+
return {};
|
|
70
|
+
return Object.fromEntries(operations[definition.viewer].map(operation => [operation, { description: definition.tools?.[operation]?.description ?? defaults[operation] }]));
|
|
71
|
+
}
|
|
72
|
+
export function assertArtifactAudience(request, { allowLegacy = false } = {}) {
|
|
73
|
+
const audience = request.profile.kind;
|
|
74
|
+
if (audience !== 'agent' && audience !== 'human')
|
|
75
|
+
return;
|
|
76
|
+
for (const artifact of request.artifacts) {
|
|
77
|
+
if (request.configManifest) {
|
|
78
|
+
if (!Object.keys(request.configManifest.types[artifact.type]?.[audience === 'agent' ? 'agentTools' : 'humanTools'] ?? {}).length)
|
|
79
|
+
throw Object.assign(new Error(`Artifact ${artifact.id} has no ${audience} tools.`), { code: 'ARTIFACT_TOOLS_UNAVAILABLE' });
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const type = validateArtifactType(artifact.type, request.artifactTypes[artifact.type]);
|
|
83
|
+
if (!Object.keys(artifactAudienceTools(type, audience, { allowLegacy })).length)
|
|
84
|
+
throw Object.assign(new Error(`Artifact ${artifact.id} has no ${audience} tools. Register ${audience}Tools on artifact type ${artifact.type}.`), { code: 'ARTIFACT_TOOLS_UNAVAILABLE' });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export function toolDescription(typeDefinition, toolName, artifactName, audience) {
|
|
88
|
+
const definition = validateArtifactType('artifact', typeDefinition);
|
|
89
|
+
if ((toolName !== 'read' && toolName !== 'list') || !definition.viewer || !operations[definition.viewer].includes(toolName)) {
|
|
90
|
+
throw new Error(`Unsupported artifact tool for ${definition.viewer} viewer: ${String(toolName)}`);
|
|
91
|
+
}
|
|
92
|
+
if (typeof artifactName !== 'string' || !artifactName)
|
|
93
|
+
throw new Error('Artifact name is required for its tool description.');
|
|
94
|
+
const template = audience ? artifactAudienceTools(definition, audience, { allowLegacy: true })[toolName]?.description ?? defaults[toolName] : definition.tools?.[toolName]?.description ?? defaults[toolName];
|
|
95
|
+
return template.replaceAll('{artifactName}', () => artifactName);
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/artifacts/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RepoConfig } from '../contracts.js';
|
|
2
|
+
export interface WorkspaceTreeEntry {
|
|
3
|
+
path: string;
|
|
4
|
+
type: string;
|
|
5
|
+
mode: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function validateRelativePath(value: unknown): string;
|
|
8
|
+
export declare function readWorkspaceConfig(repoPath: string, signal?: AbortSignal): Promise<{
|
|
9
|
+
config: RepoConfig;
|
|
10
|
+
}>;
|
|
11
|
+
export declare function validateConfig(config: unknown, tree: WorkspaceTreeEntry[]): asserts config is RepoConfig;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { lstat, readFile, readdir, realpath } from 'node:fs/promises';
|
|
3
|
+
import { validateArtifactType } from '../artifacts/types.js';
|
|
4
|
+
import { isArtifactGroup, validateArtifactDefinitions } from '../artifacts/groups.js';
|
|
5
|
+
import { createGraphDefinition } from './graph.js';
|
|
6
|
+
import { openToolHost } from '../tools/host.js';
|
|
7
|
+
const errorCode = (error) => error !== null && typeof error === 'object' && 'code' in error ? error.code : undefined;
|
|
8
|
+
const identifier = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
|
|
9
|
+
const object = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
10
|
+
export function validateRelativePath(value) {
|
|
11
|
+
if (typeof value !== 'string' || !value || value.length > 1024 ||
|
|
12
|
+
path.posix.isAbsolute(value) || path.win32.isAbsolute(value) ||
|
|
13
|
+
/[\\\x00-\x1f\x7f]/.test(value) || value.split('/').some(part => !part || part === '.' || part === '..')) {
|
|
14
|
+
throw new Error(`Artifact path must be a safe repository-relative path: ${String(value)}`);
|
|
15
|
+
}
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
export async function readWorkspaceConfig(repoPath, signal) {
|
|
19
|
+
signal?.throwIfAborted();
|
|
20
|
+
const root = await realpath(repoPath);
|
|
21
|
+
const configPath = path.join(root, 'ccdd.config.json');
|
|
22
|
+
const info = await lstat(configPath).catch(() => null);
|
|
23
|
+
const tsInfo = await lstat(path.join(root, 'ccdd.config.ts')).catch(() => null);
|
|
24
|
+
if (info && tsInfo)
|
|
25
|
+
throw new Error('Both ccdd.config.ts and ccdd.config.json exist; keep one configuration.');
|
|
26
|
+
if (!info?.isFile() && !tsInfo?.isFile())
|
|
27
|
+
throw new Error('Workspace must contain a regular ccdd.config.ts or ccdd.config.json file.');
|
|
28
|
+
let config;
|
|
29
|
+
try {
|
|
30
|
+
if (tsInfo) {
|
|
31
|
+
const host = await openToolHost(root, signal);
|
|
32
|
+
try {
|
|
33
|
+
config = host.config;
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
await host.close();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
config = JSON.parse(await readFile(configPath, 'utf8'));
|
|
41
|
+
if (object(config) && (config.configManifest !== undefined || object(config.artifactTypes) && Object.values(config.artifactTypes).some(value => object(value) && value.custom)))
|
|
42
|
+
throw new Error('Custom tools must be registered in ccdd.config.ts.');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
throw new Error(`Cannot read workspace configuration: ${error instanceof Error ? error.message : String(error)}`);
|
|
47
|
+
}
|
|
48
|
+
// Inspect only declared Artifact roots here. The workspace engine validates the entire input tree.
|
|
49
|
+
const tree = [];
|
|
50
|
+
const visited = new Set();
|
|
51
|
+
const walk = async (relative) => {
|
|
52
|
+
signal?.throwIfAborted();
|
|
53
|
+
if (visited.has(relative))
|
|
54
|
+
return;
|
|
55
|
+
visited.add(relative);
|
|
56
|
+
const absolute = path.join(root, relative);
|
|
57
|
+
const entry = await lstat(absolute).catch(error => { if (errorCode(error) === 'ENOENT')
|
|
58
|
+
return null; throw error; });
|
|
59
|
+
if (!entry)
|
|
60
|
+
return;
|
|
61
|
+
const resolved = await realpath(absolute);
|
|
62
|
+
const sub = path.relative(root, resolved);
|
|
63
|
+
if (path.isAbsolute(sub) || sub === '..' || sub.startsWith(`..${path.sep}`))
|
|
64
|
+
throw new Error(`Artifact escapes the workspace: ${relative}`);
|
|
65
|
+
if (entry.isDirectory()) {
|
|
66
|
+
tree.push({ path: relative, type: 'tree', mode: '040000' });
|
|
67
|
+
for (const name of await readdir(absolute))
|
|
68
|
+
await walk(`${relative}/${name}`);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
tree.push({ path: relative, type: entry.isFile() ? 'blob' : 'unsupported', mode: entry.isSymbolicLink() ? '120000' : '100644' });
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
if (object(config) && object(config.artifacts)) {
|
|
75
|
+
validateArtifactDefinitions(config.artifacts);
|
|
76
|
+
for (const artifact of Object.values(config.artifacts)) {
|
|
77
|
+
if (!isArtifactGroup(artifact))
|
|
78
|
+
await walk(validateRelativePath(artifact.path));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
validateConfig(config, tree);
|
|
82
|
+
return { config };
|
|
83
|
+
}
|
|
84
|
+
export function validateConfig(config, tree) {
|
|
85
|
+
if (!object(config) || !object(config.artifacts) || !object(config.artifactTypes) ||
|
|
86
|
+
!Array.isArray(config.critics) || config.critics.length === 0 || config.critics.length > 32) {
|
|
87
|
+
throw new Error('Config requires artifacts, artifactTypes, and 1–32 critics.');
|
|
88
|
+
}
|
|
89
|
+
for (const [type, definition] of Object.entries(config.artifactTypes)) {
|
|
90
|
+
validateArtifactType(type, definition);
|
|
91
|
+
if (object(definition) && definition.custom && (!object(config.configManifest) || !object(config.configManifest.types) || !Object.hasOwn(config.configManifest.types, type)))
|
|
92
|
+
throw new Error('Custom Artifact type requires a recorded tool manifest.');
|
|
93
|
+
}
|
|
94
|
+
validateArtifactDefinitions(config.artifacts);
|
|
95
|
+
for (const [id, artifact] of Object.entries(config.artifacts)) {
|
|
96
|
+
if (isArtifactGroup(artifact))
|
|
97
|
+
continue;
|
|
98
|
+
if (!Object.hasOwn(config.artifactTypes, artifact.type)) {
|
|
99
|
+
throw new Error(`Invalid artifact definition or unknown type: ${id}`);
|
|
100
|
+
}
|
|
101
|
+
const artifactPath = validateRelativePath(artifact.path);
|
|
102
|
+
const entries = tree.filter(entry => entry.path === artifactPath || entry.path.startsWith(`${artifactPath}/`));
|
|
103
|
+
if (entries.length === 0 || entries.some(entry => !['blob', 'tree'].includes(entry.type) || entry.mode === '120000')) {
|
|
104
|
+
throw new Error(`Artifact must contain workspace files or directories without symlinks: ${id}`);
|
|
105
|
+
}
|
|
106
|
+
if (config.artifactTypes[artifact.type].viewer === 'text' && !entries.some(entry => entry.path === artifactPath && entry.type === 'blob')) {
|
|
107
|
+
throw new Error(`Text viewer requires a file artifact: ${id}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const artifacts = config.artifacts;
|
|
111
|
+
const seen = new Set();
|
|
112
|
+
for (const critic of config.critics) {
|
|
113
|
+
if (!object(critic) || typeof critic.id !== 'string' || !identifier.test(critic.id) || seen.has(critic.id))
|
|
114
|
+
throw new Error('Critic IDs must be unique safe identifiers.');
|
|
115
|
+
seen.add(critic.id);
|
|
116
|
+
if (Object.hasOwn(critic, 'dependsOn') || Object.hasOwn(critic, 'artifacts')) {
|
|
117
|
+
throw new Error(`Critic ${critic.id}: dependsOn/artifacts have been replaced by target (one Artifact ID) and deps (Artifact ID array). Migrate the configuration explicitly; see docs/artifact-graph.md.`);
|
|
118
|
+
}
|
|
119
|
+
if (typeof critic.title !== 'string' || !critic.title.trim() ||
|
|
120
|
+
typeof critic.target !== 'string' || !Object.hasOwn(artifacts, critic.target) ||
|
|
121
|
+
!Array.isArray(critic.deps) || new Set(critic.deps).size !== critic.deps.length ||
|
|
122
|
+
critic.deps.some(id => typeof id !== 'string' || !Object.hasOwn(artifacts, id))) {
|
|
123
|
+
throw new Error(`Critic ${critic.id} requires a title, a known target Artifact and unique known deps.`);
|
|
124
|
+
}
|
|
125
|
+
if (!object(critic.payload) || typeof critic.payload.instruction !== 'string' || !critic.payload.instruction.trim()) {
|
|
126
|
+
throw new Error(`Critic ${critic.id} requires a review request payload instruction.`);
|
|
127
|
+
}
|
|
128
|
+
const profile = critic.profile;
|
|
129
|
+
if (!object(profile) || typeof profile.kind !== 'string' || !['agent', 'runtime', 'human'].includes(profile.kind))
|
|
130
|
+
throw new Error(`Invalid executor profile: ${critic.id}`);
|
|
131
|
+
if (profile.kind === 'agent' && ['provider', 'model', 'reasoning'].some(key => typeof profile[key] !== 'string' || !profile[key].trim())) {
|
|
132
|
+
throw new Error(`Agent profile requires provider, model and reasoning: ${critic.id}`);
|
|
133
|
+
}
|
|
134
|
+
if (profile.kind === 'runtime' && (typeof profile.command !== 'string' || !profile.command.trim() ||
|
|
135
|
+
!Array.isArray(profile.args) || profile.args.some(arg => typeof arg !== 'string'))) {
|
|
136
|
+
throw new Error(`Runtime profile requires command and string args: ${critic.id}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
createGraphDefinition(config);
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/broker/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { ArtifactEntryDefinition, CriticProfile, RepoConfig, ReviewEnvelope, ReviewStatus } from '../contracts.js';
|
|
2
|
+
import type { ValidationStatus } from '../project/types.js';
|
|
3
|
+
export interface GraphCriticDefinition {
|
|
4
|
+
id: string;
|
|
5
|
+
title: string;
|
|
6
|
+
target: string;
|
|
7
|
+
deps: string[];
|
|
8
|
+
kind: CriticProfile['kind'];
|
|
9
|
+
}
|
|
10
|
+
export interface GraphDefinition {
|
|
11
|
+
version: 1;
|
|
12
|
+
artifacts: Record<string, ArtifactEntryDefinition>;
|
|
13
|
+
critics: GraphCriticDefinition[];
|
|
14
|
+
}
|
|
15
|
+
export type ArtifactStatus = 'BASIS' | 'UNREVIEWED' | ReviewStatus;
|
|
16
|
+
export interface GraphRequest {
|
|
17
|
+
id: string;
|
|
18
|
+
criticId: string;
|
|
19
|
+
status: ReviewStatus;
|
|
20
|
+
claimedBy?: string | null;
|
|
21
|
+
blockedReason?: string | null;
|
|
22
|
+
}
|
|
23
|
+
interface GraphArtifactStateBase {
|
|
24
|
+
id: string;
|
|
25
|
+
basis: boolean;
|
|
26
|
+
status: ArtifactStatus;
|
|
27
|
+
criticIds: string[];
|
|
28
|
+
passed: number;
|
|
29
|
+
total: number;
|
|
30
|
+
included: number;
|
|
31
|
+
validationStatus?: ValidationStatus;
|
|
32
|
+
}
|
|
33
|
+
export type GraphArtifactState = GraphArtifactStateBase & ({
|
|
34
|
+
kind?: 'artifact';
|
|
35
|
+
type: string;
|
|
36
|
+
path: string;
|
|
37
|
+
} | {
|
|
38
|
+
kind: 'group';
|
|
39
|
+
members: string[];
|
|
40
|
+
});
|
|
41
|
+
export interface GraphCriticState extends GraphCriticDefinition {
|
|
42
|
+
requestId: string | null;
|
|
43
|
+
status: ReviewStatus | null;
|
|
44
|
+
claimedBy: string | null;
|
|
45
|
+
blockedReason: string | null;
|
|
46
|
+
validationStatus?: ValidationStatus;
|
|
47
|
+
validationReason?: string;
|
|
48
|
+
reusedFrom?: {
|
|
49
|
+
requestId: string;
|
|
50
|
+
runId: string;
|
|
51
|
+
completedAt: string;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export interface GraphProjection {
|
|
55
|
+
artifacts: GraphArtifactState[];
|
|
56
|
+
critics: GraphCriticState[];
|
|
57
|
+
edges: {
|
|
58
|
+
source: string;
|
|
59
|
+
target: string;
|
|
60
|
+
criticIds: string[];
|
|
61
|
+
}[];
|
|
62
|
+
}
|
|
63
|
+
/** Validate only the immutable graph metadata; no payloads, providers or workspace reads. */
|
|
64
|
+
export declare function validateGraphDefinition(value: unknown): asserts value is GraphDefinition;
|
|
65
|
+
export declare function createGraphDefinition(config: RepoConfig): GraphDefinition;
|
|
66
|
+
export declare function prerequisiteCriticIds(request: Pick<ReviewEnvelope, 'deps'>, graph: GraphDefinition): string[];
|
|
67
|
+
/** Call with requests from exactly one Run. Missing evaluations never count as passing. */
|
|
68
|
+
export declare function projectGraph(graph: GraphDefinition, requests: readonly GraphRequest[]): GraphProjection;
|
|
69
|
+
export {};
|