contract-driven-delivery 1.7.0 → 1.8.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 (45) hide show
  1. package/assets/skills/cdd-init/SKILL.md +162 -0
  2. package/assets/skills/cdd-new/SKILL.md +162 -0
  3. package/dist/cli/index.js +20 -14
  4. package/package.json +1 -1
  5. /package/assets/{skill → skills/contract-driven-delivery}/SKILL.md +0 -0
  6. /package/assets/{skill → skills/contract-driven-delivery}/references/api-contract-standard.md +0 -0
  7. /package/assets/{skill → skills/contract-driven-delivery}/references/business-logic-standard.md +0 -0
  8. /package/assets/{skill → skills/contract-driven-delivery}/references/ci-cd-policy.md +0 -0
  9. /package/assets/{skill → skills/contract-driven-delivery}/references/css-contract-standard.md +0 -0
  10. /package/assets/{skill → skills/contract-driven-delivery}/references/data-contract-standard.md +0 -0
  11. /package/assets/{skill → skills/contract-driven-delivery}/references/e2e-standard.md +0 -0
  12. /package/assets/{skill → skills/contract-driven-delivery}/references/env-contract-standard.md +0 -0
  13. /package/assets/{skill → skills/contract-driven-delivery}/references/monkey-operation-standard.md +0 -0
  14. /package/assets/{skill → skills/contract-driven-delivery}/references/qa-gates.md +0 -0
  15. /package/assets/{skill → skills/contract-driven-delivery}/references/sdd-tdd-policy.md +0 -0
  16. /package/assets/{skill → skills/contract-driven-delivery}/references/spec-drift-policy.md +0 -0
  17. /package/assets/{skill → skills/contract-driven-delivery}/references/stress-soak-standard.md +0 -0
  18. /package/assets/{skill → skills/contract-driven-delivery}/references/visual-review-standard.md +0 -0
  19. /package/assets/{skill → skills/contract-driven-delivery}/references/workflow-router.md +0 -0
  20. /package/assets/{skill → skills/contract-driven-delivery}/scripts/detect_project_profile.py +0 -0
  21. /package/assets/{skill → skills/contract-driven-delivery}/scripts/generate_change_scaffold.py +0 -0
  22. /package/assets/{skill → skills/contract-driven-delivery}/scripts/validate_api_semantic.py +0 -0
  23. /package/assets/{skill → skills/contract-driven-delivery}/scripts/validate_ci_gates.py +0 -0
  24. /package/assets/{skill → skills/contract-driven-delivery}/scripts/validate_contract_versions.py +0 -0
  25. /package/assets/{skill → skills/contract-driven-delivery}/scripts/validate_contracts.py +0 -0
  26. /package/assets/{skill → skills/contract-driven-delivery}/scripts/validate_env_contract.py +0 -0
  27. /package/assets/{skill → skills/contract-driven-delivery}/scripts/validate_env_semantic.py +0 -0
  28. /package/assets/{skill → skills/contract-driven-delivery}/scripts/validate_spec_traceability.py +0 -0
  29. /package/assets/{skill → skills/contract-driven-delivery}/templates/archive.md +0 -0
  30. /package/assets/{skill → skills/contract-driven-delivery}/templates/change-classification.md +0 -0
  31. /package/assets/{skill → skills/contract-driven-delivery}/templates/change-request.md +0 -0
  32. /package/assets/{skill → skills/contract-driven-delivery}/templates/ci-gates.md +0 -0
  33. /package/assets/{skill → skills/contract-driven-delivery}/templates/contracts.md +0 -0
  34. /package/assets/{skill → skills/contract-driven-delivery}/templates/current-behavior.md +0 -0
  35. /package/assets/{skill → skills/contract-driven-delivery}/templates/design.md +0 -0
  36. /package/assets/{skill → skills/contract-driven-delivery}/templates/monkey-test-report.md +0 -0
  37. /package/assets/{skill → skills/contract-driven-delivery}/templates/project-profile.md +0 -0
  38. /package/assets/{skill → skills/contract-driven-delivery}/templates/proposal.md +0 -0
  39. /package/assets/{skill → skills/contract-driven-delivery}/templates/qa-report.md +0 -0
  40. /package/assets/{skill → skills/contract-driven-delivery}/templates/regression-report.md +0 -0
  41. /package/assets/{skill → skills/contract-driven-delivery}/templates/spec.md +0 -0
  42. /package/assets/{skill → skills/contract-driven-delivery}/templates/stress-soak-report.md +0 -0
  43. /package/assets/{skill → skills/contract-driven-delivery}/templates/tasks.md +0 -0
  44. /package/assets/{skill → skills/contract-driven-delivery}/templates/test-plan.md +0 -0
  45. /package/assets/{skill → skills/contract-driven-delivery}/templates/visual-review-report.md +0 -0
