@dtlabs/ai-toolkit 0.3.1 → 0.5.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.
@@ -171,51 +171,7 @@ configuration is out of scope and risks clobbering the user's existing settings.
171
171
 
172
172
  ---
173
173
 
174
- ## Step 5 — Matt Pocock Skills (version check + optional install/update)
175
-
176
- After copying the toolkit files, check the state of Matt Pocock's skills:
177
-
178
- 1. **Detect installed version**: check if `~/.claude/skills/mattpocock/.version` exists and read it. If not found, try `npm list -g mattpocock --json` to get the cached version. If neither works, assume not installed.
179
-
180
- 2. **Detect latest available version**: run `npm view mattpocock version` to get the current version on npm. If offline or unavailable, skip the version comparison.
181
-
182
- 3. **Present the appropriate prompt** using `AskUserQuestion`:
183
-
184
- **Not installed:**
185
- ```
186
- question: "Matt Pocock's skills are not installed. Install them now?"
187
- description: "Includes define-feature, grilling, TDD, prototype, handoff, and more.
188
- Installs globally via: npx skills@latest add mattpocock/skills"
189
- options:
190
- - "Yes — install now"
191
- - "No — skip (install manually later)"
192
- ```
193
-
194
- **Installed, update available (installed=vX, latest=vY):**
195
- ```
196
- question: "Matt Pocock skills v{installed} is installed. Update to v{latest}?"
197
- options:
198
- - "Yes — update now"
199
- - "No — keep current version"
200
- ```
201
-
202
- **Already up to date:**
203
- ```
204
- question: "Matt Pocock skills v{installed} is already up to date. Re-install?"
205
- options:
206
- - "Yes — re-install"
207
- - "No — skip"
208
- ```
209
-
210
- 4. If the user selects **Yes** (install or update), run:
211
- ```bash
212
- npx skills@latest add mattpocock/skills
213
- ```
214
- Report the outcome. If it fails, show the manual install command.
215
-
216
- ---
217
-
218
- ## Step 6 — Compact Instructions opt-in
174
+ ## Step 5 — Compact Instructions opt-in
219
175
 
220
176
  The toolkit includes a `# Compact instructions` section for `~/.claude/CLAUDE.md` that guides Claude's auto-compaction (what to keep, what to drop) and enables proactive topic-change suggestions.
221
177
 
@@ -304,7 +260,6 @@ New files copied: N
304
260
  Modified/overwritten: N
305
261
  Modified/kept: N (user chose to keep existing version)
306
262
  Unchanged (same): N (skipped silently)
307
- Matt Pocock skills: ✅ installed v{X} / ⬆️ updated v{old}→v{new} / ⏭ skipped / ✅ already up to date v{X}
308
263
  Spawn depth: ✅ CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=2+ present / ⚠️ MISSING — see action above
309
264
  Compact instructions: {compact_instructions_status}
310
265
  ──────────────────────────────────────────────────
@@ -93,16 +93,18 @@ Write {feature_dir}/{PREFIX}-Effort-Estimate.md with this format:
93
93
  | Human estimate | {human_estimate} (sequential, no parallelism) |
94
94
  | Agent estimate | {agent_estimate} (parallel dispatch, critical path only) |
95
95
 
96
- ## Per-User-Story Breakdown
96
+ ## Per-Phase Breakdown
97
97
 
98
- | US | Title | Tasks | Domains | Est. hours |
99
- |----|-------|-------|---------|------------|
100
- {one row per US extracted from Section 4}
98
+ | Phase | Title | Tasks | Domains | Est. Human | Est. Agent | Actual Human | Actual Agent |
99
+ |-------|-------|-------|---------|-----------|-----------|-------------|-------------|
100
+ {one row per phase (INFRA + each US) extracted from Section 4 of the Work Breakdown — use ~2h per BE task, ~1h per TEST task, ~30min per INFRA task for human estimate; agent estimate = human / 6 as baseline}
101
+ | **Total** | | **{total_tasks}** | | **{human_estimate}** | **{agent_estimate}** | **—** | **—** |
101
102
 
102
103
  ## Notes
103
104
  - Human estimate assumes sequential execution with no parallelism.
104
- - Agent estimate assumes parallel dispatch of independent tasks within each phase.
105
- - Actual effort will be recorded in the Actuals section after implementation.
105
+ - Agent estimate assumes parallel dispatch of independent tasks within each phase (critical path only).
106
+ - Actual Human: filled in if a human developer performed or reviewed the implementation.
107
+ - Actual Agent: filled in by pm-phase3 after implementation completes.
106
108
 
107
109
  TASK 3 — Write the Token-Estimate.md file.
108
110
  Write {feature_dir}/{PREFIX}-Token-Estimate.md with this format:
@@ -111,39 +113,43 @@ Write {feature_dir}/{PREFIX}-Token-Estimate.md with this format:
111
113
 
112
114
  ## Phase 1 — Documentation (Actuals)
113
115
 
114
- | Agent | Task | Model | Tokens (actual) |
115
- |-------|------|-------|----------------|
116
- | generate-requirements | Generate requirements from feature.md | haiku | ${phase1Tokens} (phase delta) |
117
- | generate-tech-spec | Generate tech spec from feature.md | haiku | (see phase delta) |
118
- | validate-feature-docs | Validate requirements + tech spec | haiku | (see phase delta) |
116
+ | Agent | Task | Model | Tokens Est. | Tokens Actual |
117
+ |-------|------|-------|------------|--------------|
118
+ | generate-requirements | Generate requirements from feature.md | haiku | — | {phase1_req_tokens} |
119
+ | generate-tech-spec | Generate tech spec from feature.md | haiku | — | {phase1_spec_tokens} |
120
+ | validate-feature-docs | Validate requirements + tech spec | haiku | — | {phase1_val_tokens} |
121
+ | **Phase 1 total** | | | **—** | **${phase1Tokens}** |
119
122
 
120
123
  ## Phase 2 — Work Breakdown (Actuals)
121
124
 
122
- | Agent | Task | Model | Tokens (actual) |
123
- |-------|------|-------|----------------|
124
- | generate-work-breakdown | Generate work breakdown from docs | haiku | ${phase1Tokens} (phase delta) |
125
+ | Agent | Task | Model | Tokens Est. | Tokens Actual |
126
+ |-------|------|-------|------------|--------------|
127
+ | generate-work-breakdown | Generate work breakdown from docs | haiku | — | {wbTokens from above} |
128
+ | **Phase 2 total** | | | **—** | **{wbTokens from above}** |
125
129
 
126
130
  ## Phase 3 — Implementation (Estimates)
127
131
 
128
132
  Estimates based on {total_tasks} tasks ({domain_breakdown}), {user_stories} User Stories.
