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

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 `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 `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-beta.1",
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": {
@@ -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(` 04.Coding/01.Requirements/[functionId]/${ctx.taskId}.md`);
219
+ lines.push(` ([functionId] — look it up in 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(` 04.Coding/01.Requirements/[functionId]/${ctx.taskId}.md`);
226
+ lines.push(` 04.Coding/02.Plans/[functionId]/${ctx.taskId}.md`);
227
+ lines.push(` ([functionId] — look it up in 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 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 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 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/task.js CHANGED
@@ -206,12 +206,8 @@ async function resetTask(taskId) {
206
206
  }
207
207
 
208
208
  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
- }
209
+ const docPaths = await findTaskDocs(taskId);
210
+ const planFiles = docPaths.map(p => path.relative(PROJECT_DIR, p));
215
211
 
216
212
  // Show what will happen
217
213
  console.log(chalk.cyan(`\nReset task: ${taskId}\n`));
@@ -220,12 +216,12 @@ async function resetTask(taskId) {
220
216
  console.log(chalk.gray(` Gate: ${taskState.currentGate} → 1 | Approvals cleared | Status: active`));
221
217
 
222
218
  const deletePlan = planFiles.length > 0 && await confirm({
223
- message: `Also delete ${planFiles.length} plan file(s) in plan/${taskId}/?`,
219
+ message: `Also delete ${planFiles.length} gate doc file(s) (04.Coding/ + legacy plan/) for ${taskId}?`,
224
220
  default: false,
225
221
  });
226
222
 
227
223
  if (deletePlan) {
228
- console.log(chalk.gray('\n Plan files to delete:'));
224
+ console.log(chalk.gray('\n Gate doc files to delete:'));
229
225
  for (const f of planFiles) console.log(chalk.gray(` • ${f}`));
230
226
  }
231
227
 
@@ -252,10 +248,13 @@ async function resetTask(taskId) {
252
248
  await fs.copy(ctxPath, CURRENT_FILE, { overwrite: true });
253
249
  }
254
250
 
255
- if (deletePlan) await fs.remove(planDir);
251
+ if (deletePlan) {
252
+ for (const p of docPaths) await fs.remove(p);
253
+ await fs.remove(path.join(PROJECT_DIR, 'plan', taskId));
254
+ }
256
255
 
257
256
  console.log(chalk.green(`✓ Task ${taskId} reset to Gate 1.`));
258
- if (deletePlan) console.log(chalk.gray(` Deleted plan/${taskId}/`));
257
+ if (deletePlan) console.log(chalk.gray(` Deleted ${planFiles.length} gate doc file(s).`));
259
258
  console.log(chalk.gray(' Open Claude to start Gate 1: claude'));
260
259
  }
261
260
 
@@ -271,9 +270,9 @@ async function removeTask(taskId) {
271
270
 
272
271
  const isActive = await fs.pathExists(CURRENT_FILE) &&
273
272
  ((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) : [];
273
+ const docPaths = await findTaskDocs(taskId);
274
+ const hasPlan = docPaths.length > 0;
275
+ const planFiles = docPaths.map(p => path.relative(PROJECT_DIR, p));
277
276
 
278
277
  // Show what will be deleted
279
278
  console.log(chalk.cyan(`\nRemove task: ${taskId}\n`));
@@ -281,8 +280,8 @@ async function removeTask(taskId) {
281
280
  console.log(chalk.gray(` • .aiflow/tasks/${taskId}/ (context snapshot + gate state)`));
282
281
  if (isActive) console.log(chalk.gray(` • .aiflow/context/current.json (this is the active task)`));
283
282
  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}`));
283
+ console.log(chalk.gray(` • Gate docs (${planFiles.length} file(s)):`));
284
+ for (const f of planFiles) console.log(chalk.gray(` - ${f}`));
286
285
  }
287
286
 
288
287
  console.log();
@@ -294,7 +293,10 @@ async function removeTask(taskId) {
294
293
 
295
294
  await fs.remove(taskDir);
296
295
  if (isActive) await fs.remove(CURRENT_FILE);
297
- if (hasPlan) await fs.remove(planDir);
296
+ if (hasPlan) {
297
+ for (const p of docPaths) await fs.remove(p);
298
+ await fs.remove(path.join(PROJECT_DIR, 'plan', taskId));
299
+ }
298
300
 
299
301
  console.log(chalk.green(`✓ Task ${taskId} removed.`));
300
302
  }
@@ -348,23 +350,21 @@ async function nextGate(taskId) {
348
350
  // Clear current context so no task is "active"
349
351
  await fs.remove(CURRENT_FILE);
350
352
 
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');
353
+ // Generate cumulative task-summary.md (task-internal state — lives in .aiflow/, not gate docs)
354
+ const summaryPath = path.join(TASKS_DIR, resolvedId, 'task-summary.md');
355
355
  const summaryContent = await generateMarkdownSummary(taskState);
356
356
  await fs.writeFile(summaryPath, summaryContent, 'utf-8');
357
357
 
358
358
  const taskType = existing.taskType || 'feature';
359
359
  console.log(chalk.green(`✓ Gate ${currentGate} approved for ${resolvedId}.`));
360
- console.log(chalk.gray(` Summary saved to: plan/${resolvedId}/task-summary.md`));
360
+ console.log(chalk.gray(` Summary saved to: .aiflow/tasks/${resolvedId}/task-summary.md`));
361
361
  const nextLabel = gateLabel(nextGateNum, taskType);
362
362
  console.log(chalk.white(`\n Next: Gate ${nextGateNum} — ${nextLabel}`));
363
363
  console.log(chalk.cyan(`\n To continue in a fresh session (Recommended to avoid context pollution):`));
364
364
  console.log(chalk.gray(` 1. Open a NEW chatbox or terminal session.`));
365
365
  console.log(chalk.gray(` 2. Run: aiflow task resume ${resolvedId} (to load context).`));
366
366
  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.`));
367
+ console.log(chalk.yellow(` (Note: Gate 3 progress is saved via [x] checkboxes in the Gate 2 plan doc (04.Coding/02.Plans/).`));
368
368
  console.log(chalk.yellow(` The AI will automatically resume the exact task you left off.)`));
369
369
  console.log();
370
370
  }
