@dtlabs/ai-toolkit 0.2.1 → 0.2.3
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/.claude/workflows/pm-phase1.js +40 -0
- package/.claude/workflows/pm-phase2.js +105 -6
- package/.claude/workflows/pm-phase3.js +35 -0
- package/CHANGELOG.md +15 -0
- package/package.json +1 -1
|
@@ -139,6 +139,46 @@ for (let cycle = 1; cycle <= MAX_CYCLES; cycle++) {
|
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
+
// ── Write process-log (phase 1 snapshot) ─────────────────────────────────────
|
|
143
|
+
const reqEntry = tokenLedger.find(e => e.agent === 'generate-requirements')
|
|
144
|
+
const specEntry = tokenLedger.find(e => e.agent === 'generate-tech-spec')
|
|
145
|
+
const valEntries = tokenLedger.filter(e => e.agent.startsWith('validate-feature-docs'))
|
|
146
|
+
const phase1Events = [
|
|
147
|
+
`pm-phase1 START — documentation phase`,
|
|
148
|
+
reqEntry
|
|
149
|
+
? `Agent DONE: generate-requirements — tokens: ${reqEntry.phase_delta_tokens}`
|
|
150
|
+
: `generate-requirements: skipped (fresh)`,
|
|
151
|
+
specEntry
|
|
152
|
+
? `Agent DONE: generate-tech-spec — tokens: ${specEntry.phase_delta_tokens}`
|
|
153
|
+
: `generate-tech-spec: skipped (fresh)`,
|
|
154
|
+
...valEntries.map(e => `Agent DONE: ${e.agent} — tokens: ${e.phase_delta_tokens}`),
|
|
155
|
+
`Validation result: ${validationSummary}`,
|
|
156
|
+
`APPROVAL REQUESTED — Gate 1`,
|
|
157
|
+
].join('\n')
|
|
158
|
+
|
|
159
|
+
await agent(
|
|
160
|
+
`Create the process-log file for this feature delivery run.
|
|
161
|
+
|
|
162
|
+
File path: ${feature_dir}/${prefix}-process-log.txt
|
|
163
|
+
|
|
164
|
+
Steps:
|
|
165
|
+
1. Get current UTC datetime via Bash: run \`date -u +"%Y-%m-%dT%H:%M:%S"\`
|
|
166
|
+
2. Read feature.md at: ${featurePath} — extract the feature title (first H1 heading after the frontmatter).
|
|
167
|
+
3. Write the file using the Write tool. Use the datetime from step 1 for ALL timestamps.
|
|
168
|
+
Format each event line as: [{datetime}] {event text}
|
|
169
|
+
|
|
170
|
+
File structure:
|
|
171
|
+
════════════════════════════════════════════════════════
|
|
172
|
+
RUN STARTED — {datetime}
|
|
173
|
+
Feature: ${prefix} — {title from step 2}
|
|
174
|
+
════════════════════════════════════════════════════════
|
|
175
|
+
{one line per event below, each prefixed with [{datetime}]}
|
|
176
|
+
|
|
177
|
+
Events to log:
|
|
178
|
+
${phase1Events}`,
|
|
179
|
+
{ label: 'write-process-log', phase: 'Validation' }
|
|
180
|
+
)
|
|
181
|
+
|
|
142
182
|
// ── Build gate1_payload ───────────────────────────────────────────────────────
|
|
143
183
|
const gate1Payload = {
|
|
144
184
|
prefix,
|
|
@@ -26,7 +26,7 @@ const wbTokens = budget.spent() - beforeWB
|
|
|
26
26
|
tokenLedger.push({ agent: 'generate-work-breakdown', model: 'haiku', phase_delta_tokens: wbTokens })
|
|
27
27
|
log(`generate-work-breakdown done — phase delta: ${wbTokens} tokens`)
|
|
28
28
|
|
|
29
|
-
// ── Parse WB + write Effort-Estimate
|
|
29
|
+
// ── Parse WB + write Effort-Estimate + Token-Estimate ────────────────────────
|
|
30
30
|
phase('Effort Estimate')
|
|
31
31
|
|
|
32
32
|
const PARSE_SCHEMA = {
|
|
@@ -42,12 +42,15 @@ const PARSE_SCHEMA = {
|
|
|
42
42
|
agent_estimate: { type: 'string' },
|
|
43
43
|
work_breakdown_path: { type: 'string' },
|
|
44
44
|
effort_estimate_path: { type: 'string' },
|
|
45
|
+
token_estimate_path: { type: 'string' },
|
|
45
46
|
},
|
|
46
47
|
required: ['prefix', 'user_stories', 'total_tasks', 'work_breakdown_path'],
|
|
47
48
|
}
|
|
48
49
|
|
|
50
|
+
const phase1Tokens = wbTokens // tokens consumed by this phase so far
|
|
51
|
+
|
|
49
52
|
const metrics = await agent(
|
|
50
|
-
`You have
|
|
53
|
+
`You have four tasks:
|
|
51
54
|
|
|
52
55
|
TASK 1 — Read the Work Breakdown file.
|
|
53
56
|
The feature.md is at: ${featurePath}
|
|
@@ -58,6 +61,7 @@ Use Glob or Read to find and read that file.
|
|
|
58
61
|
Extract from the Summary table:
|
|
59
62
|
- prefix (e.g. "FTR-009")
|
|
60
63
|
- feature_dir (directory containing feature.md)
|
|
64
|
+
- feature_title (full feature title from the Work Breakdown header)
|
|
61
65
|
- user_stories (integer)
|
|
62
66
|
- total_tasks (integer)
|
|
63
67
|
- domain_breakdown (e.g. "DB:0, BE:11, FE:0, INFRA:4, TEST:0")
|
|
@@ -66,10 +70,19 @@ Extract from the Summary table:
|
|
|
66
70
|
- agent_estimate (e.g. "~2h 6min")
|
|
67
71
|
- work_breakdown_path (full path to the Work Breakdown file)
|
|
68
72
|
|
|
73
|
+
Also read Section 4 of the Work Breakdown to extract per-User-Story details:
|
|
74
|
+
- US ID (e.g. US-01)
|
|
75
|
+
- US title
|
|
76
|
+
- task count
|
|
77
|
+
- domains involved
|
|
78
|
+
- estimated hours (from the Work Breakdown if present, otherwise estimate based on task count: ~2h per BE task, ~1h per TEST task, ~30min per INFRA task)
|
|
79
|
+
|
|
69
80
|
TASK 2 — Write the Effort-Estimate.md file.
|
|
70
|
-
Write {feature_dir}/{PREFIX}-Effort-Estimate.md with
|
|
81
|
+
Write {feature_dir}/{PREFIX}-Effort-Estimate.md with this format:
|
|
82
|
+
|
|
83
|
+
# Effort Estimate — {PREFIX} — {feature_title}
|
|
71
84
|
|
|
72
|
-
|
|
85
|
+
## Summary
|
|
73
86
|
|
|
74
87
|
| Metric | Value |
|
|
75
88
|
|--------|-------|
|
|
@@ -79,11 +92,68 @@ Write {feature_dir}/{PREFIX}-Effort-Estimate.md with the extracted metrics in th
|
|
|
79
92
|
| Human estimate | {human_estimate} (sequential, no parallelism) |
|
|
80
93
|
| Agent estimate | {agent_estimate} (parallel dispatch, critical path only) |
|
|
81
94
|
|
|
82
|
-
|
|
95
|
+
## Per-User-Story Breakdown
|
|
96
|
+
|
|
97
|
+
| US | Title | Tasks | Domains | Est. hours |
|
|
98
|
+
|----|-------|-------|---------|------------|
|
|
99
|
+
{one row per US extracted from Section 4}
|
|
100
|
+
|
|
101
|
+
## Notes
|
|
102
|
+
- Human estimate assumes sequential execution with no parallelism.
|
|
103
|
+
- Agent estimate assumes parallel dispatch of independent tasks within each phase.
|
|
104
|
+
- Actual effort will be recorded in the Actuals section after implementation.
|
|
105
|
+
|
|
106
|
+
TASK 3 — Write the Token-Estimate.md file.
|
|
107
|
+
Write {feature_dir}/{PREFIX}-Token-Estimate.md with this format:
|
|
108
|
+
|
|
109
|
+
# Token Estimate — {PREFIX} — {feature_title}
|
|
110
|
+
|
|
111
|
+
## Phase 1 — Documentation (Actuals)
|
|
112
|
+
|
|
113
|
+
| Agent | Task | Model | Tokens (actual) |
|
|
114
|
+
|-------|------|-------|----------------|
|
|
115
|
+
| generate-requirements | Generate requirements from feature.md | haiku | ${phase1Tokens} (phase delta) |
|
|
116
|
+
| generate-tech-spec | Generate tech spec from feature.md | haiku | (see phase delta) |
|
|
117
|
+
| validate-feature-docs | Validate requirements + tech spec | haiku | (see phase delta) |
|
|
118
|
+
|
|
119
|
+
## Phase 2 — Work Breakdown (Actuals)
|
|
120
|
+
|
|
121
|
+
| Agent | Task | Model | Tokens (actual) |
|
|
122
|
+
|-------|------|-------|----------------|
|
|
123
|
+
| generate-work-breakdown | Generate work breakdown from docs | haiku | ${phase1Tokens} (phase delta) |
|
|
124
|
+
|
|
125
|
+
## Phase 3 — Implementation (Estimates)
|
|
126
|
+
|
|
127
|
+
Estimates based on {total_tasks} tasks ({domain_breakdown}), {user_stories} User Stories.
|
|
128
|
+
Token estimates use ~15,000 tokens per BE task, ~8,000 per TEST task, ~5,000 per INFRA task as baseline.
|
|
129
|
+
|
|
130
|
+
| Agent | Task | Model | Tokens (estimated) |
|
|
131
|
+
|-------|------|-------|-------------------|
|
|
132
|
+
| implementation-orchestrator | Full implementation loop | sonnet | {estimated: total_tasks * 12000} |
|
|
133
|
+
| review-solution (×{user_stories}) | Architect review per US | sonnet | {estimated: user_stories * 8000} |
|
|
134
|
+
| remediation | Fix WARNING issues | sonnet | ~10,000 |
|
|
135
|
+
| pr-and-registry | Push branch, create PR | sonnet | ~5,000 |
|
|
136
|
+
| write-actuals | Update Token/Effort Estimate | sonnet | ~3,000 |
|
|
137
|
+
|
|
138
|
+
## Grand Total (Estimate)
|
|
139
|
+
|
|
140
|
+
| Phase | Tokens (estimated) | Notes |
|
|
141
|
+
|-------|-------------------|-------|
|
|
142
|
+
| Phase 1 — Documentation | ${phase1Tokens} | Actual (phase delta) |
|
|
143
|
+
| Phase 2 — Work Breakdown | {wbTokens from above} | Actual (phase delta) |
|
|
144
|
+
| Phase 3 — Implementation | {sum of phase 3 estimates} | Estimated |
|
|
145
|
+
| **Total** | **{grand total}** | |
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
*Actuals will be appended by pm-phase3 after implementation completes.*
|
|
149
|
+
|
|
150
|
+
TASK 4 — Set return values.
|
|
151
|
+
Set effort_estimate_path to the full path of the written Effort-Estimate.md.
|
|
152
|
+
Set token_estimate_path to the full path of the written Token-Estimate.md.
|
|
83
153
|
|
|
84
154
|
Return the extracted metrics as structured output.`,
|
|
85
155
|
{
|
|
86
|
-
label: 'parse-wb-write-
|
|
156
|
+
label: 'parse-wb-write-estimates',
|
|
87
157
|
phase: 'Effort Estimate',
|
|
88
158
|
schema: PARSE_SCHEMA,
|
|
89
159
|
}
|
|
@@ -91,6 +161,34 @@ Return the extracted metrics as structured output.`,
|
|
|
91
161
|
|
|
92
162
|
log(`WB parsed: ${metrics.user_stories} US, ${metrics.total_tasks} tasks, ${metrics.implementation_phases} phases`)
|
|
93
163
|
log(`Effort-Estimate written: ${metrics.effort_estimate_path}`)
|
|
164
|
+
log(`Token-Estimate written: ${metrics.token_estimate_path}`)
|
|
165
|
+
|
|
166
|
+
// ── Append to process-log (phase 2 events) ───────────────────────────────────
|
|
167
|
+
const wbEntry = tokenLedger.find(e => e.agent === 'generate-work-breakdown')
|
|
168
|
+
const phase2Events = [
|
|
169
|
+
`APPROVAL GRANTED by user — Gate 1`,
|
|
170
|
+
`pm-phase2 START — work breakdown phase`,
|
|
171
|
+
`Agent DONE: generate-work-breakdown — tokens: ${wbEntry ? wbEntry.phase_delta_tokens : 'N/A'}`,
|
|
172
|
+
`Written: ${metrics.prefix}-Work-Breakdown.md (${metrics.user_stories} US, ${metrics.total_tasks} tasks, ${metrics.implementation_phases} phases)`,
|
|
173
|
+
`Written: ${metrics.prefix}-Effort-Estimate.md`,
|
|
174
|
+
`pm-phase2 COMPLETE`,
|
|
175
|
+
`APPROVAL REQUESTED — Gate 2`,
|
|
176
|
+
].join('\n')
|
|
177
|
+
|
|
178
|
+
await agent(
|
|
179
|
+
`Append phase 2 events to the process-log for this feature delivery run.
|
|
180
|
+
|
|
181
|
+
Process-log path: ${metrics.feature_dir}/${metrics.prefix}-process-log.txt
|
|
182
|
+
|
|
183
|
+
Steps:
|
|
184
|
+
1. Get current UTC datetime via Bash: run \`date -u +"%Y-%m-%dT%H:%M:%S"\`
|
|
185
|
+
2. Append the following lines to the existing file. Use the datetime from step 1 for ALL event lines.
|
|
186
|
+
Format each event line as: [{datetime}] {event text}
|
|
187
|
+
|
|
188
|
+
Events to append:
|
|
189
|
+
${phase2Events}`,
|
|
190
|
+
{ label: 'append-process-log', phase: 'Effort Estimate' }
|
|
191
|
+
)
|
|
94
192
|
|
|
95
193
|
return {
|
|
96
194
|
prefix: metrics.prefix,
|
|
@@ -103,6 +201,7 @@ return {
|
|
|
103
201
|
agent_estimate: metrics.agent_estimate || 'N/A',
|
|
104
202
|
work_breakdown_path: metrics.work_breakdown_path,
|
|
105
203
|
effort_estimate_path: metrics.effort_estimate_path || '',
|
|
204
|
+
token_estimate_path: metrics.token_estimate_path || '',
|
|
106
205
|
token_ledger: tokenLedger,
|
|
107
206
|
errors: [],
|
|
108
207
|
}
|
|
@@ -297,6 +297,41 @@ const actualsTokens = budget.spent() - beforeActuals
|
|
|
297
297
|
tokenLedger.push({ agent: 'write-actuals', model: 'sonnet', phase_delta_tokens: actualsTokens })
|
|
298
298
|
log(`Actuals written | phase delta: ${actualsTokens} tokens`)
|
|
299
299
|
|
|
300
|
+
// ── Append to process-log (phase 3 events + RUN COMPLETE) ────────────────────
|
|
301
|
+
const usPassed = (implResult.us_passed || []).join(', ') || 'none'
|
|
302
|
+
const usEscalated = (implResult.us_escalated || []).join(', ') || 'none'
|
|
303
|
+
const phase3Events = [
|
|
304
|
+
`APPROVAL GRANTED by user — Gate 2`,
|
|
305
|
+
`pm-phase3 START — implementation phase — branch: ${branch || '(current)'}`,
|
|
306
|
+
`Implementation DONE — ${implResult.phases_done} phases | US passed: ${usPassed} | US escalated: ${usEscalated}`,
|
|
307
|
+
issuesFixed + issuesDeferred > 0
|
|
308
|
+
? `Remediation: ${issuesFixed} fixed, ${issuesDeferred} deferred`
|
|
309
|
+
: `Remediation: skipped (no open issues)`,
|
|
310
|
+
`PR created: ${prResult.pr_url}`,
|
|
311
|
+
`Actuals written: Token-Estimate.md + Effort-Estimate.md`,
|
|
312
|
+
`RUN COMPLETE`,
|
|
313
|
+
`════════════════════════════════════════════════════════`,
|
|
314
|
+
].join('\n')
|
|
315
|
+
|
|
316
|
+
// feature_dir is not directly available in pm-phase3; derive from featurePath
|
|
317
|
+
const featureDir3 = featurePath.replace(/\/[^/]+$/, '')
|
|
318
|
+
|
|
319
|
+
await agent(
|
|
320
|
+
`Append phase 3 events to the process-log for this feature delivery run.
|
|
321
|
+
|
|
322
|
+
Process-log path: ${featureDir3}/${prefix}-process-log.txt
|
|
323
|
+
|
|
324
|
+
Steps:
|
|
325
|
+
1. Get current UTC datetime via Bash: run \`date -u +"%Y-%m-%dT%H:%M:%S"\`
|
|
326
|
+
2. Append the following lines to the existing file. Use the datetime from step 1 for ALL event lines.
|
|
327
|
+
Format each event line as: [{datetime}] {event text}
|
|
328
|
+
The final line (════…) is a separator — append it as-is, without a timestamp prefix.
|
|
329
|
+
|
|
330
|
+
Events to append:
|
|
331
|
+
${phase3Events}`,
|
|
332
|
+
{ label: 'finalize-process-log', phase: 'Actuals' }
|
|
333
|
+
)
|
|
334
|
+
|
|
300
335
|
return {
|
|
301
336
|
pr_url: prResult.pr_url,
|
|
302
337
|
token_ledger: tokenLedger,
|
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
## 0.1.4 (2026-07-21)
|
|
2
|
+
## [0.2.3](https://github.com/dtlab-tech/ai-toolkit/compare/v0.2.2...v0.2.3) (2026-07-28)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
* **pm-phase2:** generate full Effort-Estimate and Token-Estimate in phase 2 ([f3afbae](https://github.com/dtlab-tech/ai-toolkit/commit/f3afbae8b445632e8d8dd0ba8930d89042e9f3f4))
|
|
8
|
+
|
|
9
|
+
## [0.2.2](https://github.com/dtlab-tech/ai-toolkit/compare/v0.2.1...v0.2.2) (2026-07-28)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* restore process-log trace across pm-phase1/2/3 workflow scripts ([6748cf9](https://github.com/dtlab-tech/ai-toolkit/commit/6748cf9aab94efc76aa41c6c97cfe9493bc8db92))
|
|
15
|
+
* restore process-log trace across pm-phase1/2/3 workflow scripts ([844965a](https://github.com/dtlab-tech/ai-toolkit/commit/844965abe5f0486cc5915819e5879b0486a3e993))
|
|
16
|
+
|
|
2
17
|
## [0.2.1](https://github.com/dtlab-tech/ai-toolkit/compare/v0.2.0...v0.2.1) (2026-07-27)
|
|
3
18
|
|
|
4
19
|
|