@dtlabs/ai-toolkit 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/.claude/agents/generate-work-breakdown.md +212 -192
  2. package/.claude/agents/install-toolkit.md +6 -1
  3. package/.claude/agents/validate-work-breakdown-semantic.md +96 -0
  4. package/.claude/scripts/.gitkeep +0 -0
  5. package/.claude/scripts/tests/fixtures/ac-table-format.md +48 -0
  6. package/.claude/scripts/tests/fixtures/test-feature/TEST-001-Work-Breakdown.json +234 -0
  7. package/.claude/scripts/tests/fixtures/test-feature/TEST-001-semantic-output.json +4 -0
  8. package/.claude/scripts/tests/fixtures/test-feature/feature.md +45 -0
  9. package/.claude/scripts/tests/fixtures/wb-invalid-bad-domain.json +39 -0
  10. package/.claude/scripts/tests/fixtures/wb-invalid-cycle.json +61 -0
  11. package/.claude/scripts/tests/fixtures/wb-invalid-duplicate-id.json +72 -0
  12. package/.claude/scripts/tests/fixtures/wb-invalid-missing-field.json +38 -0
  13. package/.claude/scripts/tests/fixtures/wb-valid.json +189 -0
  14. package/.claude/scripts/tests/helpers/buildWaves.js +21 -0
  15. package/.claude/scripts/tests/helpers/pm-phase2-flow.js +29 -0
  16. package/.claude/scripts/tests/helpers/pm-phase2-gate2.js +55 -0
  17. package/.claude/scripts/tests/helpers/pm-phase2-ledger.js +108 -0
  18. package/.claude/scripts/tests/installer.scripts-distribution.test.js +131 -0
  19. package/.claude/scripts/tests/pm-phase2.gate2-payload.test.js +353 -0
  20. package/.claude/scripts/tests/pm-phase2.ledger-transitions.test.js +346 -0
  21. package/.claude/scripts/tests/pm-phase2.orchestration-flow.test.js +276 -0
  22. package/.claude/scripts/tests/verify-us-01-t03.js +288 -0
  23. package/.claude/scripts/tests/verify-us-03-t04.js +262 -0
  24. package/.claude/scripts/tests/wb-render.checks-md-csv-deps.test.js +337 -0
  25. package/.claude/scripts/tests/wb-render.checks-sanitize-commit-paths.test.js +352 -0
  26. package/.claude/scripts/tests/wb-render.regression-pm-phase3-csv.test.js +219 -0
  27. package/.claude/scripts/tests/wb-validate.checks-1-7.test.js +330 -0
  28. package/.claude/scripts/tests/wb-validate.checks-11.test.js +166 -0
  29. package/.claude/scripts/tests/wb-validate.checks-12-14.test.js +222 -0
  30. package/.claude/scripts/tests/wb-validate.checks-15-18.test.js +359 -0
  31. package/.claude/scripts/tests/wb-validate.checks-19-21.test.js +362 -0
  32. package/.claude/scripts/tests/wb-validate.checks-22-23-report.test.js +297 -0
  33. package/.claude/scripts/tests/wb-validate.checks-8-10.test.js +243 -0
  34. package/.claude/scripts/wb-render.js +309 -0
  35. package/.claude/scripts/wb-validate.js +1007 -0
  36. package/.claude/workflows/pm-phase1.js +22 -13
  37. package/.claude/workflows/pm-phase2.js +304 -32
  38. package/.claude/workflows/pm-phase3.js +57 -21
  39. package/CHANGELOG.md +82 -0
  40. package/bin/cli.js +1 -0
  41. package/package.json +1 -1
@@ -11,6 +11,40 @@ export const meta = {
11
11
  ],
12
12
  }
13
13
 
