@dtlabs/ai-toolkit 0.17.4 → 0.18.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 (35) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/lib/agent-registry.js +39 -0
  3. package/lib/workflow-control.js +65 -13
  4. package/package.json +1 -1
  5. package/src/claude/agents/gaia-generate-requirements-use-case.md +97 -0
  6. package/src/claude/agents/gaia-generate-requirements.md +22 -27
  7. package/src/claude/agents/gaia-generate-tech-spec-component.md +93 -0
  8. package/src/claude/agents/gaia-generate-tech-spec.md +47 -103
  9. package/src/claude/agents/gaia-generate-work-breakdown-task.md +151 -0
  10. package/src/claude/agents/gaia-generate-work-breakdown.md +94 -100
  11. package/src/claude/agents/gaia-validate-feature-docs.md +13 -8
  12. package/src/claude/commands/assemble-docs.md +16 -0
  13. package/src/claude/commands/feature-status.md +9 -4
  14. package/src/claude/scripts/ac-task-matrix.js +87 -0
  15. package/src/claude/scripts/assemble-docs.js +66 -0
  16. package/src/claude/scripts/req-assembler.js +127 -0
  17. package/src/claude/scripts/req-graph-checks.js +71 -0
  18. package/src/claude/scripts/req-skeleton-check.js +64 -0
  19. package/src/claude/scripts/tech-spec-assembler.js +188 -0
  20. package/src/claude/scripts/tech-spec-graph-checks.js +84 -0
  21. package/src/claude/scripts/templates/gaia-component-template.md +64 -0
  22. package/src/claude/scripts/templates/gaia-dependency-graph-template.md +85 -0
  23. package/src/claude/scripts/templates/gaia-requirements-index-template.md +144 -0
  24. package/src/claude/scripts/templates/gaia-task-template.md +92 -0
  25. package/src/claude/scripts/templates/gaia-tech-spec-index-template.md +137 -0
  26. package/src/claude/scripts/templates/gaia-use-case-template.md +56 -0
  27. package/src/claude/scripts/templates/gaia-user-story-template.md +61 -0
  28. package/src/claude/scripts/wb-graph-checks.js +754 -0
  29. package/src/claude/scripts/wb-render.js +6 -11
  30. package/src/claude/scripts/wb-skeleton-check.js +99 -0
  31. package/src/claude/scripts/wb-validate.js +49 -655
  32. package/src/claude/scripts/wbs-assembler.js +368 -0
  33. package/src/claude/skills/implement-feature/SKILL.md +12 -6
  34. package/src/claude/workflows/pm-phase1.js +342 -16
  35. package/src/claude/workflows/pm-phase2.js +277 -14
@@ -2,6 +2,7 @@
2
2
 
3
3
  const fs = require('fs')
4
4
  const path = require('path')
5
+ const { loadWorkBreakdown } = require('./wbs-assembler')
5
6
 
6
7
  // ── Argument parsing ──────────────────────────────────────────────────────────
7
8
 
@@ -17,21 +18,15 @@ const destDir = process.argv[4]
17
18
  ? process.argv[4]
18
19
  : path.dirname(path.resolve(jsonPath))
19
20
 
20
- // ── Read and parse JSON ───────────────────────────────────────────────────────
21
-
22
- let raw
23
- try {
24
- raw = fs.readFileSync(jsonPath, 'utf8')
25
- } catch (err) {
26
- process.stderr.write(`Error: cannot read file "${jsonPath}": ${err.message}\n`)
27
- process.exit(1)
28
- }
21
+ // ── Read and assemble ──────────────────────────────────────────────────────────
22
+ // Accepts either a single legacy JSON file (schema v2) or a {PREFIX}-wbs/ split
23
+ // directory (schema v3), returning the same in-memory shape either way (FTR-020).
29
24
 
30
25
  let wb
31
26
  try {
32
- wb = JSON.parse(raw)
27
+ wb = loadWorkBreakdown(jsonPath)
33
28
  } catch (err) {
34
- process.stderr.write(`Error: "${jsonPath}" is not valid JSON: ${err.message}\n`)
29
+ process.stderr.write(`Error: ${err.message}\n`)
35
30
  process.exit(1)
36
31
  }
37
32
 
