@relipa/ai-flow-kit 0.1.5-beta.0 → 0.1.5

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.
@@ -1,123 +1,123 @@
1
- # Feature Development Workflow
2
-
3
- > See the full workflow at [AIFLOW.md](../../AIFLOW.md)
4
- > **Gates must pass in order: 1 → 2 → 3 → 4 → 5**
5
-
6
- ---
7
-
8
- ## Step 1: Load ticket & AI analyzes (Gate 1)
9
-
10
- ```bash
11
- aiflow use PROJ-33 # from Backlog/Jira
12
- claude # AI auto-starts Gate 1
13
- ```
14
-
15
- AI will **automatically**:
16
- 1. Load ticket info from Backlog/Jira
17
- 2. Read source code — understand architecture, related files, patterns
18
- 3. Ask clarifying questions if anything is unclear (one at a time)
19
- 4. Output `plan/[ticket-id]/requirement.md` containing:
20
- - Requirements summary (AI's understanding)
21
- - Source code analysis (related files, data flow)
22
- - **Proposed solution** with options and recommendation
23
- - **Impact analysis** — affected areas, risks
24
- - **Effort estimate** (S/M/L/XL)
25
- - Testing plan
26
-
27
- **PM needs to prepare on the ticket:**
28
- ```markdown
29
- ## Description
30
- Clear business requirement. Who uses it, and for what purpose.
31
-
32
- ## Acceptance Criteria
33
- - [ ] [Condition for completion 1]
34
- - [ ] [Condition for completion 2]
35
-
36
- ## Mockup / Wireframe
37
- [Link or UI description]
38
-
39
- ## Context
40
- Constraints, business rules specially requiring attention.
41
- ```
42
-
43
- **If ticket content is unclear:** AI will ask questions based on source code analysis — not just checking format.
44
-
45
- **When satisfied with the requirement document, type:**
46
- ```
47
- APPROVED
48
- ```
49
-
50
- ---
51
-
52
- ## Step 2: Review Implementation Plan (Gate 2)
53
-
54
- AI generates a detailed implementation plan:
55
- - TDD task breakdown (test first → implement → verify)
56
- - Commit strategy (small, focused commits)
57
- - Test commands
58
-
59
- **When agreed, type:**
60
- ```
61
- APPROVED
62
- ```
63
-
64
- **CODE WILL NOT BE GENERATED BEFORE RECEIVING "APPROVED".**
65
-
66
- ---
67
-
68
- ## Step 3: AI Generate Code (Gate 3)
69
-
70
- AI performs automatically:
71
- 1. Complex feature (3+ files): `superpowers:subagent-driven-development`
72
- 2. Write tests FIRST → run → confirm FAIL
73
- 3. Implement → tests PASS
74
- 4. Commit each small step
75
-
76
- Developer doesn't need to do anything at this step — just monitor.
77
-
78
- ---
79
-
80
- ## Step 4: Review Summary (Gate 4)
81
-
82
- AI runs:
83
- 1. `superpowers:verification-before-completion` — all tests PASS
84
- 2. `impact-analysis` — no breaking changes outside of scope
85
- 3. Review checklist — all items ticked
86
- 4. Create `plan/[ticket-id]/summary.md`
87
-
88
- AI displays summary and waits for developer review.
89
-
90
- **If OK, type:**
91
- ```
92
- APPROVED
93
- ```
94
-
95
- **If there are bugs, type:**
96
- ```
97
- BUG: [specific description]
98
- ```
99
- - Coding bug → AI fixes → repeat Gate 4
100
- - Requirement bug → AI returns to Gate 1, update requirement doc
101
-
102
- ---
103
-
104
- ## Step 5: Peer Review & PR (Gate 5)
105
-
106
- AI invokes `superpowers:requesting-code-review` and guides PR creation.
107
-
108
- ```bash
109
- git push origin feature/PROJ-33-feature-name
110
- # Create PR with full description following the template in AIFLOW.md
111
- ```
112
-
113
- Peer reviewer uses the `superpowers:receiving-code-review` skill during review.
114
-
115
- ---
116
-
117
- ## Completion Checklist
118
-
119
- - [ ] Gate 1 APPROVED — requirement doc with solution, impact, estimate
120
- - [ ] Gate 2 APPROVED — implementation plan confirmed by developer
121
- - [ ] Gate 3 done — code + tests are green
122
- - [ ] Gate 4 APPROVED — summary + checklist complete
123
- - [ ] Gate 5 done — PR is peer-reviewed and merged
1
+ # Feature Development Workflow
2
+
3
+ > See the full workflow at [AIFLOW.md](../../AIFLOW.md)
4
+ > **Gates must pass in order: 1 → 2 → 3 → 4 → 5**
5
+
6
+ ---
7
+
8
+ ## Step 1: Load ticket & AI analyzes (Gate 1)
9
+
10
+ ```bash
11
+ aiflow use PROJ-33 # from Backlog/Jira
12
+ claude # AI auto-starts Gate 1
13
+ ```
14
+
15
+ AI will **automatically**:
16
+ 1. Load ticket info from Backlog/Jira
17
+ 2. Read source code — understand architecture, related files, patterns
18
+ 3. Ask clarifying questions if anything is unclear (one at a time)
19
+ 4. Output `AK-Docs/04.Coding/01.Requirements/[functionId]/[ticketId].md` containing:
20
+ - Requirements summary (AI's understanding)
21
+ - Source code analysis (related files, data flow)
22
+ - **Proposed solution** with options and recommendation
23
+ - **Impact analysis** — affected areas, risks
24
+ - **Effort estimate** (S/M/L/XL)
25
+ - Testing plan
26
+
27
+ **PM needs to prepare on the ticket:**
28
+ ```markdown
29
+ ## Description
30
+ Clear business requirement. Who uses it, and for what purpose.
31
+
32
+ ## Acceptance Criteria
33
+ - [ ] [Condition for completion 1]
34
+ - [ ] [Condition for completion 2]
35
+
36
+ ## Mockup / Wireframe
37
+ [Link or UI description]
38
+
39
+ ## Context
40
+ Constraints, business rules specially requiring attention.
41
+ ```
42
+
43
+ **If ticket content is unclear:** AI will ask questions based on source code analysis — not just checking format.
44
+
45
+ **When satisfied with the requirement document, type:**
46
+ ```
47
+ APPROVED
48
+ ```
49
+
50
+ ---
51
+
52
+ ## Step 2: Review Implementation Plan (Gate 2)
53
+
54
+ AI generates a detailed implementation plan:
55
+ - TDD task breakdown (test first → implement → verify)
56
+ - Commit strategy (small, focused commits)
57
+ - Test commands
58
+
59
+ **When agreed, type:**
60
+ ```
61
+ APPROVED
62
+ ```
63
+
64
+ **CODE WILL NOT BE GENERATED BEFORE RECEIVING "APPROVED".**
65
+
66
+ ---
67
+
68
+ ## Step 3: AI Generate Code (Gate 3)
69
+
70
+ AI performs automatically:
71
+ 1. Complex feature (3+ files): `superpowers:subagent-driven-development`
72
+ 2. Write tests FIRST → run → confirm FAIL
73
+ 3. Implement → tests PASS
74
+ 4. Commit each small step
75
+
76
+ Developer doesn't need to do anything at this step — just monitor.
77
+
78
+ ---
79
+
80
+ ## Step 4: Review Summary (Gate 4)
81
+
82
+ AI runs:
83
+ 1. `superpowers:verification-before-completion` — all tests PASS
84
+ 2. `impact-analysis` — no breaking changes outside of scope
85
+ 3. Review checklist — all items ticked
86
+ 4. Create `AK-Docs/04.Coding/04.Reviews/[functionId]/[ticketId].md`
87
+
88
+ AI displays summary and waits for developer review.
89
+
90
+ **If OK, type:**
91
+ ```
92
+ APPROVED
93
+ ```
94
+
95
+ **If there are bugs, type:**
96
+ ```
97
+ BUG: [specific description]
98
+ ```
99
+ - Coding bug → AI fixes → repeat Gate 4
100
+ - Requirement bug → AI returns to Gate 1, update requirement doc
101
+
102
+ ---
103
+
104
+ ## Step 5: Peer Review & PR (Gate 5)
105
+
106
+ AI invokes `superpowers:requesting-code-review` and guides PR creation.
107
+
108
+ ```bash
109
+ git push origin feature/PROJ-33-feature-name
110
+ # Create PR with full description following the template in AIFLOW.md
111
+ ```
112
+
113
+ Peer reviewer uses the `superpowers:receiving-code-review` skill during review.
114
+
115
+ ---
116
+
117
+ ## Completion Checklist
118
+
119
+ - [ ] Gate 1 APPROVED — requirement doc with solution, impact, estimate
120
+ - [ ] Gate 2 APPROVED — implementation plan confirmed by developer
121
+ - [ ] Gate 3 done — code + tests are green
122
+ - [ ] Gate 4 APPROVED — summary + checklist complete
123
+ - [ ] Gate 5 done — PR is peer-reviewed and merged
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@relipa/ai-flow-kit",
3
- "version": "0.1.5-beta.0",
3
+ "version": "0.1.5",
4
4
  "description": "All-in-one AI Flow Kit for team development with Claude AI - skills, templates, and MCP adapters",
5
5
  "author": "Example Team",
6
6
  "publishConfig": {
@@ -0,0 +1,49 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+ const chalk = require('chalk');
4
+ const { execSync } = require('child_process');
5
+
6
+ // AK-Docs (per-project docs) and Shared-Docs (cross-project templates) are
7
+ // fixed-name folders living directly under the workspace root — the folder
8
+ // opened in the editor, which contains one or more source repos plus these
9
+ // two docs repos as siblings. `ak` is run from that root, so projectDir
10
+ // (process.cwd()) already IS the root — see docs/internal/Project-Structure.md.
11
+ const DOC_REPOS = [
12
+ { name: 'AK-Docs', purpose: 'tài liệu dự án (Requirements, Specs, Test Cases, Coding docs...)' },
13
+ { name: 'Shared-Docs', purpose: 'template dùng chung cho tất cả dự án (Spec, QA, Test Case, Test Report...)' },
14
+ ];
15
+
16
+ function resolveDocsRepoPath(projectDir, repoName) {
17
+ return path.join(projectDir, repoName);
18
+ }
19
+
20
+ async function syncDocsRepo(projectDir, repoName, purpose) {
21
+ const repoPath = resolveDocsRepoPath(projectDir, repoName);
22
+
23
+ if (!(await fs.pathExists(repoPath))) {
24
+ console.log(chalk.yellow(`⚠ ${repoName}/ chưa tồn tại tại ${repoPath} (${purpose}). Hãy clone repo này vào thư mục root.`));
25
+ return;
26
+ }
27
+
28
+ if (!(await fs.pathExists(path.join(repoPath, '.git')))) {
29
+ console.log(chalk.yellow(`⚠ ${repoName}/ tồn tại tại ${repoPath} nhưng không phải git repo — bỏ qua pull.`));
30
+ return;
31
+ }
32
+
33
+ console.log(chalk.cyan(`\n⟳ Pulling latest ${repoName}...`));
34
+ try {
35
+ execSync('git pull', { cwd: repoPath, stdio: 'inherit' });
36
+ console.log(chalk.green(`✓ ${repoName} đã cập nhật mới nhất.`));
37
+ } catch (err) {
38
+ console.log(chalk.red(`✗ Không thể pull ${repoName}: ${err.message}`));
39
+ }
40
+ }
41
+
42
+ async function syncDocsRepos(projectDir) {
43
+ console.log(chalk.blue('\nĐồng bộ AK-Docs / Shared-Docs...'));
44
+ for (const repo of DOC_REPOS) {
45
+ await syncDocsRepo(projectDir, repo.name, repo.purpose);
46
+ }
47
+ }
48
+
49
+ module.exports = { syncDocsRepos, resolveDocsRepoPath, DOC_REPOS };
@@ -215,14 +215,16 @@ function buildContextPrompt(ctx, taskState) {
215
215
 
216
216
  if (currentGate === 2) {
217
217
  lines.push('Gate 1 is already APPROVED. The requirement document is at:');
218
- lines.push(` plan/${ctx.taskId}/requirement.md`);
218
+ lines.push(` AK-Docs/04.Coding/01.Requirements/[functionId]/${ctx.taskId}.md`);
219
+ lines.push(` ([functionId] — look it up in AK-Docs/04.Coding/00.Overview/_Index.md or the folder containing ${ctx.taskId}.md)`);
219
220
  lines.push('');
220
221
  lines.push('Proceed to Gate 2: create the implementation plan.');
221
222
  lines.push(buildModeInstruction(mode, 2));
222
223
  } else if (currentGate === 3) {
223
224
  lines.push('Gates 1 and 2 are already APPROVED. Plans are at:');
224
- lines.push(` plan/${ctx.taskId}/requirement.md`);
225
- lines.push(` plan/${ctx.taskId}/plan.md`);
225
+ lines.push(` AK-Docs/04.Coding/01.Requirements/[functionId]/${ctx.taskId}.md`);
226
+ lines.push(` AK-Docs/04.Coding/02.Plans/[functionId]/${ctx.taskId}.md`);
227
+ lines.push(` ([functionId] — look it up in AK-Docs/04.Coding/00.Overview/_Index.md)`);
226
228
  lines.push('');
227
229
  lines.push('Proceed to Gate 3: implement code following the plan (TDD).');
228
230
  lines.push(buildModeInstruction(mode, 3));
@@ -246,17 +248,19 @@ function buildContextPrompt(ctx, taskState) {
246
248
 
247
249
  if (mode === 'fast') {
248
250
  lines.push('**MODE: fast** — Use the FAST TRACK path in the skill:');
251
+ lines.push('- Pre-flight: determine functionId first (from context / input UC Spec file / ask DEV to confirm) — see the DEV workflow Pre-flight step');
249
252
  lines.push('- Read ticket + identify changed files only (no deep source scan)');
250
253
  lines.push('- Skip Q&A unless there is a critical blocking ambiguity');
251
- lines.push('- Output a lite requirement doc (Sections 1, 3, 5 only)');
254
+ lines.push('- Output a lite requirement doc (Sections 1, 3, 5 only) to AK-Docs/04.Coding/01.Requirements/[functionId]/' + ctx.taskId + '.md');
252
255
  lines.push('- Target: Gate 1 complete in < 5 minutes');
253
256
  } else {
254
257
  lines.push('Gate 1 process:');
258
+ lines.push('0. Pre-flight: determine functionId (from context / input UC Spec file / ask DEV to confirm) + ensure AK-Docs/04.Coding/ tree exists — see the DEV workflow Pre-flight step. DO NOT continue without functionId.');
255
259
  lines.push('1. Read the ticket context above');
256
260
  lines.push('2. Read CLAUDE.md — understand project architecture and conventions');
257
261
  lines.push('3. Read source code — identify related files, data flow, patterns');
258
262
  lines.push('4. If anything is unclear — ask ONE question at a time');
259
- lines.push('5. Output plan/' + ctx.taskId + '/requirement.md');
263
+ lines.push('5. Output AK-Docs/04.Coding/01.Requirements/[functionId]/' + ctx.taskId + '.md');
260
264
  lines.push('6. Display GATE 1 prompt and wait for APPROVED');
261
265
  }
262
266
 
package/scripts/init.js CHANGED
@@ -3,6 +3,7 @@ const path = require('path');
3
3
  const os = require('os');
4
4
  const chalk = require('chalk');
5
5
  const { input, checkbox, confirm } = require('@inquirer/prompts');
6
+ const { syncDocsRepos } = require('./docs-repo');
6
7
 
7
8
  const PKG_DIR = path.join(__dirname, '..');
8
9
  const GLOBAL_AIFLOW_DIR = path.join(os.homedir(), '.aiflow');
@@ -752,7 +753,6 @@ async function ensureAiflowGitignored(projectDir) {
752
753
  const gitignorePath = path.join(projectDir, '.gitignore');
753
754
  const entries = [
754
755
  '.aiflow/',
755
- 'plan/',
756
756
  '.claude/',
757
757
  '.rules/',
758
758
  '.mcp.json',
@@ -1048,6 +1048,9 @@ async function init(options) {
1048
1048
  try {
1049
1049
  console.log(chalk.blue(`Initializing ai-flow-kit (v${PKG_VERSION})...`));
1050
1050
 
1051
+ // ── Sync AK-Docs / Shared-Docs sibling repos ──────────────────
1052
+ await syncDocsRepos(projectDir);
1053
+
1051
1054
  // ── Auto-detect or prompt for framework if not supplied ──────
1052
1055
  if (frameworks.length === 0) {
1053
1056
  const stateFilePath = path.join(aiflowDir, 'state.json');
File without changes
package/scripts/prompt.js CHANGED
@@ -25,7 +25,7 @@ AI must:
25
25
  1. Load ticket context + read source code related to the bug
26
26
  2. Trace data flow to form root cause hypothesis (\`superpowers:systematic-debugging\`)
27
27
  3. If unclear → ask ONE question at a time, wait for reply
28
- 4. Output \`plan/[ticket-id]/requirement.md\` with:
28
+ 4. Output \`AK-Docs/04.Coding/01.Requirements/[functionId]/[ticketId].md\` with:
29
29
  - Bug analysis (current vs expected behavior)
30
30
  - Root cause hypothesis with evidence from source code
31
31
  - Proposed fix approach (options if multiple)
@@ -52,7 +52,7 @@ Only runs after Gate 2 APPROVED.
52
52
  1. \`superpowers:verification-before-completion\` — all tests PASS (including old tests)
53
53
  2. \`impact-analysis\` skill — fix doesn't cause new bugs elsewhere
54
54
  3. Tick \`custom/rules/review-checklist.md\`
55
- 4. Create \`plan/[ticket-id]/summary.md\`
55
+ 4. Create \`AK-Docs/04.Coding/04.Reviews/[functionId]/[ticketId].md\`
56
56
  - Display: "GATE 4: type APPROVED or BUG: [description]"
57
57
  - Coding bug → fix → repeat Gate 4
58
58
  - Requirement bug → back to Gate 1
@@ -77,7 +77,7 @@ AI must:
77
77
  2. Investigate related files, data flow, existing patterns
78
78
  3. Propose 2-3 solution approaches using Q&A if the problem is complex
79
79
  4. If unclear → ask ONE question at a time, wait for reply
80
- 5. Output \`plan/[ticket-id]/requirement.md\` with:
80
+ 5. Output \`AK-Docs/04.Coding/01.Requirements/[functionId]/[ticketId].md\` with:
81
81
  - Requirements summary (AI's understanding in technical language)
82
82
  - Source code analysis (related files, data flow, patterns)
83
83
  - Proposed solution with options (recommended + alternatives)
@@ -104,7 +104,7 @@ Only runs after Gate 2 APPROVED.
104
104
  1. \`superpowers:verification-before-completion\` — all tests PASS
105
105
  2. \`impact-analysis\` skill — no regressions
106
106
  3. Tick \`custom/rules/review-checklist.md\`
107
- 4. Create \`plan/[ticket-id]/summary.md\`
107
+ 4. Create \`AK-Docs/04.Coding/04.Reviews/[functionId]/[ticketId].md\`
108
108
  - Display: "GATE 4: type APPROVED or BUG: [description]"
109
109
  - Coding bug → fix → repeat Gate 4
110
110
  - Requirement bug → back to Gate 1
@@ -129,7 +129,7 @@ AI must:
129
129
  2. **INVOKE:** \`superpowers:systematic-debugging\` — trace through all layers
130
130
  3. **INVOKE:** \`investigate-bug\` skill — trace data flow through all layers
131
131
  4. If unclear → ask ONE question at a time
132
- 5. Output \`plan/[ticket-id]/requirement.md\` with:
132
+ 5. Output \`AK-Docs/04.Coding/01.Requirements/[functionId]/[ticketId].md\` with:
133
133
  - Investigation scope and approach
134
134
  - Source code analysis (all related files traced)
135
135
  - Findings with evidence (log output, code references)
@@ -156,7 +156,7 @@ AI must:
156
156
  1. Load ticket context + read source code to understand current state
157
157
  2. **INVOKE:** \`impact-analysis\` skill — map ALL callers and dependants
158
158
  3. If unclear → ask ONE question at a time
159
- 4. Output \`plan/[ticket-id]/requirement.md\` with:
159
+ 4. Output \`AK-Docs/04.Coding/01.Requirements/[functionId]/[ticketId].md\` with:
160
160
  - Current state analysis (what exists, what's wrong)
161
161
  - Target state (what it should look like after refactor)
162
162
  - Proposed approach (step-by-step refactor strategy)
@@ -182,7 +182,7 @@ Only runs after Gate 2 APPROVED.
182
182
  1. \`superpowers:verification-before-completion\` — all tests PASS
183
183
  2. \`impact-analysis\` skill — verify no regressions
184
184
  3. Tick \`custom/rules/review-checklist.md\`
185
- 4. Create \`plan/[ticket-id]/summary.md\`
185
+ 4. Create \`AK-Docs/04.Coding/04.Reviews/[functionId]/[ticketId].md\`
186
186
  - Display: "GATE 4: type APPROVED or BUG: [description]"
187
187
 
188
188
  ### GATE 5 — Peer Review & Done
@@ -203,7 +203,7 @@ AI must:
203
203
  1. Load ticket context + read source code thoroughly
204
204
  2. Map all dependencies, callers, services, jobs, tests
205
205
  3. If unclear → ask ONE question at a time
206
- 4. Output \`plan/[ticket-id]/requirement.md\` with:
206
+ 4. Output \`AK-Docs/04.Coding/01.Requirements/[functionId]/[ticketId].md\` with:
207
207
  - Change description and scope
208
208
  - Dependency map (all callers, services, jobs, tests)
209
209
  - Impact level: 🟢 Low / 🟡 Medium / 🔴 High / 🔥 Critical
@@ -229,7 +229,7 @@ AI must:
229
229
  1. Load ticket context + read source code thoroughly
230
230
  2. Understand what needs to be tested (unit, integration, e2e)
231
231
  3. If unclear → ask ONE question at a time
232
- 4. Output \`plan/[ticket-id]/requirement.md\` with:
232
+ 4. Output \`AK-Docs/04.Coding/01.Requirements/[functionId]/[ticketId].md\` with:
233
233
  - Test scope and strategy
234
234
  - Test cases to cover (happy path + edge cases + failure cases)
235
235
  - Source code references
@@ -239,7 +239,7 @@ AI must:
239
239
  ### GATE 2 — Implementation Plan
240
240
  **INVOKE:** \`generate-spec\` skill, then \`superpowers:writing-plans\`
241
241
  - Create detailed TDD test implementation plan.
242
- - Output \`plan/[ticket-id]/plan.md\`.
242
+ - Output \`AK-Docs/04.Coding/02.Plans/[functionId]/[ticketId].md\`.
243
243
  - Display: "GATE 2 PAUSED: type APPROVED to start coding".
244
244
 
245
245
  ### GATE 3 — Write Tests (TDD)
@@ -265,7 +265,7 @@ AI must:
265
265
  1. Load ticket context + read source code
266
266
  2. Understand what needs to be documented and for whom
267
267
  3. If unclear → ask ONE question at a time
268
- 4. Output \`plan/[ticket-id]/requirement.md\` with:
268
+ 4. Output \`AK-Docs/04.Coding/01.Requirements/[functionId]/[ticketId].md\` with:
269
269
  - Documentation scope and target audience
270
270
  - Content outline (sections to cover)
271
271
  - Source code references
package/scripts/task.js CHANGED
@@ -2,12 +2,14 @@ const fs = require('fs-extra');
2
2
  const path = require('path');
3
3
  const chalk = require('chalk');
4
4
  const { confirm } = require('@inquirer/prompts');
5
+ const { resolveDocsRepoPath } = require('./docs-repo');
5
6
 
6
7
  const PROJECT_DIR = process.cwd();
7
8
  const AIFLOW_DIR = path.join(PROJECT_DIR, '.aiflow');
8
9
  const CONTEXT_DIR = path.join(AIFLOW_DIR, 'context');
9
10
  const CURRENT_FILE = path.join(CONTEXT_DIR, 'current.json');
10
11
  const TASKS_DIR = path.join(AIFLOW_DIR, 'tasks');
12
+ const CODING_DIR = path.join(resolveDocsRepoPath(PROJECT_DIR, 'AK-Docs'), '04.Coding');
11
13
 
12
14
  // ──────────────────────────────────────────────────────────────
13
15
  // Entry point
@@ -206,12 +208,8 @@ async function resetTask(taskId) {
206
208
  }
207
209
 
208
210
  const taskState = await fs.readJson(statePath);
209
- const planDir = path.join(PROJECT_DIR, 'plan', taskId);
210
- const planFiles = [];
211
- if (await fs.pathExists(planDir)) {
212
- const entries = await fs.readdir(planDir);
213
- for (const f of entries) planFiles.push(path.join('plan', taskId, f));
214
- }
211
+ const docPaths = await findTaskDocs(taskId);
212
+ const planFiles = docPaths.map(p => path.relative(PROJECT_DIR, p));
215
213
 
216
214
  // Show what will happen
217
215
  console.log(chalk.cyan(`\nReset task: ${taskId}\n`));
@@ -220,12 +218,12 @@ async function resetTask(taskId) {
220
218
  console.log(chalk.gray(` Gate: ${taskState.currentGate} → 1 | Approvals cleared | Status: active`));
221
219
 
222
220
  const deletePlan = planFiles.length > 0 && await confirm({
223
- message: `Also delete ${planFiles.length} plan file(s) in plan/${taskId}/?`,
221
+ message: `Also delete ${planFiles.length} gate doc file(s) (AK-Docs/04.Coding/ + legacy plan/) for ${taskId}?`,
224
222
  default: false,
225
223
  });
226
224
 
227
225
  if (deletePlan) {
228
- console.log(chalk.gray('\n Plan files to delete:'));
226
+ console.log(chalk.gray('\n Gate doc files to delete:'));
229
227
  for (const f of planFiles) console.log(chalk.gray(` • ${f}`));
230
228
  }
231
229
 
@@ -252,10 +250,13 @@ async function resetTask(taskId) {
252
250
  await fs.copy(ctxPath, CURRENT_FILE, { overwrite: true });
253
251
  }
254
252
 
255
- if (deletePlan) await fs.remove(planDir);
253
+ if (deletePlan) {
254
+ for (const p of docPaths) await fs.remove(p);
255
+ await fs.remove(path.join(PROJECT_DIR, 'plan', taskId));
256
+ }
256
257
 
257
258
  console.log(chalk.green(`✓ Task ${taskId} reset to Gate 1.`));
258
- if (deletePlan) console.log(chalk.gray(` Deleted plan/${taskId}/`));
259
+ if (deletePlan) console.log(chalk.gray(` Deleted ${planFiles.length} gate doc file(s).`));
259
260
  console.log(chalk.gray(' Open Claude to start Gate 1: claude'));
260
261
  }
261
262
 
@@ -271,9 +272,9 @@ async function removeTask(taskId) {
271
272
 
272
273
  const isActive = await fs.pathExists(CURRENT_FILE) &&
273
274
  ((await fs.readJson(CURRENT_FILE).catch(() => ({}))).taskId === taskId);
274
- const planDir = path.join(PROJECT_DIR, 'plan', taskId);
275
- const hasPlan = await fs.pathExists(planDir);
276
- const planFiles = hasPlan ? await fs.readdir(planDir) : [];
275
+ const docPaths = await findTaskDocs(taskId);
276
+ const hasPlan = docPaths.length > 0;
277
+ const planFiles = docPaths.map(p => path.relative(PROJECT_DIR, p));
277
278
 
278
279
  // Show what will be deleted
279
280
  console.log(chalk.cyan(`\nRemove task: ${taskId}\n`));
@@ -281,8 +282,8 @@ async function removeTask(taskId) {
281
282
  console.log(chalk.gray(` • .aiflow/tasks/${taskId}/ (context snapshot + gate state)`));
282
283
  if (isActive) console.log(chalk.gray(` • .aiflow/context/current.json (this is the active task)`));
283
284
  if (hasPlan) {
284
- console.log(chalk.gray(` • plan/${taskId}/ (${planFiles.length} file(s)):`));
285
- for (const f of planFiles) console.log(chalk.gray(` - plan/${taskId}/${f}`));
285
+ console.log(chalk.gray(` • Gate docs (${planFiles.length} file(s)):`));
286
+ for (const f of planFiles) console.log(chalk.gray(` - ${f}`));
286
287
  }
287
288
 
288
289
  console.log();
@@ -294,7 +295,10 @@ async function removeTask(taskId) {
294
295
 
295
296
  await fs.remove(taskDir);
296
297
  if (isActive) await fs.remove(CURRENT_FILE);
297
- if (hasPlan) await fs.remove(planDir);
298
+ if (hasPlan) {
299
+ for (const p of docPaths) await fs.remove(p);
300
+ await fs.remove(path.join(PROJECT_DIR, 'plan', taskId));
301
+ }
298
302
 
299
303
  console.log(chalk.green(`✓ Task ${taskId} removed.`));
300
304
  }
@@ -348,23 +352,21 @@ async function nextGate(taskId) {
348
352
  // Clear current context so no task is "active"
349
353
  await fs.remove(CURRENT_FILE);
350
354
 
351
- // Generate cumulative task-summary.md
352
- const planDir = path.join(PROJECT_DIR, 'plan', resolvedId);
353
- await fs.ensureDir(planDir);
354
- const summaryPath = path.join(planDir, 'task-summary.md');
355
+ // Generate cumulative task-summary.md (task-internal state — lives in .aiflow/, not gate docs)
356
+ const summaryPath = path.join(TASKS_DIR, resolvedId, 'task-summary.md');
355
357
  const summaryContent = await generateMarkdownSummary(taskState);
356
358
  await fs.writeFile(summaryPath, summaryContent, 'utf-8');
357
359
 
358
360
  const taskType = existing.taskType || 'feature';
359
361
  console.log(chalk.green(`✓ Gate ${currentGate} approved for ${resolvedId}.`));
360
- console.log(chalk.gray(` Summary saved to: plan/${resolvedId}/task-summary.md`));
362
+ console.log(chalk.gray(` Summary saved to: .aiflow/tasks/${resolvedId}/task-summary.md`));
361
363
  const nextLabel = gateLabel(nextGateNum, taskType);
362
364
  console.log(chalk.white(`\n Next: Gate ${nextGateNum} — ${nextLabel}`));
363
365
  console.log(chalk.cyan(`\n To continue in a fresh session (Recommended to avoid context pollution):`));
364
366
  console.log(chalk.gray(` 1. Open a NEW chatbox or terminal session.`));
365
367
  console.log(chalk.gray(` 2. Run: aiflow task resume ${resolvedId} (to load context).`));
366
368
  console.log(chalk.gray(` 3. Type "start" or "continue from the current plan".`));
367
- console.log(chalk.yellow(` (Note: Gate 3 progress is saved via [x] checkboxes in plan.md.`));
369
+ console.log(chalk.yellow(` (Note: Gate 3 progress is saved via [x] checkboxes in the Gate 2 plan doc (AK-Docs/04.Coding/02.Plans/).`));
368
370
  console.log(chalk.yellow(` The AI will automatically resume the exact task you left off.)`));
369
371
  console.log();
370
372
  }
@@ -373,6 +375,37 @@ async function nextGate(taskId) {
373
375
  // Internal helpers
374
376
  // ──────────────────────────────────────────────────────────────
375
377
 
378
+ /**
379
+ * Find gate output docs for a task under AK-Docs/04.Coding/<section>/<functionId>/<taskId>.md
380
+ * (new convention) plus the legacy plan/<taskId>/ folder. Returns absolute paths.
381
+ */
382
+ async function findTaskDocs(taskId) {
383
+ const results = [];
384
+
385
+ if (await fs.pathExists(CODING_DIR)) {
386
+ const sections = await fs.readdir(CODING_DIR, { withFileTypes: true }).catch(() => []);
387
+ for (const section of sections) {
388
+ if (!section.isDirectory()) continue;
389
+ const sectionDir = path.join(CODING_DIR, section.name);
390
+ const featureDirs = await fs.readdir(sectionDir, { withFileTypes: true }).catch(() => []);
391
+ for (const feature of featureDirs) {
392
+ if (!feature.isDirectory()) continue;
393
+ const docPath = path.join(sectionDir, feature.name, `${taskId}.md`);
394
+ if (await fs.pathExists(docPath)) results.push(docPath);
395
+ }
396
+ }
397
+ }
398
+
399
+ // Legacy convention: plan/<taskId>/
400
+ const legacyDir = path.join(PROJECT_DIR, 'plan', taskId);
401
+ if (await fs.pathExists(legacyDir)) {
402
+ const entries = await fs.readdir(legacyDir).catch(() => []);
403
+ for (const f of entries) results.push(path.join(legacyDir, f));
404
+ }
405
+
406
+ return results;
407
+ }
408
+
376
409
  async function deactivateOtherTasks(exceptTaskId) {
377
410
  if (!(await fs.pathExists(TASKS_DIR))) return;
378
411
  const entries = await fs.readdir(TASKS_DIR, { withFileTypes: true });
@@ -410,6 +443,21 @@ async function detectCurrentGate(taskId) {
410
443
  if (state.currentGate) return state.currentGate;
411
444
  }
412
445
 
446
+ // New convention: AK-Docs/04.Coding/<section>/<functionId>/<taskId>.md
447
+ const hasDocInSection = async (section) => {
448
+ const dir = path.join(CODING_DIR, section);
449
+ if (!(await fs.pathExists(dir))) return false;
450
+ const features = await fs.readdir(dir, { withFileTypes: true }).catch(() => []);
451
+ for (const f of features) {
452
+ if (f.isDirectory() && await fs.pathExists(path.join(dir, f.name, `${taskId}.md`))) return true;
453
+ }
454
+ return false;
455
+ };
456
+ if (await hasDocInSection('04.Reviews')) return 5;
457
+ if (await hasDocInSection('02.Plans')) return 3;
458
+ if (await hasDocInSection('01.Requirements')) return 2;
459
+
460
+ // Legacy convention: plan/<taskId>/
413
461
  const planDir = path.join(PROJECT_DIR, 'plan', taskId);
414
462
  if (!(await fs.pathExists(planDir))) return 1;
415
463
  if (await fs.pathExists(path.join(planDir, 'summary.md'))) return 5;