contract-driven-delivery 1.0.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -18
- package/assets/CLAUDE.template.md +59 -3
- package/assets/agents/backend-engineer.md +43 -0
- package/assets/agents/change-classifier.md +40 -0
- package/assets/agents/ci-cd-gatekeeper.md +53 -4
- package/assets/agents/contract-reviewer.md +49 -3
- package/assets/agents/dependency-security-reviewer.md +95 -0
- package/assets/agents/e2e-resilience-engineer.md +42 -1
- package/assets/agents/frontend-engineer.md +44 -1
- package/assets/agents/monkey-test-engineer.md +40 -1
- package/assets/agents/qa-reviewer.md +52 -0
- package/assets/agents/repo-context-scanner.md +40 -0
- package/assets/agents/spec-architect.md +77 -3
- package/assets/agents/spec-drift-auditor.md +40 -0
- package/assets/agents/stress-soak-engineer.md +42 -0
- package/assets/agents/test-strategist.md +44 -1
- package/assets/agents/ui-ux-reviewer.md +41 -1
- package/assets/agents/visual-reviewer.md +41 -1
- package/assets/ci/github-actions/contract-driven-gates.yml +50 -5
- package/assets/ci-templates/bun.yml +5 -0
- package/assets/ci-templates/conda.yml +11 -0
- package/assets/ci-templates/go.yml +12 -0
- package/assets/ci-templates/npm.yml +6 -0
- package/assets/ci-templates/pip.yml +10 -0
- package/assets/ci-templates/pnpm.yml +9 -0
- package/assets/ci-templates/poetry.yml +12 -0
- package/assets/ci-templates/rust.yml +12 -0
- package/assets/ci-templates/unknown.yml +4 -0
- package/assets/ci-templates/uv.yml +12 -0
- package/assets/ci-templates/yarn.yml +6 -0
- package/assets/contracts/CHANGELOG.md +27 -0
- package/assets/contracts/api/api-contract.md +7 -0
- package/assets/contracts/business/business-rules.md +7 -0
- package/assets/contracts/ci/ci-gate-contract.md +7 -0
- package/assets/contracts/css/css-contract.md +7 -0
- package/assets/contracts/data/data-shape-contract.md +7 -0
- package/assets/contracts/env/env-contract.md +7 -0
- package/assets/hooks/pre-commit +23 -0
- package/assets/skill/SKILL.md +20 -4
- package/assets/skill/scripts/detect_project_profile.py +68 -1
- package/assets/skill/scripts/generate_change_scaffold.py +2 -2
- package/assets/skill/scripts/validate_api_semantic.py +162 -0
- package/assets/skill/scripts/validate_ci_gates.py +34 -6
- package/assets/skill/scripts/validate_contract_versions.py +385 -0
- package/assets/skill/scripts/validate_contracts.py +25 -1
- package/assets/skill/scripts/validate_env_contract.py +3 -1
- package/assets/skill/scripts/validate_env_semantic.py +182 -0
- package/assets/skill/scripts/validate_spec_traceability.py +34 -8
- package/assets/tests-templates/soak/k6-example.js +19 -0
- package/assets/tests-templates/soak/locust-example.py +21 -0
- package/assets/tests-templates/soak/soak-profile.md +16 -0
- package/assets/tests-templates/stress/artillery-example.yml +27 -0
- package/assets/tests-templates/stress/k6-example.js +22 -0
- package/assets/tests-templates/stress/load-profile.md +14 -0
- package/assets/tests-templates/stress/locust-example.py +21 -0
- package/dist/cli/index.js +593 -106
- package/package.json +7 -4
- package/assets/skill/agents/openai.yaml +0 -2
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: visual-reviewer
|
|
3
|
-
description: Review visual output, layout, responsive behavior, screenshot diffs, CSS contract compliance, and component state coverage.
|
|
3
|
+
description: Review pixel-level visual output, layout, responsive viewport behavior, screenshot diffs, CSS contract compliance, and component visual state coverage. Does not cover interaction or copy -- those go to ui-ux-reviewer.
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
|
+
model: claude-haiku-4-5-20251001
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
You are the visual reviewer.
|
|
@@ -17,6 +18,13 @@ Frontend visual changes require evidence. Use screenshots, videos, or a clear ma
|
|
|
17
18
|
- shared component contract compliance
|
|
18
19
|
- visual regression diff acceptance
|
|
19
20
|
|
|
21
|
+
## Tooling and matrix
|
|
22
|
+
|
|
23
|
+
- Snapshot tools — Percy, Chromatic, Playwright `toHaveScreenshot()`; pick one per repo.
|
|
24
|
+
- Diff threshold — start strict (~0.1%) and relax only with documented reason; "approved with diff" must list the changed pixels.
|
|
25
|
+
- Variant matrix — themes (light, dark), languages (LTR, RTL), density (default, compact), reduced motion, high contrast — at least theme + RTL on top of viewport matrix.
|
|
26
|
+
- Asset review — icons, fonts, images must come from the design system or have a documented exception.
|
|
27
|
+
|
|
20
28
|
## Output
|
|
21
29
|
|
|
22
30
|
```md
|
|
@@ -42,3 +50,35 @@ Frontend visual changes require evidence. Use screenshots, videos, or a clear ma
|
|
|
42
50
|
## Decision
|
|
43
51
|
approved / changes-required
|
|
44
52
|
```
|
|
53
|
+
|
|
54
|
+
## Machine-Verifiable Evidence
|
|
55
|
+
|
|
56
|
+
After completing your task, write or append to `specs/changes/<change-id>/agent-log/<your-agent-name>.md`
|
|
57
|
+
with this exact structure (lines starting with `- ` are required):
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
# Visual Reviewer Log
|
|
61
|
+
- change-id: <id>
|
|
62
|
+
- timestamp: <ISO 8601, e.g. 2026-04-27T14:30:00Z>
|
|
63
|
+
- status: complete | needs-review | blocked
|
|
64
|
+
- artifacts:
|
|
65
|
+
- <evidence-type>: <concrete pointer>
|
|
66
|
+
- <evidence-type>: <concrete pointer>
|
|
67
|
+
- next-action: <one line, or "none">
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Required artifacts for this agent
|
|
71
|
+
- `screenshots-compared`: list of `<screen>: baseline → current`
|
|
72
|
+
- `diff-percentage`: per-screen
|
|
73
|
+
- `state-coverage`: matrix
|
|
74
|
+
- `tokens-violated`: list of CSS contract violations or "none"
|
|
75
|
+
|
|
76
|
+
### Rules
|
|
77
|
+
- NEVER omit this log file. `cdd-kit gate` rejects changes whose agent-log
|
|
78
|
+
is missing the `status:` line or has an invalid status.
|
|
79
|
+
- If you cannot complete the task, set `status: blocked` and write a
|
|
80
|
+
concrete `next-action` (NOT "investigate further" — write the actual
|
|
81
|
+
next step a human can act on).
|
|
82
|
+
- Evidence must be concrete: file:line, command name + last-10-line stdout,
|
|
83
|
+
contract path + section, test name, etc. NEVER write "verified" or "OK"
|
|
84
|
+
without a pointer.
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
# Contract-driven gates baseline (provided by cdd-kit).
|
|
2
|
+
# Contract validation steps run as-is; application/test commands MUST be customized for your stack.
|
|
3
|
+
# See README.md and ci/gate-policy.md for tier semantics and promotion policy.
|
|
4
|
+
|
|
1
5
|
name: contract-driven-gates
|
|
2
6
|
|
|
3
7
|
on:
|
|
@@ -11,28 +15,69 @@ jobs:
|
|
|
11
15
|
runs-on: ubuntu-latest
|
|
12
16
|
steps:
|
|
13
17
|
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Python
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: '3.10'
|
|
23
|
+
|
|
14
24
|
- name: Detect project profile
|
|
15
25
|
run: python .claude/skills/contract-driven-delivery/scripts/detect_project_profile.py . --write project-profile.generated.md || true
|
|
26
|
+
|
|
16
27
|
- name: Validate contracts
|
|
17
28
|
run: python .claude/skills/contract-driven-delivery/scripts/validate_contracts.py .
|
|
29
|
+
|
|
18
30
|
- name: Validate env contract
|
|
19
31
|
run: python .claude/skills/contract-driven-delivery/scripts/validate_env_contract.py contracts/env/env-contract.md
|
|
32
|
+
|
|
33
|
+
- name: Validate ci gates
|
|
34
|
+
run: python .claude/skills/contract-driven-delivery/scripts/validate_ci_gates.py
|
|
35
|
+
|
|
36
|
+
- name: Validate spec traceability
|
|
37
|
+
run: python .claude/skills/contract-driven-delivery/scripts/validate_spec_traceability.py
|
|
38
|
+
|
|
39
|
+
- name: Validate contract versions
|
|
40
|
+
run: python .claude/skills/contract-driven-delivery/scripts/validate_contract_versions.py .
|
|
41
|
+
|
|
20
42
|
- name: Repository-specific fast gate
|
|
21
43
|
run: |
|
|
22
|
-
|
|
44
|
+
# TODO: add your stack-specific commands here.
|
|
45
|
+
# This step is intentionally left as a placeholder — cdd-kit does not assume your stack.
|
|
46
|
+
# Examples of what belongs here:
|
|
47
|
+
# lint: npx eslint src/ / ruff check . / golangci-lint run
|
|
48
|
+
# typecheck: npx tsc --noEmit / mypy src/
|
|
49
|
+
# build: npm run build / go build ./...
|
|
50
|
+
# unit tests: your test runner command (jest, vitest, pytest, go test, etc.)
|
|
51
|
+
echo "No stack-specific fast gate configured — add lint/typecheck/build/unit-test commands above."
|
|
23
52
|
|
|
24
53
|
e2e-critical:
|
|
25
54
|
if: github.event_name == 'pull_request'
|
|
26
55
|
runs-on: ubuntu-latest
|
|
27
56
|
steps:
|
|
28
57
|
- uses: actions/checkout@v4
|
|
29
|
-
|
|
30
|
-
|
|
58
|
+
|
|
59
|
+
- name: Critical E2E
|
|
60
|
+
run: |
|
|
61
|
+
# TODO: add your critical E2E command here (Tier 1 — blocks merge).
|
|
62
|
+
# This step is intentionally left as a placeholder — cdd-kit does not assume your stack.
|
|
63
|
+
# Examples:
|
|
64
|
+
# Playwright: npx playwright test --project=critical
|
|
65
|
+
# Cypress: npx cypress run --spec "cypress/e2e/critical/**"
|
|
66
|
+
# pytest: python -m pytest tests/e2e/critical/ -x
|
|
67
|
+
echo "No critical E2E command configured — add your runner command above."
|
|
31
68
|
|
|
32
69
|
scheduled-stress-soak:
|
|
33
70
|
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
|
|
34
71
|
runs-on: ubuntu-latest
|
|
35
72
|
steps:
|
|
36
73
|
- uses: actions/checkout@v4
|
|
37
|
-
|
|
38
|
-
|
|
74
|
+
|
|
75
|
+
- name: Stress and soak tests
|
|
76
|
+
run: |
|
|
77
|
+
# TODO: add your stress/soak workflow here (Tier 4 — weekly long-run gate).
|
|
78
|
+
# This step is intentionally left as a placeholder — cdd-kit does not assume your stack.
|
|
79
|
+
# Examples:
|
|
80
|
+
# pytest soak: python -m pytest tests/stress/ --soak-hours=4
|
|
81
|
+
# k6 load: k6 run --vus=50 --duration=4h tests/load/scenario.js
|
|
82
|
+
# locust: locust -f tests/stress/locustfile.py --headless -u 100 -r 10 --run-time 4h
|
|
83
|
+
echo "No stress/soak command configured — add your runner command above."
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
- uses: conda-incubator/setup-miniconda@v3
|
|
2
|
+
with:
|
|
3
|
+
environment-file: environment.yml
|
|
4
|
+
activate-environment: "" # 空字串讓 conda 從 environment.yml 讀 name
|
|
5
|
+
auto-activate-base: false
|
|
6
|
+
- name: Lint + Type + Test
|
|
7
|
+
shell: bash -el {0}
|
|
8
|
+
run: |
|
|
9
|
+
ruff check . || true
|
|
10
|
+
mypy src/ || true
|
|
11
|
+
pytest
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
- uses: actions/setup-python@v5
|
|
2
|
+
with:
|
|
3
|
+
python-version: '3.11'
|
|
4
|
+
- name: Install Poetry
|
|
5
|
+
run: pip install poetry
|
|
6
|
+
- name: Install dependencies
|
|
7
|
+
run: poetry install --no-interaction
|
|
8
|
+
- name: Lint + Type + Test
|
|
9
|
+
run: |
|
|
10
|
+
poetry run ruff check . || true
|
|
11
|
+
poetry run mypy src/ || true
|
|
12
|
+
poetry run pytest
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
2
|
+
with:
|
|
3
|
+
components: clippy, rustfmt
|
|
4
|
+
- uses: Swatinem/rust-cache@v2
|
|
5
|
+
- name: Lint
|
|
6
|
+
run: |
|
|
7
|
+
cargo fmt --check || true
|
|
8
|
+
cargo clippy -- -D warnings || true
|
|
9
|
+
- name: Build + Test
|
|
10
|
+
run: |
|
|
11
|
+
cargo build
|
|
12
|
+
cargo test
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
- uses: actions/setup-python@v5
|
|
2
|
+
with:
|
|
3
|
+
python-version: '3.11'
|
|
4
|
+
- name: Install uv
|
|
5
|
+
run: pip install uv
|
|
6
|
+
- name: Install dependencies
|
|
7
|
+
run: uv sync
|
|
8
|
+
- name: Lint + Type + Test
|
|
9
|
+
run: |
|
|
10
|
+
uv run ruff check . || true
|
|
11
|
+
uv run mypy src/ || true
|
|
12
|
+
uv run pytest
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Contracts Changelog
|
|
2
|
+
|
|
3
|
+
All notable contract surface changes belong here.
|
|
4
|
+
Format: Keep-a-Changelog (https://keepachangelog.com/).
|
|
5
|
+
Versions are semantic per contract type.
|
|
6
|
+
|
|
7
|
+
While a contract is at 0.x (draft), entries here are optional.
|
|
8
|
+
Once a contract reaches 1.0.0, every schema-version bump must have
|
|
9
|
+
a corresponding entry below.
|
|
10
|
+
|
|
11
|
+
## [api 0.1.0] — 2026-04-27
|
|
12
|
+
Initial draft.
|
|
13
|
+
|
|
14
|
+
## [css 0.1.0] — 2026-04-27
|
|
15
|
+
Initial draft.
|
|
16
|
+
|
|
17
|
+
## [env 0.1.0] — 2026-04-27
|
|
18
|
+
Initial draft.
|
|
19
|
+
|
|
20
|
+
## [data 0.1.0] — 2026-04-27
|
|
21
|
+
Initial draft.
|
|
22
|
+
|
|
23
|
+
## [business 0.1.0] — 2026-04-27
|
|
24
|
+
Initial draft.
|
|
25
|
+
|
|
26
|
+
## [ci 0.1.0] — 2026-04-27
|
|
27
|
+
Initial draft.
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
contract: env
|
|
3
|
+
schema-version: 0.1.0
|
|
4
|
+
last-changed: 2026-04-27
|
|
5
|
+
breaking-change-policy: deprecate-2-minors
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
# Env Contract
|
|
2
9
|
|
|
3
10
|
| name | scope | environments | required | secret | default | example | owner | validation | restart required | failure behavior |
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# cdd-kit-managed-block-start
|
|
3
|
+
# Auto-runs cdd-kit gate for any change folder touched in this commit.
|
|
4
|
+
# Generated by: cdd-kit install-hooks (re-run to update).
|
|
5
|
+
# Bypass with --no-verify (NOT recommended; defeats AI process enforcement).
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
staged=$(git diff --cached --name-only --diff-filter=ACM)
|
|
10
|
+
[ -z "$staged" ] && exit 0
|
|
11
|
+
|
|
12
|
+
change_ids=$(echo "$staged" | grep -oE '^specs/changes/[^/]+' | sort -u | sed 's|specs/changes/||')
|
|
13
|
+
[ -z "$change_ids" ] && exit 0
|
|
14
|
+
|
|
15
|
+
for id in $change_ids; do
|
|
16
|
+
echo "[cdd-kit] running gate for change: $id"
|
|
17
|
+
if ! cdd-kit gate "$id"; then
|
|
18
|
+
echo "[cdd-kit] gate failed for $id — commit rejected."
|
|
19
|
+
echo "[cdd-kit] fix issues above; --no-verify bypasses but defeats the kit."
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
done
|
|
23
|
+
# cdd-kit-managed-block-end
|
package/assets/skill/SKILL.md
CHANGED
|
@@ -13,32 +13,47 @@ Use this skill to turn software requests into traceable, testable, CI/CD-gated c
|
|
|
13
13
|
|
|
14
14
|
1. Classify the request.
|
|
15
15
|
- Use `references/workflow-router.md`.
|
|
16
|
-
- Create or update `classification.md`.
|
|
16
|
+
- Create or update `change-classification.md`.
|
|
17
|
+
- Invoke change-classifier to perform classification.
|
|
17
18
|
2. Scan project context.
|
|
18
19
|
- Use `scripts/detect_project_profile.py` when useful.
|
|
19
20
|
- Capture stack, commands, contracts, tests, and CI/CD.
|
|
21
|
+
- Invoke repo-context-scanner to capture project profile and standardization gaps.
|
|
20
22
|
3. Select required artifacts.
|
|
21
23
|
- Use templates in `templates/`.
|
|
22
|
-
- Do not force every artifact for tiny changes, but do require `classification.md`, `test-plan.md`, and `ci-gates.md` for implementation changes.
|
|
23
|
-
4. Update contracts before or alongside implementation.
|
|
24
|
+
- Do not force every artifact for tiny changes, but do require `change-classification.md`, `test-plan.md`, and `ci-gates.md` for implementation changes.
|
|
25
|
+
4. Update contracts before or alongside implementation. Invoke contract-reviewer to validate API/CSS/env/data/business/CI-CD contracts before or alongside implementation.
|
|
24
26
|
- API: `references/api-contract-standard.md`
|
|
25
27
|
- CSS/UI: `references/css-contract-standard.md`
|
|
26
28
|
- Env: `references/env-contract-standard.md`
|
|
27
29
|
- Data/report shape: `references/data-contract-standard.md`
|
|
28
30
|
- Business logic: `references/business-logic-standard.md`
|
|
29
31
|
- CI/CD: `references/ci-cd-policy.md`
|
|
30
|
-
|
|
32
|
+
- Deps/migrations: invoke `dependency-security-reviewer` whenever the change touches lockfiles, dependency manifests, or database migrations.
|
|
33
|
+
5. Apply SDD + TDD discipline and commission test engineers.
|
|
31
34
|
- Use `references/sdd-tdd-policy.md`.
|
|
32
35
|
- Tests should be planned before implementation and should fail first when feasible.
|
|
36
|
+
- `test-strategist` authors the test plan (write target: specs/changes/<id>/test-plan.md only).
|
|
37
|
+
- `e2e-resilience-engineer` implements E2E, failure-injection, and data-boundary tests.
|
|
38
|
+
- `monkey-test-engineer` implements adversarial-input, fuzz, and rapid-UI-action tests.
|
|
39
|
+
- `stress-soak-engineer` implements load, soak, and long-running stability tests.
|
|
40
|
+
- Invoke the relevant test engineer(s) before or alongside implementation based on the risk tier.
|
|
41
|
+
- Each engineer must read the matching standard before authoring tests: e2e-resilience-engineer → references/e2e-standard.md, monkey-test-engineer → references/monkey-operation-standard.md, stress-soak-engineer → references/stress-soak-standard.md.
|
|
33
42
|
6. Implement through the right role.
|
|
34
43
|
- Backend/frontend work must follow contracts and tests.
|
|
35
44
|
- UI changes require UI/UX and visual review.
|
|
45
|
+
- Invoke ui-ux-reviewer for interaction, copy, accessibility, and information hierarchy review whenever UI changes.
|
|
46
|
+
- Invoke visual-reviewer for layout, responsive, CSS contract, and screenshot diff review whenever UI changes.
|
|
47
|
+
- If implementation reveals an unexpected boundary or architectural constraint, halt and re-invoke `spec-architect` before continuing.
|
|
36
48
|
7. Run quality gates.
|
|
37
49
|
- Use `references/qa-gates.md`.
|
|
38
50
|
- CI/CD gate plan is mandatory.
|
|
51
|
+
- `qa-reviewer` decides release readiness; Tier 1 gates must be green; Tier 3+ gates must be green or explicitly deferred with a recorded promotion policy.
|
|
52
|
+
- Invoke ci-cd-gatekeeper to design and enforce the gate plan.
|
|
39
53
|
8. Archive and audit drift.
|
|
40
54
|
- Use `references/spec-drift-policy.md`.
|
|
41
55
|
- Durable learnings must be promoted back to contracts or CLAUDE.md.
|
|
56
|
+
- `spec-drift-auditor` must run before every release to main and weekly during active multi-iteration development.
|
|
42
57
|
|
|
43
58
|
## Required gates by risk
|
|
44
59
|
|
|
@@ -66,6 +81,7 @@ Use this skill to turn software requests into traceable, testable, CI/CD-gated c
|
|
|
66
81
|
- visual review evidence
|
|
67
82
|
- E2E or component interaction coverage
|
|
68
83
|
- accessibility check
|
|
84
|
+
- See references/visual-review-standard.md for the required state matrix.
|
|
69
85
|
|
|
70
86
|
### API/backend/data/report change
|
|
71
87
|
|
|
@@ -8,12 +8,54 @@ BACKEND_MARKERS = ['pyproject.toml', 'requirements.txt', 'app.py', 'main.py', 'm
|
|
|
8
8
|
CI_MARKERS = ['.github/workflows', '.gitlab-ci.yml', 'bitbucket-pipelines.yml', '.circleci']
|
|
9
9
|
CONTRACT_DIRS = ['contracts', 'contract']
|
|
10
10
|
|
|
11
|
+
# The cdd-kit skill directory name — used to detect whether cdd-kit is installed.
|
|
12
|
+
CDD_KIT_SKILL = 'contract-driven-delivery'
|
|
13
|
+
|
|
11
14
|
def exists(root: Path, rel: str) -> bool:
|
|
12
15
|
return (root / rel).exists()
|
|
13
16
|
|
|
14
17
|
def list_existing(root: Path, rels):
|
|
15
18
|
return [r for r in rels if exists(root, r)]
|
|
16
19
|
|
|
20
|
+
def cdd_kit_installed(root: Path) -> bool:
|
|
21
|
+
"""Return True if cdd-kit's skill is present in this repo's .claude directory."""
|
|
22
|
+
return (root / '.claude' / 'skills' / CDD_KIT_SKILL).exists()
|
|
23
|
+
|
|
24
|
+
def classify_agents(root: Path, kit_installed: bool):
|
|
25
|
+
"""
|
|
26
|
+
Return (kit_agents, user_agents) lists of agent .md basenames.
|
|
27
|
+
|
|
28
|
+
When cdd-kit is installed, ALL agents found under .claude/agents/ are
|
|
29
|
+
assumed to originate from the kit installation (the kit ships its own
|
|
30
|
+
agent suite and deploys it there). Users who add their own agents
|
|
31
|
+
alongside the kit should note this in their AGENTS.md.
|
|
32
|
+
If cdd-kit is NOT installed, all agents are treated as user-authored.
|
|
33
|
+
"""
|
|
34
|
+
agents_dir = root / '.claude' / 'agents'
|
|
35
|
+
if not agents_dir.is_dir():
|
|
36
|
+
return [], []
|
|
37
|
+
all_agents = sorted(p.name for p in agents_dir.glob('*.md'))
|
|
38
|
+
if not all_agents:
|
|
39
|
+
return [], []
|
|
40
|
+
if kit_installed:
|
|
41
|
+
return all_agents, []
|
|
42
|
+
return [], all_agents
|
|
43
|
+
|
|
44
|
+
def classify_skills(root: Path, kit_installed: bool):
|
|
45
|
+
"""
|
|
46
|
+
Return (kit_skills, user_skills) lists of skill directory names.
|
|
47
|
+
|
|
48
|
+
contract-driven-delivery is always flagged as a cdd-kit skill when present.
|
|
49
|
+
Other skills are user-authored.
|
|
50
|
+
"""
|
|
51
|
+
skills_dir = root / '.claude' / 'skills'
|
|
52
|
+
if not skills_dir.is_dir():
|
|
53
|
+
return [], []
|
|
54
|
+
all_skills = sorted(p.name for p in skills_dir.iterdir() if p.is_dir())
|
|
55
|
+
kit_skills = [s for s in all_skills if s == CDD_KIT_SKILL]
|
|
56
|
+
user_skills = [s for s in all_skills if s != CDD_KIT_SKILL]
|
|
57
|
+
return kit_skills, user_skills
|
|
58
|
+
|
|
17
59
|
def detect_commands(root: Path):
|
|
18
60
|
commands = {}
|
|
19
61
|
pkg = root / 'package.json'
|
|
@@ -32,18 +74,42 @@ def main():
|
|
|
32
74
|
ap.add_argument('--write', help='optional output markdown path')
|
|
33
75
|
args = ap.parse_args()
|
|
34
76
|
root = Path(args.root).resolve()
|
|
77
|
+
|
|
35
78
|
frontend = list_existing(root, FRONTEND_MARKERS)
|
|
36
79
|
backend = list_existing(root, BACKEND_MARKERS)
|
|
37
80
|
ci = list_existing(root, CI_MARKERS)
|
|
38
81
|
contracts = [d for d in CONTRACT_DIRS if (root/d).exists()]
|
|
39
82
|
tests = [p for p in ['tests','frontend/tests','e2e','playwright.config.ts','playwright.config.js'] if (root/p).exists()]
|
|
40
83
|
commands = detect_commands(root)
|
|
41
|
-
|
|
84
|
+
|
|
85
|
+
kit_installed = cdd_kit_installed(root)
|
|
86
|
+
kit_agents, user_agents = classify_agents(root, kit_installed)
|
|
87
|
+
kit_skills, user_skills = classify_skills(root, kit_installed)
|
|
88
|
+
|
|
89
|
+
lines = ['# Project Profile', '', '## Root', str(root), '', '## Detected Markers']
|
|
42
90
|
lines += ['- frontend: ' + (', '.join(frontend) if frontend else 'none detected')]
|
|
43
91
|
lines += ['- backend: ' + (', '.join(backend) if backend else 'none detected')]
|
|
44
92
|
lines += ['- contracts: ' + (', '.join(contracts) if contracts else 'none detected')]
|
|
45
93
|
lines += ['- tests: ' + (', '.join(tests) if tests else 'none detected')]
|
|
46
94
|
lines += ['- ci/cd: ' + (', '.join(ci) if ci else 'none detected')]
|
|
95
|
+
|
|
96
|
+
lines += ['', '## Claude Assets (.claude/)']
|
|
97
|
+
if kit_installed:
|
|
98
|
+
lines += [f'- cdd-kit detected (skill: {CDD_KIT_SKILL})']
|
|
99
|
+
if kit_agents:
|
|
100
|
+
lines += [f'- agents installed by cdd-kit ({len(kit_agents)}): ' + ', '.join(kit_agents)]
|
|
101
|
+
lines += [' (these are bundled by cdd-kit; not user-authored)']
|
|
102
|
+
if user_agents:
|
|
103
|
+
lines += [f'- user-authored agents ({len(user_agents)}): ' + ', '.join(user_agents)]
|
|
104
|
+
if not kit_agents and not user_agents:
|
|
105
|
+
lines += ['- agents: none detected']
|
|
106
|
+
if kit_skills:
|
|
107
|
+
lines += [f'- skills installed by cdd-kit ({len(kit_skills)}): ' + ', '.join(kit_skills)]
|
|
108
|
+
if user_skills:
|
|
109
|
+
lines += [f'- user-authored skills ({len(user_skills)}): ' + ', '.join(user_skills)]
|
|
110
|
+
if not kit_skills and not user_skills:
|
|
111
|
+
lines += ['- skills: none detected']
|
|
112
|
+
|
|
47
113
|
lines += ['', '## Suggested Commands']
|
|
48
114
|
if commands:
|
|
49
115
|
lines += [f'- {k}: `{v}`' for k,v in sorted(commands.items())]
|
|
@@ -57,5 +123,6 @@ def main():
|
|
|
57
123
|
if args.write:
|
|
58
124
|
Path(args.write).write_text(out, encoding='utf-8')
|
|
59
125
|
print(out)
|
|
126
|
+
|
|
60
127
|
if __name__ == '__main__':
|
|
61
128
|
main()
|
|
@@ -15,8 +15,8 @@ def main():
|
|
|
15
15
|
dest=root/'specs'/'changes'/args.change_id
|
|
16
16
|
dest.mkdir(parents=True, exist_ok=False)
|
|
17
17
|
mapping={
|
|
18
|
-
'change-request.md':'request.md',
|
|
19
|
-
'change-classification.md':'classification.md',
|
|
18
|
+
'change-request.md':'change-request.md',
|
|
19
|
+
'change-classification.md':'change-classification.md',
|
|
20
20
|
'current-behavior.md':'current-behavior.md',
|
|
21
21
|
'proposal.md':'proposal.md',
|
|
22
22
|
'spec.md':'spec.md',
|