ctx-cc 4.0.0 → 4.1.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 +378 -424
- package/agents/ctx-arch-mapper.md +1 -1
- package/agents/ctx-auditor.md +1 -1
- package/agents/ctx-codex-reviewer.md +214 -0
- package/agents/ctx-concerns-mapper.md +1 -1
- package/agents/ctx-criteria-suggester.md +2 -2
- package/agents/ctx-debugger.md +1 -1
- package/agents/ctx-discusser.md +1 -1
- package/agents/ctx-executor.md +1 -1
- package/agents/ctx-handoff.md +2 -2
- package/agents/ctx-learner.md +1 -1
- package/agents/ctx-mapper.md +1 -1
- package/agents/ctx-parallelizer.md +1 -1
- package/agents/ctx-planner.md +1 -1
- package/agents/ctx-predictor.md +1 -1
- package/agents/ctx-quality-mapper.md +1 -1
- package/agents/ctx-researcher.md +1 -1
- package/agents/ctx-reviewer.md +2 -2
- package/agents/ctx-team-coordinator.md +1 -1
- package/agents/ctx-tech-mapper.md +1 -1
- package/agents/ctx-verifier.md +1 -1
- package/bin/ctx.js +33 -2
- package/commands/cross-review.md +142 -0
- package/commands/ctx.md +10 -10
- package/commands/help.md +6 -5
- package/commands/init.md +25 -0
- package/commands/metrics.md +1 -1
- package/commands/milestone.md +1 -1
- package/commands/monitor.md +1 -1
- package/commands/voice.md +1 -1
- package/hooks/pre-tool-use.js +2 -1
- package/package.json +2 -2
- package/plugin.json +2 -1
- package/skills/ctx-review-gate/SKILL.md +49 -13
- package/src/capabilities.js +97 -42
- package/src/install.js +10 -3
- package/src/review-gate.js +103 -9
- package/templates/config.json +3 -0
package/commands/ctx.md
CHANGED
|
@@ -120,29 +120,29 @@ Call Task 4 times in a SINGLE message with these parameters:
|
|
|
120
120
|
|
|
121
121
|
```
|
|
122
122
|
Task 1:
|
|
123
|
-
subagent_type: "
|
|
124
|
-
prompt: "
|
|
123
|
+
subagent_type: "ctx-tech-mapper"
|
|
124
|
+
prompt: "Analyze technology stack. Write to .ctx/codebase/TECH.md with languages, frameworks, dependencies, build tools, versions."
|
|
125
125
|
model: "haiku"
|
|
126
126
|
run_in_background: true
|
|
127
127
|
description: "Map tech stack"
|
|
128
128
|
|
|
129
129
|
Task 2:
|
|
130
|
-
subagent_type: "
|
|
131
|
-
prompt: "
|
|
130
|
+
subagent_type: "ctx-arch-mapper"
|
|
131
|
+
prompt: "Analyze architecture. Write to .ctx/codebase/ARCH.md with patterns, layers, modules, entry points, data flow."
|
|
132
132
|
model: "haiku"
|
|
133
133
|
run_in_background: true
|
|
134
134
|
description: "Map architecture"
|
|
135
135
|
|
|
136
136
|
Task 3:
|
|
137
|
-
subagent_type: "
|
|
138
|
-
prompt: "
|
|
137
|
+
subagent_type: "ctx-quality-mapper"
|
|
138
|
+
prompt: "Analyze code quality. Write to .ctx/codebase/QUALITY.md with test coverage, linting, type safety, documentation, code smells."
|
|
139
139
|
model: "haiku"
|
|
140
140
|
run_in_background: true
|
|
141
141
|
description: "Map quality"
|
|
142
142
|
|
|
143
143
|
Task 4:
|
|
144
|
-
subagent_type: "
|
|
145
|
-
prompt: "
|
|
144
|
+
subagent_type: "ctx-concerns-mapper"
|
|
145
|
+
prompt: "Analyze risks and concerns. Write to .ctx/codebase/CONCERNS.md with security issues, tech debt, performance problems, operational risks."
|
|
146
146
|
model: "haiku"
|
|
147
147
|
run_in_background: true
|
|
148
148
|
description: "Map concerns"
|
|
@@ -264,7 +264,7 @@ If .ctx/codebase/ doesn't exist, run quick mapping first.
|
|
|
264
264
|
**Spawn debugger agent:**
|
|
265
265
|
```
|
|
266
266
|
Task:
|
|
267
|
-
subagent_type: "debugger"
|
|
267
|
+
subagent_type: "ctx-debugger"
|
|
268
268
|
prompt: "Investigate this issue: [user's problem]. Use scientific method: reproduce, isolate, fix, verify. The codebase analysis is in .ctx/codebase/. Write debug session to .ctx/debug/SESSION-[timestamp].md"
|
|
269
269
|
description: "Debug issue"
|
|
270
270
|
```
|
|
@@ -283,7 +283,7 @@ Task:
|
|
|
283
283
|
**Spawn QA agent:**
|
|
284
284
|
```
|
|
285
285
|
Task:
|
|
286
|
-
subagent_type: "qa
|
|
286
|
+
subagent_type: "ctx-qa"
|
|
287
287
|
prompt: "Run comprehensive QA validation on this codebase. Test user flows, validate accessibility, check for regressions. Write report to .ctx/qa/REPORT-[timestamp].md"
|
|
288
288
|
description: "QA validation"
|
|
289
289
|
```
|
package/commands/help.md
CHANGED
|
@@ -4,18 +4,18 @@ description: Show CTX commands and usage guide
|
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<objective>
|
|
7
|
-
Display the CTX
|
|
7
|
+
Display the CTX 4.0 command reference.
|
|
8
8
|
|
|
9
9
|
Output ONLY the reference content below. Do NOT add project-specific analysis.
|
|
10
10
|
</objective>
|
|
11
11
|
|
|
12
12
|
<reference>
|
|
13
|
-
# CTX
|
|
13
|
+
# CTX 4.0 Command Reference
|
|
14
14
|
|
|
15
15
|
**CTX** (Continuous Task eXecution) - Intelligent workflow orchestration for Claude Code.
|
|
16
16
|
|
|
17
17
|
**Conversational-first.** Just describe what you want - no commands to memorize.
|
|
18
|
-
|
|
18
|
+
26 agents. 7 skills. Deterministic hooks. Three-stage review gate with Codex cross-model review. Phase-based lifecycle.
|
|
19
19
|
|
|
20
20
|
## Quick Start
|
|
21
21
|
|
|
@@ -115,6 +115,7 @@ Or use commands directly:
|
|
|
115
115
|
| `/ctx plan [goal]` | Force research + planning |
|
|
116
116
|
| `/ctx verify` | Force three-level verification |
|
|
117
117
|
| `/ctx quick "task"` | Quick task bypass |
|
|
118
|
+
| `/ctx cross-review [range] [--focus=area]` | On-demand Codex cross-model review (any project) |
|
|
118
119
|
|
|
119
120
|
### Debug
|
|
120
121
|
| Command | Purpose |
|
|
@@ -269,7 +270,7 @@ Or use commands directly:
|
|
|
269
270
|
|-------|---------|
|
|
270
271
|
| ctx-orchestrator | Pipeline execution, lifecycle, autonomous mode |
|
|
271
272
|
| ctx-state | STATE.json management, phase transitions |
|
|
272
|
-
| ctx-review-gate |
|
|
273
|
+
| ctx-review-gate | Three-stage review (spec compliance + code quality + optional Codex cross-review) |
|
|
273
274
|
| ctx-design-system | W3C DTCG tokens, Figma sync, theme management |
|
|
274
275
|
| ctx-visual-qa | Pixel-perfect measurement, accessibility audit |
|
|
275
276
|
| ctx-ml-experiment | ML experiment lifecycle, hypothesis tracking |
|
|
@@ -354,5 +355,5 @@ npx ctx-cc --force
|
|
|
354
355
|
```
|
|
355
356
|
|
|
356
357
|
---
|
|
357
|
-
*CTX
|
|
358
|
+
*CTX 4.0 - Learning. Prediction. Self-healing. Cross-model review. Voice control.*
|
|
358
359
|
</reference>
|
package/commands/init.md
CHANGED
|
@@ -20,6 +20,7 @@ Initialize a new CTX project through unified flow: questioning → research →
|
|
|
20
20
|
- `.ctx/STATE.md` — Living project state
|
|
21
21
|
- `.ctx/PRD.json` — Requirements contract
|
|
22
22
|
- `.ctx/config.json` — Workflow preferences
|
|
23
|
+
- `.ctx/capability-manifest.json` — Tool restrictions read by the PreToolUse hook
|
|
23
24
|
- `.ctx/research/` — Domain research (ArguSeek)
|
|
24
25
|
- `.ctx/ROADMAP.md` — Phase structure
|
|
25
26
|
|
|
@@ -136,6 +137,29 @@ cat > .ctx/.gitignore << 'EOF'
|
|
|
136
137
|
*.secrets
|
|
137
138
|
credentials.json
|
|
138
139
|
EOF
|
|
140
|
+
|
|
141
|
+
# Seed the capability manifest used by the PreToolUse hook.
|
|
142
|
+
# The plugin install step generates this template; prefer the global install,
|
|
143
|
+
# fall back to project-local, warn if neither exists (enforcement is optional).
|
|
144
|
+
# If an older-version manifest already exists, back it up before copying.
|
|
145
|
+
CTX_TEMPLATE_DIR="${HOME}/.claude/ctx/templates"
|
|
146
|
+
if [ ! -f "${CTX_TEMPLATE_DIR}/capability-manifest.json" ]; then
|
|
147
|
+
CTX_TEMPLATE_DIR=".claude/ctx/templates"
|
|
148
|
+
fi
|
|
149
|
+
if [ -f "${CTX_TEMPLATE_DIR}/capability-manifest.json" ]; then
|
|
150
|
+
if [ -f .ctx/capability-manifest.json ]; then
|
|
151
|
+
OLD_VER=$(grep -oE '"_version"\s*:\s*[0-9]+' .ctx/capability-manifest.json | grep -oE '[0-9]+$' || echo "0")
|
|
152
|
+
NEW_VER=$(grep -oE '"_version"\s*:\s*[0-9]+' "${CTX_TEMPLATE_DIR}/capability-manifest.json" | grep -oE '[0-9]+$' || echo "0")
|
|
153
|
+
if [ "${OLD_VER}" != "${NEW_VER}" ]; then
|
|
154
|
+
mv .ctx/capability-manifest.json ".ctx/capability-manifest.v${OLD_VER}.backup.json"
|
|
155
|
+
fi
|
|
156
|
+
fi
|
|
157
|
+
cp "${CTX_TEMPLATE_DIR}/capability-manifest.json" .ctx/capability-manifest.json
|
|
158
|
+
else
|
|
159
|
+
echo "WARN: capability-manifest.json template not found in ${HOME}/.claude/ctx/templates or .claude/ctx/templates"
|
|
160
|
+
echo " The PreToolUse hook will silently no-op until the manifest is seeded."
|
|
161
|
+
echo " Reinstall ctx-cc (npx ctx-cc --force) to regenerate it."
|
|
162
|
+
fi
|
|
139
163
|
```
|
|
140
164
|
|
|
141
165
|
## Phase 5: Write STATE.md
|
|
@@ -181,6 +205,7 @@ EOF
|
|
|
181
205
|
|
|
182
206
|
```bash
|
|
183
207
|
git add .ctx/STATE.md .ctx/.gitignore
|
|
208
|
+
[ -f .ctx/capability-manifest.json ] && git add .ctx/capability-manifest.json
|
|
184
209
|
git commit -m "docs: initialize CTX project - {{project_name}}"
|
|
185
210
|
```
|
|
186
211
|
|
package/commands/metrics.md
CHANGED
|
@@ -4,7 +4,7 @@ description: Metrics dashboard - understand AI productivity impact with stories
|
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<objective>
|
|
7
|
-
CTX
|
|
7
|
+
CTX 4.0 Metrics Dashboard - Comprehensive productivity analytics for understanding AI development impact.
|
|
8
8
|
</objective>
|
|
9
9
|
|
|
10
10
|
<usage>
|
package/commands/milestone.md
CHANGED
|
@@ -4,7 +4,7 @@ description: Milestone workflow - list, audit, complete, and start new milestone
|
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<objective>
|
|
7
|
-
CTX
|
|
7
|
+
CTX 4.0 Milestone Workflow - Full release management with audit, archive, and git tagging.
|
|
8
8
|
</objective>
|
|
9
9
|
|
|
10
10
|
<usage>
|
package/commands/monitor.md
CHANGED
|
@@ -4,7 +4,7 @@ description: Self-healing deployments - connect to error tracking (Sentry/LogRoc
|
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<objective>
|
|
7
|
-
CTX
|
|
7
|
+
CTX 4.0 Self-Healing Deployments - Monitor production errors and automatically create fix stories or even auto-fix with PR creation.
|
|
8
8
|
</objective>
|
|
9
9
|
|
|
10
10
|
<usage>
|
package/commands/voice.md
CHANGED
|
@@ -4,7 +4,7 @@ description: Voice control for CTX - speak your requirements and commands using
|
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<objective>
|
|
7
|
-
CTX
|
|
7
|
+
CTX 4.0 Voice Control - Speak your requirements instead of typing. Natural language processing converts speech to CTX commands and story descriptions.
|
|
8
8
|
</objective>
|
|
9
9
|
|
|
10
10
|
<usage>
|
package/hooks/pre-tool-use.js
CHANGED
|
@@ -63,7 +63,8 @@ if (agentName && agentName.startsWith('ctx-')) {
|
|
|
63
63
|
if (fs.existsSync(manifestPath)) {
|
|
64
64
|
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
|
|
65
65
|
for (const [category, cfg] of Object.entries(manifest)) {
|
|
66
|
-
if (
|
|
66
|
+
if (category.startsWith('_')) continue; // skip metadata keys like _version
|
|
67
|
+
if (cfg?.agents?.includes(agentName + '.md') && cfg.denied.includes(toolName)) {
|
|
67
68
|
process.stderr.write(`CTX: Tool "${toolName}" blocked for ${category} agent "${agentName}".\n`);
|
|
68
69
|
fs.appendFileSync(
|
|
69
70
|
path.join(ctxDir, 'violations.log'),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ctx-cc",
|
|
3
|
-
"version": "4.
|
|
4
|
-
"description": "CTX 4.0 — Intelligent workflow orchestration for Claude Code.
|
|
3
|
+
"version": "4.1.1",
|
|
4
|
+
"description": "CTX 4.0 — Intelligent workflow orchestration for Claude Code. 26 subagents, 7 skills, deterministic hooks. Phase-based lifecycle with autonomous execution.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
7
7
|
"claude-code",
|
package/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ctx",
|
|
3
3
|
"version": "4.0.0",
|
|
4
|
-
"description": "CTX — Intelligent workflow orchestration for Claude Code.
|
|
4
|
+
"description": "CTX — Intelligent workflow orchestration for Claude Code. Specialized agents, phase-based lifecycle, three-stage review gate with OpenAI Codex cross-model review, autonomous execution.",
|
|
5
5
|
"author": "jufjuf",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://github.com/jufjuf/CTX",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"settings": {
|
|
40
40
|
"reviewGate": true,
|
|
41
|
+
"codexReview": true,
|
|
41
42
|
"tddMode": "off",
|
|
42
43
|
"maxReviewCycles": 3,
|
|
43
44
|
"maxAutoIterations": 5
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ctx-review-gate
|
|
3
3
|
description: |
|
|
4
|
-
WHEN: Code has been implemented and needs quality verification before marking a story complete. Runs
|
|
4
|
+
WHEN: Code has been implemented and needs quality verification before marking a story complete. Runs three-stage review: spec compliance, code quality, and optional cross-model adversarial review via OpenAI Codex.
|
|
5
5
|
WHEN NOT: During planning, research, or when review gate is disabled in config.
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# CTX
|
|
8
|
+
# CTX Three-Stage Review Gate
|
|
9
9
|
|
|
10
10
|
Automated quality gate that runs after execution and before verification.
|
|
11
11
|
|
|
12
|
-
##
|
|
12
|
+
## Three Stages
|
|
13
13
|
|
|
14
14
|
### Stage 1: Spec Compliance (ctx-reviewer)
|
|
15
15
|
Checks whether the code satisfies the story's acceptance criteria.
|
|
@@ -23,18 +23,39 @@ Agent({
|
|
|
23
23
|
})
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
### Stage 2: Code Quality (ctx-
|
|
27
|
-
|
|
26
|
+
### Stage 2: Code Quality (ctx-reviewer)
|
|
27
|
+
Reuses ctx-reviewer with a quality-focused prompt: security, performance, error handling, style. **Only runs if Stage 1 passes.**
|
|
28
|
+
|
|
29
|
+
(Note: earlier versions of this skill called `ctx-auditor` here. That was a miscast — `ctx-auditor` is an audit-trail/compliance agent, not a code-quality reviewer. `ctx-reviewer` already covers type checks, imports, security scans, and best-practice enforcement, so it handles both stages with different framings.)
|
|
28
30
|
|
|
29
31
|
Spawn:
|
|
30
32
|
```
|
|
31
33
|
Agent({
|
|
32
|
-
subagent_type: "ctx-
|
|
34
|
+
subagent_type: "ctx-reviewer",
|
|
33
35
|
prompt: "Review recent changes for CODE QUALITY. Check: security vulnerabilities, performance, error handling, style. Output VERDICT: PASS or FAIL with ISSUES list.",
|
|
34
|
-
description: "Code quality
|
|
36
|
+
description: "Code quality review"
|
|
35
37
|
})
|
|
36
38
|
```
|
|
37
39
|
|
|
40
|
+
### Stage 3: Cross-Model Review (ctx-codex-reviewer) — optional
|
|
41
|
+
Sends the diff to OpenAI Codex via MCP for a second-pair-of-eyes review with different model priors. **Only runs if Stage 2 passes AND `config.codexReview !== false`.**
|
|
42
|
+
|
|
43
|
+
Short-circuits on docs-only, test-only, or trivial (<20 LOC) diffs. Fails soft — if the Codex MCP is unavailable, rate-limited, or unauthenticated, returns `SKIP` rather than `FAIL` so infrastructure problems never block the gate.
|
|
44
|
+
|
|
45
|
+
Spawn:
|
|
46
|
+
```
|
|
47
|
+
Agent({
|
|
48
|
+
subagent_type: "ctx-codex-reviewer",
|
|
49
|
+
prompt: "Cross-model review story <ID>. Dispatch the current diff to Codex via mcp__codex__codex with sandbox=read-only. Acceptance criteria: <list>. Output VERDICT: PASS, FAIL, or SKIP.",
|
|
50
|
+
description: "Codex adversarial review"
|
|
51
|
+
})
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Prerequisites (user-side, not automated by CTX):
|
|
55
|
+
- Codex CLI installed (`npm i -g @openai/codex`)
|
|
56
|
+
- Signed in via ChatGPT subscription (`codex login` — no `--api-key` flag)
|
|
57
|
+
- MCP registered (`claude mcp add codex -- codex mcp-server`)
|
|
58
|
+
|
|
38
59
|
## Flow
|
|
39
60
|
|
|
40
61
|
```
|
|
@@ -51,6 +72,12 @@ Stage 2: ctx-auditor (code quality)
|
|
|
51
72
|
├── FAIL → Feed issues back to executor, increment cycle
|
|
52
73
|
│
|
|
53
74
|
▼ PASS
|
|
75
|
+
Stage 3: ctx-codex-reviewer (cross-model, if enabled)
|
|
76
|
+
│
|
|
77
|
+
├── FAIL → Feed issues back to executor, increment cycle
|
|
78
|
+
├── SKIP → Treat as pass (infra problem, not code problem)
|
|
79
|
+
│
|
|
80
|
+
▼ PASS
|
|
54
81
|
Mark story for verification
|
|
55
82
|
```
|
|
56
83
|
|
|
@@ -85,27 +112,36 @@ Update `.ctx/STATE.json`:
|
|
|
85
112
|
"reviewGate": {
|
|
86
113
|
"cycle": 2,
|
|
87
114
|
"history": [
|
|
88
|
-
{ "cycle": 1, "timestamp": "ISO", "stage1": { "passed": true }, "stage2": { "passed": false, "issues": "..." }, "result": "fail" },
|
|
89
|
-
{ "cycle": 2, "timestamp": "ISO", "stage1": { "passed": true }, "stage2": { "passed": true }, "result": "pass" }
|
|
115
|
+
{ "cycle": 1, "timestamp": "ISO", "stage1": { "passed": true }, "stage2": { "passed": false, "issues": "..." }, "stage3": null, "result": "fail" },
|
|
116
|
+
{ "cycle": 2, "timestamp": "ISO", "stage1": { "passed": true }, "stage2": { "passed": true }, "stage3": { "passed": true, "threadId": "thr_...", "skipped": false }, "result": "pass" }
|
|
90
117
|
]
|
|
91
118
|
}
|
|
92
119
|
}
|
|
93
120
|
```
|
|
94
121
|
|
|
122
|
+
`stage3` is `null` when Stage 2 fails (not reached) or when `codexReview` is disabled. When Stage 3 runs, record `threadId` so follow-ups reuse the same Codex session.
|
|
123
|
+
|
|
95
124
|
## Save Review Artifacts
|
|
96
125
|
|
|
97
126
|
Write review results to `.ctx/reviews/<story-id>-<timestamp>.json`.
|
|
98
127
|
|
|
99
128
|
## Configuration
|
|
100
129
|
|
|
101
|
-
Review gate can be disabled:
|
|
130
|
+
Review gate can be disabled entirely:
|
|
102
131
|
- Check `.ctx/config.json` for `"reviewGate": false`
|
|
103
132
|
- If disabled, skip directly to verification
|
|
104
133
|
|
|
134
|
+
Stage 3 (Codex cross-review) can be disabled independently:
|
|
135
|
+
- Check `.ctx/config.json` for `"codexReview": false`
|
|
136
|
+
- Useful when offline, when the ChatGPT rate-limit budget is depleted, or when the change is trivial
|
|
137
|
+
- Stages 1 and 2 continue to run normally
|
|
138
|
+
|
|
105
139
|
## Rules
|
|
106
140
|
|
|
107
|
-
- ALWAYS run Stage 1 before Stage 2
|
|
108
|
-
- NEVER run Stage 2 if Stage 1 fails
|
|
141
|
+
- ALWAYS run Stage 1 before Stage 2, Stage 2 before Stage 3 (fail-fast ordering)
|
|
142
|
+
- NEVER run Stage 2 if Stage 1 fails
|
|
143
|
+
- NEVER run Stage 3 if Stage 2 fails, or if `codexReview === false`
|
|
144
|
+
- Stage 3 SKIP (infrastructure failure) is NOT a gate failure — treat as pass
|
|
109
145
|
- ALWAYS feed review issues back to executor as context on retry
|
|
110
146
|
- Max 3 cycles — then escalate to human
|
|
111
|
-
- Record every cycle in state
|
|
147
|
+
- Record every cycle in state, including `stage3: null` when not reached
|
package/src/capabilities.js
CHANGED
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Schema version for the on-disk capability manifest.
|
|
6
|
+
* Bump when adding categories, renaming fields, or changing policy semantics
|
|
7
|
+
* so stale project manifests can be detected and regenerated.
|
|
8
|
+
*/
|
|
9
|
+
export const MANIFEST_VERSION = 1;
|
|
10
|
+
|
|
4
11
|
/**
|
|
5
12
|
* Default capability manifests per agent category.
|
|
6
|
-
* Defines which tools each agent
|
|
13
|
+
* Defines which tools each ctx-* agent category is allowed to use.
|
|
14
|
+
*
|
|
15
|
+
* The runtime enforcement point is `hooks/pre-tool-use.js`, which reads
|
|
16
|
+
* `.ctx/capability-manifest.json` (written at project init from this table)
|
|
17
|
+
* and blocks tool calls whose name appears in the agent's `denied` list.
|
|
18
|
+
*
|
|
19
|
+
* `allowed` is the declared whitelist and is used for documentation and tests;
|
|
20
|
+
* the hook itself is denylist-driven so unknown tools default to permissive.
|
|
21
|
+
*
|
|
22
|
+
* Iterators over a loaded manifest MUST skip keys starting with `_`
|
|
23
|
+
* (reserved for metadata like `_version`).
|
|
7
24
|
*/
|
|
8
25
|
const DEFAULT_CAPABILITIES = {
|
|
9
26
|
// Planning agents — read-only + write plans
|
|
@@ -22,14 +39,22 @@ const DEFAULT_CAPABILITIES = {
|
|
|
22
39
|
reason: 'Execution agents should not spawn other agents.',
|
|
23
40
|
},
|
|
24
41
|
|
|
25
|
-
// Review agents — read + run tests, no modifications
|
|
42
|
+
// Review agents — read + run tests + Codex cross-review, no modifications
|
|
26
43
|
review: {
|
|
27
|
-
agents: ['ctx-reviewer.md', 'ctx-
|
|
28
|
-
allowed: ['Read', 'Glob', 'Grep', 'Bash'],
|
|
44
|
+
agents: ['ctx-reviewer.md', 'ctx-verifier.md', 'ctx-codex-reviewer.md', 'ctx-ml-reviewer.md'],
|
|
45
|
+
allowed: ['Read', 'Glob', 'Grep', 'Bash', 'mcp__codex__codex'],
|
|
29
46
|
denied: ['Write', 'Edit', 'NotebookEdit'],
|
|
30
47
|
reason: 'Review agents should not modify code.',
|
|
31
48
|
},
|
|
32
49
|
|
|
50
|
+
// Audit agents — write audit trails, but never modify source
|
|
51
|
+
audit: {
|
|
52
|
+
agents: ['ctx-auditor.md'],
|
|
53
|
+
allowed: ['Read', 'Write', 'Bash', 'Glob', 'Grep'],
|
|
54
|
+
denied: ['Edit', 'Agent', 'NotebookEdit'],
|
|
55
|
+
reason: 'Audit agents record trails but should not modify source or spawn agents.',
|
|
56
|
+
},
|
|
57
|
+
|
|
33
58
|
// Mapper agents — read-only analysis
|
|
34
59
|
mapping: {
|
|
35
60
|
agents: ['ctx-mapper.md', 'ctx-arch-mapper.md', 'ctx-tech-mapper.md', 'ctx-quality-mapper.md', 'ctx-concerns-mapper.md'],
|
|
@@ -69,25 +94,23 @@ const DEFAULT_CAPABILITIES = {
|
|
|
69
94
|
denied: ['Edit'],
|
|
70
95
|
reason: 'QA agents test but should not fix code.',
|
|
71
96
|
},
|
|
72
|
-
};
|
|
73
97
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return DEFAULT_CAPABILITIES;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
98
|
+
// ML agents — implement and analyze ML pipelines
|
|
99
|
+
ml: {
|
|
100
|
+
agents: ['ctx-ml-scientist.md', 'ctx-ml-engineer.md', 'ctx-ml-analyst.md'],
|
|
101
|
+
allowed: ['Read', 'Write', 'Edit', 'Bash', 'Glob', 'Grep'],
|
|
102
|
+
denied: ['Agent', 'NotebookEdit'],
|
|
103
|
+
reason: 'ML agents implement and analyze pipelines but should not orchestrate.',
|
|
104
|
+
},
|
|
105
|
+
};
|
|
85
106
|
|
|
86
107
|
/**
|
|
87
108
|
* Find the category for a given agent file.
|
|
109
|
+
* Skips metadata keys (prefix `_`) so a versioned on-disk manifest still works.
|
|
88
110
|
*/
|
|
89
111
|
export function findAgentCategory(agentFile, manifest = DEFAULT_CAPABILITIES) {
|
|
90
112
|
for (const [category, config] of Object.entries(manifest)) {
|
|
113
|
+
if (category.startsWith('_')) continue;
|
|
91
114
|
if (config.agents.includes(agentFile)) {
|
|
92
115
|
return { category, ...config };
|
|
93
116
|
}
|
|
@@ -97,12 +120,14 @@ export function findAgentCategory(agentFile, manifest = DEFAULT_CAPABILITIES) {
|
|
|
97
120
|
|
|
98
121
|
/**
|
|
99
122
|
* Check if a tool is allowed for an agent.
|
|
123
|
+
* Denylist-driven (matches the runtime hook in hooks/pre-tool-use.js).
|
|
124
|
+
* Unknown agents are permissive by default.
|
|
125
|
+
*
|
|
100
126
|
* Returns { allowed: boolean, reason: string|null }.
|
|
101
127
|
*/
|
|
102
128
|
export function checkToolAllowed(agentFile, toolName, manifest = DEFAULT_CAPABILITIES) {
|
|
103
129
|
const category = findAgentCategory(agentFile, manifest);
|
|
104
130
|
if (!category) {
|
|
105
|
-
// Unknown agent — allow everything (permissive for custom agents)
|
|
106
131
|
return { allowed: true, reason: null };
|
|
107
132
|
}
|
|
108
133
|
|
|
@@ -117,37 +142,66 @@ export function checkToolAllowed(agentFile, toolName, manifest = DEFAULT_CAPABIL
|
|
|
117
142
|
}
|
|
118
143
|
|
|
119
144
|
/**
|
|
120
|
-
*
|
|
121
|
-
*
|
|
145
|
+
* Save the capability manifest to `<ctxDir>/capability-manifest.json`.
|
|
146
|
+
* Called from the install flow to seed the template and from the project
|
|
147
|
+
* init command to materialize the manifest that the PreToolUse hook reads.
|
|
122
148
|
*/
|
|
123
|
-
export function
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const mPath=p.join('${ctxDir}','capability-manifest.json');
|
|
130
|
-
let manifest;
|
|
131
|
-
try{manifest=JSON.parse(fs.readFileSync(mPath,'utf-8'));}catch{process.exit(0);}
|
|
132
|
-
for(const[cat,cfg]of Object.entries(manifest)){
|
|
133
|
-
if(cfg.agents.includes(agent)&&cfg.denied.includes(tool)){
|
|
134
|
-
console.error('CTX: Tool '+tool+' blocked for '+cat+' agent '+agent);
|
|
135
|
-
const logDir=p.join('${ctxDir}','violations.log');
|
|
136
|
-
fs.appendFileSync(logDir,new Date().toISOString()+' | '+agent+' | '+tool+' | BLOCKED\\n');
|
|
137
|
-
process.exit(2);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
"`.replace(/\n\s*/g, ' ').trim();
|
|
149
|
+
export function saveCapabilityManifest(ctxDir) {
|
|
150
|
+
const manifestPath = path.join(ctxDir, 'capability-manifest.json');
|
|
151
|
+
if (!fs.existsSync(ctxDir)) fs.mkdirSync(ctxDir, { recursive: true });
|
|
152
|
+
const payload = { _version: MANIFEST_VERSION, ...DEFAULT_CAPABILITIES };
|
|
153
|
+
fs.writeFileSync(manifestPath, JSON.stringify(payload, null, 2) + '\n');
|
|
154
|
+
return manifestPath;
|
|
141
155
|
}
|
|
142
156
|
|
|
143
157
|
/**
|
|
144
|
-
*
|
|
158
|
+
* Read the `_version` field from an on-disk manifest.
|
|
159
|
+
* Returns 0 for pre-versioned manifests, null if file missing/invalid.
|
|
160
|
+
* Callers compare against MANIFEST_VERSION to decide whether to regenerate.
|
|
145
161
|
*/
|
|
146
|
-
export function
|
|
162
|
+
export function readManifestVersion(ctxDir) {
|
|
147
163
|
const manifestPath = path.join(ctxDir, 'capability-manifest.json');
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
164
|
+
try {
|
|
165
|
+
const data = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
|
|
166
|
+
return typeof data._version === 'number' ? data._version : 0;
|
|
167
|
+
} catch {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Migrate an existing project's capability manifest to the current version.
|
|
174
|
+
* - Missing: writes a fresh manifest, returns { action: 'created' }.
|
|
175
|
+
* - Current: no-op, returns { action: 'current' }.
|
|
176
|
+
* - Stale: backs up old manifest as `capability-manifest.v<N>.backup.json`
|
|
177
|
+
* and regenerates, returns { action: 'migrated', backup }.
|
|
178
|
+
*
|
|
179
|
+
* Used by the `ctx-cc update-manifest` CLI subcommand so projects that
|
|
180
|
+
* predate MANIFEST_VERSION can pick up policy changes without re-initting.
|
|
181
|
+
*/
|
|
182
|
+
export function updateProjectManifest(ctxDir) {
|
|
183
|
+
const manifestPath = path.join(ctxDir, 'capability-manifest.json');
|
|
184
|
+
const current = readManifestVersion(ctxDir);
|
|
185
|
+
|
|
186
|
+
if (current === null) {
|
|
187
|
+
saveCapabilityManifest(ctxDir);
|
|
188
|
+
return { action: 'created', from: null, to: MANIFEST_VERSION, path: manifestPath };
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (current === MANIFEST_VERSION) {
|
|
192
|
+
return { action: 'current', from: current, to: current, path: manifestPath };
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const backupPath = path.join(ctxDir, `capability-manifest.v${current}.backup.json`);
|
|
196
|
+
fs.copyFileSync(manifestPath, backupPath);
|
|
197
|
+
saveCapabilityManifest(ctxDir);
|
|
198
|
+
return {
|
|
199
|
+
action: 'migrated',
|
|
200
|
+
from: current,
|
|
201
|
+
to: MANIFEST_VERSION,
|
|
202
|
+
path: manifestPath,
|
|
203
|
+
backup: backupPath,
|
|
204
|
+
};
|
|
151
205
|
}
|
|
152
206
|
|
|
153
207
|
/**
|
|
@@ -156,6 +210,7 @@ export function saveCapabilityManifest(ctxDir) {
|
|
|
156
210
|
export function formatCapabilities(manifest = DEFAULT_CAPABILITIES) {
|
|
157
211
|
const lines = [];
|
|
158
212
|
for (const [category, config] of Object.entries(manifest)) {
|
|
213
|
+
if (category.startsWith('_')) continue;
|
|
159
214
|
lines.push(` ${category}:`);
|
|
160
215
|
lines.push(` Agents: ${config.agents.map(a => a.replace('ctx-', '').replace('.md', '')).join(', ')}`);
|
|
161
216
|
lines.push(` Allowed: ${config.allowed.join(', ')}`);
|
package/src/install.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
|
+
import { saveCapabilityManifest } from './capabilities.js';
|
|
4
5
|
|
|
5
6
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
7
|
const __dirname = path.dirname(__filename);
|
|
@@ -28,7 +29,7 @@ function printBanner() {
|
|
|
28
29
|
`));
|
|
29
30
|
console.log(` ${bold('CTX 4.0')} ${dim(`v${VERSION}`)}`);
|
|
30
31
|
console.log(' Intelligent workflow orchestration for Claude Code.');
|
|
31
|
-
console.log('
|
|
32
|
+
console.log(' 26 agents. 7 skills. Hooks. Phase-based lifecycle.\n');
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
function copyDir(src, dest) {
|
|
@@ -170,6 +171,12 @@ export async function install(options) {
|
|
|
170
171
|
console.log(green(` ✓`) + ` Installed templates (${count} files)`);
|
|
171
172
|
}
|
|
172
173
|
|
|
174
|
+
// Generate capability-manifest.json template from DEFAULT_CAPABILITIES.
|
|
175
|
+
// /ctx:init copies this into each project's .ctx/ so the PreToolUse hook
|
|
176
|
+
// (hooks/pre-tool-use.js) has a manifest to enforce against.
|
|
177
|
+
saveCapabilityManifest(destTemplates);
|
|
178
|
+
console.log(green(` ✓`) + ` Generated capability-manifest.json template`);
|
|
179
|
+
|
|
173
180
|
// Write VERSION file
|
|
174
181
|
fs.writeFileSync(path.join(ctxDir, 'VERSION'), VERSION);
|
|
175
182
|
console.log(green(` ✓`) + ` Wrote VERSION (${VERSION})`);
|
|
@@ -178,8 +185,8 @@ export async function install(options) {
|
|
|
178
185
|
console.log(`\n ${green('Done!')} Launch Claude Code and run ${cyan('/ctx:help')}.`);
|
|
179
186
|
console.log(`
|
|
180
187
|
${bold('What was installed:')}
|
|
181
|
-
${dim('Agents:')} ~/.claude/agents/ctx-*.md (
|
|
182
|
-
${dim('Skills:')} ~/.claude/skills/ctx-*/ (
|
|
188
|
+
${dim('Agents:')} ~/.claude/agents/ctx-*.md (26 subagents)
|
|
189
|
+
${dim('Skills:')} ~/.claude/skills/ctx-*/ (7 skills)
|
|
183
190
|
${dim('Commands:')} ~/.claude/commands/ctx/ (slash commands)
|
|
184
191
|
${dim('Hooks:')} ~/.claude/hooks/ctx-*.js (3 hook scripts)
|
|
185
192
|
${dim('Config:')} ~/.claude/settings.json (hooks registered)
|