14
+ // ── Ledger helper functions ───────────────────────────────────────────────────
15
+ // Route all ledger I/O through agent() — fs and require() are not available in
16
+ // the Workflow runtime. Mirrors the pattern used by pm-phase2.js.
17
+
18
+ async function appendLedgerEntry(featureDir, prefix, entry) {
19
+ const ledgerPath = `${featureDir}/${prefix}-token-ledger.json`
20
+ const entryWithoutTs = JSON.stringify({ ...entry, started_at: '__TS__', completed_at: null })
21
+ await agent(
22
+ `Append a JSON object to the ledger array at: ${ledgerPath}\n\n` +
23
+ `1. Run: date -u +"%Y-%m-%dT%H:%M:%SZ" and capture the output as NOW.\n` +
24
+ `2. Read the file. If it does not exist or cannot be parsed as a JSON array, start with [].\n` +
25
+ `3. Push this object onto the array, replacing "__TS__" in started_at with NOW: ${entryWithoutTs}\n` +
26
+ `4. Write the full array back (JSON, 2-space indent). Return no output.`,
27
+ { label: 'append-ledger', phase: 'Implementation', model: 'haiku' }
28
+ )
29
+ }
30
+
31
+ async function updateLedgerEntry(featureDir, prefix, agentKey, updates) {
32
+ const ledgerPath = `${featureDir}/${prefix}-token-ledger.json`
33
+ const updatesWithoutTs = JSON.stringify({ ...updates, completed_at: '__TS__' })
34
+ await agent(
35
+ `Update an entry in the ledger array at: ${ledgerPath}\n\n` +
36
+ `1. Run: date -u +"%Y-%m-%dT%H:%M:%SZ" and capture the output as NOW.\n` +
37
+ `2. Read the file. If it does not exist or cannot be parsed as a JSON array, do nothing.\n` +
38
+ `3. Search from the end for the last entry where agent === "${agentKey}".\n` +
39
+ `4. If found, merge these fields into that entry, replacing "__TS__" in completed_at with NOW: ${updatesWithoutTs}\n` +
40
+ `5. Write the full array back (JSON, 2-space indent). Return no output.\n` +
41
+ `6. If not found, do nothing.`,
42
+ { label: 'update-ledger', phase: 'Implementation', model: 'haiku' }
43
+ )
44
+ }
45
+
46
+ // ── Parse args ────────────────────────────────────────────────────────────────
47
+
14
48
  // args: "<path-to-feature.md> --branch feature/FTR-NNN-slug"
15
49
  const argStr = typeof args === 'string' ? args : ''
16
50
  const featurePath = argStr.trim().split(/\s+/)[0]
@@ -31,10 +65,13 @@ const csvPath = `${featureDir}/${prefix}-Work-Breakdown.csv`
31
65
 
32
66
  log(`Reading CSV: ${csvPath}`)
33
67
 
68
+ await appendLedgerEntry(featureDir, prefix, { agent: 'read-wb-csv:phase3', phase: 'phase3', model: 'haiku', status: 'running', phase_delta_tokens: 0, started_at: '__TS__', completed_at: null })
69
+ const beforeCsv = budget.spent()
34
70
  const csvContent = await agent(
35
71
  `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.`,
36
72
  { label: 'read-wb-csv', phase: 'Parse', model: 'haiku' }
37
73
  )
74
+ await updateLedgerEntry(featureDir, prefix, 'read-wb-csv:phase3', { status: 'done', completed_at: '__TS__', phase_delta_tokens: budget.spent() - beforeCsv })
38
75
 
39
76
  // Parse CSV into structured phases — pure JS, no AI
40
77
  const rows = csvContent
