@ccdd/core 3.3.1 → 4.1.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.
Files changed (38) hide show
  1. package/README.md +69 -62
  2. package/dist/src/artifact-scope.d.ts +6 -0
  3. package/dist/src/artifact-scope.js +27 -0
  4. package/dist/src/artifact-scope.js.map +1 -0
  5. package/dist/src/definitions.d.ts +33 -23
  6. package/dist/src/sdk.d.ts +3 -8
  7. package/dist/src/sdk.js +2 -3
  8. package/dist/src/sdk.js.map +1 -1
  9. package/dist/src/tools/contracts.d.ts +44 -80
  10. package/examples/artifact-folders/README.md +18 -0
  11. package/examples/artifact-folders/coding-style/ccdd.json +128 -0
  12. package/examples/artifact-folders/coding-style/style.md +3 -0
  13. package/examples/artifact-folders/explosion/blind-pair.mjs +19 -0
  14. package/examples/artifact-folders/explosion/ccdd.json +220 -0
  15. package/examples/artifact-folders/explosion/effect/ccdd.json +128 -0
  16. package/examples/artifact-folders/explosion/preview/ccdd.json +142 -0
  17. package/examples/artifact-folders/theme-image/ccdd.json +128 -0
  18. package/examples/artifact-folders/theme-image/theme.png +0 -0
  19. package/examples/computed-views/README.md +12 -0
  20. package/examples/computed-views/checkout/ccdd.json +133 -0
  21. package/examples/computed-views/search/ccdd.json +133 -0
  22. package/examples/computed-views/view.mjs +13 -0
  23. package/examples/custom-text-reader/README.md +7 -19
  24. package/examples/custom-text-reader/spec/ccdd.json +60 -0
  25. package/examples/custom-text-reader/view.mjs +20 -0
  26. package/examples/custom-text-reader/why/ccdd.json +46 -0
  27. package/package.json +21 -7
  28. package/examples/artifact-groups/README.md +0 -60
  29. package/examples/artifact-groups/ccdd.config.ts +0 -37
  30. package/examples/custom-text-reader/ccdd.config.ts +0 -64
  31. package/examples/generated-artifacts/README.md +0 -55
  32. package/examples/generated-artifacts/ccdd.config.ts +0 -86
  33. /package/examples/{artifact-groups → artifact-folders/explosion/effect}/effect.md +0 -0
  34. /package/examples/{artifact-groups → artifact-folders/explosion/preview}/preview.png +0 -0
  35. /package/examples/{generated-artifacts/scenarios/checkout.json → computed-views/checkout/scenario.json} +0 -0
  36. /package/examples/{generated-artifacts/scenarios/search.json → computed-views/search/scenario.json} +0 -0
  37. /package/examples/custom-text-reader/{spec.md → spec/spec.md} +0 -0
  38. /package/examples/custom-text-reader/{why.md → why/why.md} +0 -0
package/README.md CHANGED
@@ -1,94 +1,101 @@
1
1
  # CCDD
2
2
 