@@ -373,6 +373,38 @@ async function nextGate(taskId) {
373
373
  // Internal helpers
374
374
  // ──────────────────────────────────────────────────────────────
375
375
 
376
+ /**
377
+ * Find gate output docs for a task under 04.Coding/<section>/<functionId>/<taskId>.md
378
+ * (new convention) plus the legacy plan/<taskId>/ folder. Returns absolute paths.
379
+ */
380
+ async function findTaskDocs(taskId) {
381
+ const results = [];
382
+
383
+ const codingDir = path.join(PROJECT_DIR, '04.Coding');
384
+ if (await fs.pathExists(codingDir)) {
385
+ const sections = await fs.readdir(codingDir, { withFileTypes: true }).catch(() => []);
386
+ for (const section of sections) {
387
+ if (!section.isDirectory()) continue;
388
+ const sectionDir = path.join(codingDir, section.name);
389
+ const featureDirs = await fs.readdir(sectionDir, { withFileTypes: true }).catch(() => []);
390
+ for (const feature of featureDirs) {
391
+ if (!feature.isDirectory()) continue;
392
+ const docPath = path.join(sectionDir, feature.name, `${taskId}.md`);
393
+ if (await fs.pathExists(docPath)) results.push(docPath);
394
+ }
395
+ }
396
+ }
397
+
398
+ // Legacy convention: plan/<taskId>/
399
+ const legacyDir = path.join(PROJECT_DIR, 'plan', taskId);
400
+ if (await fs.pathExists(legacyDir)) {
401
+ const entries = await fs.readdir(legacyDir).catch(() => []);
402
+ for (const f of entries) results.push(path.join(legacyDir, f));
403
+ }
404
+
405
+ return results;
406
+ }
407
+
376
408
  async function deactivateOtherTasks(exceptTaskId) {
377
409
  if (!(await fs.pathExists(TASKS_DIR))) return;
378
410
  const entries = await fs.readdir(TASKS_DIR, { withFileTypes: true });
@@ -410,6 +442,21 @@ async function detectCurrentGate(taskId) {
410
442
  if (state.currentGate) return state.currentGate;
411
443
  }
412
444
 
445
+ // New convention: 04.Coding/<section>/<functionId>/<taskId>.md
446
+ const hasDocInSection = async (section) => {
447
+ const dir = path.join(PROJECT_DIR, '04.Coding', section);
448
+ if (!(await fs.pathExists(dir))) return false;
449
+ const features = await fs.readdir(dir, { withFileTypes: true }).catch(() => []);
450
+ for (const f of features) {
451
+ if (f.isDirectory() && await fs.pathExists(path.join(dir, f.name, `${taskId}.md`))) return true;
452
+ }
453
+ return false;
454
+ };
455
+ if (await hasDocInSection('04.Reviews')) return 5;
456
+ if (await hasDocInSection('02.Plans')) return 3;
457
+ if (await hasDocInSection('01.Requirements')) return 2;
458
+
459
+ // Legacy convention: plan/<taskId>/
413
460
  const planDir = path.join(PROJECT_DIR, 'plan', taskId);
414
461
  if (!(await fs.pathExists(planDir))) return 1;
415
462
  if (await fs.pathExists(path.join(planDir, 'summary.md'))) return 5;