@@ -148,6 +185,8 @@ const executePhase = async (implPhase) => {
148
185
 
149
186
  // Step 1 — impl groups in parallel (INFRA / BE / FE)
150
187
  if (implPhase.impl_groups.length > 0) {
188
+ const implKey = `${implPhase.impl_groups.map(g => g.agent_type).join('+')}:${implPhase.phase_id}${reworkCycle > 0 ? ':rework' + reworkCycle : ''}`
189
+ await appendLedgerEntry(featureDir, prefix, { agent: implKey, phase: 'phase3', model: 'sonnet', status: 'running', phase_delta_tokens: 0, started_at: '__TS__', completed_at: null })
151
190
  const beforeImpl = budget.spent()
152
191
  await parallel(implPhase.impl_groups.map(group => () =>
153
192
  agent(
@@ -160,16 +199,15 @@ const executePhase = async (implPhase) => {
160
199
  )
161
200
  ))
162
201
  const implTokens = budget.spent() - beforeImpl
163
- tokenLedger.push({
164
- agent: `${implPhase.impl_groups.map(g => g.agent_type).join('+')}:${implPhase.phase_id}${reworkCycle > 0 ? ':rework' + reworkCycle : ''}`,
165
- model: 'sonnet',
166
- phase_delta_tokens: implTokens,
167
- })
202
+ await updateLedgerEntry(featureDir, prefix, implKey, { status: 'done', completed_at: '__TS__', phase_delta_tokens: implTokens })
203
+ tokenLedger.push({ agent: implKey, model: 'sonnet', phase_delta_tokens: implTokens })
168
204
  log(`Phase ${implPhase.phase_id} impl groups done — ${implTokens} tokens`)
169
205
  }
170
206
 
171
207
  // Step 2 — test groups in parallel (TEST) — after impl groups
172
208
  if (implPhase.test_groups.length > 0) {
209
+ const testKey = `developer-testing:${implPhase.phase_id}${reworkCycle > 0 ? ':rework' + reworkCycle : ''}`
210
+ await appendLedgerEntry(featureDir, prefix, { agent: testKey, phase: 'phase3', model: 'sonnet', status: 'running', phase_delta_tokens: 0, started_at: '__TS__', completed_at: null })
173
211
  const beforeTest = budget.spent()
174
212
  await parallel(implPhase.test_groups.map(group => () =>
175
213
  agent(
@@ -182,15 +220,14 @@ const executePhase = async (implPhase) => {
182
220
  )
183
221
  ))
184
222
  const testTokens = budget.spent() - beforeTest
185
- tokenLedger.push({
186
- agent: `developer-testing:${implPhase.phase_id}${reworkCycle > 0 ? ':rework' + reworkCycle : ''}`,
187
- model: 'sonnet',
188
- phase_delta_tokens: testTokens,
189
- })
223
+ await updateLedgerEntry(featureDir, prefix, testKey, { status: 'done', completed_at: '__TS__', phase_delta_tokens: testTokens })
224
+ tokenLedger.push({ agent: testKey, model: 'sonnet', phase_delta_tokens: testTokens })
190
225
  log(`Phase ${implPhase.phase_id} test groups done — ${testTokens} tokens`)
191
226
  }
192
227
 
193
228
  // Step 3 — review-solution
229
+ const reviewKey = `review-solution:${implPhase.phase_id}`
230
+ await appendLedgerEntry(featureDir, prefix, { agent: reviewKey, phase: 'phase3', model: 'sonnet', status: 'running', phase_delta_tokens: 0, started_at: '__TS__', completed_at: null })
194
231
  const beforeReview = budget.spent()
195
232
  const review = await agent(
196
233
  `${featurePath} --scope ${implPhase.phase_id}`,
@@ -202,8 +239,9 @@ const executePhase = async (implPhase) => {
202
239
  }
203
240
  )
204
241
  const reviewTokens = budget.spent() - beforeReview
242
+ await updateLedgerEntry(featureDir, prefix, reviewKey, { status: 'done', completed_at: '__TS__', phase_delta_tokens: reviewTokens })
205
243
  tokenLedger.push({
206
- agent: `review-solution:${implPhase.phase_id}`,
244
+ agent: reviewKey,
207
245
  model: 'sonnet',
208
246
  phase_delta_tokens: reviewTokens,
209
247
  })
@@ -238,16 +276,6 @@ const executePhase = async (implPhase) => {
238
276
  }
239
277
 
240
278
  phasesDone++
241
-
242
- // Persist the cumulative token ledger to disk after every completed phase.
243
- // budget.spent() is an in-memory counter — if the workflow is stopped (manual
244
- // stop, crash, timeout) before the Actuals phase, all token data would be lost.
245
- // Writing the full ledger here means the file always reflects real consumption
246
- // up to the last completed phase, recoverable manually or by a resumed run.
247
- await agent(
248
- `Write the following JSON to ${featureDir}/${prefix}-token-ledger.json (overwrite the file if it exists):\n${JSON.stringify(tokenLedger, null, 2)}`,
249
- { label: `persist-ledger:${implPhase.phase_id}`, phase: 'Implementation', model: 'haiku' }
250
- )
251
279
  }
252
280
 
253
281
  // Execute waves: phases in the same wave run in parallel, waves are sequential
@@ -285,6 +313,7 @@ log(`Implementation complete — ${phasesDone} phases, ${usPassed.length} US pas
285
313
  // contention down to a single centralized run with one consolidated failure report.
286
314
  phase('Test')
287
315
 
316
+ await appendLedgerEntry(featureDir, prefix, { agent: 'final-test-run', phase: 'phase3', model: 'haiku', status: 'running', phase_delta_tokens: 0, started_at: '__TS__', completed_at: null })
288
317
  const beforeTest = budget.spent()
289
318
  await agent(
290
319
  `Run the full test suite in the repository root and report the result.
@@ -297,6 +326,7 @@ Do NOT fix failing tests — only report them.`,
297
326
  { label: 'final-test-run', phase: 'Test', model: 'haiku' }
298
327
  )
299
328
  const testTokens = budget.spent() - beforeTest
329
+ await updateLedgerEntry(featureDir, prefix, 'final-test-run', { status: 'done', completed_at: '__TS__', phase_delta_tokens: testTokens })
300
330
  tokenLedger.push({ agent: 'final-test-run', model: 'haiku', phase_delta_tokens: testTokens })
301
331
  log(`Test run complete — ${testTokens} tokens`)
302
332
 
@@ -317,6 +347,7 @@ let issuesDeferred = 0
317
347
 
318
348
  if (issuesOpen > 0 && issuesPath) {
319
349
  log(`Remediation: ${issuesOpen} OPEN issues`)
350
+ await appendLedgerEntry(featureDir, prefix, { agent: 'remediation', phase: 'phase3', model: 'sonnet', status: 'running', phase_delta_tokens: 0, started_at: '__TS__', completed_at: null })
320
351
  const beforeRem = budget.spent()
321
352
 
322
353
  const remResult = await agent(
@@ -339,6 +370,7 @@ Update the Issues Register Status column in place for each resolved/deferred iss
339
370
  )
340
371
 
341
372
  const remTokens = budget.spent() - beforeRem
373
+ await updateLedgerEntry(featureDir, prefix, 'remediation', { status: 'done', completed_at: '__TS__', phase_delta_tokens: remTokens })
342
374
  tokenLedger.push({ agent: 'remediation', model: 'sonnet', phase_delta_tokens: remTokens })
343
375
  issuesFixed = remResult.issues_fixed || 0
344
376
  issuesDeferred = remResult.issues_deferred || 0
@@ -359,6 +391,7 @@ const PR_SCHEMA = {
359
391
  required: ['pr_url'],
360
392
  }
361
393
 
394
+ await appendLedgerEntry(featureDir, prefix, { agent: 'pr-and-registry', phase: 'phase3', model: 'sonnet', status: 'running', phase_delta_tokens: 0, started_at: '__TS__', completed_at: null })
362
395
  const beforePR = budget.spent()
363
396
 
364
397
  const prResult = await agent(
@@ -408,6 +441,7 @@ If the PR creation fails, return { "pr_url": "(PR creation failed)", "registry_u
408
441
  )
409
442
 
410
443
  const prTokens = budget.spent() - beforePR
444
+ await updateLedgerEntry(featureDir, prefix, 'pr-and-registry', { status: 'done', completed_at: '__TS__', phase_delta_tokens: prTokens })
411
445
  tokenLedger.push({ agent: 'pr-and-registry', model: 'sonnet', phase_delta_tokens: prTokens })
412
446
  log(`PR done: ${prResult.pr_url} — ${prTokens} tokens`)
413
447
 
@@ -494,6 +528,7 @@ const ACTUALS_SCHEMA = {
494
528
  required: [],
495
529
  }
496
530
 
531
+ await appendLedgerEntry(featureDir, prefix, { agent: 'write-actuals', phase: 'phase3', model: 'sonnet', status: 'running', phase_delta_tokens: 0, started_at: '__TS__', completed_at: null })
497
532
  const beforeActuals = budget.spent()
498
533
 
499
534
  await agent(
@@ -587,6 +622,7 @@ Return { "token_estimate_path": "<path>", "effort_estimate_path": "<path>" }.`,
587
622
  )
588
623
 
589
624
  const actualsTokens = budget.spent() - beforeActuals
625
+ await updateLedgerEntry(featureDir, prefix, 'write-actuals', { status: 'done', completed_at: '__TS__', phase_delta_tokens: actualsTokens })
590
626
  tokenLedger.push({ agent: 'write-actuals', model: 'sonnet', phase_delta_tokens: actualsTokens })
591
627
  log(`Actuals written — ${actualsTokens} tokens`)
592
628
 
package/CHANGELOG.md CHANGED
@@ -1,4 +1,86 @@
1
1
  ## 0.1.4 (2026-07-21)
2
+ ## [0.10.0](https://github.com/dtlab-tech/ai-toolkit/compare/v0.9.0...v0.10.0) (2026-08-12)
3
+
4
+
5
+ ### Features
6
+
7
+ * **FTR-014:** Atomic Work Breakdown validation pipeline ([59a3be5](https://github.com/dtlab-tech/ai-toolkit/commit/59a3be511238229ca49f280262306b26e5ceb9a0))
8
+ * **FTR-014:** INFRA-T01 Create .claude/scripts/ directory structure ([27773ac](https://github.com/dtlab-tech/ai-toolkit/commit/27773ac03d916ddb64acba03e2f9a21985a59886))
9
+ * **FTR-014:** INFRA-T02 Define WB JSON schema v2 constants ([52c45d0](https://github.com/dtlab-tech/ai-toolkit/commit/52c45d06576e2a7717f98d056953ae6ad821cc75))
10
+ * **FTR-014:** INFRA-T03 Create AC table parser test fixture ([4e6a7a3](https://github.com/dtlab-tech/ai-toolkit/commit/4e6a7a3490f4de53354ac7ae384a00f0e4f98e34))
11
+ * **FTR-014:** INFRA-T04 Define WB_WRAPPER_SCHEMA and WB_RENDER_SCHEMA in pm-phase2.js ([b92e81c](https://github.com/dtlab-tech/ai-toolkit/commit/b92e81c348f3ec4fc2b3b8fe14fd6ecdbd60c3fa))
12
+ * **FTR-014:** INFRA-T05 Create valid and invalid WB JSON test fixtures ([ea5233c](https://github.com/dtlab-tech/ai-toolkit/commit/ea5233c4b1fccd782682533596ddd4febadd3c29))
13
+ * **FTR-014:** INFRA-T06 Extract buildWaves algorithm as shared test utility ([0b2fd25](https://github.com/dtlab-tech/ai-toolkit/commit/0b2fd25bf0d11679b0fef9140bf688b811316f8c))
14
+ * **FTR-014:** INFRA-T07 Define duration policy constants in wb-validate.js ([cd6cfee](https://github.com/dtlab-tech/ai-toolkit/commit/cd6cfee7bffb4dfd1d9ebbf1cc4732cc9def6acf))
15
+ * **FTR-014:** INFRA-T08 Define wb-validate error catalog constants ([06a9cd8](https://github.com/dtlab-tech/ai-toolkit/commit/06a9cd8d4f4e3583b84ac62ae94138184a8d96b8))
16
+ * **FTR-014:** US-01-T01 Update generate-work-breakdown.md to produce schema v2 JSON ([44a9674](https://github.com/dtlab-tech/ai-toolkit/commit/44a9674f897bcb70cbddd11cd9f72f220765e512))
17
+ * **FTR-014:** US-01-T02 Generate Work Breakdown JSON for a test feature ([8b1f3ed](https://github.com/dtlab-tech/ai-toolkit/commit/8b1f3ed65cb75350c2f2c181f5a1e8a8a7642a10))
18
+ * **FTR-014:** US-01-T03 Verify schema v2 compliance of generated JSON ([afdc774](https://github.com/dtlab-tech/ai-toolkit/commit/afdc774b0fc56466eaddbb462bb1230ad31b7792))
19
+ * **FTR-014:** US-02-T01 Implement wb-validate.js entry point and schema version check ([8ff1c30](https://github.com/dtlab-tech/ai-toolkit/commit/8ff1c308934830551c0bae6a1122e68af10dbcd9))
20
+ * **FTR-014:** US-02-T02 Implement unique ID and required field validation ([c426adc](https://github.com/dtlab-tech/ai-toolkit/commit/c426adc3796cc0705a40bb8ac34b1b79ca9f85d0))
21
+ * **FTR-014:** US-02-T03 Implement task ID format, domain, agentType validation ([a2166f7](https://github.com/dtlab-tech/ai-toolkit/commit/a2166f76a1b9e4f1cd7de0925e9ff20fe6d2cb36))
22
+ * **FTR-014:** US-02-T04 Implement task dependency resolution — refs, self-dep, phase consistency ([8fe5906](https://github.com/dtlab-tech/ai-toolkit/commit/8fe59060643a2704ce8aa1bd8a363c8a4a1794ef))
23
+ * **FTR-014:** US-02-T05 Implement task cycle detection (DFS gray/black coloring) ([94e18a3](https://github.com/dtlab-tech/ai-toolkit/commit/94e18a342ae025ff7574ee1fd9b038a6de4dea60))
24
+ * **FTR-014:** US-02-T06 Implement phase-level dependency projection and cycle detection ([a6e7469](https://github.com/dtlab-tech/ai-toolkit/commit/a6e7469541957a2dab3a3d525a87f060f64b2ecd))
25
+ * **FTR-014:** US-02-T07 Implement phase schedulability check (buildWaves) ([6a710a1](https://github.com/dtlab-tech/ai-toolkit/commit/6a710a13c4a4e3132f79f90f9f0d286120e64fb0))
26
+ * **FTR-014:** US-02-T08 Implement duration policy checks (four-band classification) ([44a61fb](https://github.com/dtlab-tech/ai-toolkit/commit/44a61fb62370e06eb7ac1f6e20d0b3e2ec628195))
27
+ * **FTR-014:** US-02-T09 Implement verification commands, commit subject, grouping rationale checks ([cbd64f0](https://github.com/dtlab-tech/ai-toolkit/commit/cbd64f00331e03ac9582b656c3e75b0921246630))
28
+ * **FTR-014:** US-02-T10 Implement AC table parser (Section 3.2 contract) ([317abe4](https://github.com/dtlab-tech/ai-toolkit/commit/317abe4f4a5848370a68d6ad3bae7e8a92755c53))
29
+ * **FTR-014:** US-02-T11 Implement AC existence and scope validation (checks 19-20) ([132e97a](https://github.com/dtlab-tech/ai-toolkit/commit/132e97a804175a2d5b2a97cfbc8816031ea81c87))
30
+ * **FTR-014:** US-02-T12 Implement AC priority derivation and Must coverage check (check 21) ([6483986](https://github.com/dtlab-tech/ai-toolkit/commit/6483986959a603ba1dc75c321db9b08d8808a2be))
31
+ * **FTR-014:** US-02-T13 Implement text field character validation and empty phase detection (checks 22-23) ([d93464e](https://github.com/dtlab-tech/ai-toolkit/commit/d93464e13444e0969a5cb9e58ad0a1c0fc3b865c))
32
+ * **FTR-014:** US-02-T14 Implement domain distribution in validator report output ([2d462f0](https://github.com/dtlab-tech/ai-toolkit/commit/2d462f07a00be04275d15608d2916e15b56df44b))
33
+ * **FTR-014:** US-02-T15 Add Jest suite for wb-validate checks 1-7 (schema, IDs, fields, format, domain, agentType) ([0affff6](https://github.com/dtlab-tech/ai-toolkit/commit/0affff6d986ab3da1b321e1baae91cc49fa402e1))
34
+ * **FTR-014:** US-02-T16 Add Jest suite for wb-validate checks 8-10 (task deps, self-dep, phase consistency) ([17427a2](https://github.com/dtlab-tech/ai-toolkit/commit/17427a2ab900238bf757a11040bb1380dc49fa4e))
35
+ * **FTR-014:** US-02-T17 Add Jest suite for wb-validate check 11 (task cycle detection) ([43e06aa](https://github.com/dtlab-tech/ai-toolkit/commit/43e06aa95fc7203be5d5594443d5dd8a891ba71a))
36
+ * **FTR-014:** US-02-T18 Add Jest suite for wb-validate checks 12-14 (phase graph, cycles, schedulability) ([a4f710e](https://github.com/dtlab-tech/ai-toolkit/commit/a4f710e6ab996251d98af5006f519a497d7ca850))
37
+ * **FTR-014:** US-02-T19 Add Jest suite for wb-validate checks 15-18 (duration policy, commands, commit, rationale) ([3bdfc81](https://github.com/dtlab-tech/ai-toolkit/commit/3bdfc810f4dea82e29493e06fb98e83991d21c9c))
38
+ * **FTR-014:** US-02-T20 Add Jest suite for wb-validate checks 19-21 (AC parsing, scope, priority, Must coverage) ([e237c8e](https://github.com/dtlab-tech/ai-toolkit/commit/e237c8e03f83a499e4f265c2f67ed51b629967f2))
39
+ * **FTR-014:** US-02-T21 Add Jest suite for wb-validate checks 22-23 and report output contract ([9cbb57a](https://github.com/dtlab-tech/ai-toolkit/commit/9cbb57a5f8d781fb20e84235d8c492032c102893))
40
+ * **FTR-014:** US-03-T01 Create validate-work-breakdown-semantic agent definition ([6b34656](https://github.com/dtlab-tech/ai-toolkit/commit/6b3465634632f03f9c79ab27f31a8e842971d66d))
41
+ * **FTR-014:** US-03-T02 US-03-T03 Semantic analysis logic and structured output (covered by T01 agent definition) ([762b648](https://github.com/dtlab-tech/ai-toolkit/commit/762b64853d52b42f9535f4531cb4010d66ae4da2))
42
+ * **FTR-014:** US-03-T04 Manual semantic validation on test features (7/7 schema checks PASS) ([db6ee3c](https://github.com/dtlab-tech/ai-toolkit/commit/db6ee3cefc698216876f479b5fdbe64120e7e2bf))
43
+ * **FTR-014:** US-04-T01 Implement wb-render.js entry point (arg parsing, JSON read, file path setup) ([3d82ca3](https://github.com/dtlab-tech/ai-toolkit/commit/3d82ca3d7427df5e6208c58d1d1625224bcd079f))
44
+ * **FTR-014:** US-04-T02 Implement phase-level depends_on aggregation in wb-render.js ([726a756](https://github.com/dtlab-tech/ai-toolkit/commit/726a756cfee589ea9a2879c7f5d2732ccea682c8))
45
+ * **FTR-014:** US-04-T03 Implement defensive character stripping and commit message construction ([d9262dc](https://github.com/dtlab-tech/ai-toolkit/commit/d9262dc25866100afe74fe468a963c5034745c9a))
46
+ * **FTR-014:** US-04-T04 Implement Markdown output generation in wb-render.js ([2a7a384](https://github.com/dtlab-tech/ai-toolkit/commit/2a7a3842f642cb514e6efd48d94d8f818a3a1414))
47
+ * **FTR-014:** US-04-T05 Implement CSV output generation in wb-render.js ([1c2a386](https://github.com/dtlab-tech/ai-toolkit/commit/1c2a386078ae54015048f32b76a3789efa82f03a))
48
+ * **FTR-014:** US-04-T06 Tests for Markdown structure, CSV structure, dependency aggregation ([03de433](https://github.com/dtlab-tech/ai-toolkit/commit/03de433b1643751d68abc5dc121715c75872775d))
49
+ * **FTR-014:** US-04-T07 Tests for character stripping, commit construction, output file paths ([ace21ba](https://github.com/dtlab-tech/ai-toolkit/commit/ace21ba2f1eff5777254a9174a3f4b2ff0383b97))
50
+ * **FTR-014:** US-04-T08 CSV regression test against pm-phase3 parser ([3a83ed5](https://github.com/dtlab-tech/ai-toolkit/commit/3a83ed5a1dd3f9bb8add57e8abc97b8f80303a62))
51
+ * **FTR-014:** US-05-T01..T06 Update pm-phase2.js with validation pipeline and gate2_payload ([711b71e](https://github.com/dtlab-tech/ai-toolkit/commit/711b71e8b3d3f78a7cac43841fc9b42625d4749b))
52
+ * **FTR-014:** US-05-T07 Update implement-feature SKILL.md Gate 2 presentation with validator results ([e617b3d](https://github.com/dtlab-tech/ai-toolkit/commit/e617b3d28036969adecff78c26df382e871e9ed2))
53
+ * **FTR-014:** US-05-T08 Tests for orchestration flow wb-validate to semantic to render ([c1341e2](https://github.com/dtlab-tech/ai-toolkit/commit/c1341e23566d6efaa33c58db368d52fdbbef9fe1))
54
+ * **FTR-014:** US-05-T09 Tests for Gate 2 blocking logic and gate2_payload assembly ([8421695](https://github.com/dtlab-tech/ai-toolkit/commit/8421695ff0aeee3f9fd0d01d21cfc863a9344c91))
55
+ * **FTR-014:** US-06-T01..T04 Ledger tracking for wb-validate, semantic, wb-render in pm-phase2 ([2f9a9f7](https://github.com/dtlab-tech/ai-toolkit/commit/2f9a9f7ff935314bb591a4d1bb8ea8eaf9ad19bc))
56
+ * **FTR-014:** US-07-T01..T02 Add .claude/scripts/ to installer distribution for wb-validate and wb-render ([bcba12a](https://github.com/dtlab-tech/ai-toolkit/commit/bcba12ad340d071b794dd6608318e34dea7e846b))
57
+ * **FTR-014:** US-07-T03..T05 Tests for installer script distribution verification ([2bb57bd](https://github.com/dtlab-tech/ai-toolkit/commit/2bb57bd4a918052ed05a421d310ae2124252a6f8))
58
+
59
+
60
+ ### Bug Fixes
61
+
62
+ * **FTR-014:** align warning/split task details field to agentMinutes ([ba7dbf8](https://github.com/dtlab-tech/ai-toolkit/commit/ba7dbf8f8dd5e34f55bc825bdefabdaaf2160eba))
63
+ * **FTR-014:** enforce groupingRationale as a required task field in check 4 ([e5cb733](https://github.com/dtlab-tech/ai-toolkit/commit/e5cb7336e91f44c653d979cfeba8f21de3da3d19))
64
+ * **FTR-014:** guard wb.phases in checks 22 and 23 against missing/non-array ([32ec505](https://github.com/dtlab-tech/ai-toolkit/commit/32ec50560c5e1fe855ac15bf9d40ec7b0ba3d8ae))
65
+ * **FTR-014:** preserve completed_at for skipped ledger entries (I6) ([389f280](https://github.com/dtlab-tech/ai-toolkit/commit/389f280d4ebdfc6a3d694e9c9e43e57042043493))
66
+ * **FTR-014:** relax symmetric-wrapping assertion in pm-phase2-source test ([8bc663e](https://github.com/dtlab-tech/ai-toolkit/commit/8bc663ec098d645cf3e6dcdd7793a08e44104784))
67
+ * **FTR-014:** use exit(2) for parseAcTable fatal errors (I5) ([1244066](https://github.com/dtlab-tech/ai-toolkit/commit/12440663cf57ddfea523535829ebbb9a66a300fd))
68
+
69
+ ## [0.9.0](https://github.com/dtlab-tech/ai-toolkit/compare/v0.8.0...v0.9.0) (2026-08-05)
70
+
71
+
72
+ ### Features
73
+
74
+ * **FTR-020:** add initial documentation for Atomic Work Breakdown, Execution Ledger, and Task Checkpoints and Resume ([c5f724a](https://github.com/dtlab-tech/ai-toolkit/commit/c5f724af068e003d36ec196cdec3502fe0c47333))
75
+
76
+
77
+ ### Bug Fixes
78
+
79
+ * **pm-phase3:** replace require/fs/execSync with agent()-based ledger helpers ([1166d6f](https://github.com/dtlab-tech/ai-toolkit/commit/1166d6f17e913405ea737e74236742569740cd0a))
80
+ * **pm-phase3:** replace require/fs/execSync with agent()-based ledger helpers ([bf4077c](https://github.com/dtlab-tech/ai-toolkit/commit/bf4077cca28920876185535aa553ec91c6ffc08b))
81
+ * **pm-phase3:** replace require/fs/execSync with agent()-based ledger helpers ([bb4c88d](https://github.com/dtlab-tech/ai-toolkit/commit/bb4c88df20c62db09de327975ab57e045247dc51))
82
+ * **workflows:** remove new Date() from all workflow call sites ([343b604](https://github.com/dtlab-tech/ai-toolkit/commit/343b604dba2d4d0b12e5590c1b5323b2a9e888f2))
83
+
2
84
  ## [0.8.0](https://github.com/dtlab-tech/ai-toolkit/compare/v0.7.0...v0.8.0) (2026-08-04)
3
85
 
4
86
 
package/bin/cli.js CHANGED
@@ -679,6 +679,7 @@ async function installGlobal(force) {
679
679
  { src: path.join(packageRoot, '.claude', 'skills'), dest: path.join(target, 'skills') },
680
680
  { src: path.join(packageRoot, '.claude', 'commands'), dest: path.join(target, 'commands') },
681
681
  { src: path.join(packageRoot, '.claude', 'workflows'), dest: path.join(target, 'workflows') },
682
+ { src: path.join(packageRoot, '.claude', 'scripts'), dest: path.join(target, 'scripts') },
682
683
  { src: path.join(packageRoot, 'docs'), dest: path.join(target, 'docs') },
683
684
  { src: path.join(packageRoot, 'CLAUDE.global.md'), dest: path.join(target, 'CLAUDE.md') },
684
685
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dtlabs/ai-toolkit",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "AI Toolkit — reusable agents and procedures for developers to build AI-powered applications.",
5
5
  "files": [
6
6
  "docs/",