129
- Token estimates use ~15,000 tokens per BE task, ~8,000 per TEST task, ~5,000 per INFRA task as baseline.
130
-
131
- | Agent | Task | Model | Tokens (estimated) |
132
- |-------|------|-------|-------------------|
133
- | implementation-orchestrator | Full implementation loop | sonnet | {estimated: total_tasks * 12000} |
134
- | review-solution (×{user_stories}) | Architect review per US | sonnet | {estimated: user_stories * 8000} |
135
- | remediation | Fix WARNING issues | sonnet | ~10,000 |
136
- | pr-and-registry | Push branch, create PR | sonnet | ~5,000 |
137
- | write-actuals | Update Token/Effort Estimate | sonnet | ~3,000 |
138
-
139
- ## Grand Total (Estimate)
140
-
141
- | Phase | Tokens (estimated) | Notes |
142
- |-------|-------------------|-------|
143
- | Phase 1 — Documentation | ${phase1Tokens} | Actual (phase delta) |
144
- | Phase 2 — Work Breakdown | {wbTokens from above} | Actual (phase delta) |
145
- | Phase 3 — Implementation | {sum of phase 3 estimates} | Estimated |
146
- | **Total** | **{grand total}** | |
133
+ Baseline: ~15,000 tokens/BE task, ~8,000/TEST task, ~5,000/INFRA task.
134
+
135
+ | Agent | Task | Model | Tokens Est. | Tokens Actual |
136
+ |-------|------|-------|------------|--------------|
137
+ | developer-backend | Implement BE/INFRA tasks | sonnet | {estimated: be_tasks * 15000 + infra_tasks * 5000} | — |
138
+ | developer-testing | Implement TEST tasks | sonnet | {estimated: test_tasks * 8000} | — |
139
+ | review-solution (×{user_stories}) | Architect review per US | sonnet | {estimated: user_stories * 8000} | — |
140
+ | remediation | Fix review issues | sonnet | ~10,000 | — |
141
+ | pr-and-registry | Push branch, create PR | sonnet | ~5,000 | — |
142
+ | write-actuals | Update Token/Effort Estimate | sonnet | ~3,000 | — |
143
+ | **Phase 3 total** | | | **{sum of phase 3 estimates}** | **—** |
144
+
145
+ ## Grand Total
146
+
147
+ | Phase | Tokens Est. | Tokens Actual |
148
+ |-------|------------|--------------|
149
+ | Phase 1 — Documentation | — | ${phase1Tokens} |
150
+ | Phase 2 — Work Breakdown | — | {wbTokens from above} |
151
+ | Phase 3 — Implementation | {sum of phase 3 estimates} | — |
152
+ | **Total** | **{sum of phase 3 estimates}** | **{phase1Tokens + wbTokens} (partial)** |
147
153
 
148
154
  ---
149
155
  *Actuals will be appended by pm-phase3 after implementation completes.*