3
- [![npm: @ccdd/project](https://img.shields.io/npm/v/@ccdd/project?logo=npm&label=%40ccdd%2Fproject)](https://www.npmjs.com/package/@ccdd/project)
4
- [![CDD concept](https://img.shields.io/badge/CDD-Concept-3976c7)](https://cdd.boardsketch.com)
3
+ **Let verification define the project.** Give each Artifact its own criteria and the tools a reviewer needs to inspect it. An Artifact can be code, tests, a specification, an image or any other folder of project material.
5
4
 
6
- **Check that the pieces of your project fit together.**
5
+ Put a `ccdd.json` in that folder. It owns the Artifact's name, view tools and Critics. CCDD finds those declarations, connects references and collects actual review evidence.
7
6
 
8
- A project has requirements, designs, tests, and implementations. CCDD connects these pieces to the checks that review them. An AI agent can compare a design with its requirements, a person can inspect an image, and a test runner can check an implementation.
9
-
10
- You choose the materials, the review criteria, and the tools reviewers can use. CCDD keeps track of what was reviewed and which checks are still needed.
11
-
12
- ## How it fits together
13
-
14
- **Blue dashed lines: configuration. Orange solid lines: requests and reviews.**
15
-
16
- ![CCDD: a Critic DAG, customizable Artifact types and tools, Validation, and Pi-based AI agents, people, and test runners.](.github/assets/how-it-fits-together.png)
17
-
18
- Three terms explain the picture:
19
-
20
- | Term | Meaning | Example |
21
- | --- | --- | --- |
22
- | **Artifact** | A named file, folder, captured data value, or group of materials to review. | `spec.md`, `tests/`, an image, or a generated scenario. |
23
- | **Critic** | A check with one target, reference materials, and a reviewer. | “Does this design meet these requirements?” |
24
- | **Artifact tool** | A way for a reviewer to inspect an Artifact. | Read text, view an image, or open a desktop application. |
25
-
26
- Each Critic declares its target and references. These relationships form a directed acyclic graph, or **DAG**: checks can branch and join, but cannot depend on themselves through a cycle. Design and Tests connect to Implementation through separate Critic lines. Requirements are an explicitly accepted starting point in this example.
27
-
28
- ## What you do
29
-
30
- 1. **Name your materials.** Give each Artifact an ID, a type, and a file/folder path or a source for generated data. Groups collect existing Artifacts.
31
- 2. **Connect tools.** Use the optional default tools or write your own `metadata` and `execute` function. Register them by Artifact type in `ccdd.config.ts`.
32
- 3. **Define checks.** For each Critic, choose the target, its references, the review criteria, and an Agent, Human, or Runtime reviewer.
33
- 4. **Request a review.** Read the findings, update your project, and request another check when needed.
34
-
35
- For example, a document tool registered as `read` becomes `read_spec` when connected to the `spec` Artifact. CCDD gives the Agent its name, description, and input schema. When the Agent calls it, CCDD invokes your local `execute` function against the fixed review input and returns the content to the Agent.
7
+ ```text
8
+ project/
9
+ why/ccdd.json
10
+ spec/ccdd.json
11
+ tests/ccdd.json
12
+ implementation/ccdd.json
13
+ ```
36
14
 
37
- Artifact types act as plugin slots through explicit registration. Importing a tool library does not register or run its tools. Agent and Human tools are registered separately; Runtime reviewers execute configured Node tests against the declared inputs.
15
+ A Critic can ask an Agent to compare Spec with Why, ask a person to compare two images, or run tests against an implementation. It belongs to the Artifact it evaluates. References such as `{spec}` connect it to the other Artifacts it uses.
16
+
17
+ ```mermaid
18
+ flowchart LR
19
+ subgraph Project[Your project]
20
+ Why[Why] -. instruction .-> Spec[Spec]
21
+ Spec -. instruction .-> Tests[Tests]
22
+ Tests -. mount / instruction .-> Implementation[Implementation]
23
+ end
24
+ Project -. folder declarations .-> CCDD
25
+ CCDD --> Agent[Agent review]
26
+ CCDD --> Human[Human review]
27
+ CCDD --> Runtime[Runtime tests]
28
+ Agent --> Evidence[Actual evidence]
29
+ Human --> Evidence
30
+ Runtime --> Evidence
31
+ Evidence --> CCDD
32
+ style Project fill:#eef6ff,stroke:#5c83aa
33
+ style CCDD fill:#eef9ef,stroke:#588060
34
+ ```
38
35
 
39
- ## Try your first review
36
+ These relationships define required input and verification, not execution order. Mutual dependencies are allowed: both Critics may run together, and final validation requires both matching results. Child Artifact folders are automatic dependencies. Logical `mounts` connect other folders without copies or symlinks.
40
37
 
41
- CCDD supports **Node.js 22 LTS (22.19.0 or later)**. Use the latest patch of a supported LTS release.
38
+ ## Start with a runtime check
42
39
 
43
- For published packages, install:
40
+ Use Node.js 22 LTS, version 22.19.0 or later.
44
41
 
45
42
  ```sh
46
- npm install --ignore-scripts @ccdd/core @ccdd/project
43
+ npm install --ignore-scripts @ccdd/core@^4 @ccdd/project@^4
47
44
  ```
48
45
 
49
- Follow [Your first review](docs/getting-started.md) for a complete, small example that runs a real test without an AI account. It also covers installation from local packages when a version has not been published.
46
+ Inside an Artifact folder, create `ccdd.json`:
47
+
48
+ ```json
49
+ {
50
+ "name": "implementation",
51
+ "critics": [{
52
+ "id": "tests",
53
+ "title": "Pass the implementation tests",
54
+ "profile": { "kind": "runtime", "command": "node", "args": ["--test", "check.test.mjs"] },
55
+ "payload": { "instruction": "Run the tests for {implementation}." }
56
+ }]
57
+ }
58
+ ```
50
59
 
51
- Once your project has a configuration, the usual loop is:
60
+ Add your actual `check.test.mjs`, then run from the workspace root:
52
61
 
53
62
  ```sh
54
- npx ccdd-project status
63
+ npx ccdd-project config check
55
64
  npx ccdd-project plan implementation --recursive
56
65
  npx ccdd-project verify implementation --recursive --wait
57
- npx ccdd-project history implementation
66
+ npx ccdd-project status implementation
58
67
  ```
59
68
 
60
- `status` and `plan` explain what is needed without starting reviews. `verify --recursive` includes any required earlier checks. To review only the selected scope, omit `--recursive`; blocked checks are reported as incomplete.
61
-
62
- ## What you get back
69
+ The [getting-started guide](docs/getting-started.md) includes a complete runnable example. Version 4 is a breaking change; existing projects should follow the [migration guide](docs/migration-v4.md).
63
70
 
64
- A completed review contains a **verdict, a summary, and concrete evidence**. GREEN means that Critic's criteria were met; RED means they were not. An execution problem is reported as ERROR. All required Critics must pass before their Artifact satisfies a dependent check.
71
+ ## Read the result
65
72
 
66
- CCDD can reuse an actual passing review when its criteria, target, and direct reference materials still match and its dependencies are satisfied. An unchanged intermediate Artifact can therefore prevent unnecessary downstream reviews.
73
+ Every actual review returns a verdict, summary and concrete evidence. GREEN means its criteria were met; RED means they were not. Execution problems produce ERROR. Final validation needs matching PASS evidence for all required Critics and dependencies. A folder without Critics stays UNREVIEWED unless explicitly declared `basis: true`.
67
74
 
68
- Reviews use a fixed copy of the project by default. Records and generated output live outside the reviewed project. You can keep editing the original while a copied review runs. Reviewers inspect and judge; you or your coding tools make the changes.
75
+ An individual check runs its selected Critics immediately. If other required evidence is missing, their results are saved and the request is INCOMPLETE. Add `--recursive` to include those other evaluations. CCDD reuses matching actual evidence and computes freshness when queried; it does not store stale flags.
69
76
 
70
- ## Choose your next step
77
+ Reviews run in the workspace you supply. Keep it unchanged until completion, including Human waiting. Records, caches and generated output live outside it. To keep editing elsewhere, create your own worktree and pass it with `--repo`.
71
78
 
72
- - [Write an Artifact tool](examples/custom-text-reader/README.md) using the public tool contract.
73
- - [Use default text, file, image, and desktop tools](packages/default-tools/README.md).
74
- - [Review a group of materials](examples/artifact-groups/README.md), such as an effect description and its preview image.
75
- - [Review generated scenario data](docs/generated-artifacts.md) through tools that read a fixed captured value.
76
- - [Use Agent and Human reviewers](docs/reviewers.md), including credentials and result submission.
77
- - [Explore the demo](docs/demo.md): Why → Spec → Tests → Implementation.
78
- - [Look up commands, reuse rules, and exit codes](docs/project-validation.md).
79
+ ## Next steps
79
80
 
80
- An optional local monitor shows current-input checks and saved reviews. Start it with `npx ccdd-project monitor`.
81
+ - [Define a custom view script](examples/custom-text-reader/README.md) with JSON stdin/stdout, using any language.
82
+ - [Register optional text, image and desktop tools](packages/default-tools/README.md).
83
+ - [Compose folders and mounts](examples/artifact-folders/README.md), including coding-style and blind image comparison Critics.
84
+ - [Compute views on demand](examples/computed-views/README.md) from scenario material.
85
+ - [Configure Agent and Human reviewers](docs/reviewers.md).
86
+ - [Try Why → Spec → Tests → Implementation](docs/demo.md).
87
+ - [Look up commands and evidence rules](docs/project-validation.md).
81
88
 
82
- ## Packages and development
89
+ The optional local monitor shows folders, relationships, cycles, review progress and saved results. Start it with `npx ccdd-project monitor`.
83
90
 
84
- | Package | Purpose |
91
+ | Package | Responsibility |
85
92
  | --- | --- |
86
- | `@ccdd/core` | Define Artifacts, Critics, and tools. |
87
- | `@ccdd/project` | Run the CLI, manage reviews, and view their history. |
88
- | `@ccdd/default-tools` | Optional ready-made Artifact tools. |
93
+ | `@ccdd/core` | Public definitions and logical path resolution. |
94
+ | `@ccdd/project` | Validation, CLI, Broker, Executors and monitor. |
95
+ | `@ccdd/default-tools` | Optional common view scripts; no automatic registration. |
89
96
 
90
- The repository, examples, CLI, monitor, and built-in review instructions use English. See [Contributing](CONTRIBUTING.md) for setup and checks, [the context map](CONTEXT-MAP.md) for architecture, and [release instructions](docs/releases.md) for packaging and publication.
97
+ See [Contributing](CONTRIBUTING.md), [the context map](CONTEXT-MAP.md), [detailed contracts](docs/contracts.md) and [release instructions](docs/releases.md). Repository content and review prompts use English.
91
98
 
92
99
  ## License
93
100
 
94
- Licensed under the [MIT License](LICENSE).
101
+ [MIT](LICENSE).
@@ -0,0 +1,6 @@
1
+ import type { ArtifactScope } from './definitions.js';
2
+ /** Resolve logical paths without a filesystem. Every hop consumes path components. */
3
+ export declare function resolveScopePath(scope: ArtifactScope, artifactId: string, path?: string): {
4
+ artifactId: string;
5
+ path: string;
6
+ };
@@ -0,0 +1,27 @@
1
+ /** Resolve logical paths without a filesystem. Every hop consumes path components. */
2
+ export function resolveScopePath(scope, artifactId, path = '') {
3
+ if (typeof path !== 'string' || path.length > 4096 || /[\\\x00-\x1f\x7f:]/.test(path) || path.startsWith('/') || path.split('/').some(part => part === '.' || part === '..' || !part && path !== ''))
4
+ throw new Error('Artifact path must be a safe relative logical path.');
5
+ let current = artifactId, remaining = path;
6
+ for (;;) {
7
+ if (!Object.hasOwn(scope, current))
8
+ throw new Error(`Artifact is outside this review: ${current}`);
9
+ const entry = scope[current];
10
+ if (!remaining)
11
+ return { artifactId: current, path: '' };
12
+ const first = remaining.split('/')[0];
13
+ if (Object.hasOwn(entry.mounts, first)) {
14
+ current = entry.mounts[first];
15
+ remaining = remaining.slice(first.length).replace(/^\//, '');
16
+ continue;
17
+ }
18
+ const child = Object.keys(entry.children).find(name => remaining === name || remaining.startsWith(`${name}/`));
19
+ if (child !== undefined) {
20
+ current = entry.children[child];
21
+ remaining = remaining.slice(child.length).replace(/^\//, '');
22
+ continue;
23
+ }
24
+ return { artifactId: current, path: remaining };
25
+ }
26
+ }
27
+ //# sourceMappingURL=artifact-scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-scope.js","sourceRoot":"","sources":["../../src/artifact-scope.ts"],"names":[],"mappings":"AAEA,sFAAsF;AACtF,MAAM,UAAU,gBAAgB,CAAC,KAAoB,EAAE,UAAkB,EAAE,IAAI,GAAG,EAAE;IAClF,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,IAAI,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IAC7Q,IAAI,OAAO,GAAG,UAAU,EAAE,SAAS,GAAG,IAAI,CAAC;IAC3C,SAAS,CAAC;QACR,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,OAAO,EAAE,CAAC,CAAC;QACnG,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACzD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;YACvC,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAAC,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAAC,SAAS;QACxG,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,KAAK,IAAI,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;QAC/G,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAAC,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAAC,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QACrI,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAClD,CAAC;AACH,CAAC"}
@@ -1,4 +1,5 @@
1
- /** The definition package has no dependency on persistence or review execution. */
1
+ import type { ArtifactViews, EnvironmentRequirement } from './tools/contracts.js';
2
+ /** Public declarations contain data only; discovery never executes code. */
2
3
  export interface AgentProfile {
3
4
  kind: 'agent';
4
5
  provider: string;
@@ -23,8 +24,6 @@ export interface ReviewPayload {
23
24
  export interface CriticDefinition {
24
25
  id: string;
25
26
  title: string;
26
- target: string;
27
- deps: string[];
28
27
  profile: CriticProfile;
29
28
  payload: ReviewPayload;
30
29
  }
@@ -34,32 +33,43 @@ export type StaleStrategy = {
34
33
  } | {
35
34
  kind: 'always';
36
35
  };
37
- export interface ArtifactDefinition {
38
- type: string;
39
- path: string;
36
+ export interface ArtifactManifest {
37
+ name: string;
38
+ critics?: CriticDefinition[];
39
+ views?: ArtifactViews;
40
+ mounts?: Record<string, string>;
40
41
  basis?: boolean;
41
42
  stale?: StaleStrategy;
43
+ envRequirements?: Record<string, EnvironmentRequirement>;
42
44
  }
43
- export interface ArtifactGroupDefinition {
44
- kind: 'group';
45
- members: string[];
45
+ export interface ArtifactDefinition {
46
+ name: string;
47
+ path: string;
48
+ views: ArtifactViews;
49
+ mounts: Record<string, string>;
50
+ /** Nearest marked descendants, indexed by their physical relative paths. */
51
+ children: Record<string, string>;
46
52
  basis?: boolean;
47
53
  stale?: StaleStrategy;
54
+ envRequirements?: Record<string, EnvironmentRequirement>;
48
55
  }
49
- /** Generated material is captured separately from configuration evaluation. */
50
- export interface GeneratedArtifactDefinition {
51
- kind: 'generated';
52
- type: string;
56
+ export interface ResolvedCriticDefinition extends CriticDefinition {
57
+ localId: string;
58
+ target: string;
59
+ deps: string[];
60
+ /** Original instruction names map to canonical Artifact identities. */
61
+ references: Record<string, string>;
62
+ }
63
+ export interface ArtifactRelation {
53
64
  source: string;
54
- params?: import('./tools/contracts.js').JsonValue;
55
- basis?: boolean;
56
- stale?: {
57
- kind: 'always';
58
- };
59
- path?: never;
65
+ target: string;
66
+ kind: 'child' | 'mount' | 'instruction';
67
+ name?: string;
68
+ criticId?: string;
60
69
  }
61
- export type ArtifactEntryDefinition = ArtifactDefinition | GeneratedArtifactDefinition | ArtifactGroupDefinition;
62
- export interface ArtifactGroupReference {
63
- id: string;
64
- members: string[];
70
+ export interface ArtifactScopeEntry {
71
+ path: string;
72
+ children: Record<string, string>;
73
+ mounts: Record<string, string>;
65
74
  }
75
+ export type ArtifactScope = Record<string, ArtifactScopeEntry>;
package/dist/src/sdk.d.ts CHANGED
@@ -1,15 +1,10 @@
1
- import type { ArtifactSourceDefinition, DataToolContext, Config, ConfigFactory, InferSchema, JsonSchema, ToolDefinition, ToolMetadata } from './tools/contracts.js';
1
+ import type { InferSchema, JsonSchema, ToolDefinition, ToolMetadata } from './tools/contracts.js';
2
2
  export type * from './tools/contracts.js';
3
3
  export type * from './definitions.js';
4
- export declare function defineConfig<T extends Config | ConfigFactory>(config: T): T;
4
+ export { resolveScopePath } from './artifact-scope.js';
5
+ /** An optional script-authoring helper, not a configuration registration API. */
5
6
  export declare function defineTool<const S extends JsonSchema>(tool: Omit<ToolDefinition<InferSchema<S>>, 'metadata'> & {
6
7
  metadata: Omit<ToolMetadata, 'inputSchema'> & {
7
8
  inputSchema: S;
8
9
  };
9
10
  }): ToolDefinition<InferSchema<S>>;
10
- export declare function defineDataTool<const S extends JsonSchema>(tool: Omit<ToolDefinition<InferSchema<S>, DataToolContext>, 'metadata'> & {
11
- metadata: Omit<ToolMetadata, 'inputSchema' | 'artifactKind'> & {
12
- inputSchema: S;
13
- };
14
- }): ToolDefinition<InferSchema<S>, DataToolContext>;
15
- export declare function defineArtifactSource(source: ArtifactSourceDefinition): ArtifactSourceDefinition;
package/dist/src/sdk.js CHANGED
@@ -1,5 +1,4 @@
1
- export function defineConfig(config) { return config; }
1
+ export { resolveScopePath } from './artifact-scope.js';
2
+ /** An optional script-authoring helper, not a configuration registration API. */
2
3
  export function defineTool(tool) { return tool; }
3
- export function defineDataTool(tool) { return { ...tool, metadata: { ...tool.metadata, artifactKind: 'data' } }; }
4
- export function defineArtifactSource(source) { return source; }
5
4
  //# sourceMappingURL=sdk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/sdk.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,YAAY,CAAmC,MAAS,IAAO,OAAO,MAAM,CAAC,CAAC,CAAC;AAC/F,MAAM,UAAU,UAAU,CAA6B,IAA6H,IAAoC,OAAO,IAAI,CAAC,CAAC,CAAC;AACtO,MAAM,UAAU,cAAc,CAA6B,IAA+J,IAAqD,OAAO,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;AAC1V,MAAM,UAAU,oBAAoB,CAAC,MAAgC,IAA8B,OAAO,MAAM,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/sdk.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,iFAAiF;AACjF,MAAM,UAAU,UAAU,CAA6B,IAA6H,IAAoC,OAAO,IAAI,CAAC,CAAC,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { ArtifactEntryDefinition, CriticDefinition } from '../definitions.js';
1
+ import type { ArtifactDefinition, ArtifactManifest, ArtifactScope } from '../definitions.js';
2
2
  export type JsonValue = null | boolean | number | string | JsonValue[] | {
3
3
  [key: string]: JsonValue;
4
4
  };
@@ -9,21 +9,22 @@ export interface ToolMetadata {
9
9
  inputSchema: JsonSchema;
10
10
  resultKinds: ToolResultKind[];
11
11
  observation: 'content' | 'none';
12
- artifactKind?: 'file' | 'directory' | 'any' | 'data';
12
+ artifactKind?: 'file' | 'directory' | 'any';
13
13
  timeoutMs?: number;
14
- /** Project-relative runtime files or directories whose bytes affect this tool. */
14
+ /** Workspace-relative runtime material whose content affects this tool. */
15
15
  executionPaths?: string[];
16
16
  }
17
- export interface ToolContext {
18
- artifactId: string;
19
- artifactPath: string;
20
- artifactDirectory: boolean;
21
- outputDir: string;
22
- tmpDir: string;
23
- signal: AbortSignal;
24
- resolvePath(path?: string): Promise<string>;
25
- /** Resolve only paths explicitly registered in metadata.executionPaths. */
26
- resolveExecutionPath?(path: string): Promise<string>;
17
+ export interface ScriptDefinition {
18
+ command: string;
19
+ args: string[];
20
+ }
21
+ export interface ScriptToolDefinition {
22
+ metadata: ToolMetadata;
23
+ script: ScriptDefinition;
24
+ }
25
+ export interface ArtifactViews {
26
+ agentTools?: Record<string, ScriptToolDefinition>;
27
+ humanTools?: Record<string, ScriptToolDefinition>;
27
28
  }
28
29
  export type ToolContent = {
29
30
  type: 'text';
@@ -43,59 +44,40 @@ export type ToolContent = {
43
44
  type: 'launch';
44
45
  launched: true;
45
46
  };
46
- export interface ToolResult {
47
+ export type ToolResult = {
47
48
  content: ToolContent[];
48
49
  observation?: {
49
50
  kind: 'content' | 'empty';
50
51
  detail?: string;
51
52
  };
52
- }
53
- /** Data tools receive only their bound, captured Artifact data. */
54
- export interface DataToolContext {
53
+ isError?: never;
54
+ } | {
55
+ isError: true;
56
+ content: [{
57
+ type: 'text';
58
+ text: string;
59
+ }];
60
+ observation?: never;
61
+ };
62
+ export interface ScriptToolContext {
55
63
  artifactId: string;
64
+ artifactPath: string;
56
65
  outputDir: string;
57
66
  tmpDir: string;
58
- signal: AbortSignal;
59
- readData(): JsonValue;
60
- resolveExecutionPath(path: string): Promise<string>;
67
+ /** Canonical paths and logical connections for this review's allowed scope. */
68
+ scope: ArtifactScope;
61
69
  }
62
- export interface ArtifactIdentityStrategy {
63
- kind: 'canonical-data' | 'immutable-revision' | 'custom';
64
- namespace: string;
65
- version: string;
66
- }
67
- export interface ArtifactSourceMetadata {
68
- identity: ArtifactIdentityStrategy;
69
- /** Queries may invoke only sources explicitly declaring read-only preparation. */
70
- preparation: 'read-only' | 'explicit';
71
- timeoutMs?: number;
70
+ export interface ScriptToolRequest {
71
+ version: 1;
72
+ context: ScriptToolContext;
73
+ args: Record<string, unknown>;
72
74
  }
73
- export interface ArtifactSourceContext {
74
- artifactId: string;
75
- params: JsonValue;
75
+ /** Convenience interface for script authors. Project never imports these functions. */
76
+ export interface ToolContext extends ScriptToolContext {
77
+ artifactDirectory: boolean;
76
78
  signal: AbortSignal;
77
- /** Resolve captured project files, never the mutable original copy source. */
78
- resolvePath(path: string): Promise<string>;
79
- }
80
- export interface ArtifactSourceResult {
81
- data: JsonValue;
82
- revision?: string;
83
- }
84
- export interface ArtifactSourceDefinition {
85
- metadata: ArtifactSourceMetadata;
86
- prepare(context: ArtifactSourceContext): ArtifactSourceResult | Promise<ArtifactSourceResult>;
87
- /** A custom identity asserts equivalence of the complete supplied data. */
88
- fingerprint?(data: JsonValue): string | Promise<string>;
89
- }
90
- export interface PreparedArtifactData {
91
- version: 1;
92
- identity: ArtifactIdentityStrategy & {
93
- fingerprint: string;
94
- };
95
- /** Integrity hash of the canonical data, independent of semantic equivalence. */
96
- contentHash: string;
97
- data: JsonValue;
98
- revision?: string;
79
+ resolvePath(path?: string): Promise<string>;
80
+ resolveExecutionPath?(path: string): Promise<string>;
99
81
  }
100
82
  export interface ToolDefinition<Args = Record<string, unknown>, Context = ToolContext> {
101
83
  metadata: ToolMetadata;
@@ -108,48 +90,31 @@ export interface ToolDefinition<Args = Record<string, unknown>, Context = ToolCo
108
90
  message: string;
109
91
  }>;
110
92
  }
111
- export interface ArtifactToolsConfig {
112
- agentTools?: Record<string, ToolDefinition<any, any>>;
113
- humanTools?: Record<string, ToolDefinition<any, any>>;
114
- }
115
93
  export interface EnvironmentRequirement {
116
94
  description: string;
117
- /** Project-relative Node script; a zero exit status confirms readiness. */
118
95
  script: string;
119
96
  timeoutMs?: number;
120
- /** Additional project files or directories used by the check. */
121
97
  inputs?: string[];
122
98
  }
123
- export interface Config {
124
- artifacts: Record<string, ArtifactEntryDefinition>;
125
- artifactTypes: Record<string, ArtifactToolsConfig>;
126
- critics: CriticDefinition[];
127
- envRequirements?: Record<string, EnvironmentRequirement>;
128
- artifactSources?: Record<string, ArtifactSourceDefinition>;
129
- }
130
- export type ConfigFactory = () => Config | Promise<Config>;
131
99
  export interface ConfigManifest {
132
- version: 1;
100
+ version: 2;
133
101
  configHash: string;
134
- modules: {
102
+ artifacts: Record<string, ArtifactDefinition>;
103
+ declarations: {
135
104
  path: string;
136
105
  hash: string;
137
106
  }[];
138
- types: Record<string, {
139
- agentTools: Record<string, ToolMetadata>;
140
- humanTools: Record<string, ToolMetadata>;
141
- }>;
142
- envRequirements?: Record<string, EnvironmentRequirement>;
143
- environmentInputs?: {
107
+ executionInputs?: {
144
108
  path: string;
145
109
  hash: string;
146
110
  }[];
147
- executionInputs?: {
111
+ envRequirements?: Record<string, EnvironmentRequirement>;
112
+ environmentInputs?: {
148
113
  path: string;
149
114
  hash: string;
150
115
  }[];
151
- sources?: Record<string, ArtifactSourceMetadata>;
152
116
  }
117
+ export type { ArtifactManifest };
153
118
  type Properties<S> = S extends {
154
119
  properties: infer P;
155
120
  } ? P : {};
@@ -176,4 +141,3 @@ export type InferSchema<S> = S extends {
176
141
  } & {
177
142
  [K in keyof Properties<S> as K extends RequiredKeys<S> ? never : K]?: InferSchema<Properties<S>[K]>;
178
143
  } : unknown;
179
- export {};
@@ -0,0 +1,18 @@
1
+ # Folder composition and logical mounts
2
+
3
+ `explosion/ccdd.json` owns the parent's tools and Critics. The nearest marked children, `effect` and `preview`, remain separate Artifacts. The parent automatically depends on both. `style` and `theme` are logical mounts to sibling Artifacts; no directories, copies or symlinks are created for them.
4
+
5
+ Install `@ccdd/core`, `@ccdd/project` and `@ccdd/default-tools` in this directory, then run:
6
+
7
+ ```sh
8
+ ccdd-project config check
9
+ ccdd-project graph explosion --json
10
+ ccdd-project tools check --artifact explosion --for agent --tool blind_pair --execute
11
+ ccdd-project verify explosion --recursive --wait
12
+ ```
13
+
14
+ The last command uses real Agent evaluation. No verdict is included in this example. The theme and screenshot intentionally use the same supplied sample image; replace them before using this as a project criterion.
15
+
16
+ The coding-style Critic references `{style}` through the existing instruction template. The blind comparison procedure is a normal user script: it resolves the theme mount and preview child, randomizes A/B, returns images, and writes its private mapping to the external output directory. The Critic instructs its reviewer not to open named views. That is a review procedure, not an access-control guarantee against a reviewer who deliberately ignores it. CCDD adds no presentation-specific runner. The other Critic demonstrates direct `{effect}` and `{preview}` references.
17
+
18
+ Repeated mounts share the canonical Artifact and its evidence. Each Artifact controls its own tools; parent declarations do not merge child Critics or views.