@@ -0,0 +1,99 @@
1
+ 'use strict'
2
+
3
+ const fs = require('fs')
4
+ const path = require('path')
5
+ const graphChecks = require('./wb-graph-checks')
6
+
7
+ // Deterministic structural pre-check for a Work Breakdown SKELETON (schema v3 index.json),
8
+ // run by pm-phase2.js before any per-task generation call is dispatched (FTR-020 UC-02).
9
+ //
10
+ // This is a SEPARATE script from wb-validate.js, not a reuse of it, because wb-validate.js
11
+ // also runs checks 4/15-18/22/23 (inline, not extracted to wb-graph-checks.js), which need
12
+ // full per-task detail (verification.commands, groupingRationale) the skeleton does not
13
+ // carry yet — running wb-validate.js against a skeleton would falsely report every task as
14
+ // missing those fields. This script runs only the 11 skeleton-answerable checks (reusing the
15
+ // exact same wb-graph-checks.js functions wb-validate.js itself now imports) plus empty-phase
16
+ // detection (check 23's logic, trivial enough from taskIds alone not to warrant importing it).
17
+ //
18
+ // pm-phase2.js cannot call wb-graph-checks.js's functions in-process — its workflow-script
19
+ // runtime has no `require` (see lib/workflow-runner.js) — so this is invoked as a real Node
20
+ // subprocess via `c.command(['run-asset', 'scripts/wb-skeleton-check.js', ...])`, the same
21
+ // pattern already used for wb-validate.js/wb-render.js.
22
+
23
+ const indexPath = process.argv[2]
24
+ const requirementsPath = process.argv[3]
25
+
26
+ if (!indexPath) {
27
+ process.stderr.write('Error: missing required argument <path-to-index.json>\n')
28
+ process.exit(2)
29
+ }
30
+
31
+ let index
32
+ try {
33
+ index = JSON.parse(fs.readFileSync(path.resolve(indexPath), 'utf8'))
34
+ } catch (err) {
35
+ process.stderr.write(`Error: cannot read or parse "${indexPath}": ${err.message}\n`)
36
+ process.exit(2)
37
+ }
38
+
39
+ if (index.schemaVersion !== 3) {
40
+ process.stderr.write(`Error: index.json must have schemaVersion 3, got ${JSON.stringify(index.schemaVersion)}\n`)
41
+ process.exit(2)
42
+ }
43
+
44
+ // Project the skeleton's map-of-tasks shape into the array-of-tasks-per-phase shape every
45
+ // wb-graph-checks.js function expects (the same shape wb-validate.js/wb-render.js use after
46
+ // assembly) — the skeleton's own `index.tasks` map has no `id` field per entry (it's the map
47
+ // key), so it is added back here.
48
+ const phases = (index.phases || []).map(phaseSkeleton => ({
49
+ id: phaseSkeleton.id,
50
+ type: phaseSkeleton.type,
51
+ // sourceUC must survive this projection — checkAcCoverage's check 20 (AC scope validation)
52
+ // scopes an AC against the citing phase's own sourceUC, not its ID (see wbs-assembler.js's
53
+ // identical fix, commit fab14cb); omitting it here made the skeleton check reject any
54
+ // genuinely multi-UC phase that wb-validate.js (post-assembly) would already accept.
55
+ sourceUC: phaseSkeleton.sourceUC,
56
+ tasks: (phaseSkeleton.taskIds || []).map(taskId => ({ id: taskId, ...(index.tasks || {})[taskId] })),
57
+ }))
58
+
59
+ const errors = []
60
+
61
+ const check3 = graphChecks.checkUniqueTaskIds({ phases })
62
+ errors.push(...check3.errors)
63
+ const seenTaskIds = check3.seenTaskIds
64
+
65
+ errors.push(...graphChecks.checkTaskIdFormat({ phases }).errors)
66
+ errors.push(...graphChecks.checkDomainWhitelist({ phases }).errors)
67
+ errors.push(...graphChecks.checkAgentTypeWhitelist({ phases }).errors)
68
+
69
+ const allTaskIds = new Set(seenTaskIds.keys())
70
+ errors.push(...graphChecks.checkDependencyExistence({ phases }, allTaskIds).errors)
71
+ errors.push(...graphChecks.checkSelfDependency({ phases }).errors)
72
+ errors.push(...graphChecks.checkPhaseIdConsistency({ phases }).errors)
73
+ errors.push(...graphChecks.checkTaskCycle({ phases }, allTaskIds).errors)
74
+
75
+ const check1213 = graphChecks.checkPhaseDependencyAndCycle({ phases }, seenTaskIds)
76
+ errors.push(...check1213.errors)
77
+ errors.push(...graphChecks.checkPhaseSchedulability({ phases }, check1213.phaseDepsMap).errors)
78
+
79
+ const acMap = graphChecks.parseAcTable(requirementsPath)
80
+ errors.push(...graphChecks.checkAcCoverage({ phases }, acMap, seenTaskIds).errors)
81
+
82
+ // Empty-phase detection (check 23's logic — simple enough from taskIds alone not to import)
83
+ for (const phase of phases) {
84
+ if (phase.tasks.length === 0) {
85
+ errors.push({
86
+ category: graphChecks.ERRORS.EMPTY_PHASE,
87
+ severity: 'error',
88
+ taskId: null,
89
+ phaseId: phase.id,
90
+ field: 'taskIds',
91
+ message: `Phase "${phase.id}" has no tasks; each phase must contain at least one task`,
92
+ details: { phaseId: phase.id },
93
+ })
94
+ }
95
+ }
96
+
97
+ const report = { valid: errors.length === 0, errors }
98
+ process.stdout.write(JSON.stringify(report, null, 2) + '\n')
99
+ process.exit(report.valid ? 0 : 1)