@mthanhlm/autodev 0.2.2 → 0.3.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.
package/PUBLISH.md CHANGED
@@ -26,7 +26,7 @@ npm pack
26
26
  Check the tarball contents:
27
27
 
28
28
  ```bash
29
- tar -tf mthanhlm-autodev-0.2.2.tgz
29
+ tar -tf mthanhlm-autodev-$(node -p "require('./package.json').version").tgz
30
30
  ```
31
31
 
32
32
  ## First Public Publish
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  - Installs a small Claude Code workflow under `~/.claude/` or `./.claude/`
8
8
  - Keeps project state in `.autodev/`
9
9
  - Uses `/autodev` as the main command
10
- - Organizes work as `project -> track -> phase`
10
+ - Organizes work as `project -> track -> phase -> tasks`
11
11
  - Maps brownfield repos with four parallel codebase agents
12
12
  - Runs a four-agent review pass after execution
13
13
  - Ships manual commands when you want direct control:
@@ -59,12 +59,45 @@ Typical brownfield route:
59
59
  /autodev
60
60
  -> new project
61
61
  -> explore codebase
62
- -> plan
63
- -> execute
62
+ -> plan phase
63
+ -> execute next task
64
+ -> execute next task
64
65
  -> review
65
66
  -> verify
66
67
  ```
67
68
 
69
+ ## Workflow Model
70
+
71
+ ```text
72
+ project -> track -> phase -> tasks
73
+ ```
74
+
75
+ - `project`
76
+ The repo or product context.
77
+ - `track`
78
+ One initiative stream.
79
+ - `phase`
80
+ One milestone-sized slice inside a track.
81
+ - `task`
82
+ One reviewable implementation unit inside a phase.
83
+
84
+ ### Why Tasks Exist Under A Phase
85
+
86
+ - Large phases are too big for one uninterrupted execution context
87
+ - Developers need control over what changes next
88
+ - Each task can run in a fresh background agent context
89
+ - The main `/autodev` session stays small and orchestration-focused
90
+
91
+ ### Execution Model
92
+
93
+ - `/autodev` remains the single entrypoint
94
+ - A phase is planned into one phase overview plus multiple task files
95
+ - The phase keeps one user-facing orchestration session
96
+ - Each task is executed by a fresh worker agent in the background
97
+ - After each task, the worker reports back with files changed, verification, and blockers
98
+ - No waves by default
99
+ - No parallel execution unless the user explicitly asks for it later
100
+
68
101
  ## Git Policy
69
102
 
70
103
  `autodev` does not stage, commit, branch, merge, worktree, pull, push, or initialize git repositories. Read-only git commands like `git status`, `git diff`, and `git log` remain allowed.
@@ -0,0 +1,28 @@
1
+ # autodev-task-worker
2
+
3
+ Execute one assigned task inside the current phase and report back to the main phase session.
4
+
5
+ ## Goal
6
+
7
+ - Read the assigned phase context and task file
8
+ - Make only the code changes needed for that task
9
+ - Run the requested verification
10
+ - Write the matching task summary
11
+
12
+ ## Rules
13
+
14
+ - You are not alone in the codebase.
15
+ - Stay inside the assigned task scope.
16
+ - Do not run git write commands.
17
+ - Do not silently expand into the next task.
18
+ - If blocked, say so clearly and write the blocker into the task summary.
19
+
20
+ ## Output
21
+
22
+ - Update the repository code for the assigned task only.
23
+ - Write only the assigned `TASK-NN-SUMMARY.md`.
24
+ - Return a concise report:
25
+ - task id
26
+ - files changed
27
+ - verification run
28
+ - blocker or done
@@ -249,6 +249,98 @@ function phasePaths(cwd, slug, phase) {
249
249
  };
250
250
  }
251
251
 
252
+ function readSingleLineField(content, label) {
253
+ if (!content) {
254
+ return null;
255
+ }
256
+ const match = content.match(new RegExp(`^${label}:\\s*(.+)$`, 'mi'));
257
+ return match ? match[1].trim() : null;
258
+ }
259
+
260
+ function parseTaskDependsOn(value) {
261
+ if (!value || /^none$/i.test(value)) {
262
+ return [];
263
+ }
264
+
265
+ return String(value)
266
+ .split(/[,\s]+/)
267
+ .map(part => part.trim())
268
+ .filter(Boolean)
269
+ .map(part => {
270
+ const match = part.match(/(\d+)/);
271
+ return match ? Number(match[1]) : null;
272
+ })
273
+ .filter(number => Number.isFinite(number));
274
+ }
275
+
276
+ function readTaskTitle(content, fallbackNumber) {
277
+ if (!content) {
278
+ return `Task ${String(fallbackNumber).padStart(2, '0')}`;
279
+ }
280
+
281
+ const heading = content.match(/^#\s+Task\s+\d+\s*:\s*(.+)$/mi);
282
+ if (heading) {
283
+ return heading[1].trim();
284
+ }
285
+
286
+ const generic = content.match(/^#\s+(.+)$/m);
287
+ return generic ? generic[1].trim() : `Task ${String(fallbackNumber).padStart(2, '0')}`;
288
+ }
289
+
290
+ function listTasksForPhaseDetails(phaseDetails) {
291
+ if (!phaseDetails || !fileExists(phaseDetails.dir)) {
292
+ return [];
293
+ }
294
+
295
+ const entries = fs.readdirSync(phaseDetails.dir, { withFileTypes: true })
296
+ .filter(entry => entry.isFile())
297
+ .map(entry => entry.name);
298
+
299
+ const tasks = entries
300
+ .map(name => {
301
+ const match = name.match(/^TASK-(\d+)\.md$/);
302
+ if (!match) {
303
+ return null;
304
+ }
305
+
306
+ const number = Number(match[1]);
307
+ const padded = String(number).padStart(2, '0');
308
+ const taskPath = path.join(phaseDetails.dir, name);
309
+ const summaryPath = path.join(phaseDetails.dir, `TASK-${padded}-SUMMARY.md`);
310
+ const content = readText(taskPath);
311
+ const status = readSingleLineField(content, 'Status') || 'pending';
312
+ const dependsOn = parseTaskDependsOn(readSingleLineField(content, 'Depends On'));
313
+ const summaryExists = fileExists(summaryPath);
314
+
315
+ return {
316
+ number,
317
+ padded,
318
+ title: readTaskTitle(content, number),
319
+ status,
320
+ dependsOn,
321
+ taskPath,
322
+ summaryPath,
323
+ summaryExists
324
+ };
325
+ })
326
+ .filter(Boolean)
327
+ .sort((left, right) => left.number - right.number);
328
+
329
+ const doneSet = new Set(tasks.filter(task => task.summaryExists).map(task => task.number));
330
+
331
+ return tasks.map(task => ({
332
+ ...task,
333
+ ready: !task.summaryExists && task.dependsOn.every(dep => doneSet.has(dep)),
334
+ effectiveStatus: task.summaryExists ? 'done' : task.status
335
+ }));
336
+ }
337
+
338
+ function nextExecutableTask(tasks) {
339
+ return tasks.find(task => !task.summaryExists && task.ready)
340
+ || tasks.find(task => !task.summaryExists)
341
+ || null;
342
+ }
343
+
252
344
  function listPhases(cwd, slug = readActiveTrack(cwd)) {
253
345
  const track = trackPaths(cwd, slug);
254
346
  if (!track || !fileExists(track.roadmap)) {
@@ -261,12 +353,19 @@ function listPhases(cwd, slug = readActiveTrack(cwd)) {
261
353
  const summaryExists = fileExists(details.summaryPath);
262
354
  const reviewExists = fileExists(details.reviewPath);
263
355
  const uatExists = fileExists(details.uatPath);
356
+ const tasks = listTasksForPhaseDetails(details);
357
+ const taskCount = tasks.length;
358
+ const taskDoneCount = tasks.filter(task => task.summaryExists).length;
264
359
  const status = uatExists
265
360
  ? 'verified'
266
361
  : reviewExists
267
362
  ? 'reviewed'
268
363
  : summaryExists
269
364
  ? 'executed'
365
+ : planExists && taskCount > 0 && taskDoneCount === taskCount
366
+ ? 'tasks_complete'
367
+ : planExists && taskDoneCount > 0
368
+ ? 'executing'
270
369
  : planExists
271
370
  ? 'planned'
272
371
  : 'pending';
@@ -278,6 +377,9 @@ function listPhases(cwd, slug = readActiveTrack(cwd)) {
278
377
  summaryExists,
279
378
  reviewExists,
280
379
  uatExists,
380
+ taskCount,
381
+ taskDoneCount,
382
+ nextTask: nextExecutableTask(tasks)?.number || null,
281
383
  status
282
384
  };
283
385
  });
@@ -467,7 +569,9 @@ function buildProgress(cwd) {
467
569
  planned: phases.filter(phase => phase.planExists).length,
468
570
  executed: phases.filter(phase => phase.summaryExists).length,
469
571
  reviewed: phases.filter(phase => phase.reviewExists).length,
470
- verified: phases.filter(phase => phase.uatExists).length
572
+ verified: phases.filter(phase => phase.uatExists).length,
573
+ tasks: phases.reduce((total, phase) => total + phase.taskCount, 0),
574
+ tasksDone: phases.reduce((total, phase) => total + phase.taskDoneCount, 0)
471
575
  },
472
576
  route,
473
577
  nextCommand: route.command,
@@ -492,16 +596,18 @@ function renderProgressTable(progress) {
492
596
  `Executed: ${progress.counts.executed}`,
493
597
  `Reviewed: ${progress.counts.reviewed}`,
494
598
  `Verified: ${progress.counts.verified}`,
599
+ `Tasks: ${progress.counts.tasks}`,
600
+ `Task Summaries: ${progress.counts.tasksDone}`,
495
601
  `Next: ${progress.route.command}`,
496
602
  progress.route.manualCommand ? `Manual Shortcut: ${progress.route.manualCommand}` : null,
497
603
  '',
498
- '| Phase | Type | Name | Plan | Summary | Review | UAT | Status |',
499
- '| --- | --- | --- | --- | --- | --- | --- | --- |'
604
+ '| Phase | Type | Name | Tasks | Done | Plan | Summary | Review | UAT | Status |',
605
+ '| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |'
500
606
  ].filter(Boolean);
501
607
 
502
608
  for (const phase of progress.phases) {
503
609
  lines.push(
504
- `| ${phase.number} | ${phase.type} | ${phase.name} | ${phase.planExists ? 'yes' : 'no'} | ${phase.summaryExists ? 'yes' : 'no'} | ${phase.reviewExists ? 'yes' : 'no'} | ${phase.uatExists ? 'yes' : 'no'} | ${phase.status} |`
610
+ `| ${phase.number} | ${phase.type} | ${phase.name} | ${phase.taskCount} | ${phase.taskDoneCount} | ${phase.planExists ? 'yes' : 'no'} | ${phase.summaryExists ? 'yes' : 'no'} | ${phase.reviewExists ? 'yes' : 'no'} | ${phase.uatExists ? 'yes' : 'no'} | ${phase.status} |`
505
611
  );
506
612
  }
507
613
 
@@ -598,6 +704,8 @@ function initPayload(cwd, mode, requestedPhase) {
598
704
  const track = trackPaths(cwd, activeTrack);
599
705
  const phaseMode = mode === 'review-phase' ? 'review' : mode === 'verify-work' ? 'verify' : mode === 'execute-phase' ? 'execute' : mode === 'plan-phase' ? 'plan' : null;
600
706
  const phase = phaseMode && activeTrack ? resolvePhase(cwd, activeTrack, requestedPhase, phaseMode) : null;
707
+ const tasks = phase ? listTasksForPhaseDetails(phase) : [];
708
+ const nextTask = nextExecutableTask(tasks);
601
709
  const codebase = codebasePaths(cwd);
602
710
 
603
711
  return {
@@ -641,6 +749,23 @@ function initPayload(cwd, mode, requestedPhase) {
641
749
  summary_exists: phase ? phase.summaryExists : false,
642
750
  review_exists: phase ? phase.reviewExists : false,
643
751
  uat_exists: phase ? phase.uatExists : false,
752
+ tasks_dir: phase ? phase.dir : null,
753
+ task_count: tasks.length,
754
+ task_done_count: tasks.filter(task => task.summaryExists).length,
755
+ all_tasks_done: tasks.length > 0 && tasks.every(task => task.summaryExists),
756
+ next_task_number: nextTask ? nextTask.number : null,
757
+ next_task_path: nextTask ? nextTask.taskPath : null,
758
+ next_task_summary_path: nextTask ? nextTask.summaryPath : null,
759
+ tasks: tasks.map(task => ({
760
+ number: task.number,
761
+ title: task.title,
762
+ status: task.effectiveStatus,
763
+ depends_on: task.dependsOn,
764
+ ready: task.ready,
765
+ task_path: task.taskPath,
766
+ summary_path: task.summaryPath,
767
+ summary_exists: task.summaryExists
768
+ })),
644
769
  workflow: config.workflow,
645
770
  git_mode: config.git.mode
646
771
  };
@@ -743,5 +868,7 @@ module.exports = {
743
868
  renderProgressTable,
744
869
  resolvePhase,
745
870
  rootPaths,
746
- trackPaths
871
+ trackPaths,
872
+ listTasksForPhaseDetails,
873
+ nextExecutableTask
747
874
  };
@@ -13,17 +13,28 @@ Type: [feature|bugfix|refactor|research|polish]
13
13
  - ROADMAP.md
14
14
  - Current codebase state
15
15
 
16
- ## Steps
17
- 1. [Concrete task]
18
- 2. [Concrete task]
16
+ ## Execution Model
17
+ - This phase is executed through task files.
18
+ - Keep one orchestration session for the phase.
19
+ - Execute one task at a time.
20
+ - No waves by default.
19
21
 
20
- ## Files Likely To Change
21
- - [path]
22
+ ## Phase-Level Risks
23
+ - [Risk]
22
24
 
23
- ## Verification
25
+ ## Shared Verification
24
26
  - [Command]
25
27
  - [Manual check]
26
28
 
29
+ ## Task List
30
+ | Task | Status | Depends On | Goal |
31
+ | --- | --- | --- | --- |
32
+ | 01 | pending | none | [Concrete task goal] |
33
+ | 02 | pending | 01 | [Concrete task goal] |
34
+
35
+ ## Notes
36
+ - [Anything the worker agents must know]
37
+
27
38
  ## Git Policy
28
39
  - Read-only only.
29
40
  - Allowed: `git status`, `git diff`, `git log`, `git show`, `git rev-parse`, `git ls-files`, `git branch --show-current`.
@@ -3,6 +3,8 @@
3
3
  Project Type: [greenfield or brownfield]
4
4
  Active Track: [slug]
5
5
  Current Step: initialized
6
+ Current Task: none
7
+ Current Task Status: idle
6
8
  Status: active
7
9
  Next Command: /autodev
8
10
  Last Updated: [ISO timestamp]
@@ -3,6 +3,8 @@
3
3
  Project Type: [greenfield or brownfield]
4
4
  Active Track: [slug]
5
5
  Current Step: initialized
6
+ Current Task: none
7
+ Current Task Status: idle
6
8
  Status: active
7
9
  Next Command: /autodev
8
10
  Last Updated: [ISO timestamp]
@@ -2,7 +2,11 @@
2
2
 
3
3
  Type: [feature|bugfix|refactor|research|polish]
4
4
 
5
- ## Completed
5
+ ## Tasks Completed
6
+ - Task 01 - [Outcome]
7
+ - Task 02 - [Outcome]
8
+
9
+ ## Phase Outcome
6
10
  - [What shipped]
7
11
 
8
12
  ## Files Changed
@@ -0,0 +1,18 @@
1
+ # Task [NN] Summary: [Name]
2
+
3
+ Status: done
4
+
5
+ ## Completed
6
+ - [What changed]
7
+
8
+ ## Files Changed
9
+ - [path]
10
+
11
+ ## Verification
12
+ - [Command and result]
13
+
14
+ ## Risks Or Follow-Up
15
+ - [Risk or none]
16
+
17
+ ## Recommended Next Step
18
+ - Return to `/autodev`
@@ -0,0 +1,23 @@
1
+ # Task [NN]: [Name]
2
+
3
+ Status: pending
4
+ Depends On: none
5
+
6
+ ## Goal
7
+ [What this task accomplishes]
8
+
9
+ ## Why This Task Exists
10
+ - [Why this should be a separate unit]
11
+
12
+ ## Files Likely To Change
13
+ - [path]
14
+
15
+ ## Implementation Notes
16
+ - [Concrete implementation guidance]
17
+
18
+ ## Verification
19
+ - [Command]
20
+ - [Manual check]
21
+
22
+ ## Done Looks Like
23
+ - [Observable completion signal]
@@ -4,6 +4,8 @@ Track: [Name]
4
4
  Current Phase: 1
5
5
  Current Phase Type: [feature]
6
6
  Current Step: planning
7
+ Current Task: none
8
+ Current Task Status: idle
7
9
  Status: active
8
10
  Next Command: /autodev
9
11
  Last Updated: [ISO timestamp]
@@ -5,7 +5,7 @@ Use `/autodev` as the single entrypoint for the normal workflow. Route automatic
5
5
  <rules>
6
6
  - Prefer `/autodev` over telling the user to run a different command manually.
7
7
  - Manual commands remain valid escape hatches. Mention them only as shortcuts.
8
- - Keep the model `project -> track -> phase`.
8
+ - Keep the model `project -> track -> phase -> tasks`.
9
9
  - Brownfield repositories should be mapped before detailed phase planning.
10
10
  - Never run git write commands.
11
11
  </rules>
@@ -23,7 +23,7 @@ node "$HOME/.claude/autodev/bin/autodev-tools.cjs" status
23
23
  - `init_project`: perform the new-project workflow.
24
24
  - `explore_codebase`: perform the explore-codebase workflow.
25
25
  - `plan_phase`: perform the plan-phase workflow.
26
- - `execute_phase`: perform the execute-phase workflow.
26
+ - `execute_phase`: perform the execute-phase workflow, which should advance one task-sized unit in the current phase session.
27
27
  - `review_phase`: perform the review-phase workflow.
28
28
  - `verify_phase`: perform the verify-work workflow.
29
29
 
@@ -1,12 +1,14 @@
1
1
  <purpose>
2
- Execute an active-track phase plan sequentially, keep the edits pragmatic, and capture the real outcome in a summary.
2
+ Execute an active-track phase through task-sized worker runs, keep the main session orchestration-focused, and capture both task summaries and the final phase summary.
3
3
  </purpose>
4
4
 
5
5
  <rules>
6
6
  - Never run git write commands.
7
7
  - Do not create commits, branches, merges, or worktrees.
8
8
  - Stay within the current phase. Do not silently expand scope.
9
- - Execute sequentially by default. Do not create parallel sub-work unless the user explicitly asks for it.
9
+ - Execute one task at a time by default.
10
+ - Do not use waves.
11
+ - Use a fresh background worker for each task so the phase session does not bloat.
10
12
  </rules>
11
13
 
12
14
  <process>
@@ -23,37 +25,77 @@ node "$HOME/.claude/autodev/bin/autodev-tools.cjs" init execute-phase "$ARGUMENT
23
25
  - `.autodev/tracks/<active-track>/STATE.md`
24
26
  - `.autodev/codebase/summary.md` if it exists
25
27
  - the target `NN-PLAN.md`
26
- - the source files needed for the current phase
28
+ - all `TASK-*.md`
29
+ - all existing `TASK-*-SUMMARY.md`
27
30
 
28
- 4. Execute the plan directly in the repository. Use normal coding tools, tests, and read-only git inspection if useful.
31
+ 4. If the phase has no `TASK-*.md` files:
32
+ - create `TASK-01.md` as a compatibility bridge from the current phase plan
33
+ - keep it narrow and explicit
34
+ - then continue
29
35
 
30
- 5. Keep a short running note of:
31
- - files changed
32
- - commands run
33
- - tests passed or failed
34
- - any scope adjustments the user explicitly approved
36
+ 5. Determine the next executable task:
37
+ - prefer the first task without a summary whose dependencies are already done
38
+ - if no executable task remains and all task summaries exist, move to phase aggregation
39
+ - if task dependencies are inconsistent, stop and ask the user how to repair the plan
35
40
 
36
- 6. Write or update `NN-SUMMARY.md` from the template with:
37
- - completed work
38
- - files changed
39
- - verification results
40
- - remaining risks
41
- - next step
41
+ 6. Before running a task, show the user:
42
+ - task id and title
43
+ - likely files to touch
44
+ - verification plan
45
+ - any dependency note
42
46
 
43
- 7. Update the active track `STATE.md` so it points to:
47
+ 7. Spawn one fresh background worker using `autodev-task-worker` for the selected task.
48
+ Tell it:
49
+ - phase path
50
+ - task path
51
+ - summary path to write
52
+ - required context files to read first
53
+ - to return a concise outcome only
54
+
55
+ 8. After the worker returns:
56
+ - confirm `TASK-NN-SUMMARY.md` exists
57
+ - inspect whether the task is done or blocked
58
+ - report the result to the user
59
+
60
+ 9. If more tasks remain:
61
+ - update project and track state to:
62
+ - `Current Step: execution`
63
+ - `Current Task: <next-task>`
64
+ - `Current Task Status: ready`
65
+ - `Next Command: /autodev`
66
+ - end by telling the user `/autodev` will continue with the next task
67
+
68
+ 10. If all tasks are done:
69
+ - write or update `NN-SUMMARY.md` from the template with:
70
+ - completed tasks
71
+ - aggregate files changed
72
+ - overall verification results
73
+ - remaining risks
74
+ - next step
75
+
76
+ 11. Update the active track `STATE.md` so it points to:
44
77
  - `Current Phase: N`
45
78
  - `Current Phase Type: <type>`
46
79
  - `Current Step: review`
80
+ - `Current Task: none`
81
+ - `Current Task Status: complete`
47
82
  - `Next Command: /autodev`
48
83
  - current ISO timestamp
49
84
 
50
- 8. Update `.autodev/STATE.md` so it points to:
85
+ 12. Update `.autodev/STATE.md` so it points to:
51
86
  - `Active Track: <slug>`
52
87
  - `Current Step: review`
88
+ - `Current Task: none`
89
+ - `Current Task Status: complete`
53
90
  - `Next Command: /autodev`
54
91
  - current ISO timestamp
55
92
 
56
- 9. If the phase is blocked or incomplete, say so clearly in the summary and set both state files back to `Current Step: execution`, with `Next Command: /autodev`.
93
+ 13. If the current task is blocked or incomplete:
94
+ - say so clearly in the task summary
95
+ - set both state files to `Current Step: execution`
96
+ - set `Current Task: <same-task>`
97
+ - set `Current Task Status: blocked`
98
+ - keep `Next Command: /autodev`
57
99
 
58
- 10. End with a short outcome summary and the next recommended command. Mention that the automatic review bundle is the next routed step.
100
+ 14. End with a short outcome summary and the next recommended command. Mention that the automatic review bundle is the next routed step only when the whole phase is complete.
59
101
  </process>
@@ -16,9 +16,9 @@ Lean Claude Code workflow. No automatic commits. No branches. No worktrees. Git
16
16
  - `/autodev-explore-codebase`
17
17
  Spawns four parallel agents to map a brownfield repo into `.autodev/codebase/`.
18
18
  - `/autodev-plan-phase [phase]`
19
- Creates or revises one phase plan in `.autodev/tracks/<track>/phases/NN-type-name/NN-PLAN.md`.
19
+ Creates or revises one phase plan plus task files in `.autodev/tracks/<track>/phases/NN-type-name/`.
20
20
  - `/autodev-execute-phase [phase]`
21
- Executes one phase plan sequentially and writes `NN-SUMMARY.md`.
21
+ Orchestrates one phase task-by-task and writes `TASK-NN-SUMMARY.md` plus the final `NN-SUMMARY.md`.
22
22
  - `/autodev-review-phase [phase]`
23
23
  Spawns four review agents for code quality, security, integration, and polish, then writes `NN-REVIEW.md`.
24
24
  - `/autodev-verify-work [phase]`
@@ -31,7 +31,7 @@ Lean Claude Code workflow. No automatic commits. No branches. No worktrees. Git
31
31
  ## Workflow Model
32
32
 
33
33
  ```text