@@ -0,0 +1,162 @@
1
+ ---
2
+ name: cdd-init
3
+ description: Initialize contract-driven delivery for a project. Handles both brand-new projects (no specs/ directory) and brownfield adoption (existing codebase). Run once per project before using /cdd-new.
4
+ ---
5
+
6
+ # cdd-init — Project Initialization
7
+
8
+ ## Overview
9
+
10
+ This skill sets up the contract-driven delivery system for a project. It auto-detects whether this is a new project or brownfield adoption and follows the appropriate path.
11
+
12
+ ---
13
+
14
+ ## Step 1: Detect project type
15
+
16
+ Run these commands from the repository root:
17
+
18
+ ```
19
+ cdd-kit detect-stack
20
+ ```
21
+
22
+ Then check whether `specs/` directory already exists in the repo root.
23
+
24
+ - `specs/` does **NOT** exist → **New Project** → follow Section A
25
+ - `specs/` **already exists** → **Brownfield Adoption** → follow Section B
26
+
27
+ ---
28
+
29
+ ## Section A: New Project
30
+
31
+ ### A1. Initialize scaffold
32
+
33
+ ```
34
+ cdd-kit init
35
+ ```
36
+
37
+ Creates: `specs/`, `contracts/` (if not present), CI template for detected stack.
38
+
39
+ ### A2. Install pre-commit hook
40
+
41
+ ```
42
+ cdd-kit install-hooks
43
+ ```
44
+
45
+ ### A3. Scan project baseline
46
+
47
+ Invoke `repo-context-scanner` agent to scan the repository and emit an initial project profile. Write output to `specs/project-profile.md`.
48
+
49
+ ### A4. Create stub contracts
50
+
51
+ For each surface the scanner found, create stub files in `contracts/` using frontmatter `version: 0.1.0` and `status: draft`:
52
+
53
+ | Surface | File |
54
+ |---------|------|
55
+ | API endpoints found | `contracts/api.md` |
56
+ | Env variables found | `contracts/env.md` |
57
+ | Data/report shapes found | `contracts/data.md` (skip if none) |
58
+
59
+ Use the standard table format from `.claude/skills/contract-driven-delivery/references/api-contract-standard.md` and `env-contract-standard.md` as the column schema.
60
+
61
+ **Note**: 0.x contracts are informational only — `cdd-kit gate` does not enforce them until bumped to 1.0.0.
62
+
63
+ ### A5. Report to user
64
+
65
+ Output a summary:
66
+ ```
67
+ ## cdd-init complete (new project)
68
+
69
+ Stack detected: <stack>
70
+ Files created:
71
+ - specs/ (scaffold)
72
+ - contracts/api.md (draft, v0.1.0)
73
+ - contracts/env.md (draft, v0.1.0)
74
+ Hook installed: .git/hooks/pre-commit
75
+
76
+ Next step: /cdd-new <describe your first feature or change>
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Section B: Brownfield Adoption
82
+
83
+ ### B1. Initialize scaffold (non-destructive)
84
+
85
+ ```
86
+ cdd-kit init
87
+ ```
88
+
89
+ Will not overwrite existing files. Creates missing scaffold directories only.
90
+
91
+ ### B2. Install pre-commit hook
92
+
93
+ ```
94
+ cdd-kit install-hooks
95
+ ```
96
+
97
+ Idempotent — safe to run even if hook already exists.
98
+
99
+ ### B3. Scan existing project
100
+
101
+ Invoke `repo-context-scanner` agent with full scope:
102
+ - Tech stack and commands
103
+ - Existing contracts (if any)
104
+ - Existing tests and CI/CD
105
+ - Standardization gaps vs cdd-kit expectations
106
+
107
+ Write output to `specs/project-profile.md`.
108
+
109
+ ### B4. Reverse-engineer draft contracts
110
+
111
+ For each existing surface discovered by the scanner, create or update draft contracts:
112
+
113
+ - **API**: Read existing route definitions → list endpoints in `contracts/api.md` using the standard table format (method, path, auth, request shape, response shape). Set `version: 0.1.0`, `status: draft`.
114
+ - **Env**: Read existing `.env.example`, config loaders, or runtime env reads → list variables in `contracts/env.md` (name, required, default, secret). Set `version: 0.1.0`, `status: draft`.
115
+ - **Data**: If report shapes, DB schemas, or shared data types exist and are significant → list in `contracts/data.md`. Set `version: 0.1.0`, `status: draft`.
116
+
117
+ **Rules for brownfield reverse-engineering**:
118
+ - Document what exists — do NOT prescribe what should exist
119
+ - Mark all fields you are unsure about with `<!-- verify -->`
120
+ - Do NOT bump any contract above 0.x during init
121
+ - Do NOT delete or overwrite any existing `contracts/` files — append sections if a file exists
122
+
123
+ ### B5. Run gap analysis
124
+
125
+ Invoke `spec-drift-auditor` to compare the current state against cdd-kit expectations. Ask it to produce:
126
+ 1. What is already in place (contracts, tests, CI gates)
127
+ 2. What is missing and at what priority
128
+ 3. Recommended first tracked change to close the highest-risk gap
129
+
130
+ ### B6. Report to user
131
+
132
+ Output a summary:
133
+ ```
134
+ ## cdd-init complete (brownfield adoption)
135
+
136
+ Stack detected: <stack>
137
+ Contracts reverse-engineered (all at v0.1.0 draft):
138
+ - contracts/api.md — <N> endpoints documented
139
+ - contracts/env.md — <N> variables documented
140
+ Hook installed: .git/hooks/pre-commit
141
+
142
+ Gap report:
143
+ ## Existing (found)
144
+ - ...
145
+
146
+ ## Missing (needs work)
147
+ - ...
148
+
149
+ ## Recommended first tracked change
150
+ - ...
151
+
152
+ Next step: /cdd-new <describe the gap or feature to address first>
153
+ ```
154
+
155
+ ---
156
+
157
+ ## Rules
158
+
159
+ - Never delete existing files
160
+ - Never bump any contract version above 0.x during init
161
+ - Gate enforcement (cdd-kit gate) is only required once contracts reach 1.0.0 — during init, draft contracts are informational
162
+ - If `cdd-kit init` fails because the tool is not installed, instruct the user: `npm install -g contract-driven-delivery@latest`
@@ -0,0 +1,162 @@
1
+ ---
2
+ name: cdd-new
3
+ description: Start a new tracked change. Scaffolds all required artifacts, classifies the change by risk tier, commissions the right agents in order, and runs cdd-kit gate. Args: <change description in natural language>
4
+ ---
5
+
6
+ # cdd-new — New Change Request
7
+
8
+ ## Input
9
+
10
+ The skill argument is the user's change description in natural language (e.g., "add JWT authentication to the API" or "redesign the dashboard homepage").
11
+
12
+ If no description is provided, ask the user: "Please describe the change you want to make."
13
+
14
+ ---
15
+
16
+ ## Step 1: Generate change-id and scaffold
17
+
18
+ Derive a `change-id` from the description:
19
+ - kebab-case, max 5 words
20
+ - examples: `add-jwt-auth`, `redesign-dashboard-home`, `fix-order-export-timeout`
21
+
22
+ Check that `specs/changes/<change-id>/` does not already exist. If it does, append `-2` (or next available suffix).
23
+
24
+ Run the scaffold generator:
25
+
26
+ ```
27
+ python .claude/skills/contract-driven-delivery/scripts/generate_change_scaffold.py <change-id>
28
+ ```
29
+
30
+ If the script is unavailable, manually create `specs/changes/<change-id>/` and copy these template files:
31
+
32
+ | Source | Destination |
33
+ |--------|-------------|
34
+ | `.claude/skills/contract-driven-delivery/templates/change-request.md` | `specs/changes/<change-id>/change-request.md` |
35
+ | `.claude/skills/contract-driven-delivery/templates/change-classification.md` | `specs/changes/<change-id>/change-classification.md` |
36
+ | `.claude/skills/contract-driven-delivery/templates/test-plan.md` | `specs/changes/<change-id>/test-plan.md` |
37
+ | `.claude/skills/contract-driven-delivery/templates/ci-gates.md` | `specs/changes/<change-id>/ci-gates.md` |
38
+ | `.claude/skills/contract-driven-delivery/templates/tasks.md` | `specs/changes/<change-id>/tasks.md` |
39
+
40
+ Fill in `change-request.md`:
41
+ - `## Original Request` → the user's exact description
42
+ - `## Business / User Goal` → infer from context
43
+ - `## Requested Delivery Date / Priority` → "as soon as possible" if not specified
44
+
45
+ ---
46
+
47
+ ## Step 2: Classify the change
48
+
49
+ Invoke `change-classifier` agent with:
50
+ - The user's change description
51
+ - The project profile at `specs/project-profile.md` (if it exists)
52
+ - The existing contracts in `contracts/` (if any)
53
+
54
+ The classifier must write a complete `specs/changes/<change-id>/change-classification.md` including:
55
+ - Risk tier (Tier 0–5, or low / medium / high / critical)
56
+ - Affected surfaces (API, UI, env, data, CI)
57
+ - List of required agents
58
+
59
+ Wait for `change-classification.md` to be written before continuing.
60
+
61
+ ---
62
+
63
+ ## Step 3: Read the tier and commission agents
64
+
65
+ Read `change-classification.md` to determine the tier. Then invoke agents **in the exact order below**, waiting for each to complete its `specs/changes/<change-id>/agent-log/<agent-name>.md` before proceeding.
66
+
67
+ ### Tier 4–5 (low risk: docs, prompts, config-only, no behavior change)
68
+
69
+ 1. `contract-reviewer` — confirm no contracts are touched or all touched ones are already updated
70
+ 2. `qa-reviewer` — confirm release readiness
71
+
72
+ ### Tier 2–3 (normal: feature, enhancement, bug fix with behavior change)
73
+
74
+ 1. `contract-reviewer` — update or create contracts in `contracts/` before any implementation starts
75
+ 2. `test-strategist` — author `specs/changes/<change-id>/test-plan.md`
76
+ 3. `spec-architect` — only if the classifier flagged an architectural boundary or cross-module impact
77
+ 4. `backend-engineer` — if the change touches server, API, data, or business logic
78
+ 5. `frontend-engineer` — if the change touches UI, components, or client-side behavior
79
+ 6. `ui-ux-reviewer` — if any UI change (run alongside or after frontend-engineer)
80
+ 7. `visual-reviewer` — if any UI change (run after ui-ux-reviewer)
81
+ 8. `dependency-security-reviewer` — if the change touches lockfiles, package manifests, or DB migrations
82
+ 9. `ci-cd-gatekeeper` — update `specs/changes/<change-id>/ci-gates.md`
83
+ 10. `qa-reviewer` — release readiness decision
84
+
85
+ ### Tier 0–1 (high risk: production data, concurrency, queues, large queries, auth, payments, exports)
86
+
87
+ All agents from Tier 2–3, plus insert these after `frontend-engineer` / `backend-engineer`:
88
+
89
+ - `e2e-resilience-engineer` — E2E, failure-injection, data-boundary tests
90
+ - `monkey-test-engineer` — adversarial input, fuzz, rapid-UI-action tests
91
+ - `stress-soak-engineer` — load, soak, and long-running stability tests
92
+
93
+ **Agent commission rules**:
94
+ - Skip an agent only if the classifier explicitly marks its surface as "not affected"
95
+ - If any agent sets `status: blocked` in its log, halt immediately and report the agent's `next-action` to the user — do not proceed to subsequent agents
96
+ - If the change is UI-only with no backend, skip `backend-engineer`; if backend-only with no UI, skip `frontend-engineer`, `ui-ux-reviewer`, `visual-reviewer`
97
+
98
+ ---
99
+
100
+ ## Step 4: Run the gate
101
+
102
+ After all required agents have completed:
103
+
104
+ ```
105
+ cdd-kit gate <change-id>
106
+ ```
107
+
108
+ **If gate passes**: proceed to Step 5.
109
+
110
+ **If gate fails**:
111
+ 1. Read the gate error output carefully
112
+ 2. Identify which artifact is missing, stub, or invalid
113
+ 3. Re-invoke the specific agent responsible for that artifact with the exact fix required
114
+ 4. Re-run `cdd-kit gate <change-id>`
115
+ 5. Repeat until gate passes (max 3 iterations; if still failing after 3, report to user)
116
+
117
+ ---
118
+
119
+ ## Step 5: Report to user
120
+
121
+ Output a final summary:
122
+
123
+ ```
124
+ ## /cdd-new complete
125
+
126
+ Change ID: <change-id>
127
+ Risk tier: <tier>
128
+ Agents invoked: <list in order>
129
+ Gate: PASSED
130
+
131
+ All artifacts written to: specs/changes/<change-id>/
132
+
133
+ Next step:
134
+ git add specs/changes/<change-id>/
135
+ git add <any implementation files changed>
136
+ git commit -m "feat(<change-id>): <one-line description>"
137
+ ```
138
+
139
+ If gate did not pass after 3 iterations:
140
+
141
+ ```
142
+ ## /cdd-new — gate blocked
143
+
144
+ Change ID: <change-id>
145
+ Gate failed after 3 attempts.
146
+
147
+ Blocking items:
148
+ - <item 1>
149
+ - <item 2>
150
+
151
+ Please review the above items and re-run: cdd-kit gate <change-id>
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Rules
157
+
158
+ - Never start implementation (backend/frontend-engineer) before `contract-reviewer` has completed for Tier 0–3 changes
159
+ - Never skip `test-plan.md` for Tier 0–3 changes
160
+ - Never skip `ci-gates.md` for any implementation change
161
+ - Every agent must write its `agent-log/<name>.md` — the gate will reject changes missing it
162
+ - `qa-reviewer` always runs last and makes the release-readiness decision
package/dist/cli/index.js CHANGED
@@ -6,7 +6,7 @@ import { Command } from "commander";
6
6
 
7
7
  // src/commands/init.ts
8
8
  import { join as join4 } from "path";
9
- import { rmSync, readFileSync as readFileSync2, writeFileSync, existsSync as existsSync3 } from "fs";
9
+ import { rmSync, readFileSync as readFileSync2, writeFileSync, existsSync as existsSync3, readdirSync as readdirSync2 } from "fs";
10
10
 
11
11
  // src/utils/paths.ts
12
12
  import { join, dirname } from "path";
@@ -20,7 +20,8 @@ var AGENTS_HOME = join(CLAUDE_HOME, "agents");
20
20
  var SKILLS_HOME = join(CLAUDE_HOME, "skills");
21
21
  var ASSET = {
22
22
  agents: join(ASSETS_DIR, "agents"),
23
- skill: join(ASSETS_DIR, "skill"),
23
+ skills: join(ASSETS_DIR, "skills"),
24
+ skill: join(ASSETS_DIR, "skills", "contract-driven-delivery"),
24
25
  contracts: join(ASSETS_DIR, "contracts"),
25
26
  specsTemplates: join(ASSETS_DIR, "specs-templates"),
26
27
  testsTemplates: join(ASSETS_DIR, "tests-templates"),
@@ -283,11 +284,16 @@ async function init(opts) {
283
284
  const { count: agentCount, created: agentCreated } = copyDirTracked(ASSET.agents, AGENTS_HOME, { overwrite: true });
284
285
  track(agentCreated);
285
286
  log.ok(`${agentCount} agent file(s) installed.`);
286
- const skillDest = join4(SKILLS_HOME, "contract-driven-delivery");
287
- log.info(`Installing skill \u2192 ${skillDest}`);
288
- const { count: skillCount, created: skillCreated } = copyDirTracked(ASSET.skill, skillDest, { overwrite: true });
289
- track(skillCreated);
290
- log.ok(`${skillCount} skill file(s) installed.`);
287
+ const skillDirs = readdirSync2(ASSET.skills, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
288
+ let totalSkillFiles = 0;
289
+ for (const skillName of skillDirs) {
290
+ const skillDest = join4(SKILLS_HOME, skillName);
291
+ log.info(`Installing skill \u2192 ${skillDest}`);
292
+ const { count, created } = copyDirTracked(join4(ASSET.skills, skillName), skillDest, { overwrite: true });
293
+ track(created);
294
+ totalSkillFiles += count;
295
+ }
296
+ log.ok(`${totalSkillFiles} skill file(s) installed (${skillDirs.length} skills).`);
291
297
  log.blank();
292
298
  }
293
299
  if (!opts.globalOnly) {
@@ -384,7 +390,7 @@ async function init(opts) {
384
390
 
385
391
  // src/commands/update.ts
386
392
  import { join as join5 } from "path";
387
- import { existsSync as existsSync4, mkdirSync as mkdirSync2, readdirSync as readdirSync2, copyFileSync as copyFileSync2, readFileSync as readFileSync3 } from "fs";
393
+ import { existsSync as existsSync4, mkdirSync as mkdirSync2, readdirSync as readdirSync3, copyFileSync as copyFileSync2, readFileSync as readFileSync3 } from "fs";
388
394
  import { createHash } from "crypto";
389
395
  import { homedir as homedir2 } from "os";
390
396
  function fileHash(filePath) {
@@ -396,7 +402,7 @@ function diffDir(src, dest) {
396
402
  if (!existsSync4(src))
397
403
  return entries;
398
404
  function walk(currentSrc, currentDest) {
399
- const items = readdirSync2(currentSrc, { withFileTypes: true });
405
+ const items = readdirSync3(currentSrc, { withFileTypes: true });
400
406
  for (const item of items) {
401
407
  const srcPath = join5(currentSrc, item.name);
402
408
  const destPath = join5(currentDest, item.name);
@@ -432,7 +438,7 @@ function backupDir(dir, backupDest) {
432
438
  return;
433
439
  mkdirSync2(backupDest, { recursive: true });
434
440
  function walk(src, dst) {
435
- const items = readdirSync2(src, { withFileTypes: true });
441
+ const items = readdirSync3(src, { withFileTypes: true });
436
442
  for (const item of items) {
437
443
  const s = join5(src, item.name);
438
444
  const d = join5(dst, item.name);
@@ -499,7 +505,7 @@ async function update(opts) {
499
505
 
500
506
  // src/commands/new-change.ts
501
507
  import { join as join6 } from "path";
502
- import { existsSync as existsSync5, readdirSync as readdirSync3 } from "fs";
508
+ import { existsSync as existsSync5, readdirSync as readdirSync4 } from "fs";
503
509
  var REQUIRED_TEMPLATES = [
504
510
  "change-request.md",
505
511
  "change-classification.md",
@@ -509,7 +515,7 @@ var REQUIRED_TEMPLATES = [
509
515
  ];
510
516
  function listOptional() {
511
517
  try {
512
- const all = readdirSync3(ASSET.specsTemplates).filter((f) => f.endsWith(".md"));
518
+ const all = readdirSync4(ASSET.specsTemplates).filter((f) => f.endsWith(".md"));
513
519
  return all.filter((f) => !REQUIRED_TEMPLATES.includes(f));
514
520
  } catch {
515
521
  return [];
@@ -641,7 +647,7 @@ async function validate(opts) {
641
647
  }
642
648
 
643
649
  // src/commands/gate.ts
644
- import { existsSync as existsSync7, readFileSync as readFileSync4, readdirSync as readdirSync4 } from "fs";
650
+ import { existsSync as existsSync7, readFileSync as readFileSync4, readdirSync as readdirSync5 } from "fs";
645
651
  import { join as join8 } from "path";
646
652
  import { spawnSync as spawnSync2 } from "child_process";
647
653
  var REQUIRED_FILES = [
@@ -685,7 +691,7 @@ async function gate(changeId) {
685
691
  }
686
692
  const agentLogDir = join8(changeDir, "agent-log");
687
693
  if (existsSync7(agentLogDir)) {
688
- const logFiles = readdirSync4(agentLogDir).filter((f) => f.endsWith(".md"));
694
+ const logFiles = readdirSync5(agentLogDir).filter((f) => f.endsWith(".md"));
689
695
  for (const f of logFiles) {
690
696
  const content = readFileSync4(join8(agentLogDir, f), "utf8");
691
697
  const statusMatch = content.match(/^\s*-\s*status:\s*(complete|needs-review|blocked)\s*$/m);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contract-driven-delivery",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "Contract-driven delivery kit CLI — spec-first, test-first AI-assisted delivery for brownfield systems",
5
5
  "keywords": [
6
6
  "contract-driven",