@@ -1,10 +1,10 @@
1
1
  export const meta = {
2
2
  name: 'pm-phase3',
3
- description: 'Feature delivery phase 3: parse WB → dispatch specialist agents per US (developer-backend/frontend/testing + review-solution per US, max 2 rework cycles, git commit per US) → remediation → PR → Token-Estimate actuals → Effort-Estimate actuals.',
3
+ description: 'Feature delivery phase 3: parse WB → dispatch specialist agents per US (commit per phase) → single architect review → PR → actuals.',
4
4
  phases: [
5
- { title: 'Parse', detail: 'Parse Work Breakdown into structured implementation phases' },
6
- { title: 'Implementation', detail: 'Dispatch developer agents per US, review, commit' },
7
- { title: 'Remediation', detail: 'Fix OPEN issues from Issues Register' },
5
+ { title: 'Parse', detail: 'Parse Work Breakdown CSV into structured phases' },
6
+ { title: 'Implementation', detail: 'Dispatch developer agents per phase, commit each one' },
7
+ { title: 'Review', detail: 'Single architect review on full feature diff' },
8
8
  { title: 'PR', detail: 'Push branch, create PR, update registry' },
9
9
  { title: 'Actuals', detail: 'Write Token-Estimate and Effort-Estimate actuals' },
10
10
  ],
@@ -17,12 +17,10 @@ const branchMatch = argStr.match(/--branch\s+(\S+)/)
17
17
  const branch = branchMatch ? branchMatch[1] : null
18
18
 
19
19
  const tokenLedger = []
20
- const escalations = []
21
20
 
22
21
  // ── Parse Work Breakdown CSV (deterministic, no AI) ───────────────────────────
23
22
  phase('Parse')
24
23
 
25
- // Derive feature_dir and prefix from featurePath (e.g. "docs/features/FTR-004-.../feature.md")
26
24
  const featureDir = featurePath.replace(/\/[^/]+$/, '')
27
25
  const prefixMatch = featureDir.match(/([A-Z]+-\d+)/)
28
26
  const prefix = prefixMatch ? prefixMatch[1] : 'FTR-000'
@@ -30,22 +28,16 @@ const csvPath = `${featureDir}/${prefix}-Work-Breakdown.csv`
30
28
 
31
29
  log(`Reading CSV: ${csvPath}`)
32
30
 
33
- const READ_SCHEMA = {
34
- type: 'object',
35
- properties: { content: { type: 'string' } },
36
- required: ['content'],
37
- }
38
-
39
- const csvResult = await agent(
40
- `Read the file at path: ${csvPath}\nReturn its full text content as the "content" field.`,
41
- { label: 'read-wb-csv', phase: 'Parse', schema: READ_SCHEMA, model: 'haiku' }
31
+ const csvContent = await agent(
32
+ `Read the file at path: ${csvPath}\nReturn ONLY the raw file contents, nothing else. No explanation, no formatting, no JSON wrapping — just the raw text of the file.`,
33
+ { label: 'read-wb-csv', phase: 'Parse', model: 'haiku' }
42
34
  )
43
35
 
44
36
  // Parse CSV into structured phases — pure JS, no AI
45
- const rows = csvResult.content
37
+ const rows = csvContent
46
38
  .split('\n')
47
39
  .map(l => l.trim())
48
- .filter(l => l && !l.startsWith('phase_id')) // skip header and empty lines
40
+ .filter(l => l && !l.startsWith('phase_id'))
49
41
  .map(l => {
50
42
  const [phase_id, phase_title, commit_message, depends_on, task_id, task_title, domain, agent_type] = l.split('|')
51
43
  return { phase_id, phase_title, commit_message, depends_on: depends_on || '', task_id, task_title, domain, agent_type }
@@ -60,7 +52,7 @@ for (const row of rows) {
60
52
  phase_id: row.phase_id,
61
53
  title: row.phase_title,
62
54
  commit_message: row.commit_message,
63
- depends_on: row.depends_on.split(' ').filter(Boolean), // [] for empty
55
+ depends_on: row.depends_on.split(' ').filter(Boolean),
64
56
  impl_tasks: [],
65
57
  test_tasks: [],
66
58
  })
@@ -93,11 +85,9 @@ const allPhases = Array.from(phaseMap.values()).map(p => ({
93
85
  }))
94
86
 
95
87
  const wb = { prefix, feature_dir: featureDir, phases: allPhases }
96
-
97
88
  log(`CSV parsed: ${rows.length} tasks → ${wb.phases.length} phases for ${wb.prefix}`)
98
89
 
99
- // Build execution waves: phases whose dependencies are all satisfied can run in parallel.
100
- // Wave 0 = no deps, Wave 1 = depends only on Wave 0 phases, etc.
90
+ // Build execution waves: phases whose dependencies are all satisfied run in parallel
101
91
  const buildWaves = (phases) => {
102
92
  const done = new Set()
103
93
  const waves = []
@@ -105,7 +95,6 @@ const buildWaves = (phases) => {
105
95
  while (remaining.length > 0) {
106
96
  const ready = remaining.filter(p => p.depends_on.every(d => done.has(d)))
107
97
  if (ready.length === 0) {
108
- // Circular or unresolvable deps — run the rest sequentially to avoid deadlock
109
98
  waves.push(remaining)
110
99
  break
111
100
  }
@@ -119,131 +108,71 @@ const buildWaves = (phases) => {
119
108
  const waves = buildWaves(wb.phases)
120
109
  log(`Execution plan: ${waves.length} wave(s) — ${waves.map((w, i) => `wave${i+1}:[${w.map(p => p.phase_id).join(',')}]`).join(' ')}`)
121
110
 
122
- const prefix = wb.prefix
123
- let phasesDone = 0
124
- const usPassed = []
125
- const usEscalated = []
126
- let issuesPath = ''
127
- let issuesOpen = 0
111
+ let phasesDone = 0
112
+ const usPassed = []
128
113
 
129
114
  // ── Implementation ────────────────────────────────────────────────────────────
130
115
  phase('Implementation')
131
116
 
132
- const REVIEW_SCHEMA = {
133
- type: 'object',
134
- properties: {
135
- has_critical: { type: 'boolean' },
136
- findings: { type: 'string' },
137
- issues_md: { type: 'string' },
138
- },
139
- required: ['has_critical'],
140
- }
141
-
142
- // executePhase: runs impl_groups → test_groups → review → rework → commit for one phase
117
+ // executePhase: impl_groups (parallel) → test_groups (parallel) → commit
118
+ // No inline review — review runs once after all phases complete.
143
119
  const executePhase = async (implPhase) => {
144
120
  log(`Starting phase ${implPhase.phase_id}: ${implPhase.title}`)
145
121
 
146
- let reworkCycle = 0
147
- let passed = false
148
- let lastFindings = ''
149
-
150
- while (reworkCycle <= 2 && !passed) {
151
- const reworkSuffix = reworkCycle > 0
152
- ? ` -- REWORK CYCLE ${reworkCycle}: address these critical findings:\n${lastFindings}`
153
- : ''
154
-
155
- // Step 1 — impl groups in parallel (INFRA / BE / FE)
156
- if (implPhase.impl_groups.length > 0) {
157
- const beforeImpl = budget.spent()
158
- await parallel(implPhase.impl_groups.map(group => () =>
159
- agent(
160
- `${featurePath} ${group.task_ids.join(',')}${reworkSuffix}`,
161
- {
162
- agentType: group.agent_type,
163
- label: `${group.agent_type}:${implPhase.phase_id}${reworkCycle > 0 ? ':rework' + reworkCycle : ''}`,
164
- phase: 'Implementation',
165
- }
166
- )
167
- ))
168
- const implTokens = budget.spent() - beforeImpl
169
- tokenLedger.push({
170
- agent: `${implPhase.impl_groups.map(g => g.agent_type).join('+')}:${implPhase.phase_id}${reworkCycle > 0 ? ':rework' + reworkCycle : ''}`,
171
- model: 'sonnet',
172
- phase_delta_tokens: implTokens,
173
- })
174
- log(`Phase ${implPhase.phase_id} impl groups done — ${implTokens} tokens`)
175
- }
176
-
177
- // Step 2 — test groups in parallel (TEST) — after impl groups
178
- if (implPhase.test_groups.length > 0) {
179
- const beforeTest = budget.spent()
180
- await parallel(implPhase.test_groups.map(group => () =>
181
- agent(
182
- `${featurePath} ${group.task_ids.join(',')}${reworkSuffix}`,
183
- {
184
- agentType: group.agent_type,
185
- label: `${group.agent_type}:${implPhase.phase_id}${reworkCycle > 0 ? ':rework' + reworkCycle : ''}`,
186
- phase: 'Implementation',
187
- }
188
- )
189
- ))
190
- const testTokens = budget.spent() - beforeTest
191
- tokenLedger.push({
192
- agent: `developer-testing:${implPhase.phase_id}${reworkCycle > 0 ? ':rework' + reworkCycle : ''}`,
193
- model: 'sonnet',
194
- phase_delta_tokens: testTokens,
195
- })
196
- log(`Phase ${implPhase.phase_id} test groups done — ${testTokens} tokens`)
197
- }
198
-
199
- // Step 3 — review-solution
200
- const beforeReview = budget.spent()
201
- const review = await agent(
202
- `${featurePath} --scope ${implPhase.phase_id}`,
203
- {
204
- agentType: 'review-solution',
205
- label: `review-solution:${implPhase.phase_id}`,
206
- phase: 'Implementation',
207
- schema: REVIEW_SCHEMA,
208
- }
209
- )
210
- const reviewTokens = budget.spent() - beforeReview
122
+ // Step 1 — impl groups in parallel (INFRA / BE / FE)
123
+ if (implPhase.impl_groups.length > 0) {
124
+ const beforeImpl = budget.spent()
125
+ await parallel(implPhase.impl_groups.map(group => () =>
126
+ agent(
127
+ `${featurePath} ${group.task_ids.join(',')}`,
128
+ {
129
+ agentType: group.agent_type,
130
+ label: `${group.agent_type}:${implPhase.phase_id}`,
131
+ phase: 'Implementation',
132
+ }
133
+ )
134
+ ))
135
+ const implTokens = budget.spent() - beforeImpl
211
136
  tokenLedger.push({
212
- agent: `review-solution:${implPhase.phase_id}`,
213
- model: 'sonnet',
214
- phase_delta_tokens: reviewTokens,
137
+ agent: `${implPhase.impl_groups.map(g => g.agent_type).join('+')}:${implPhase.phase_id}`,
138
+ model: 'sonnet',
139
+ phase_delta_tokens: implTokens,
215
140
  })
216
-
217
- if (review && !review.has_critical) {
218
- passed = true
219
- if (review.issues_md) {
220
- await agent(
221
- `Append the following WARNING/INFO findings to ${wb.feature_dir}/${prefix}-Issues.md (create the file if it does not exist, with a header "# Issues Register — ${prefix}"):\n\n${review.issues_md}`,
222
- { label: `log-issues:${implPhase.phase_id}`, phase: 'Implementation' }
223
- )
224
- }
225
- } else {
226
- lastFindings = review?.findings || 'unspecified critical issues'
227
- reworkCycle++
228
- log(`Phase ${implPhase.phase_id}: critical findings — rework cycle ${reworkCycle}`)
229
- }
141
+ log(`Phase ${implPhase.phase_id} impl done — ${implTokens} tokens`)
230
142
  }
231
143
 
232
- if (!passed) {
233
- log(`Phase ${implPhase.phase_id} ESCALATED after 2 rework cycles`)
234
- escalations.push({ phaseId: implPhase.phase_id, reason: 'CRITICAL review findings unresolved after 2 rework cycles' })
235
- usEscalated.push(implPhase.phase_id)
236
- } else {
237
- const commitMsg = implPhase.commit_message || `feat(${prefix}): implement ${implPhase.phase_id}`
238
- await agent(
239
- `Run these git commands in the repository root:\ngit add -A\ngit commit -m "${commitMsg}"\nIf there is nothing to commit, that is fine — just report success.`,
240
- { label: `commit:${implPhase.phase_id}`, phase: 'Implementation' }
241
- )
242
- if (implPhase.phase_id !== 'INFRA') usPassed.push(implPhase.phase_id)
243
- log(`Phase ${implPhase.phase_id} passed review and committed`)
144
+ // Step 2 — test groups in parallel (TEST)
145
+ if (implPhase.test_groups.length > 0) {
146
+ const beforeTest = budget.spent()
147
+ await parallel(implPhase.test_groups.map(group => () =>
148
+ agent(
149
+ `${featurePath} ${group.task_ids.join(',')}`,
150
+ {
151
+ agentType: group.agent_type,
152
+ label: `developer-testing:${implPhase.phase_id}`,
153
+ phase: 'Implementation',
154
+ }
155
+ )
156
+ ))
157
+ const testTokens = budget.spent() - beforeTest
158
+ tokenLedger.push({
159
+ agent: `developer-testing:${implPhase.phase_id}`,
160
+ model: 'sonnet',
161
+ phase_delta_tokens: testTokens,
162
+ })
163
+ log(`Phase ${implPhase.phase_id} tests done — ${testTokens} tokens`)
244
164
  }
245
165
 
166
+ // Step 3 — commit this phase
167
+ const commitMsg = implPhase.commit_message || `feat(${prefix}): implement ${implPhase.phase_id}`
168
+ await agent(
169
+ `Run these git commands in the repository root:\ngit add -A\ngit commit -m "${commitMsg}"\nIf there is nothing to commit, that is fine — just report success.`,
170
+ { label: `commit:${implPhase.phase_id}`, phase: 'Implementation', model: 'haiku' }
171
+ )
172
+
173
+ if (implPhase.phase_id !== 'INFRA') usPassed.push(implPhase.phase_id)
246
174
  phasesDone++
175
+ log(`Phase ${implPhase.phase_id} committed`)
247
176
  }
248
177
 
249
178
  // Execute waves: phases in the same wave run in parallel, waves are sequential
@@ -256,69 +185,57 @@ for (const wave of waves) {
256
185
  }
257
186
  }
258
187
 
259
- // Count open issues
260
- const ISSUES_SCHEMA = {
261
- type: 'object',
262
- properties: {
263
- exists: { type: 'boolean' },
264
- open_count: { type: 'number' },
265
- path: { type: 'string' },
266
- },
267
- required: ['exists', 'open_count'],
268
- }
269
- const issuesResult = await agent(
270
- `Check if ${wb.feature_dir}/${prefix}-Issues.md exists. If it does, count rows with status OPEN. Return exists, open_count, and the full path.`,
271
- { label: 'count-open-issues', phase: 'Implementation', schema: ISSUES_SCHEMA }
272
- )
273
- issuesPath = issuesResult?.path || ''
274
- issuesOpen = issuesResult?.open_count || 0
275
- log(`Implementation complete — ${phasesDone} phases, ${usPassed.length} US passed, ${usEscalated.length} escalated, ${issuesOpen} open issues`)
188
+ log(`Implementation complete — ${phasesDone} phases, ${usPassed.length} US implemented`)
276
189
 
277
- // ── Remediation ───────────────────────────────────────────────────────────────
278
- phase('Remediation')
190
+ // ── Review — single pass over the full feature diff ───────────────────────────
191
+ phase('Review')
279
192
 
280
- const REM_SCHEMA = {
193
+ const REVIEW_SCHEMA = {
281
194
  type: 'object',
282
195
  properties: {
283
- issues_fixed: { type: 'number' },
284
- issues_deferred: { type: 'number' },
196
+ has_critical: { type: 'boolean' },
197
+ findings: { type: 'string' },
198
+ issues_md: { type: 'string' },
285
199
  },
286
- required: ['issues_fixed', 'issues_deferred'],
200
+ required: ['has_critical'],
287
201
  }
288
202
 
289
- let issuesFixed = 0
290
- let issuesDeferred = 0
291
-
292
- if (issuesOpen > 0 && issuesPath) {
293
- log(`Remediation: ${issuesOpen} OPEN issues`)
294
- const beforeRem = budget.spent()
295
-
296
- const remResult = await agent(
297
- `You are a remediation agent for the feature delivery pipeline.
298
-
299
- Read the Issues Register at: ${issuesPath}
300
-
301
- For each OPEN issue:
302
- - If severity is INFO: mark it DEFERRED immediately (update Status column to DEFERRED). Do not dispatch a developer agent.
303
- - If severity is WARNING: dispatch the appropriate developer agent (developer-backend for most cases) with the issue description. Then spawn review-solution to verify the fix. Max 1 retry per issue. If unresolved after 1 retry, mark DEFERRED.
304
-
305
- After processing all issues, return: { "issues_fixed": N, "issues_deferred": N }
203
+ const beforeReview = budget.spent()
204
+ const review = await agent(
205
+ `${featurePath} --scope all`,
206
+ {
207
+ agentType: 'review-solution',
208
+ label: 'review-solution:full-feature',
209
+ phase: 'Review',
210
+ schema: REVIEW_SCHEMA,
211
+ }
212
+ )
213
+ const reviewTokens = budget.spent() - beforeReview
214
+ tokenLedger.push({ agent: 'review-solution:full-feature', model: 'sonnet', phase_delta_tokens: reviewTokens })
306
215
 
307
- Update the Issues Register Status column in place for each resolved/deferred issue.`,
308
- {
309
- label: 'remediation',
310
- phase: 'Remediation',
311
- schema: REM_SCHEMA,
312
- }
313
- )
216
+ let issuesOpen = 0
217
+ let issuesPath = `${wb.feature_dir}/${prefix}-Issues.md`
218
+ let hasCritical = false
314
219
 
315
- const remTokens = budget.spent() - beforeRem
316
- tokenLedger.push({ agent: 'remediation', model: 'sonnet', phase_delta_tokens: remTokens })
317
- issuesFixed = remResult.issues_fixed || 0
318
- issuesDeferred = remResult.issues_deferred || 0
319
- log(`Remediation done — fixed: ${issuesFixed}, deferred: ${issuesDeferred} — ${remTokens} tokens`)
220
+ if (review) {
221
+ hasCritical = review.has_critical || false
222
+ if (review.issues_md) {
223
+ await agent(
224
+ `Write the following content to ${issuesPath} (create or overwrite the file):\n\n# Issues Register — ${prefix}\n\n${review.issues_md}`,
225
+ { label: 'write-issues', phase: 'Review', model: 'haiku' }
226
+ )
227
+ // Count OPEN issues from issues_md (rough count of "OPEN" occurrences)
228
+ issuesOpen = (review.issues_md.match(/\bOPEN\b/g) || []).length
229
+ log(`Review complete — has_critical: ${hasCritical}, open issues: ${issuesOpen}`)
230
+ } else {
231
+ log(`Review complete — no issues found`)
232
+ }
320
233
  } else {
321
- log('Remediation: no OPEN issues — skipped')
234
+ log(`Review agent returned null — skipping issues register`)
235
+ }
236
+
237
+ if (hasCritical) {
238
+ log(`WARNING: critical issues found — PR will be created but marked as blocked. Inspect ${prefix}-Issues.md before merging.`)
322
239
  }
323
240
 
324
241
  // ── PR ────────────────────────────────────────────────────────────────────────
@@ -341,39 +258,37 @@ const prResult = await agent(
341
258
  Feature path: ${featurePath}
342
259
  Branch: ${branch || 'current branch'}
343
260
  Prefix: ${prefix}
344
- Issues fixed: ${issuesFixed}, deferred: ${issuesDeferred}
261
+ Critical issues found: ${hasCritical}
262
+ Open issues: ${issuesOpen}
345
263
 
346
264
  Your tasks:
347
265
 
348
- 1. If there are remediation fixes, commit them:
349
- git add -A
350
- git commit -m "fix(${prefix}): remediate review issues"
351
-
352
- 2. Push the branch:
266
+ 1. Push the branch:
353
267
  git push -u origin ${branch || 'HEAD'}
354
268
 
355
- 3. Create a PR targeting develop:
269
+ 2. Create a PR targeting develop:
356
270
  gh pr create \\
357
271
  --title "feat(${prefix}): <Feature Title from feature.md>" \\
358
272
  --base develop \\
359
273
  --body "## Summary
360
- - Implements <Feature Title> (<N> User Stories, <N> tasks)
274
+ - Implements <Feature Title from feature.md> (${usPassed.length} User Stories, ${phasesDone} phases)
361
275
  - Source docs: ${prefix}-Requirements.md, ${prefix}-Tech-Spec.md
362
276
 
363
277
  ## Implementation
364
- - Architect review: all US passed
365
- - Issues Register: ${issuesFixed} fixed, ${issuesDeferred} deferred → see ${prefix}-Issues.md
278
+ - Phases implemented: ${usPassed.join(', ') || 'N/A'}
279
+ - Architect review: ${hasCritical ? '⚠️ CRITICAL issues found — see ' + prefix + '-Issues.md before merging' : '✅ No critical issues'}
280
+ - Open issues: ${issuesOpen} → see ${prefix}-Issues.md
366
281
 
367
282
  ## Test plan
368
283
  - [ ] Build passes
369
284
  - [ ] Tests pass
370
285
  - [ ] Manual smoke test of key flows"
371
286
 
372
- 4. Update the Feature Registry (internal_docs/features/REGISTRY.md):
373
- Find or append the entry for ${prefix}. Set Status to "completed".
287
+ 3. Update the Feature Registry (internal_docs/features/REGISTRY.md):
288
+ Find or append the entry for ${prefix}. Set Status to "${hasCritical ? 'review-required' : 'completed'}".
374
289
 
375
290
  Return { "pr_url": "<url>", "registry_updated": true/false }.
376
- If the PR creation fails, return { "pr_url": "(PR creation failed)", "registry_updated": false }.`,
291
+ If the PR already exists, return its URL. If creation fails, return { "pr_url": "(PR creation failed)", "registry_updated": false }.`,
377
292
  {
378
293
  label: 'pr-and-registry',
379
294
  phase: 'PR',
@@ -390,15 +305,6 @@ phase('Actuals')
390
305
 
391
306
  const totalPhase3Tokens = tokenLedger.reduce((s, e) => s + (e.phase_delta_tokens || 0), 0)
392
307
 
393
- const ACTUALS_SCHEMA = {
394
- type: 'object',
395
- properties: {
396
- token_estimate_path: { type: 'string' },
397
- effort_estimate_path: { type: 'string' },
398
- },
399
- required: [],
400
- }
401
-
402
308
  const beforeActuals = budget.spent()
403
309
 
404
310
  await agent(
@@ -419,42 +325,56 @@ Append this section at the end of the file:
419
325
 
420
326
  ---
421
327
 
422
- ## Actuals vs Estimate (pm-phase3)
328
+ ## Phase 3 — Implementation (Actuals)
423
329
 
424
330
  > Phase totals are exact measurements from budget tracking.
425
331
  > Per-agent values are exact where each agent ran separately; proportional where merged.
426
332
 
427
- | Agent | Phase | Model | Phase delta tokens |
428
- |-------|-------|-------|-------------------|
429
- ${tokenLedger.map(e => `| ${e.agent} | — | ${e.model} | ${e.phase_delta_tokens} |`).join('\n')}
333
+ | Agent | Phase | Model | Tokens Est. | Tokens Actual |
334
+ |-------|-------|-------|------------|--------------|
335
+ ${tokenLedger.map(e => `| ${e.agent} | — | ${e.model} | — | ${e.phase_delta_tokens} |`).join('\n')}
336
+ | **Phase 3 total** | | | **—** | **${totalPhase3Tokens}** |
337
+
338
+ ## Grand Total (updated)
430
339
 
431
- ## Grand Total (pm-phase3)
340
+ | Phase | Tokens Est. | Tokens Actual |
341
+ |-------|------------|--------------|
342
+ | Phase 1 — Documentation | — | *(see above)* |
343
+ | Phase 2 — Work Breakdown | — | *(see above)* |
344
+ | Phase 3 — Implementation | *(see above)* | ${totalPhase3Tokens} |
345
+
346
+ ## Implementation Summary
432
347
 
433
348
  | Metric | Value |
434
349
  |--------|-------|
435
- | Total tokens (pm-phase3) | ${totalPhase3Tokens} (exact) |
436
350
  | Implementation phases done | ${phasesDone} |
437
- | US passed | ${usPassed.join(', ') || 'N/A'} |
438
- | US escalated | ${usEscalated.join(', ') || 'none'} |
351
+ | US implemented | ${usPassed.join(', ') || 'N/A'} |
352
+ | Critical issues | ${hasCritical} |
353
+ | Open issues | ${issuesOpen} |
354
+
355
+ TASK 2 — Update actuals in ${prefix}-Effort-Estimate.md:
356
+ Find the file in the feature directory. Read the existing Per-Phase Breakdown table and update
357
+ the "Actual Agent" column for each phase that was implemented:
358
+ - Phases implemented (${usPassed.join(', ') || 'none'} + INFRA): write "done (agent)"
359
+ - Any phase not in the list: leave "—"
439
360
 
440
- TASK 2 — Append actuals to ${prefix}-Effort-Estimate.md:
441
- Find the file in the feature directory. Append:
361
+ Also append this section at the end of the file:
442
362
 
443
363
  ---
444
364
 
445
- ## Actuals vs Estimate
365
+ ## Implementation Summary
446
366
 
447
367
  | Metric | Estimated | Actual |
448
368
  |--------|-----------|--------|
449
369
  | Implementation phases | ${phasesDone} | ${phasesDone} |
450
- | Issues fixed | — | ${issuesFixed} |
451
- | Issues deferred | — | ${issuesDeferred} |
370
+ | Critical review issues | — | ${hasCritical ? 'yes' : 'none'} |
371
+ | Open issues | — | ${issuesOpen} |
452
372
 
453
373
  Return { "token_estimate_path": "<path>", "effort_estimate_path": "<path>" }.`,
454
374
  {
455
375
  label: 'write-actuals',
456
376
  phase: 'Actuals',
457
- schema: ACTUALS_SCHEMA,
377
+ schema: { type: 'object', properties: { token_estimate_path: { type: 'string' }, effort_estimate_path: { type: 'string' } }, required: [] },
458
378
  }
459
379
  )
460
380
 
@@ -463,28 +383,22 @@ tokenLedger.push({ agent: 'write-actuals', model: 'sonnet', phase_delta_tokens:
463
383
  log(`Actuals written — ${actualsTokens} tokens`)
464
384
 
465
385
  // ── Append to process-log ─────────────────────────────────────────────────────
466
- const usPassed3 = usPassed.join(', ') || 'none'
467
- const usEscalated3 = usEscalated.join(', ') || 'none'
468
386
  const phase3Events = [
469
387
  `APPROVAL GRANTED by user — Gate 2`,
470
388
  `pm-phase3 START — implementation phase — branch: ${branch || '(current)'}`,
471
389
  `WB parsed: ${wb.phases.length} phases`,
472
- `Implementation DONE — ${phasesDone} phases | US passed: ${usPassed3} | US escalated: ${usEscalated3}`,
473
- issuesFixed + issuesDeferred > 0
474
- ? `Remediation: ${issuesFixed} fixed, ${issuesDeferred} deferred`
475
- : `Remediation: skipped (no open issues)`,
390
+ `Implementation DONE — ${phasesDone} phases implemented: ${usPassed.join(', ') || 'none'}`,
391
+ `Review DONE — critical: ${hasCritical}, open issues: ${issuesOpen}`,
476
392
  `PR created: ${prResult.pr_url}`,
477
393
  `Actuals written: Token-Estimate.md + Effort-Estimate.md`,
478
394
  `RUN COMPLETE`,
479
395
  `════════════════════════════════════════════════════════`,
480
396
  ].join('\n')
481
397
 
482
- const featureDir3 = featurePath.replace(/\/[^/]+$/, '')
483
-
484
398
  await agent(
485
399
  `Append phase 3 events to the process-log for this feature delivery run.
486
400
 
487
- Process-log path: ${featureDir3}/${prefix}-process-log.txt
401
+ Process-log path: ${featureDir}/${prefix}-process-log.txt
488
402
 
489
403
  Steps:
490
404
  1. Get current UTC datetime via Bash: run \`date -u +"%Y-%m-%dT%H:%M:%S"\`
@@ -494,16 +408,14 @@ Steps:
494
408
 
495
409
  Events to append:
496
410
  ${phase3Events}`,
497
- { label: 'finalize-process-log', phase: 'Actuals' }
411
+ { label: 'finalize-process-log', phase: 'Actuals', model: 'haiku' }
498
412
  )
499
413
 
500
414
  return {
501
415
  pr_url: prResult.pr_url,
502
416
  token_ledger: tokenLedger,
503
417
  issues_summary: {
504
- escalations: escalations.length,
505
- escalation_details: escalations,
506
- issues_fixed: issuesFixed,
507
- issues_deferred: issuesDeferred,
418
+ has_critical: hasCritical,
419
+ open_issues: issuesOpen,
508
420
  },
509
421
  }
package/CHANGELOG.md CHANGED
@@ -1,4 +1,26 @@
1
1
  ## 0.1.4 (2026-07-21)
2
+ ## [0.5.0](https://github.com/dtlab-tech/ai-toolkit/compare/v0.4.0...v0.5.0) (2026-07-29)
3
+
4
+
5
+ ### Features
6
+
7
+ * **pm-phase3:** Option C review architecture + estimate format improvements ([b385b3e](https://github.com/dtlab-tech/ai-toolkit/commit/b385b3e35ef9121b8d9008223c77c88291c4173a))
8
+
9
+ ## [0.4.0](https://github.com/dtlab-tech/ai-toolkit/compare/v0.3.1...v0.4.0) (2026-07-29)
10
+
11
+
12
+ ### Features
13
+
14
+ * **effort-estimate:** add Est./Actual Human/Agent columns to Per-Phase Breakdown ([696146c](https://github.com/dtlab-tech/ai-toolkit/commit/696146cc583ca13ee18914af19ff4de87a91cb60))
15
+ * FTR-010 unit tests, process-log, OPT-02/03/04, remove Matt Pocock dependency ([1f43a4e](https://github.com/dtlab-tech/ai-toolkit/commit/1f43a4e6bf98a4b5821f1a0ae2dac33aca090597))
16
+ * **token-estimate:** split tokens into Est./Actual columns in pm-phase2 and pm-phase3 ([d85b6e4](https://github.com/dtlab-tech/ai-toolkit/commit/d85b6e4aa871a934190e1d65995cb8e7e8db4495))
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+ * **pm-phase3:** read CSV as raw string instead of schema-wrapped object ([1737842](https://github.com/dtlab-tech/ai-toolkit/commit/17378422f6a9dc9168a35c7114cdd227e9214ce8))
22
+ * **pm-phase3:** remove duplicate const prefix declaration ([85455e8](https://github.com/dtlab-tech/ai-toolkit/commit/85455e83929ccc6274d7d888fd429fc83ad78137))
23
+
2
24
  ## [0.3.1](https://github.com/dtlab-tech/ai-toolkit/compare/v0.3.0...v0.3.1) (2026-07-28)
3
25
 
4
26
 
@@ -0,0 +1,34 @@
1
+ # AI Toolkit — Gate Protocol
2
+
3
+ > Full catalog (Skills, Commands, Agents, Procedures): see `CLAUDE.md` in the project root,
4
+ > or [`docs/reference.md`](docs/reference.md) for the cheatsheet.
5
+
6
+ ## Gate Protocol — MANDATORY RULES
7
+
8
+ These rules apply in every session, without exception.
9
+
10
+ ### Launching the Project Manager
11
+
12
+ **Always pass `run_in_background: false` when spawning the `project-manager` agent.**
13
+
14
+ Running the PM in the background leaves the main loop free to act independently. This creates two parallel execution paths that will conflict. The PM must block the main loop until it reaches a gate and returns.
15
+
16
+ ### While the PM is running
17
+
18
+ **Do nothing.** No file reads "to prepare", no file writes "to accelerate", no implementation "because it seems stuck". The only permitted actions are:
19
+
20
+ - Receiving gate notifications and presenting them to the user
21
+ - Responding to the user's status questions ("still running")
22
+ - Sending messages to the PM via SendMessage if it is genuinely blocked and the user asks to unblock it
23
+
24
+ If the PM produces relay agents that appear to do nothing useful, that is noise — not a signal that the PM is stuck. Wait.
25
+
26
+ ### Gate notifications are hard stops
27
+
28
+ When any gate notification arrives (Gate 1, Gate 2, Findings Gate, or any **HARD STOP** in any agent output):
29
+
30
+ 1. Stop immediately — even if mid-turn
31
+ 2. Present the full gate content to the user
32
+ 3. Wait for explicit written approval before touching any file or spawning any agent
33
+
34
+ This applies even if the PM appears stuck, in a relay loop, or the gate arrives while another tool call is in progress.
package/CLAUDE.md CHANGED
@@ -2,19 +2,7 @@
2
2
 
3
3
  A reusable set of AI agents and procedures for software feature delivery and codebase assessment — from requirements to PR, and from audit to remediation.
4
4
 
5
- > **Need a quick overview of what's available?** See [`docs/reference.md`](docs/reference.md) for the cheatsheet.
6
-
7
- ## Dependencies
8
-
9
- This toolkit expects the **`define-feature`** agent from [Matt Pocock's skills package](https://github.com/mattpocock/skills) to be available. That agent is responsible for producing the `feature.md` input file that `/implement-feature` and all downstream agents consume.
10
-
11
- Install it with:
12
-
13
- ```bash
14
- npx skills@latest add mattpocock/skills
15
- ```
16
-
17
- > **Tip:** Install Matt's skills globally (`~/.claude/skills/`) so they are available in every project without repeating the setup.
5
+ > **Full catalog of skills, commands, agents, and procedures:** [`docs/reference.md`](docs/reference.md)
18
6
 
19
7
  ## How it works
20
8
 
@@ -81,89 +69,17 @@ When any gate notification arrives (Gate 1, Gate 2, Findings Gate, or any **HARD
81
69
 
82
70
  This applies even if the PM appears stuck, in a relay loop, or the gate arrives while another tool call is in progress.
83
71
 
84
- ---
85
-
86
- ## Skills (user-invocable, in `.claude/skills/`)
87
-
88
- ### Feature Delivery
89
-
90
- | Skill | Command | Purpose |
91
- |-------|---------|---------|
92
- | Install Toolkit | `/install-toolkit` | Copies all agents, skills, commands, and procedures into a destination project (no local toolkit repo needed) |
93
- | Init AGENTS.md | `/init-agents` | Analyzes a project codebase and generates the AGENTS.md convention file required by all developer agents |
94
- | Define Feature | `/define-feature` | Interviews you to define a new feature and writes `feature.md` — required input for `/implement-feature` |
95
- | Implement Feature | `/implement-feature` | Starts the full feature delivery pipeline: docs → approval → implement → review → PR |
96
-
97
- ### Assessment & Remediation
98
-
99
- | Skill | Command | Purpose |
100
- |-------|---------|---------|
101
- | Assess Codebase | `/assess-codebase` | Starts the full assessment pipeline: parallel assessment → intervention docs → approval gate → remediation → review → PR |
102
-
103
- ### General
104
-
105
- | Skill | Command | Purpose |
106
- |-------|---------|---------|
107
- | Gaia | `/hi-gaia [topic]` | Your toolkit assistant — introduces herself, explains pipelines, agents, and commands; helps you find the right tool for your situation |
108
-
109
- ## Commands (slash shortcuts, in `.claude/commands/`)
110
-
111
- ### Feature Delivery
112
-
113
- | Command | Purpose |
114
- |---------|---------|
115
- | `/feature-status <slug>` | Reports presence/state of feature.md, requirements, tech-spec, work-breakdown, and implementation progress |
116
- | `/check-docs <slug>` | Terse consistency check between feature docs — outputs only the inconsistencies |
117
- | `/pr-description` | Generates a PR description from the current branch commits + linked feature.md |
118
- | `/next-task [slug]` | Finds the next unblocked task in the work breakdown and suggests the agent to delegate it to |
119
-
120
- ### Assessment & Remediation
121
-
122
- | Command | Purpose |
123
- |---------|---------|
124
- | `/assessment-status <prefix>` | Reports presence/state of all assessment artifacts (assessments, interventions, approvals, issues register) |
125
- | `/next-intervention [prefix]` | Finds the next un-actioned flagged intervention and suggests the `/define-feature` invocation to start on it |
126
- | `/check-interventions [prefix]` | Full reconciliation table: every intervention cross-referenced against the Index, on-disk files, and existing feature folders |
127
-
128
- ## Agents (spawnable subagents, in `.claude/agents/`)
129
-
130
- ### Feature Delivery
131
-
132
- | Agent | subagent_type | Purpose |
133
- |-------|---------------|---------|
134
- | Install Toolkit | `install-toolkit` | Copies toolkit files into a destination project |
135
- | Init AGENTS.md | `init-agents-md` | Analyzes codebase and generates AGENTS.md |
136
- | Define Feature | `define-feature` | Interviews the user and writes `feature.md` in `docs/features/FTR-XXX-slug/` |
137
- | Generate Requirements | `generate-requirements` | Produces functional requirements from feature.md |
138
- | Generate Tech-Spec | `generate-tech-spec` | Produces technical specification from feature + requirements |
139
- | Validate Docs | `validate-feature-docs` | Cross-validates requirements + tech-spec against feature.md |
140
- | Generate Work Breakdown | `generate-work-breakdown` | Creates User Stories + tasks from approved docs |
141
- | Backend Developer | `developer-backend` | Implements backend tasks (DB, BE, INFRA domains) |
142
- | Frontend Developer | `developer-frontend` | Implements frontend tasks (FE domain) |
143
- | Testing Agent | `developer-testing` | Creates unit/integration tests (TEST domain) |
144
- | Review Solution | `review-solution` | Architect-level code review |
145
- | Project Manager | `project-manager` | Orchestrates the full feature delivery pipeline |
146
-
147
- ### Assessment & Remediation
148
-
149
- | Agent | subagent_type | Purpose |
150
- |-------|---------------|---------|
151
- | Assessment Manager | `assessment-manager` | Orchestrates the assessment pipeline: parallel assessment → intervention docs → approval gate → effort/token estimates → summary |
152
- | Generic Software Assessment | `generic-software-assessment` | Broad quality analysis across architecture, security, testability, observability, DevOps |
153
- | Intervention Documentation Standard | `intervention-documentation-standard` | Generates structured, self-contained intervention documents from assessment findings |
154
- | God Class Decomposition | `god-class-decomposition` | Safe incremental decomposition of oversized classes and methods |
155
- | Domain Model Refactoring | `domain-model-refactoring` | Splits monolithic model files, introduces type hierarchies, aligns domain vocabulary |
156
- | Layered Architecture Assessment | `layered-architecture-assessment` | Audits layer boundary violations and namespace/package misalignment |
157
- | Dependency Injection Refactoring | `dependency-injection-refactoring` | Converts static/direct coupling to constructor-injected services |
158
- | Security Hardening | `security-hardening` | Input validation, parameterised queries, secret management, log sanitisation, TLS |
159
- | Dependency Supply Chain Security | `dependency-supply-chain-security` | Lock files, integrity verification, unused dependency audit, SCA in CI |
160
- | Concurrency Safety Assessment | `concurrency-safety-assessment` | Race conditions, shared mutable state, unsafe shutdown patterns |
161
-
162
- ## Available procedures (in `docs/procedures/`)
163
-
164
- | Procedure | Purpose |
165
- |-----------|---------|
166
- | `code-generation.md` | Step-by-step workflow for generating/modifying code |
167
- | `code-review.md` | Checklist and process for reviewing code |
168
- | `secure-coding.md` | Security checklist for auth/data handling |
169
- | `testing.md` | Strategy and guidelines for writing tests |
72
+ ## Compact instructions
73
+
74
+ When compacting this conversation, preserve:
75
+ - Current objective and which pipeline step we are on
76
+ - User decisions and approvals (Gate 1, Gate 2, Findings Gate)
77
+ - Files created or modified this session
78
+ - Open errors or blockers
79
+ - Feature/assessment prefix IDs and artifact paths (e.g. FTR-010, ASSESS-001)
80
+
81
+ Discard:
82
+ - Raw grep/glob/read output that has already been acted on
83
+ - Successful tool-call results that produced no follow-up action
84
+ - Repeated explanations of the same concept
85
+ - Superseded plans or approaches
package/bin/cli.js CHANGED
@@ -225,53 +225,6 @@ async function runInstall(label, mappings, force) {
225
225
  );
226
226
  }
227
227
 
228
- // ── Matt Pocock skills ───────────────────────────────────────────────────────
229
-
230
- function isMattPocockInstalled() {
231
- const homedir = require('os').homedir();
232
- // 'grilling' is a skill exclusive to Matt Pocock's package — not included in this toolkit
233
- const pathsToCheck = [
234
- path.join(homedir, '.claude', 'skills', 'grilling', 'SKILL.md'),
235
- path.join(process.cwd(), '.claude', 'skills', 'grilling', 'SKILL.md'),
236
- ];
237
- return pathsToCheck.some(p => fs.existsSync(p));
238
- }
239
-
240
- async function installMattPocock() {
241
- const { execSync } = require('child_process');
242
- console.log(`\n ${clr('cyan', '↓')} Running: ${dim('npx skills@latest add mattpocock/skills')}\n`);
243
- try {
244
- execSync('npx skills@latest add mattpocock/skills', { stdio: 'inherit' });
245
- console.log(`\n ${clr('green', '✔')} Matt Pocock skills installed successfully.\n`);
246
- } catch (err) {
247
- console.error(`\n ${clr('red', '✖')} Install failed: ${err.message}`);
248
- console.error(` Run manually: ${dim('npx skills@latest add mattpocock/skills')}\n`);
249
- }
250
- }
251
-
252
- async function askMattPocock() {
253
- const installed = isMattPocockInstalled();
254
-
255
- console.log(divider());
256
- console.log(bold(' Matt Pocock Skills'));
257
- console.log(divider());
258
- console.log(` ${dim('Includes: define-feature, grilling, TDD, prototype, handoff, and more.')}`);
259
- console.log();
260
-
261
- if (!installed) {
262
- console.log(` ${clr('gray', '○')} Status : ${clr('gray', 'not installed')}\n`);
263
- const ok = await askConfirm('Install Matt Pocock\'s skills now?');
264
- if (ok) await installMattPocock();
265
- else console.log(`\n ${clr('gray', 'Skipped. Install later with: npx skills@latest add mattpocock/skills')}\n`);
266
- return;
267
- }
268
-
269
- console.log(` ${clr('green', '✔')} Status : ${clr('green', 'installed')}\n`);
270
- const ok = await askConfirm('Re-install / update Matt Pocock skills?');
271
- if (ok) await installMattPocock();
272
- else console.log(` ${clr('gray', 'Skipped.')}\n`);
273
- }
274
-
275
228
  // ── subagent spawn-depth check (verify & advise only — never write) ────────────
276
229
 
277
230
  const SPAWN_DEPTH_VAR = 'CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH';
@@ -334,7 +287,6 @@ async function installLocal(targetDir, force) {
334
287
  writeInstalledVersion(targetDir);
335
288
  console.log(` ${clr('green', '✔')} ${bold('Install complete.')}\n`);
336
289
  checkSpawnDepth(targetDir);
337
- await askMattPocock();
338
290
  console.log(divider());
339
291
  console.log(`\n ${bold('Next steps:')}`);
340
292
  console.log(` ${clr('cyan', '1.')} Run ${clr('cyan', '/init-agents')} to generate AGENTS.md`);
@@ -355,13 +307,12 @@ async function installGlobal(force) {
355
307
  { src: path.join(packageRoot, '.claude', 'commands'), dest: path.join(target, 'commands') },
356
308
  { src: path.join(packageRoot, '.claude', 'workflows'), dest: path.join(target, 'workflows') },
357
309
  { src: path.join(packageRoot, 'docs'), dest: path.join(target, 'docs') },
358
- { src: path.join(packageRoot, 'CLAUDE.md'), dest: path.join(target, 'CLAUDE.md') },
310
+ { src: path.join(packageRoot, 'CLAUDE.global.md'), dest: path.join(target, 'CLAUDE.md') },
359
311
  ];
360
312
  await runInstall('global Claude folder', mappings, force);
361
313
  writeInstalledVersion(target);
362
314
  console.log(` ${clr('green', '✔')} ${bold('Global install complete.')}\n`);
363
315
  checkSpawnDepth(homedir);
364
- await askMattPocock();
365
316
  console.log(divider());
366
317
  console.log(`\n ${bold('Next steps:')}`);
367
318
  console.log(` ${clr('cyan', '1.')} The toolkit is now available in all your projects`);
@@ -419,7 +370,6 @@ if (require.main === module) {
419
370
  expandMappings,
420
371
  categorize,
421
372
  readInstalledVersion,
422
- isMattPocockInstalled,
423
373
  NEVER_COPY,
424
374
  };
425
375
  }
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@dtlabs/ai-toolkit",
3
- "version": "0.3.1",
3
+ "version": "0.5.0",
4
4
  "description": "AI Toolkit — reusable agents and procedures for developers to build AI-powered applications.",
5
5
  "files": [
6
6
  "docs/",
7
7
  "CLAUDE.md",
8
8
  "CHANGELOG.md",
9
9
  "README.md",
10
+ "CLAUDE.global.md",
10
11
  ".claude",
11
12
  "bin"
12
13
  ],