34
- project -> track -> phase
34
+ project -> track -> phase -> tasks
35
35
  ```
36
36
 
37
37
  - `project`
@@ -39,7 +39,9 @@ project -> track -> phase
39
39
  - `track`
40
40
  The current initiative, feature line, refactor, or bugfix stream.
41
41
  - `phase`
42
- Small execution slices inside the active track.
42
+ Small milestone slices inside the active track.
43
+ - `task`
44
+ Reviewable execution units inside a phase.
43
45
 
44
46
  ## Default Flow
45
47
 
@@ -49,6 +49,8 @@ node "$HOME/.claude/autodev/bin/autodev-tools.cjs" init new-project
49
49
  - `Project Type: ...`
50
50
  - `Active Track: <slug>`
51
51
  - `Current Step: initialized`
52
+ - `Current Task: none`
53
+ - `Current Task Status: idle`
52
54
  - `Status: active`
53
55
  - `Next Command: /autodev`
54
56
  - current ISO timestamp
@@ -79,6 +81,8 @@ Each phase must include:
79
81
  - `Current Phase: 1`
80
82
  - `Current Phase Type: <type>`
81
83
  - `Current Step: planning`
84
+ - `Current Task: none`
85
+ - `Current Task Status: idle`
82
86
  - `Status: active`
83
87
  - `Next Command: /autodev`
84
88
  - current ISO timestamp
@@ -1,12 +1,14 @@
1
1
  <purpose>
2
- Create one practical phase plan for the active track. Keep it concrete, small enough to execute, and free of git-write steps.
2
+ Create one practical phase plan for the active track, then break it into reviewable task files that are small enough for fresh worker-agent execution.
3
3
  </purpose>
4
4
 
5
5
  <rules>
6
6
  - One plan file per phase: `NN-PLAN.md`.
7
+ - Use task files as the execution unit.
7
8
  - Prefer direct action over deep orchestration.
8
9
  - Optional research is allowed only when the user asks for it or `workflow.research` is true.
9
10
  - Never include git write commands in the plan.
11
+ - Do not use waves by default.
10
12
  </rules>
11
13
 
12
14
  <process>
@@ -42,24 +44,52 @@ node "$HOME/.claude/autodev/bin/autodev-tools.cjs" init plan-phase "$ARGUMENTS"
42
44
  7. Write or replace `NN-PLAN.md` from the template. The plan must include:
43
45
  - phase type
44
46
  - goal
45
- - concrete implementation steps
46
- - likely files to touch
47
- - verification commands
48
- - manual checks
47
+ - shared verification commands
48
+ - task list overview
49
49
  - explicit git read-only reminder
50
50
 
51
- 8. Update the active track `STATE.md` so it points to:
51
+ 8. Create task files in the same phase directory:
52
+
53
+ ```text
54
+ TASK-01.md
55
+ TASK-02.md
56
+ ...
57
+ ```
58
+
59
+ Each task should be:
60
+ - small enough for one fresh worker agent context
61
+ - clear about likely files to touch
62
+ - explicit about verification
63
+ - reviewable as a standalone unit
64
+ - sequential by default unless there is an obvious safe dependency split
65
+
66
+ Each task file must include:
67
+ - task title
68
+ - `Status: pending`
69
+ - `Depends On: ...`
70
+ - goal
71
+ - why it is separate
72
+ - files likely to change
73
+ - implementation notes
74
+ - verification
75
+ - done looks like
76
+
77
+ 9. Update the active track `STATE.md` so it points to:
52
78
  - `Current Phase: N`
53
79
  - `Current Phase Type: <type>`
54
80
  - `Current Step: planned`
81
+ - `Current Task: 01` if tasks exist, otherwise `none`
82
+ - `Current Task Status: ready`
55
83
  - `Next Command: /autodev`
56
84
  - current ISO timestamp
57
85
 
58
- 9. Update `.autodev/STATE.md` so it points to:
86
+ 10. Update `.autodev/STATE.md` so it points to:
59
87
  - `Active Track: <slug>`
60
88
  - `Current Step: planned`
89
+ - `Current Task: 01` if tasks exist, otherwise `none`
90
+ - `Current Task Status: ready`
61
91
  - `Next Command: /autodev`
62
92
  - current ISO timestamp
63
93
 
64
- 10. End with a short summary and direct the user to `/autodev`. Mention `/autodev-execute-phase N` as the manual shortcut.
94
+ 11. End with a short summary and direct the user to `/autodev`. Mention `/autodev-execute-phase N` as the manual shortcut.
65
95
  </process>
@@ -22,6 +22,8 @@ node "$HOME/.claude/autodev/bin/autodev-tools.cjs" init review-phase "$ARGUMENTS
22
22
  - `.autodev/STATE.md`
23
23
  - the active track `STATE.md`
24
24
  - `NN-PLAN.md`
25
+ - all `TASK-*.md`
26
+ - all `TASK-*-SUMMARY.md`
25
27
  - `NN-SUMMARY.md`
26
28
  - relevant source files and tests
27
29
 
@@ -19,6 +19,8 @@ node "$HOME/.claude/autodev/bin/autodev-tools.cjs" init verify-work "$ARGUMENTS"
19
19
 
20
20
  3. Read:
21
21
  - `NN-PLAN.md`
22
+ - all `TASK-*.md`
23
+ - all `TASK-*-SUMMARY.md`
22
24
  - `NN-SUMMARY.md`
23
25
  - `NN-REVIEW.md`
24
26
  - relevant code or UI files
@@ -40,6 +42,8 @@ node "$HOME/.claude/autodev/bin/autodev-tools.cjs" init verify-work "$ARGUMENTS"
40
42
  - if verification passed and another phase remains, move to the next phase and set `Current Step: planning`
41
43
  - if verification passed and no phase remains, set `Current Step: complete`
42
44
  - if verification failed, keep the same phase active and set `Current Step: execution`
45
+ - when moving to another phase, set `Current Task: none` and `Current Task Status: idle`
46
+ - when verification failed, set `Current Task: none` and `Current Task Status: idle`
43
47
  - always set `Next Command: /autodev`
44
48
  - always refresh the ISO timestamp
45
49
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: autodev:execute-phase
3
- description: Execute an active-track phase plan sequentially without git writes
3
+ description: Execute an active-track phase task by task with fresh background workers and no git writes
4
4
  argument-hint: "[phase-number]"
5
5
  allowed-tools:
6
6
  - Read
@@ -11,14 +11,17 @@ allowed-tools:
11
11
  - Glob
12
12
  - TodoWrite
13
13
  - AskUserQuestion
14
+ - Task
14
15
  ---
15
16
  <objective>
16
- Execute one active-track phase plan and record the result in a summary.
17
+ Execute one active-track phase through task-sized worker runs and record both task-level and phase-level summaries.
17
18
  </objective>
18
19
 
19
20
  <execution_context>
20
21
  @~/.claude/autodev/workflows/execute-phase.md
21
22
  @~/.claude/autodev/templates/summary.md
23
+ @~/.claude/autodev/templates/task-summary.md
24
+ @~/.claude/autodev/agents/autodev-task-worker.md
22
25
  </execution_context>
23
26
 
24
27
  <process>
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: autodev:plan-phase
3
- description: Create a practical plan for one phase in the active track roadmap
3
+ description: Create a practical phase plan and break it into reviewable task files
4
4
  argument-hint: "[phase-number]"
5
5
  allowed-tools:
6
6
  - Read
@@ -12,12 +12,13 @@ allowed-tools:
12
12
  - WebFetch
13
13
  ---
14
14
  <objective>
15
- Create or update a single executable phase plan under the active track in `.autodev/tracks/<track>/phases/`.
15
+ Create or update a single executable phase plan under the active track in `.autodev/tracks/<track>/phases/`, plus task files for controlled execution.
16
16
  </objective>
17
17
 
18
18
  <execution_context>
19
19
  @~/.claude/autodev/workflows/plan-phase.md
20
20
  @~/.claude/autodev/templates/plan.md
21
+ @~/.claude/autodev/templates/task.md
21
22
  </execution_context>
22
23
 
23
24
  <process>
@@ -4,6 +4,41 @@ const fs = require('fs');
4
4
  const os = require('os');
5
5
  const path = require('path');
6
6
 
7
+ function readStateFields(cwd) {
8
+ try {
9
+ let cursor = cwd;
10
+ let statePath = null;
11
+ while (cursor && cursor !== path.dirname(cursor)) {
12
+ const candidate = path.join(cursor, '.autodev', 'STATE.md');
13
+ if (fs.existsSync(candidate)) {
14
+ statePath = candidate;
15
+ break;
16
+ }
17
+ cursor = path.dirname(cursor);
18
+ }
19
+
20
+ if (!statePath) {
21
+ return {
22
+ currentTask: '',
23
+ currentTaskStatus: ''
24
+ };
25
+ }
26
+
27
+ const content = fs.readFileSync(statePath, 'utf8');
28
+ const currentTask = content.match(/^Current Task:\s*(.+)$/mi)?.[1]?.trim() || '';
29
+ const currentTaskStatus = content.match(/^Current Task Status:\s*(.+)$/mi)?.[1]?.trim() || '';
30
+ return {
31
+ currentTask: currentTask && currentTask !== 'none' ? currentTask : '',
32
+ currentTaskStatus: currentTaskStatus && currentTaskStatus !== 'idle' ? currentTaskStatus : ''
33
+ };
34
+ } catch {
35
+ return {
36
+ currentTask: '',
37
+ currentTaskStatus: ''
38
+ };
39
+ }
40
+ }
41
+
7
42
  let input = '';
8
43
  const stdinTimeout = setTimeout(() => process.exit(0), 3000);
9
44
  process.stdin.setEncoding('utf8');
@@ -19,6 +54,7 @@ process.stdin.on('end', () => {
19
54
  const currentDir = data.workspace?.current_dir || process.cwd();
20
55
  const remaining = data.context_window?.remaining_percentage;
21
56
  const sessionId = data.session_id || '';
57
+ const taskState = readStateFields(currentDir);
22
58
 
23
59
  let contextLabel = '';
24
60
  if (typeof remaining === 'number') {
@@ -38,7 +74,11 @@ process.stdin.on('end', () => {
38
74
  }
39
75
  }
40
76
 
41
- process.stdout.write(`${model} | ${path.basename(currentDir)}${contextLabel}`);
77
+ const taskLabel = taskState.currentTask
78
+ ? ` | task ${taskState.currentTask}${taskState.currentTaskStatus ? ` (${taskState.currentTaskStatus})` : ''}`
79
+ : '';
80
+
81
+ process.stdout.write(`${model} | ${path.basename(currentDir)}${taskLabel}${contextLabel}`);
42
82
  } catch {
43
83
  process.exit(0);
44
84
  }
@@ -42,7 +42,7 @@ process.stdin.on('end', () => {
42
42
  hookEventName: 'PreToolUse',
43
43
  additionalContext:
44
44
  `WORKFLOW ADVISORY: you are editing ${path.basename(filePath)} outside .autodev state files. ` +
45
- 'If this belongs to the current phase, keep STATE.md and the phase summary aligned.'
45
+ 'If this belongs to the current phase, keep STATE.md, task summaries, and the phase summary aligned.'
46
46
  }
47
47
  }));
48
48
  } catch {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mthanhlm/autodev",
3
- "version": "0.2.2",
4
- "description": "A lean Claude Code workflow system with a single entrypoint, brownfield codebase mapping, and read-only git.",
3
+ "version": "0.3.0",
4
+ "description": "A lean Claude Code workflow system with a single entrypoint, task-based phase execution, and read-only git.",
5
5
  "bin": {
6
6
  "autodev": "bin/install.js"
7
7
  },