planflow-plugin 0.1.1 → 0.1.2
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/commands/pfSyncPush/SKILL.md +177 -8
- package/commands/planFormatCheck/SKILL.md +346 -0
- package/commands/planSpec/SKILL.md +93 -31
- package/package.json +1 -1
|
@@ -193,22 +193,191 @@ echo "Tasks: $TASKS_COUNT, Completed: $COMPLETED_COUNT, Progress: $PROGRESS%"
|
|
|
193
193
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
194
194
|
```
|
|
195
195
|
|
|
196
|
-
**If tasksCount is 0 or null,
|
|
196
|
+
**If tasksCount is 0 or null, run automatic format validation (Step 3d):**
|
|
197
|
+
|
|
198
|
+
## Step 3d: Automatic Format Validation (if tasksCount is 0)
|
|
199
|
+
|
|
200
|
+
**CRITICAL: If no tasks were parsed, automatically validate and fix the format!**
|
|
201
|
+
|
|
202
|
+
When tasksCount is 0, you MUST:
|
|
203
|
+
|
|
204
|
+
1. **Read PROJECT_PLAN.md and scan for potential tasks**
|
|
205
|
+
2. **Check for common format issues**
|
|
206
|
+
3. **Offer to auto-fix if fixable**
|
|
207
|
+
|
|
208
|
+
### Format Detection Logic
|
|
209
|
+
|
|
210
|
+
```javascript
|
|
211
|
+
// Read the plan content
|
|
212
|
+
const planContent = readFile("PROJECT_PLAN.md")
|
|
213
|
+
|
|
214
|
+
// Check for tasks in various formats
|
|
215
|
+
const validHeaderFormat = /^#{2,4}\s*\*{0,2}T\d+[A-Za-z]?\.\d+\*{0,2}[:\s]+.+/gm
|
|
216
|
+
const validTableFormat = /\|\s*T\d+[A-Za-z]?\.\d+\s*\|/g
|
|
217
|
+
|
|
218
|
+
// Check for INVALID formats (common mistakes)
|
|
219
|
+
const wrongFormat1 = /^[-*]\s*T\d+[A-Za-z]?\.\d+[:\s]+.+/gm // Bullet list format
|
|
220
|
+
const wrongFormat2 = /^\d+\.\s*T\d+[A-Za-z]?\.\d+[:\s]+.+/gm // Numbered list format
|
|
221
|
+
const wrongFormat3 = /^T\d+[A-Za-z]?\.\d+[:\s]+.+/gm // No header prefix
|
|
222
|
+
|
|
223
|
+
const validTasks = (planContent.match(validHeaderFormat) || []).length +
|
|
224
|
+
(planContent.match(validTableFormat) || []).length
|
|
225
|
+
const invalidTasks = (planContent.match(wrongFormat1) || []).length +
|
|
226
|
+
(planContent.match(wrongFormat2) || []).length +
|
|
227
|
+
(planContent.match(wrongFormat3) || []).length
|
|
228
|
+
|
|
229
|
+
if (invalidTasks > 0 && validTasks === 0) {
|
|
230
|
+
// Tasks exist but in wrong format - offer to fix
|
|
231
|
+
showFormatFixCard()
|
|
232
|
+
} else if (validTasks === 0 && invalidTasks === 0) {
|
|
233
|
+
// No tasks at all
|
|
234
|
+
showNoTasksCard()
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### If wrong format detected, show fix offer card:
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
242
|
+
│ ⚠️ FORMAT ISSUE DETECTED │
|
|
243
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
244
|
+
│ │
|
|
245
|
+
│ Found {invalidTasks} tasks in incorrect format. │
|
|
246
|
+
│ │
|
|
247
|
+
│ ── Current Format (incorrect) ───────────────────────────────────────── │
|
|
248
|
+
│ │
|
|
249
|
+
│ - T1.1: Task Name ❌ Bullet list not supported │
|
|
250
|
+
│ 1. T1.2: Another Task ❌ Numbered list not supported │
|
|
251
|
+
│ T1.3: Direct task ❌ Missing header prefix │
|
|
252
|
+
│ │
|
|
253
|
+
│ ── Required Format ──────────────────────────────────────────────────── │
|
|
254
|
+
│ │
|
|
255
|
+
│ #### T1.1: Task Name ✅ Header format │
|
|
256
|
+
│ - [ ] **Status**: TODO │
|
|
257
|
+
│ - **Complexity**: Low │
|
|
258
|
+
│ - **Dependencies**: None │
|
|
259
|
+
│ │
|
|
260
|
+
│ OR table format: │
|
|
261
|
+
│ | ID | Task | Complexity | Status | Dependencies | │
|
|
262
|
+
│ |-------|-----------|------------|--------|--------------| │
|
|
263
|
+
│ | T1.1 | Task Name | Low | TODO | - | │
|
|
264
|
+
│ │
|
|
265
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
266
|
+
│ │
|
|
267
|
+
│ 🔧 Would you like me to auto-fix the format? │
|
|
268
|
+
│ │
|
|
269
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Use AskUserQuestion:**
|
|
273
|
+
```javascript
|
|
274
|
+
AskUserQuestion({
|
|
275
|
+
questions: [{
|
|
276
|
+
question: "Would you like me to convert tasks to the correct format?",
|
|
277
|
+
header: "Fix Format",
|
|
278
|
+
multiSelect: false,
|
|
279
|
+
options: [
|
|
280
|
+
{
|
|
281
|
+
label: "Yes, auto-fix (Recommended)",
|
|
282
|
+
description: "Convert all tasks to header format and re-sync"
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
label: "No, I'll fix manually",
|
|
286
|
+
description: "Keep current format, sync without tasks"
|
|
287
|
+
}
|
|
288
|
+
]
|
|
289
|
+
}]
|
|
290
|
+
})
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### If user chooses auto-fix:
|
|
294
|
+
|
|
295
|
+
**Convert tasks to correct format:**
|
|
296
|
+
|
|
297
|
+
```javascript
|
|
298
|
+
// Find all tasks in wrong format and convert
|
|
299
|
+
let fixedContent = planContent
|
|
300
|
+
|
|
301
|
+
// Convert bullet format: "- T1.1: Task" → "#### T1.1: Task\n- [ ] **Status**: TODO\n- **Complexity**: Medium\n- **Dependencies**: None"
|
|
302
|
+
fixedContent = fixedContent.replace(
|
|
303
|
+
/^[-*]\s*(T\d+[A-Za-z]?\.\d+)[:\s]+(.+)$/gm,
|
|
304
|
+
(match, taskId, taskName) => {
|
|
305
|
+
return `#### ${taskId}: ${taskName}
|
|
306
|
+
- [ ] **Status**: TODO
|
|
307
|
+
- **Complexity**: Medium
|
|
308
|
+
- **Dependencies**: None`
|
|
309
|
+
}
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
// Convert numbered format: "1. T1.1: Task" → header format
|
|
313
|
+
fixedContent = fixedContent.replace(
|
|
314
|
+
/^\d+\.\s*(T\d+[A-Za-z]?\.\d+)[:\s]+(.+)$/gm,
|
|
315
|
+
(match, taskId, taskName) => {
|
|
316
|
+
return `#### ${taskId}: ${taskName}
|
|
317
|
+
- [ ] **Status**: TODO
|
|
318
|
+
- **Complexity**: Medium
|
|
319
|
+
- **Dependencies**: None`
|
|
320
|
+
}
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
// Convert plain format: "T1.1: Task" → header format
|
|
324
|
+
fixedContent = fixedContent.replace(
|
|
325
|
+
/^(T\d+[A-Za-z]?\.\d+)[:\s]+(.+)$/gm,
|
|
326
|
+
(match, taskId, taskName) => {
|
|
327
|
+
return `#### ${taskId}: ${taskName}
|
|
328
|
+
- [ ] **Status**: TODO
|
|
329
|
+
- **Complexity**: Medium
|
|
330
|
+
- **Dependencies**: None`
|
|
331
|
+
}
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
// Write fixed content
|
|
335
|
+
writeFile("PROJECT_PLAN.md", fixedContent)
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**After fixing, re-push automatically:**
|
|
339
|
+
|
|
340
|
+
```
|
|
341
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
342
|
+
│ 🔧 FORMAT FIXED │
|
|
343
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
344
|
+
│ │
|
|
345
|
+
│ Converted {fixedCount} tasks to correct format. │
|
|
346
|
+
│ │
|
|
347
|
+
│ Re-syncing to cloud... │
|
|
348
|
+
│ │
|
|
349
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
Then repeat Step 3b (API call) with the fixed content.
|
|
353
|
+
|
|
354
|
+
### If no tasks found at all:
|
|
197
355
|
|
|
198
356
|
```
|
|
199
357
|
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
200
|
-
│ ⚠️
|
|
358
|
+
│ ⚠️ NO TASKS FOUND │
|
|
201
359
|
├──────────────────────────────────────────────────────────────────────────────┤
|
|
202
360
|
│ │
|
|
203
|
-
│
|
|
361
|
+
│ The plan was synced but no tasks were detected. │
|
|
362
|
+
│ │
|
|
363
|
+
│ Your plan may be missing the Tasks section. │
|
|
364
|
+
│ │
|
|
365
|
+
│ ── Expected Task Format ─────────────────────────────────────────────── │
|
|
366
|
+
│ │
|
|
367
|
+
│ ## Tasks & Implementation Plan │
|
|
204
368
|
│ │
|
|
205
|
-
│
|
|
206
|
-
│
|
|
207
|
-
│
|
|
208
|
-
│
|
|
369
|
+
│ ### Phase 1: Foundation │
|
|
370
|
+
│ │
|
|
371
|
+
│ #### T1.1: Setup Project │
|
|
372
|
+
│ - [ ] **Status**: TODO │
|
|
373
|
+
│ - **Complexity**: Low │
|
|
374
|
+
│ - **Dependencies**: None │
|
|
375
|
+
│ │
|
|
376
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
209
377
|
│ │
|
|
210
378
|
│ 💡 {t.ui.labels.nextSteps} │
|
|
211
|
-
│ • /
|
|
379
|
+
│ • /planNew Create a new plan with tasks │
|
|
380
|
+
│ • Manually add tasks in the format shown above │
|
|
212
381
|
│ │
|
|
213
382
|
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
214
383
|
```
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: planFormatCheck
|
|
3
|
+
description: Validate and fix PROJECT_PLAN.md task format
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Plan Format Check
|
|
7
|
+
|
|
8
|
+
Validate PROJECT_PLAN.md format and automatically fix any issues to ensure cloud sync compatibility.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
/planFormatCheck # Check format and show issues
|
|
14
|
+
/planFormatCheck --fix # Automatically fix format issues
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Step 0: Load Configuration
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
function getConfig() {
|
|
21
|
+
const localConfigPath = "./.plan-config.json"
|
|
22
|
+
let localConfig = {}
|
|
23
|
+
if (fileExists(localConfigPath)) {
|
|
24
|
+
try { localConfig = JSON.parse(readFile(localConfigPath)) } catch {}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const globalConfigPath = expandPath("~/.config/claude/plan-plugin-config.json")
|
|
28
|
+
let globalConfig = {}
|
|
29
|
+
if (fileExists(globalConfigPath)) {
|
|
30
|
+
try { globalConfig = JSON.parse(readFile(globalConfigPath)) } catch {}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return { ...globalConfig, ...localConfig }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const config = getConfig()
|
|
37
|
+
const language = config.language || "en"
|
|
38
|
+
const t = JSON.parse(readFile(`locales/${language}.json`))
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Step 1: Parse Arguments
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
const args = commandArgs.trim().split(/\s+/)
|
|
45
|
+
const autoFix = args.includes("--fix")
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Step 2: Read and Analyze Plan
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
// Check if PROJECT_PLAN.md exists
|
|
52
|
+
if (!fileExists("PROJECT_PLAN.md")) {
|
|
53
|
+
showNoPlanCard()
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const planContent = readFile("PROJECT_PLAN.md")
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Format Detection Patterns
|
|
61
|
+
|
|
62
|
+
```javascript
|
|
63
|
+
// VALID formats (will be parsed by API)
|
|
64
|
+
const validHeaderPattern = /^#{2,4}\s*\*{0,2}(T\d+[A-Za-z]?\.\d+)\*{0,2}[:\s]+(.+)/gm
|
|
65
|
+
const validTablePattern = /\|\s*(T\d+[A-Za-z]?\.\d+)\s*\|/g
|
|
66
|
+
|
|
67
|
+
// INVALID formats (won't be parsed)
|
|
68
|
+
const bulletPattern = /^[-*]\s*(T\d+[A-Za-z]?\.\d+)[:\s]+(.+)/gm
|
|
69
|
+
const numberedPattern = /^\d+\.\s*(T\d+[A-Za-z]?\.\d+)[:\s]+(.+)/gm
|
|
70
|
+
const plainPattern = /^(T\d+[A-Za-z]?\.\d+)[:\s]+([^|\n]+)$/gm
|
|
71
|
+
|
|
72
|
+
// Count tasks in each format
|
|
73
|
+
const validHeaderTasks = [...planContent.matchAll(validHeaderPattern)]
|
|
74
|
+
const validTableTasks = [...planContent.matchAll(validTablePattern)]
|
|
75
|
+
const bulletTasks = [...planContent.matchAll(bulletPattern)]
|
|
76
|
+
const numberedTasks = [...planContent.matchAll(numberedPattern)]
|
|
77
|
+
const plainTasks = [...planContent.matchAll(plainPattern)]
|
|
78
|
+
|
|
79
|
+
const totalValid = validHeaderTasks.length + validTableTasks.length
|
|
80
|
+
const totalInvalid = bulletTasks.length + numberedTasks.length + plainTasks.length
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Step 3: Show Analysis Results
|
|
84
|
+
|
|
85
|
+
### All formats valid - success card:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
89
|
+
│ ✅ FORMAT CHECK PASSED │
|
|
90
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
91
|
+
│ │
|
|
92
|
+
│ Your PROJECT_PLAN.md format is correct! │
|
|
93
|
+
│ │
|
|
94
|
+
│ ── Task Summary ─────────────────────────────────────────────────────── │
|
|
95
|
+
│ │
|
|
96
|
+
│ 📊 Total tasks found: {totalValid} │
|
|
97
|
+
│ 📝 Header format: {validHeaderTasks.length} │
|
|
98
|
+
│ 📋 Table format: {validTableTasks.length} │
|
|
99
|
+
│ │
|
|
100
|
+
│ ── Format Details ───────────────────────────────────────────────────── │
|
|
101
|
+
│ │
|
|
102
|
+
│ ✅ All tasks use valid format │
|
|
103
|
+
│ ✅ Ready for cloud sync │
|
|
104
|
+
│ │
|
|
105
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
106
|
+
│ │
|
|
107
|
+
│ 💡 Next Steps: │
|
|
108
|
+
│ • /pfSyncPush Push to cloud │
|
|
109
|
+
│ │
|
|
110
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Issues found - warning card:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
117
|
+
│ ⚠️ FORMAT ISSUES FOUND │
|
|
118
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
119
|
+
│ │
|
|
120
|
+
│ Found {totalInvalid} tasks in incorrect format. │
|
|
121
|
+
│ │
|
|
122
|
+
│ ── Current Status ───────────────────────────────────────────────────── │
|
|
123
|
+
│ │
|
|
124
|
+
│ ✅ Valid tasks: {totalValid} │
|
|
125
|
+
│ ❌ Invalid tasks: {totalInvalid} │
|
|
126
|
+
│ │
|
|
127
|
+
│ ── Issues Detected ──────────────────────────────────────────────────── │
|
|
128
|
+
│ │
|
|
129
|
+
│ {bulletTasks.length > 0 ? "• Bullet format (- T1.1: ...): " + bulletTasks.length + " tasks" : ""}
|
|
130
|
+
│ {numberedTasks.length > 0 ? "• Numbered format (1. T1.1: ...): " + numberedTasks.length + " tasks" : ""}
|
|
131
|
+
│ {plainTasks.length > 0 ? "• Plain format (T1.1: ...): " + plainTasks.length + " tasks" : ""}
|
|
132
|
+
│ │
|
|
133
|
+
│ ── Invalid Tasks ────────────────────────────────────────────────────── │
|
|
134
|
+
│ │
|
|
135
|
+
│ {Show first 5 invalid tasks as examples} │
|
|
136
|
+
│ │
|
|
137
|
+
│ ── Required Format ──────────────────────────────────────────────────── │
|
|
138
|
+
│ │
|
|
139
|
+
│ Header format: │
|
|
140
|
+
│ #### T1.1: Task Name │
|
|
141
|
+
│ - [ ] **Status**: TODO │
|
|
142
|
+
│ - **Complexity**: Low │
|
|
143
|
+
│ - **Dependencies**: None │
|
|
144
|
+
│ │
|
|
145
|
+
│ OR table format: │
|
|
146
|
+
│ | ID | Task | Complexity | Status | Deps | │
|
|
147
|
+
│ |------|-----------|------------|--------|------| │
|
|
148
|
+
│ | T1.1 | Task Name | Low | TODO | - | │
|
|
149
|
+
│ │
|
|
150
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
151
|
+
│ │
|
|
152
|
+
│ 💡 Next Steps: │
|
|
153
|
+
│ • /planFormatCheck --fix Auto-fix all issues │
|
|
154
|
+
│ • Fix manually using the format shown above │
|
|
155
|
+
│ │
|
|
156
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Step 4: Auto-Fix (if --fix flag)
|
|
160
|
+
|
|
161
|
+
If `--fix` flag is provided and there are invalid tasks:
|
|
162
|
+
|
|
163
|
+
### Convert all invalid formats to header format:
|
|
164
|
+
|
|
165
|
+
```javascript
|
|
166
|
+
let fixedContent = planContent
|
|
167
|
+
let fixedCount = 0
|
|
168
|
+
|
|
169
|
+
// Convert bullet format: "- T1.1: Task" → header format
|
|
170
|
+
fixedContent = fixedContent.replace(
|
|
171
|
+
/^([-*])\s*(T\d+[A-Za-z]?\.\d+)[:\s]+(.+)$/gm,
|
|
172
|
+
(match, bullet, taskId, taskName) => {
|
|
173
|
+
fixedCount++
|
|
174
|
+
return `#### ${taskId}: ${taskName.trim()}
|
|
175
|
+
- [ ] **Status**: TODO
|
|
176
|
+
- **Complexity**: Medium
|
|
177
|
+
- **Dependencies**: None`
|
|
178
|
+
}
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
// Convert numbered format: "1. T1.1: Task" → header format
|
|
182
|
+
fixedContent = fixedContent.replace(
|
|
183
|
+
/^(\d+)\.\s*(T\d+[A-Za-z]?\.\d+)[:\s]+(.+)$/gm,
|
|
184
|
+
(match, num, taskId, taskName) => {
|
|
185
|
+
fixedCount++
|
|
186
|
+
return `#### ${taskId}: ${taskName.trim()}
|
|
187
|
+
- [ ] **Status**: TODO
|
|
188
|
+
- **Complexity**: Medium
|
|
189
|
+
- **Dependencies**: None`
|
|
190
|
+
}
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
// Convert plain format: "T1.1: Task" → header format (only at line start, not in tables)
|
|
194
|
+
fixedContent = fixedContent.replace(
|
|
195
|
+
/^(T\d+[A-Za-z]?\.\d+)[:\s]+([^|\n]+)$/gm,
|
|
196
|
+
(match, taskId, taskName) => {
|
|
197
|
+
// Skip if this looks like it might be part of a table (has | nearby)
|
|
198
|
+
if (taskName.includes('|')) return match
|
|
199
|
+
fixedCount++
|
|
200
|
+
return `#### ${taskId}: ${taskName.trim()}
|
|
201
|
+
- [ ] **Status**: TODO
|
|
202
|
+
- **Complexity**: Medium
|
|
203
|
+
- **Dependencies**: None`
|
|
204
|
+
}
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
// Write fixed content
|
|
208
|
+
writeFile("PROJECT_PLAN.md", fixedContent)
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Show fix success card:
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
215
|
+
│ ✅ FORMAT FIXED │
|
|
216
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
217
|
+
│ │
|
|
218
|
+
│ Successfully converted {fixedCount} tasks to correct format! │
|
|
219
|
+
│ │
|
|
220
|
+
│ ── Changes Made ─────────────────────────────────────────────────────── │
|
|
221
|
+
│ │
|
|
222
|
+
│ • Converted bullet format tasks to header format │
|
|
223
|
+
│ • Converted numbered list tasks to header format │
|
|
224
|
+
│ • Converted plain format tasks to header format │
|
|
225
|
+
│ • Added Status, Complexity, and Dependencies fields │
|
|
226
|
+
│ │
|
|
227
|
+
│ ── Before → After ───────────────────────────────────────────────────── │
|
|
228
|
+
│ │
|
|
229
|
+
│ BEFORE: │
|
|
230
|
+
│ - T1.1: Setup project │
|
|
231
|
+
│ │
|
|
232
|
+
│ AFTER: │
|
|
233
|
+
│ #### T1.1: Setup project │
|
|
234
|
+
│ - [ ] **Status**: TODO │
|
|
235
|
+
│ - **Complexity**: Medium │
|
|
236
|
+
│ - **Dependencies**: None │
|
|
237
|
+
│ │
|
|
238
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
239
|
+
│ │
|
|
240
|
+
│ 💡 Next Steps: │
|
|
241
|
+
│ • Review the changes in PROJECT_PLAN.md │
|
|
242
|
+
│ • Update Status/Complexity/Dependencies as needed │
|
|
243
|
+
│ • /pfSyncPush Push to cloud │
|
|
244
|
+
│ │
|
|
245
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Error Handling
|
|
249
|
+
|
|
250
|
+
### No PROJECT_PLAN.md found:
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
254
|
+
│ ❌ ERROR │
|
|
255
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
256
|
+
│ │
|
|
257
|
+
│ No PROJECT_PLAN.md found in current directory. │
|
|
258
|
+
│ │
|
|
259
|
+
│ 💡 Next Steps: │
|
|
260
|
+
│ • /planNew Create a new project plan │
|
|
261
|
+
│ • cd to your project directory and try again │
|
|
262
|
+
│ │
|
|
263
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### No tasks found at all:
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
270
|
+
│ ⚠️ NO TASKS FOUND │
|
|
271
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
272
|
+
│ │
|
|
273
|
+
│ No tasks were found in PROJECT_PLAN.md. │
|
|
274
|
+
│ │
|
|
275
|
+
│ Your plan may be missing the Tasks section entirely. │
|
|
276
|
+
│ │
|
|
277
|
+
│ ── Add Tasks Using This Format ──────────────────────────────────────── │
|
|
278
|
+
│ │
|
|
279
|
+
│ ## Tasks & Implementation Plan │
|
|
280
|
+
│ │
|
|
281
|
+
│ ### Phase 1: Foundation │
|
|
282
|
+
│ │
|
|
283
|
+
│ #### T1.1: Setup Project │
|
|
284
|
+
│ - [ ] **Status**: TODO │
|
|
285
|
+
│ - **Complexity**: Low │
|
|
286
|
+
│ - **Dependencies**: None │
|
|
287
|
+
│ - **Description**: │
|
|
288
|
+
│ - Initialize the project structure │
|
|
289
|
+
│ - Configure development tools │
|
|
290
|
+
│ │
|
|
291
|
+
│ #### T1.2: Configure Database │
|
|
292
|
+
│ - [ ] **Status**: TODO │
|
|
293
|
+
│ - **Complexity**: Medium │
|
|
294
|
+
│ - **Dependencies**: T1.1 │
|
|
295
|
+
│ │
|
|
296
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
297
|
+
│ │
|
|
298
|
+
│ 💡 Next Steps: │
|
|
299
|
+
│ • /planNew Create a new plan with tasks │
|
|
300
|
+
│ • Add tasks manually in the format shown above │
|
|
301
|
+
│ │
|
|
302
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Valid Format Reference
|
|
306
|
+
|
|
307
|
+
### Header Format (Preferred)
|
|
308
|
+
|
|
309
|
+
```markdown
|
|
310
|
+
#### T1.1: Task Name
|
|
311
|
+
- [ ] **Status**: TODO
|
|
312
|
+
- **Complexity**: Low
|
|
313
|
+
- **Estimated**: 2 hours
|
|
314
|
+
- **Dependencies**: None
|
|
315
|
+
- **Description**:
|
|
316
|
+
- Detail 1
|
|
317
|
+
- Detail 2
|
|
318
|
+
|
|
319
|
+
#### T1.2: Another Task
|
|
320
|
+
- [x] **Status**: DONE
|
|
321
|
+
- **Complexity**: Medium
|
|
322
|
+
- **Dependencies**: T1.1
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Status values: `TODO`, `IN_PROGRESS`, `DONE`, `BLOCKED`
|
|
326
|
+
Complexity values: `Low`, `Medium`, `High`
|
|
327
|
+
|
|
328
|
+
### Table Format (Alternative)
|
|
329
|
+
|
|
330
|
+
```markdown
|
|
331
|
+
| ID | Task | Complexity | Status | Dependencies |
|
|
332
|
+
|-------|----------------|------------|--------|--------------|
|
|
333
|
+
| T1.1 | Setup Project | Low | TODO | - |
|
|
334
|
+
| T1.2 | Add Database | Medium | TODO | T1.1 |
|
|
335
|
+
| T1.3 | Create API | High | TODO | T1.1, T1.2 |
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Task ID Format
|
|
339
|
+
|
|
340
|
+
Valid task IDs:
|
|
341
|
+
- `T1.1`, `T1.2`, `T2.1` - Standard format
|
|
342
|
+
- `T5A.1`, `T5A.2`, `T5B.1` - Sub-phase format
|
|
343
|
+
- `T10.1`, `T10.15` - Multi-digit phases
|
|
344
|
+
|
|
345
|
+
Invalid task IDs:
|
|
346
|
+
- `Task1`, `T-1.1`, `T1-1` - Wrong format
|
|
@@ -694,60 +694,122 @@ try {
|
|
|
694
694
|
```
|
|
695
695
|
|
|
696
696
|
**Task generation from features:**
|
|
697
|
+
|
|
698
|
+
**CRITICAL: Use this EXACT markdown format for each task!**
|
|
699
|
+
|
|
700
|
+
```markdown
|
|
701
|
+
#### T{phase}.{num}: {Task Name}
|
|
702
|
+
- [ ] **Status**: TODO
|
|
703
|
+
- **Complexity**: Low/Medium/High
|
|
704
|
+
- **Dependencies**: None (or T1.1, T1.2)
|
|
705
|
+
- **Description**:
|
|
706
|
+
- Detail from specification
|
|
707
|
+
- Implementation notes
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
**Example generated tasks:**
|
|
711
|
+
|
|
712
|
+
```markdown
|
|
713
|
+
#### T2.1: Implement User Authentication
|
|
714
|
+
- [ ] **Status**: TODO
|
|
715
|
+
- **Complexity**: High
|
|
716
|
+
- **Dependencies**: T1.2
|
|
717
|
+
- **Description**:
|
|
718
|
+
- Setup JWT authentication
|
|
719
|
+
- Implement login/register endpoints
|
|
720
|
+
- Add password hashing
|
|
721
|
+
|
|
722
|
+
#### T2.2: Create User Dashboard
|
|
723
|
+
- [ ] **Status**: TODO
|
|
724
|
+
- **Complexity**: Medium
|
|
725
|
+
- **Dependencies**: T2.1
|
|
726
|
+
- **Description**:
|
|
727
|
+
- Build dashboard layout
|
|
728
|
+
- Display user statistics
|
|
729
|
+
- Add navigation menu
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
**Pseudo-code for task generation:**
|
|
697
733
|
```javascript
|
|
734
|
+
function generateTaskMarkdown(taskId, name, complexity, dependencies, description) {
|
|
735
|
+
const depStr = dependencies.length > 0 ? dependencies.join(", ") : "None"
|
|
736
|
+
const descLines = description.map(d => ` - ${d}`).join("\n")
|
|
737
|
+
|
|
738
|
+
return `#### ${taskId}: ${name}
|
|
739
|
+
- [ ] **Status**: TODO
|
|
740
|
+
- **Complexity**: ${complexity}
|
|
741
|
+
- **Dependencies**: ${depStr}
|
|
742
|
+
- **Description**:
|
|
743
|
+
${descLines}`
|
|
744
|
+
}
|
|
745
|
+
|
|
698
746
|
function generateTasks(features, phase) {
|
|
699
747
|
const tasks = []
|
|
700
748
|
let taskNum = 1
|
|
701
749
|
|
|
702
750
|
for (const feature of features) {
|
|
703
|
-
// Simple feature → 1 task
|
|
704
|
-
// Complex feature → 2-3 tasks
|
|
705
|
-
|
|
706
751
|
const complexity = estimateComplexity(feature)
|
|
707
752
|
|
|
708
753
|
if (complexity === "High") {
|
|
709
754
|
// Split into multiple tasks
|
|
710
|
-
tasks.push(
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
755
|
+
tasks.push(generateTaskMarkdown(
|
|
756
|
+
`T${phase}.${taskNum}`,
|
|
757
|
+
`Setup ${feature.name}`,
|
|
758
|
+
"Medium",
|
|
759
|
+
taskNum > 1 ? [`T${phase}.${taskNum-1}`] : [],
|
|
760
|
+
["Initialize component structure", "Setup dependencies"]
|
|
761
|
+
))
|
|
716
762
|
taskNum++
|
|
717
763
|
|
|
718
|
-
tasks.push(
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
764
|
+
tasks.push(generateTaskMarkdown(
|
|
765
|
+
`T${phase}.${taskNum}`,
|
|
766
|
+
`Implement ${feature.name} core logic`,
|
|
767
|
+
"High",
|
|
768
|
+
[`T${phase}.${taskNum-1}`],
|
|
769
|
+
["Implement business logic", "Add validation", "Handle edge cases"]
|
|
770
|
+
))
|
|
725
771
|
taskNum++
|
|
726
772
|
|
|
727
|
-
tasks.push(
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
773
|
+
tasks.push(generateTaskMarkdown(
|
|
774
|
+
`T${phase}.${taskNum}`,
|
|
775
|
+
`${feature.name} UI and integration`,
|
|
776
|
+
"Medium",
|
|
777
|
+
[`T${phase}.${taskNum-1}`],
|
|
778
|
+
["Build UI components", "Connect to backend", "Add error handling"]
|
|
779
|
+
))
|
|
734
780
|
taskNum++
|
|
735
781
|
} else {
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
782
|
+
tasks.push(generateTaskMarkdown(
|
|
783
|
+
`T${phase}.${taskNum}`,
|
|
784
|
+
`Implement ${feature.name}`,
|
|
785
|
+
complexity,
|
|
786
|
+
[],
|
|
787
|
+
feature.description ? [feature.description] : ["Implement feature as specified"]
|
|
788
|
+
))
|
|
743
789
|
taskNum++
|
|
744
790
|
}
|
|
745
791
|
}
|
|
746
792
|
|
|
747
|
-
return tasks
|
|
793
|
+
return tasks.join("\n\n")
|
|
748
794
|
}
|
|
749
795
|
```
|
|
750
796
|
|
|
797
|
+
**IMPORTANT: Never use these WRONG formats:**
|
|
798
|
+
```markdown
|
|
799
|
+
❌ - T2.1: Task Name (bullet format - won't parse)
|
|
800
|
+
❌ 1. T2.1: Task Name (numbered format - won't parse)
|
|
801
|
+
❌ T2.1: Task Name (plain format - won't parse)
|
|
802
|
+
❌ ## T2.1: Task Name (wrong header level)
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
**Always use this CORRECT format:**
|
|
806
|
+
```markdown
|
|
807
|
+
✅ #### T2.1: Task Name
|
|
808
|
+
✅ - [ ] **Status**: TODO
|
|
809
|
+
✅ - **Complexity**: Medium
|
|
810
|
+
✅ - **Dependencies**: T2.0
|
|
811
|
+
```
|
|
812
|
+
|
|
751
813
|
**Write the file:**
|
|
752
814
|
```javascript
|
|
753
815
|
const outputPath = `./${outputFileName}`
|