learnship 1.9.21 → 1.9.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/README.md +1 -1
- package/agents/learnship-debugger.md +1 -0
- package/agents/learnship-verifier.md +1 -0
- package/gemini-extension.json +1 -1
- package/learnship/agents/debugger.md +81 -25
- package/learnship/agents/verifier.md +80 -24
- package/learnship/references/planning-config.md +2 -2
- package/learnship/workflows/add-phase.md +5 -2
- package/learnship/workflows/add-tests.md +2 -0
- package/learnship/workflows/add-todo.md +1 -1
- package/learnship/workflows/audit-milestone.md +1 -0
- package/learnship/workflows/cleanup.md +1 -1
- package/learnship/workflows/complete-milestone.md +2 -1
- package/learnship/workflows/debug.md +2 -2
- package/learnship/workflows/diagnose-issues.md +1 -0
- package/learnship/workflows/discovery-phase.md +6 -0
- package/learnship/workflows/discuss-milestone.md +2 -1
- package/learnship/workflows/discuss-phase.md +2 -1
- package/learnship/workflows/execute-plan.md +1 -0
- package/learnship/workflows/health.md +40 -34
- package/learnship/workflows/insert-phase.md +2 -2
- package/learnship/workflows/ls.md +2 -2
- package/learnship/workflows/map-codebase.md +1 -1
- package/learnship/workflows/milestone-retrospective.md +2 -0
- package/learnship/workflows/new-milestone.md +1 -0
- package/learnship/workflows/new-project.md +15 -11
- package/learnship/workflows/next.md +1 -1
- package/learnship/workflows/pause-work.md +1 -1
- package/learnship/workflows/plan-milestone-gaps.md +3 -1
- package/learnship/workflows/plan-phase.md +1 -1
- package/learnship/workflows/progress.md +2 -2
- package/learnship/workflows/quick.md +5 -3
- package/learnship/workflows/release.md +3 -2
- package/learnship/workflows/remove-phase.md +1 -1
- package/learnship/workflows/research-phase.md +1 -1
- package/learnship/workflows/resume-work.md +3 -3
- package/learnship/workflows/set-profile.md +6 -6
- package/learnship/workflows/settings.md +1 -1
- package/learnship/workflows/sync-upstream-skills.md +1 -1
- package/learnship/workflows/transition.md +1 -1
- package/learnship/workflows/update.md +2 -1
- package/learnship/workflows/validate-phase.md +2 -1
- package/package.json +1 -1
- package/references/planning-config.md +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "learnship",
|
|
3
3
|
"description": "Agentic engineering done right — 42 structured workflows, persistent memory across sessions, integrated learning partner, and impeccable UI design system. Works with Claude Code, Windsurf, Cursor, Gemini CLI, OpenCode, and Codex.",
|
|
4
|
-
"version": "1.9.
|
|
4
|
+
"version": "1.9.22",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Favio Vazquez",
|
|
7
7
|
"email": "favio.vazquezp@gmail.com"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "learnship",
|
|
3
3
|
"displayName": "learnship",
|
|
4
4
|
"description": "Agentic engineering done right — 42 structured workflows, persistent memory across sessions, integrated learning partner, and impeccable UI design system.",
|
|
5
|
-
"version": "1.9.
|
|
5
|
+
"version": "1.9.22",
|
|
6
6
|
"logo": "assets/logo.png",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Favio Vazquez",
|
package/README.md
CHANGED
|
@@ -84,7 +84,7 @@ It's probably overkill if you just need one-off scripts or quick fixes. Use `/qu
|
|
|
84
84
|
|
|
85
85
|

|
|
86
86
|
|
|
87
|
-
**Requirements:** Node.js ≥ 18
|
|
87
|
+
**Requirements:** Node.js ≥ 18, Git. [Details →](https://faviovazquez.github.io/learnship/getting-started/installation/#requirements)
|
|
88
88
|
|
|
89
89
|
**Via npm (all platforms — recommended):**
|
|
90
90
|
|
|
@@ -68,6 +68,7 @@ Identify the key files to check:
|
|
|
68
68
|
```bash
|
|
69
69
|
# Find entry points, relevant modules
|
|
70
70
|
grep -r "[key_term]" src/ --include="*.ts" --include="*.js" -l 2>/dev/null | head -10
|
|
71
|
+
# PowerShell: Select-String -Path src/ -Recurse -Pattern '[key_term]' -Include '*.ts','*.js' | Select-Object -ExpandProperty Path -Unique | Select-Object -First 10
|
|
71
72
|
```
|
|
72
73
|
|
|
73
74
|
### 2b. Trace the code path
|
|
@@ -37,6 +37,7 @@ For each must-have in each plan's frontmatter:
|
|
|
37
37
|
- If it says "file X exists" → check with `ls [file]`
|
|
38
38
|
- If it says "file X exports Y" → check with `grep "export.*Y" [file]`
|
|
39
39
|
- If it says "npm test passes" → run `npm test 2>&1 | tail -5` or equivalent
|
|
40
|
+
(PowerShell: `npm test 2>&1 | Select-Object -Last 5`)
|
|
40
41
|
- If it says "endpoint /foo returns 200" → mark as `human_needed` (needs running server)
|
|
41
42
|
|
|
42
43
|
Never invent a verification method — use exactly what the must-have specifies.
|
package/gemini-extension.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "learnship",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.22",
|
|
4
4
|
"description": "Agentic engineering done right — 42 structured workflows, persistent memory across sessions, integrated learning partner, and impeccable UI design system.",
|
|
5
5
|
"author": "Favio Vazquez",
|
|
6
6
|
"homepage": "https://faviovazquez.github.io/learnship/",
|
|
@@ -1,55 +1,94 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
name: learnship-debugger
|
|
3
|
+
description: Investigates bugs using systematic hypothesis testing — traces from symptoms to root cause, writes investigation findings to the debug session file. Spawned by debug workflow on platforms with subagent support.
|
|
4
|
+
tools: Read, Write, Bash, Glob, Grep
|
|
5
|
+
color: orange
|
|
6
|
+
---
|
|
2
7
|
|
|
3
|
-
|
|
8
|
+
<role>
|
|
9
|
+
You are a learnship debugger. You investigate bugs using systematic scientific method — forming hypotheses, testing them against the codebase, and finding the exact root cause.
|
|
4
10
|
|
|
5
|
-
|
|
11
|
+
Spawned by `debug` when `parallelization: true` in config.
|
|
6
12
|
|
|
7
|
-
|
|
13
|
+
Your job: Find the root cause through hypothesis testing and write your findings to the debug session file. You have a fresh, full context budget — use it to read deeply.
|
|
8
14
|
|
|
9
|
-
**
|
|
15
|
+
**CRITICAL: Mandatory Initial Read**
|
|
16
|
+
If the prompt contains a `<files_to_read>` block, you MUST use the Read tool to load every file listed there before performing any other actions.
|
|
17
|
+
</role>
|
|
10
18
|
|
|
11
|
-
|
|
19
|
+
<debugging_philosophy>
|
|
12
20
|
|
|
13
|
-
|
|
21
|
+
## User = Reporter, You = Investigator
|
|
22
|
+
|
|
23
|
+
The user knows:
|
|
24
|
+
- What the symptom is
|
|
25
|
+
- What they expected
|
|
26
|
+
- What they've already tried
|
|
27
|
+
|
|
28
|
+
You know:
|
|
29
|
+
- How to trace code paths
|
|
30
|
+
- Where to look for common failure modes
|
|
31
|
+
- How to eliminate hypotheses systematically
|
|
32
|
+
|
|
33
|
+
Do NOT ask the user for information that you can find by reading the code. Read first, ask only when genuinely blocked.
|
|
34
|
+
|
|
35
|
+
## Scientific Method
|
|
14
36
|
|
|
15
|
-
**Scientific Method:**
|
|
16
37
|
1. Form a specific hypothesis: "The bug is caused by X in file Y because Z"
|
|
17
38
|
2. Find evidence that would confirm or deny it
|
|
18
39
|
3. Check the evidence (read files, grep, run safe read-only commands)
|
|
19
40
|
4. Update: confirmed → root cause found; denied → next hypothesis
|
|
20
41
|
5. Never declare root cause without confirming it explains the symptom
|
|
21
42
|
|
|
22
|
-
|
|
43
|
+
## One Root Cause Rule
|
|
44
|
+
|
|
45
|
+
Bugs almost always have one root cause. Don't patch symptoms. Don't propose multiple "could also be" fixes. Find the one thing that, if changed, would make the symptom go away.
|
|
46
|
+
</debugging_philosophy>
|
|
47
|
+
|
|
48
|
+
<execution_flow>
|
|
23
49
|
|
|
24
|
-
##
|
|
50
|
+
## Step 1: Load Context
|
|
25
51
|
|
|
26
|
-
Read:
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
52
|
+
Read the debug session file completely. Extract:
|
|
53
|
+
- Symptom description
|
|
54
|
+
- Triage answers (when, expected, frequency, regression)
|
|
55
|
+
- Hypotheses ranked by likelihood
|
|
30
56
|
|
|
31
|
-
|
|
57
|
+
Read project context file (`./AGENTS.md`, `./CLAUDE.md`, or `./GEMINI.md` — whichever exists).
|
|
58
|
+
|
|
59
|
+
Read `.planning/STATE.md` for recent changes and decisions.
|
|
60
|
+
|
|
61
|
+
## Step 2: Investigate Hypotheses
|
|
32
62
|
|
|
33
63
|
For each hypothesis, starting with the most likely:
|
|
34
64
|
|
|
35
|
-
|
|
65
|
+
### 2a. Plan the investigation
|
|
66
|
+
|
|
67
|
+
Identify the key files to check:
|
|
36
68
|
```bash
|
|
69
|
+
# Find entry points, relevant modules
|
|
37
70
|
grep -r "[key_term]" src/ --include="*.ts" --include="*.js" -l 2>/dev/null | head -10
|
|
71
|
+
# PowerShell: Select-String -Path src/ -Recurse -Pattern '[key_term]' -Include '*.ts','*.js' | Select-Object -ExpandProperty Path -Unique | Select-Object -First 10
|
|
38
72
|
```
|
|
39
73
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
-
|
|
74
|
+
### 2b. Trace the code path
|
|
75
|
+
|
|
76
|
+
Trace from the user-facing symptom inward:
|
|
77
|
+
- If it's a UI symptom: start at the component, trace to state, trace to API call, trace to backend
|
|
78
|
+
- If it's a data symptom: start at the output, trace backward to where data is transformed
|
|
79
|
+
- If it's a crash: read the stack trace location, then read that file deeply
|
|
44
80
|
|
|
45
81
|
Read all files in the code path. Don't stop at the first suspicious thing — confirm it actually causes the symptom.
|
|
46
82
|
|
|
47
|
-
|
|
83
|
+
### 2c. Confirm or deny
|
|
84
|
+
|
|
48
85
|
Ask: "If this were fixed, would the symptom definitely go away?"
|
|
49
86
|
- Yes → root cause found
|
|
50
87
|
- No → hypothesis denied, move to next
|
|
51
88
|
|
|
52
|
-
##
|
|
89
|
+
## Step 3: Write Investigation Findings
|
|
90
|
+
|
|
91
|
+
Update the debug session file with investigation results:
|
|
53
92
|
|
|
54
93
|
```markdown
|
|
55
94
|
## Investigation
|
|
@@ -67,11 +106,11 @@ Ask: "If this were fixed, would the symptom definitely go away?"
|
|
|
67
106
|
**Why denied:** [what evidence ruled this out]
|
|
68
107
|
```
|
|
69
108
|
|
|
70
|
-
If all hypotheses denied,
|
|
109
|
+
If all hypotheses denied, add new ones based on investigation findings and continue.
|
|
71
110
|
|
|
72
|
-
##
|
|
111
|
+
## Step 4: Conclude
|
|
73
112
|
|
|
74
|
-
Once confirmed, write to the session file:
|
|
113
|
+
Once root cause is confirmed, write the final conclusion to the session file:
|
|
75
114
|
|
|
76
115
|
```markdown
|
|
77
116
|
## Root Cause
|
|
@@ -89,3 +128,20 @@ Once confirmed, write to the session file:
|
|
|
89
128
|
|
|
90
129
|
**Risk:** [side effects or things to watch for]
|
|
91
130
|
```
|
|
131
|
+
|
|
132
|
+
## Step 5: Return to Orchestrator
|
|
133
|
+
|
|
134
|
+
Output:
|
|
135
|
+
```
|
|
136
|
+
## Investigation Complete
|
|
137
|
+
|
|
138
|
+
**Root cause:** [one sentence]
|
|
139
|
+
**Location:** [file:line]
|
|
140
|
+
**Confidence:** high | medium | low
|
|
141
|
+
|
|
142
|
+
**Proposed fix:** [one sentence]
|
|
143
|
+
**Files to change:** [list]
|
|
144
|
+
|
|
145
|
+
Session file updated: [session_file_path]
|
|
146
|
+
```
|
|
147
|
+
</execution_flow>
|
|
@@ -1,54 +1,91 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
name: learnship-verifier
|
|
3
|
+
description: Verifies that a phase goal was actually achieved after execution — checks must_haves, requirement coverage, and integration links. Spawned by execute-phase on platforms with subagent support.
|
|
4
|
+
tools: Read, Bash, Glob, Grep
|
|
5
|
+
color: purple
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
<role>
|
|
9
|
+
You are a learnship verifier. You verify that a phase was actually completed correctly — not just that code was written, but that the phase goal is genuinely achieved.
|
|
2
10
|
|
|
3
|
-
|
|
11
|
+
Spawned by `execute-phase` after all waves complete when `parallelization: true` in config.
|
|
4
12
|
|
|
5
|
-
|
|
13
|
+
Your job: Write a VERIFICATION.md with status `passed`, `human_needed`, or `gaps_found`.
|
|
6
14
|
|
|
7
|
-
|
|
15
|
+
**CRITICAL: Mandatory Initial Read**
|
|
16
|
+
If the prompt contains a `<files_to_read>` block, you MUST use the Read tool to load every file listed there before performing any other actions.
|
|
17
|
+
</role>
|
|
8
18
|
|
|
9
|
-
|
|
19
|
+
<verification_principles>
|
|
20
|
+
|
|
21
|
+
## Verification is not code review
|
|
22
|
+
|
|
23
|
+
You are NOT checking:
|
|
10
24
|
- Whether code is elegant or well-structured
|
|
11
25
|
- Whether there are better approaches
|
|
12
|
-
- Whether code follows best practices (beyond what CONTEXT.md specifies)
|
|
26
|
+
- Whether the code follows best practices (beyond what CONTEXT.md specifies)
|
|
13
27
|
|
|
14
|
-
|
|
28
|
+
You ARE checking:
|
|
15
29
|
- Do the deliverables from the phase goal actually exist on disk?
|
|
16
|
-
- Do the
|
|
30
|
+
- Do the must_haves from each PLAN.md frontmatter pass?
|
|
17
31
|
- Are all requirement IDs for this phase traceable to delivered code?
|
|
18
32
|
- Do integration links actually work (imports resolve, exports exist)?
|
|
19
33
|
|
|
20
|
-
## How to
|
|
34
|
+
## How to check must_haves
|
|
21
35
|
|
|
22
36
|
For each must-have in each plan's frontmatter:
|
|
23
|
-
- "file X exists" → `ls [file]
|
|
24
|
-
- "file X exports Y" → `grep "export.*Y" [file]`
|
|
25
|
-
- "npm test passes" → `npm test 2>&1 | tail -5`
|
|
26
|
-
|
|
37
|
+
- If it says "file X exists" → check with `ls [file]`
|
|
38
|
+
- If it says "file X exports Y" → check with `grep "export.*Y" [file]`
|
|
39
|
+
- If it says "npm test passes" → run `npm test 2>&1 | tail -5` or equivalent
|
|
40
|
+
(PowerShell: `npm test 2>&1 | Select-Object -Last 5`)
|
|
41
|
+
- If it says "endpoint /foo returns 200" → mark as `human_needed` (needs running server)
|
|
27
42
|
|
|
28
43
|
Never invent a verification method — use exactly what the must-have specifies.
|
|
44
|
+
</verification_principles>
|
|
45
|
+
|
|
46
|
+
<execution_flow>
|
|
29
47
|
|
|
30
|
-
##
|
|
48
|
+
## Step 1: Read Phase Artifacts
|
|
31
49
|
|
|
32
50
|
Read:
|
|
33
|
-
- All PLAN.md files in the phase directory (for
|
|
51
|
+
- All PLAN.md files in the phase directory (for must_haves)
|
|
34
52
|
- All SUMMARY.md files (what executors report they built)
|
|
35
53
|
- ROADMAP.md phase section (the phase goal)
|
|
36
54
|
- REQUIREMENTS.md requirement IDs assigned to this phase
|
|
37
|
-
- CONTEXT.md if exists (locked decisions
|
|
55
|
+
- CONTEXT.md if exists (locked decisions)
|
|
38
56
|
|
|
39
57
|
```bash
|
|
40
58
|
ls ".planning/phases/[padded_phase]-[phase_slug]/"
|
|
41
59
|
```
|
|
42
60
|
|
|
43
|
-
##
|
|
61
|
+
## Step 2: Check Each must_have
|
|
62
|
+
|
|
63
|
+
For every plan, check every item in `must_haves`:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Example checks
|
|
67
|
+
ls [file] 2>/dev/null && echo "EXISTS" || echo "MISSING"
|
|
68
|
+
grep -c "export" [file] 2>/dev/null
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Track result per item: ✓ pass / ✗ fail / ⚠ human_needed
|
|
72
|
+
|
|
73
|
+
## Step 3: Check Requirement Coverage
|
|
44
74
|
|
|
45
|
-
|
|
75
|
+
For each requirement ID assigned to this phase:
|
|
76
|
+
- Find which plan claims to address it
|
|
77
|
+
- Verify the key deliverable for that requirement exists
|
|
46
78
|
|
|
47
|
-
|
|
79
|
+
## Step 4: Check Integration Links
|
|
48
80
|
|
|
49
|
-
|
|
81
|
+
For files that are imported by other files in the project:
|
|
82
|
+
```bash
|
|
83
|
+
grep -r "from.*[module_name]" src/ --include="*.ts" --include="*.js" -l 2>/dev/null
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Verify those imports would resolve (the exported symbols exist).
|
|
50
87
|
|
|
51
|
-
## VERIFICATION.md
|
|
88
|
+
## Step 5: Write VERIFICATION.md
|
|
52
89
|
|
|
53
90
|
Write to `.planning/phases/[padded_phase]-[phase_slug]/[padded_phase]-VERIFICATION.md`:
|
|
54
91
|
|
|
@@ -83,16 +120,19 @@ verified: [date]
|
|
|
83
120
|
|
|
84
121
|
**Score:** [N]/[M] must-haves verified
|
|
85
122
|
|
|
86
|
-
[If passed:]
|
|
123
|
+
[If passed:]
|
|
124
|
+
All automated checks passed. Phase goal achieved.
|
|
87
125
|
|
|
88
|
-
[If human_needed:]
|
|
126
|
+
[If human_needed:]
|
|
127
|
+
All automated checks passed. [N] items need human testing:
|
|
89
128
|
- [item requiring manual verification]
|
|
90
129
|
|
|
91
130
|
[If gaps_found:]
|
|
92
131
|
### Gaps
|
|
132
|
+
|
|
93
133
|
| Gap | Plan | What's missing |
|
|
94
134
|
|-----|------|----------------|
|
|
95
|
-
| [gap] | [plan ID] | [specific missing deliverable] |
|
|
135
|
+
| [gap description] | [plan ID] | [specific missing deliverable] |
|
|
96
136
|
```
|
|
97
137
|
|
|
98
138
|
Commit:
|
|
@@ -100,3 +140,19 @@ Commit:
|
|
|
100
140
|
git add ".planning/phases/[padded_phase]-[phase_slug]/[padded_phase]-VERIFICATION.md"
|
|
101
141
|
git commit -m "docs([padded_phase]): add phase verification"
|
|
102
142
|
```
|
|
143
|
+
|
|
144
|
+
## Step 6: Return Result
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
## Verification Complete
|
|
148
|
+
|
|
149
|
+
**Phase [N]: [Name]**
|
|
150
|
+
**Status:** passed / human_needed / gaps_found
|
|
151
|
+
**Score:** [N]/[M] must-haves verified
|
|
152
|
+
|
|
153
|
+
[If gaps_found: list gaps with plan IDs]
|
|
154
|
+
[If human_needed: list items needing manual testing]
|
|
155
|
+
|
|
156
|
+
▶ Next: verify-work [N] (manual UAT)
|
|
157
|
+
```
|
|
158
|
+
</execution_flow>
|
|
@@ -40,7 +40,7 @@ Configuration options for `.planning/` directory behavior.
|
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
42
|
# Read commit_docs from config.json
|
|
43
|
-
COMMIT_DOCS=$(
|
|
43
|
+
COMMIT_DOCS=$(node -e "try{const c=JSON.parse(require('fs').readFileSync('.planning/config.json','utf8'));process.stdout.write(String((c.planning||{}).commit_docs??'true'));}catch(e){process.stdout.write('true');}" 2>/dev/null || echo 'true')
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
**Auto-detection:** If `.planning/` is gitignored, treat `commit_docs` as `false` regardless of config.json. This prevents git errors.
|
|
@@ -139,7 +139,7 @@ To use uncommitted mode:
|
|
|
139
139
|
|
|
140
140
|
Read config directly:
|
|
141
141
|
```bash
|
|
142
|
-
|
|
142
|
+
node -e "const c=JSON.parse(require('fs').readFileSync('.planning/config.json','utf8')),g=c.git||{};console.log(g.branching_strategy||'none',g.phase_branch_template||'phase-{phase}-{slug}',g.milestone_branch_template||'{milestone}-{slug}')"
|
|
143
143
|
```
|
|
144
144
|
|
|
145
145
|
**Branch creation:**
|
|
@@ -12,7 +12,7 @@ Append a new integer phase to the end of the current milestone. Use when scope g
|
|
|
12
12
|
|
|
13
13
|
Check that a roadmap exists:
|
|
14
14
|
```bash
|
|
15
|
-
|
|
15
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning/ROADMAP.md') ? 'OK' : 'MISSING')"
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
If missing: stop — run `new-project` first.
|
|
@@ -24,11 +24,13 @@ If no description was provided as an argument, ask: "What does this new phase de
|
|
|
24
24
|
Read `.planning/ROADMAP.md` and find the highest existing integer phase number:
|
|
25
25
|
```bash
|
|
26
26
|
grep -E "^## Phase [0-9]+" .planning/ROADMAP.md | tail -1
|
|
27
|
+
# PowerShell: Select-String -Path .planning/ROADMAP.md -Pattern '^## Phase \d+' | Select-Object -Last 1
|
|
27
28
|
```
|
|
28
29
|
|
|
29
30
|
Also scan the phases directory for any directories that may not be in the roadmap:
|
|
30
31
|
```bash
|
|
31
32
|
ls .planning/phases/ 2>/dev/null | grep -E "^[0-9]+" | sort -n | tail -3
|
|
33
|
+
# PowerShell: Get-ChildItem .planning/phases/ -ErrorAction SilentlyContinue | Where-Object { $_.Name -match '^[0-9]+' } | Sort-Object Name | Select-Object -Last 3
|
|
32
34
|
```
|
|
33
35
|
|
|
34
36
|
Set `NEXT_NUM` = highest found + 1. Pad to 2 digits (01, 02, ..., 10, 11, ...).
|
|
@@ -38,7 +40,8 @@ Generate a slug from the description (lowercase, hyphens, max 40 chars).
|
|
|
38
40
|
## Step 3: Create Phase Directory
|
|
39
41
|
|
|
40
42
|
```bash
|
|
41
|
-
|
|
43
|
+
node -e "require('fs').mkdirSync('.planning/phases/${NEXT_NUM}-${SLUG}',{recursive:true})"
|
|
44
|
+
# PowerShell: New-Item -ItemType Directory -Force -Path ".planning/phases/${NEXT_NUM}-${SLUG}"
|
|
42
45
|
```
|
|
43
46
|
|
|
44
47
|
## Step 4: Update ROADMAP.md
|
|
@@ -20,6 +20,7 @@ Example: add-tests 3 focus on edge cases in the pricing module
|
|
|
20
20
|
Find the phase directory:
|
|
21
21
|
```bash
|
|
22
22
|
ls .planning/phases/ | grep -E "^0*[N]-" | head -1
|
|
23
|
+
# PowerShell: Get-ChildItem .planning/phases/ | Where-Object { $_.Name -match "^0*[N]-" } | Select-Object -First 1 -ExpandProperty Name
|
|
23
24
|
PHASE_DIR=".planning/phases/[matched]"
|
|
24
25
|
```
|
|
25
26
|
|
|
@@ -45,6 +46,7 @@ Extract the list of files modified by the phase from SUMMARY.md.
|
|
|
45
46
|
find . \( -name "jest.config.*" -o -name "vitest.config.*" -o -name "pytest.ini" -o -name "pyproject.toml" -o -name "playwright.config.*" \) -not -path "*/node_modules/*" 2>/dev/null
|
|
46
47
|
|
|
47
48
|
find . \( -name "*.test.*" -o -name "*.spec.*" -o -name "test_*.py" \) -not -path "*/node_modules/*" 2>/dev/null | head -10
|
|
49
|
+
# PowerShell: Get-ChildItem -Recurse | Where-Object { $_.Name -match '\.test\.|spec\.|^test_.*\.py' -and $_.FullName -notmatch 'node_modules' } | Select-Object -First 10
|
|
48
50
|
```
|
|
49
51
|
|
|
50
52
|
Identify: test framework, E2E framework (if any), how to run tests, existing test file patterns and locations.
|
|
@@ -11,7 +11,7 @@ Capture an idea, task, or issue that surfaces during a session. Fast "thought
|
|
|
11
11
|
## Step 1: Ensure Directories Exist
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
|
|
14
|
+
node -e "require('fs').mkdirSync('.planning/todos/pending',{recursive:true});require('fs').mkdirSync('.planning/todos/done',{recursive:true})"
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
## Step 2: Extract Content
|
|
@@ -79,6 +79,7 @@ Check:
|
|
|
79
79
|
|
|
80
80
|
```bash
|
|
81
81
|
grep -rn "TODO\|FIXME\|PLACEHOLDER\|return null\|return undefined" src/ --include="*.ts" --include="*.tsx" --include="*.js" 2>/dev/null | grep -v "node_modules\|\.test\." | head -30
|
|
82
|
+
# PowerShell: Select-String -Path src/ -Recurse -Pattern 'TODO|FIXME|PLACEHOLDER|return null|return undefined' -Include '*.ts','*.tsx','*.js' | Where-Object { $_.Path -notmatch 'node_modules|\.test\.' } | Select-Object -First 30
|
|
82
83
|
```
|
|
83
84
|
|
|
84
85
|
## Step 5: Compile Audit Report
|
|
@@ -80,7 +80,7 @@ Wait for confirmation. If "no": stop.
|
|
|
80
80
|
For each milestone and its phase directories:
|
|
81
81
|
|
|
82
82
|
```bash
|
|
83
|
-
|
|
83
|
+
node -e "require('fs').mkdirSync('.planning/milestones/v[X.Y]-phases',{recursive:true})"
|
|
84
84
|
mv ".planning/phases/[phase-dir]/" ".planning/milestones/v[X.Y]-phases/"
|
|
85
85
|
```
|
|
86
86
|
|
|
@@ -47,6 +47,7 @@ Ask for confirmation:
|
|
|
47
47
|
Read `.planning/STATE.md` and check for existing version tags:
|
|
48
48
|
```bash
|
|
49
49
|
git tag --list "v*" | sort -V | tail -5
|
|
50
|
+
# PowerShell: git tag --list "v*" | Sort-Object | Select-Object -Last 5
|
|
50
51
|
```
|
|
51
52
|
|
|
52
53
|
Propose the next version (e.g., `v1.0`, `v1.1`, `v2.0`). Ask for confirmation or let user specify.
|
|
@@ -55,7 +56,7 @@ Propose the next version (e.g., `v1.0`, `v1.1`, `v2.0`). Ask for confirmation or
|
|
|
55
56
|
|
|
56
57
|
Create the milestones archive directory:
|
|
57
58
|
```bash
|
|
58
|
-
|
|
59
|
+
node -e "require('fs').mkdirSync('.planning/milestones',{recursive:true})"
|
|
59
60
|
```
|
|
60
61
|
|
|
61
62
|
Archive the roadmap for this milestone:
|
|
@@ -11,7 +11,7 @@ Systematic debugging workflow: triage → root cause diagnosis → fix planning
|
|
|
11
11
|
## Step 1: Create Debug Session
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
|
|
14
|
+
node -e "require('fs').mkdirSync('.planning/debug',{recursive:true})"
|
|
15
15
|
DATE=$(date +%Y%m%d-%H%M)
|
|
16
16
|
```
|
|
17
17
|
|
|
@@ -196,7 +196,7 @@ Update session file:
|
|
|
196
196
|
|
|
197
197
|
Move to resolved:
|
|
198
198
|
```bash
|
|
199
|
-
|
|
199
|
+
node -e "require('fs').mkdirSync('.planning/debug/resolved',{recursive:true})"
|
|
200
200
|
mv ".planning/debug/[session-file]" ".planning/debug/resolved/"
|
|
201
201
|
```
|
|
202
202
|
|
|
@@ -15,6 +15,7 @@ Batch-diagnose all open UAT issues after `verify-work`. Groups issues by root ca
|
|
|
15
15
|
Find the UAT file for the phase:
|
|
16
16
|
```bash
|
|
17
17
|
ls ".planning/phases/"*[N]*"/"*-UAT.md 2>/dev/null | head -1
|
|
18
|
+
# PowerShell: Get-ChildItem ".planning/phases/" -Recurse -Filter "*-UAT.md" | Where-Object { $_.FullName -match [N] } | Select-Object -First 1
|
|
18
19
|
```
|
|
19
20
|
|
|
20
21
|
If no UAT file found: stop — "Run `verify-work [N]` first to log issues."
|
|
@@ -33,13 +33,16 @@ Search for code related to the target area using key terms from the phase goal:
|
|
|
33
33
|
```bash
|
|
34
34
|
# Find files mentioning key terms
|
|
35
35
|
grep -rl "[key term 1]" src/ 2>/dev/null | head -15
|
|
36
|
+
# PowerShell: Select-String -Path src/ -Recurse -Pattern "[key term 1]" | Select-Object -ExpandProperty Path -Unique | Select-Object -First 15
|
|
36
37
|
grep -rl "[key term 2]" src/ 2>/dev/null | head -10
|
|
38
|
+
# PowerShell: Select-String -Path src/ -Recurse -Pattern "[key term 2]" | Select-Object -ExpandProperty Path -Unique | Select-Object -First 10
|
|
37
39
|
|
|
38
40
|
# Find related directories
|
|
39
41
|
find src/ -type d | grep -i "[key term]" 2>/dev/null
|
|
40
42
|
|
|
41
43
|
# Find entry points
|
|
42
44
|
grep -rn "export\|module.exports\|def " src/ --include="*.ts" --include="*.js" --include="*.py" 2>/dev/null | grep -i "[key term]" | head -20
|
|
45
|
+
# PowerShell: Select-String -Path src/ -Recurse -Pattern 'export|module.exports|def ' | Where-Object { $_.Line -imatch '[key term]' } | Select-Object -First 20
|
|
43
46
|
```
|
|
44
47
|
|
|
45
48
|
Read the 5-8 most relevant files. Focus on interfaces, types, exports, and public API — not implementation details.
|
|
@@ -51,6 +54,7 @@ For the relevant files, trace what they depend on and what depends on them:
|
|
|
51
54
|
**Incoming dependencies** (who calls this code):
|
|
52
55
|
```bash
|
|
53
56
|
grep -rl "import.*[module name]\|require.*[module name]" src/ 2>/dev/null | head -10
|
|
57
|
+
# PowerShell: Select-String -Path src/ -Recurse -Pattern 'import.*[module name]|require.*[module name]' | Select-Object -ExpandProperty Path -Unique | Select-Object -First 10
|
|
54
58
|
```
|
|
55
59
|
|
|
56
60
|
**Outgoing dependencies** (what this code calls):
|
|
@@ -80,6 +84,7 @@ Look specifically for:
|
|
|
80
84
|
```bash
|
|
81
85
|
# Files with most lines of code in the area
|
|
82
86
|
wc -l $(find src/ -name "*.ts" -o -name "*.py" 2>/dev/null | xargs grep -l "[key term]" 2>/dev/null) | sort -n | tail -10
|
|
87
|
+
# PowerShell: Select-String -Path src/ -Recurse -Pattern '[key term]' -Include '*.ts','*.py' | Select-Object -ExpandProperty Path -Unique | ForEach-Object { (Get-Content $_).Count } | Sort-Object | Select-Object -Last 10
|
|
83
88
|
```
|
|
84
89
|
|
|
85
90
|
**Test coverage gaps:**
|
|
@@ -90,6 +95,7 @@ find . -name "*.test.*" -o -name "test_*.py" | xargs grep -l "[key term]" 2>/dev
|
|
|
90
95
|
**TODO/FIXME in the area:**
|
|
91
96
|
```bash
|
|
92
97
|
grep -rn "TODO\|FIXME\|HACK\|XXX" src/ 2>/dev/null | grep -i "[key term]" | head -10
|
|
98
|
+
# PowerShell: Select-String -Path src/ -Recurse -Pattern 'TODO|FIXME|HACK|XXX' | Where-Object { $_.Line -imatch '[key term]' } | Select-Object -First 10
|
|
93
99
|
```
|
|
94
100
|
|
|
95
101
|
**Known issues from DECISIONS.md:**
|
|
@@ -17,6 +17,7 @@ Read what has already shipped:
|
|
|
17
17
|
cat .planning/PROJECT.md
|
|
18
18
|
cat .planning/STATE.md
|
|
19
19
|
ls .planning/milestones/ 2>/dev/null | sort -V | tail -3
|
|
20
|
+
# PowerShell: Get-ChildItem .planning/milestones/ -ErrorAction SilentlyContinue | Sort-Object Name | Select-Object -Last 3
|
|
20
21
|
```
|
|
21
22
|
|
|
22
23
|
Display the last milestone summary so the conversation starts informed:
|
|
@@ -29,7 +30,7 @@ Pending todos: [N] items
|
|
|
29
30
|
|
|
30
31
|
Check if a MILESTONE-CONTEXT.md already exists:
|
|
31
32
|
```bash
|
|
32
|
-
|
|
33
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning/MILESTONE-CONTEXT.md') ? 'EXISTS' : 'MISSING')"
|
|
33
34
|
```
|
|
34
35
|
|
|
35
36
|
If exists: ask "A milestone context file already exists from a prior discussion. Update it or start fresh?"
|
|
@@ -29,6 +29,7 @@ Extract from prior CONTEXT.md files: locked preferences, patterns the user has e
|
|
|
29
29
|
If `.planning/DECISIONS.md` exists, read it:
|
|
30
30
|
```bash
|
|
31
31
|
cat .planning/DECISIONS.md 2>/dev/null | head -80
|
|
32
|
+
# PowerShell: Get-Content .planning/DECISIONS.md -ErrorAction SilentlyContinue | Select-Object -First 80
|
|
32
33
|
```
|
|
33
34
|
|
|
34
35
|
Note any decisions that constrain or inform this phase's approach. Surface them during discussion rather than re-asking decided questions.
|
|
@@ -129,7 +130,7 @@ Track deferred ideas internally.
|
|
|
129
130
|
|
|
130
131
|
Find or create the phase directory:
|
|
131
132
|
```bash
|
|
132
|
-
|
|
133
|
+
node -e "require('fs').mkdirSync('.planning/phases/[padded_phase]-[phase_slug]',{recursive:true})"
|
|
133
134
|
```
|
|
134
135
|
|
|
135
136
|
Write `.planning/phases/[padded_phase]-[phase_slug]/[padded_phase]-CONTEXT.md`:
|
|
@@ -13,6 +13,7 @@ Execute a single PLAN.md file in isolation. Useful when one plan in a phase fail
|
|
|
13
13
|
Find the phase directory:
|
|
14
14
|
```bash
|
|
15
15
|
ls .planning/phases/ | grep -E "^0*[phase]-" | head -1
|
|
16
|
+
# PowerShell: Get-ChildItem .planning/phases/ | Where-Object { $_.Name -match "^0*[phase]-" } | Select-Object -First 1 -ExpandProperty Name
|
|
16
17
|
PHASE_DIR=".planning/phases/[matched]"
|
|
17
18
|
```
|
|
18
19
|
|
|
@@ -15,7 +15,7 @@ Check if `--repair` flag is present.
|
|
|
15
15
|
## Step 2: Check Project Exists
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
|
|
18
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning') ? 'OK' : 'MISSING')"
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
If `.planning/` doesn't exist:
|
|
@@ -32,40 +32,49 @@ Run the following checks and classify each as error, warning, or info:
|
|
|
32
32
|
|
|
33
33
|
### Required Files
|
|
34
34
|
```bash
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
node -e "const fs=require('fs'); if(!fs.existsSync('.planning/PROJECT.md')) console.log('E002: PROJECT.md not found')"
|
|
36
|
+
node -e "const fs=require('fs'); if(!fs.existsSync('.planning/ROADMAP.md')) console.log('E003: ROADMAP.md not found')"
|
|
37
|
+
node -e "const fs=require('fs'); if(!fs.existsSync('.planning/STATE.md')) console.log('E004: STATE.md not found (repairable)')"
|
|
38
|
+
node -e "const fs=require('fs'); if(!fs.existsSync('.planning/config.json')) console.log('W003: config.json not found (repairable)')"
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
### Config Validity
|
|
42
42
|
```bash
|
|
43
|
-
|
|
43
|
+
node -e "try{JSON.parse(require('fs').readFileSync('.planning/config.json','utf8'))}catch(e){console.log('E005: config.json parse error (repairable)')}"
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
### State / Roadmap Consistency
|
|
47
47
|
```bash
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
node -e "
|
|
49
|
+
const fs=require('fs');
|
|
50
|
+
if(!fs.existsSync('.planning/STATE.md')||!fs.existsSync('.planning/ROADMAP.md'))process.exit(0);
|
|
51
|
+
const state=fs.readFileSync('.planning/STATE.md','utf8');
|
|
52
|
+
const m=state.match(/^Phase:\s*(\d+)/m);
|
|
53
|
+
if(m){
|
|
54
|
+
const roadmap=fs.readFileSync('.planning/ROADMAP.md','utf8');
|
|
55
|
+
if(!roadmap.includes('Phase '+m[1]+':'))console.log('W002: STATE.md references phase '+m[1]+' not found in roadmap (repairable)');
|
|
56
|
+
}
|
|
57
|
+
"
|
|
53
58
|
```
|
|
54
59
|
|
|
55
60
|
### Phase Directory Checks
|
|
56
61
|
```bash
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
node -e "
|
|
63
|
+
const fs=require('fs'),path=require('path');
|
|
64
|
+
if(!fs.existsSync('.planning/ROADMAP.md'))process.exit(0);
|
|
65
|
+
const roadmap=fs.readFileSync('.planning/ROADMAP.md','utf8');
|
|
66
|
+
const phases=[...roadmap.matchAll(/^## Phase (\d+):/mg)].map(m=>m[1]);
|
|
67
|
+
const phasesDir='.planning/phases';
|
|
68
|
+
const dirs=fs.existsSync(phasesDir)?fs.readdirSync(phasesDir):[];
|
|
69
|
+
for(const n of phases){
|
|
70
|
+
const pad=n.padStart(2,'0');
|
|
71
|
+
if(!dirs.some(d=>d.startsWith(pad+'-')))console.log('W006: Phase '+n+' in roadmap but no directory');
|
|
72
|
+
}
|
|
73
|
+
for(const d of dirs){
|
|
74
|
+
const slug=d.replace(/^\d+-/,'');
|
|
75
|
+
if(!roadmap.includes(slug))console.log('W007: Directory '+d+' not in roadmap');
|
|
76
|
+
}
|
|
77
|
+
"
|
|
69
78
|
```
|
|
70
79
|
|
|
71
80
|
### Plans Without Summaries
|
|
@@ -79,21 +88,18 @@ done
|
|
|
79
88
|
### Uncommitted Changes
|
|
80
89
|
```bash
|
|
81
90
|
git status --short .planning/ 2>/dev/null | head -10
|
|
91
|
+
# PowerShell: git status --short .planning/ 2>$null | Select-Object -First 10
|
|
82
92
|
```
|
|
83
93
|
|
|
84
94
|
### Config Fields
|
|
85
95
|
```bash
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
missing
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
missing.append(key)
|
|
94
|
-
if missing:
|
|
95
|
-
print('W004: config.json missing fields: ' + ', '.join(missing))
|
|
96
|
-
" 2>/dev/null
|
|
96
|
+
node -e "
|
|
97
|
+
try{
|
|
98
|
+
const cfg=JSON.parse(require('fs').readFileSync('.planning/config.json','utf8'));
|
|
99
|
+
const missing=['mode','granularity','model_profile','learning_mode'].filter(k=>!(k in cfg));
|
|
100
|
+
if(missing.length)console.log('W004: config.json missing fields: '+missing.join(', '));
|
|
101
|
+
}catch(e){}
|
|
102
|
+
"
|
|
97
103
|
```
|
|
98
104
|
|
|
99
105
|
## Step 4: Format Output
|
|
@@ -31,7 +31,7 @@ Validate that the after-phase number is an integer.
|
|
|
31
31
|
## Step 2: Validate
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
|
-
|
|
34
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning/ROADMAP.md') ? 'OK' : 'MISSING')"
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
Check that phase `[N]` exists in ROADMAP.md:
|
|
@@ -56,7 +56,7 @@ Generate slug from description (lowercase, hyphens, max 40 chars).
|
|
|
56
56
|
## Step 4: Create Phase Directory
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
|
-
|
|
59
|
+
node -e "require('fs').mkdirSync('.planning/phases/[N].[M]-[SLUG]',{recursive:true})"
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
## Step 5: Update ROADMAP.md
|
|
@@ -13,7 +13,7 @@ The quickest way to answer "where am I and what do I do next?" Works for new use
|
|
|
13
13
|
## Step 1: Check for Project
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
|
|
16
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning/PROJECT.md') ? 'EXISTS' : 'MISSING')"
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
**If MISSING** — no project initialized yet. Display:
|
|
@@ -50,7 +50,7 @@ cat .planning/ROADMAP.md
|
|
|
50
50
|
Find the 2–3 most recent SUMMARY.md files:
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
|
-
|
|
53
|
+
node -e "const fs=require('fs'),path=require('path');function find(d){let r=[];try{for(const e of fs.readdirSync(d,{withFileTypes:true})){const f=path.join(d,e.name);r=r.concat(e.isDirectory()?find(f):e.name.endsWith('-SUMMARY.md')?[f]:[]);}}catch(e){}return r;}const files=find('.planning').map(f=>({f,t:fs.statSync(f).mtimeMs})).sort((a,b)=>b.t-a.t).slice(0,3).map(x=>x.f);files.forEach(f=>console.log(f));"
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
Read each for a one-liner summary of what was accomplished.
|
|
@@ -15,7 +15,9 @@ A structured learning retrospective after a milestone ships. Five focused questi
|
|
|
15
15
|
Read the milestone that just shipped:
|
|
16
16
|
```bash
|
|
17
17
|
ls .planning/milestones/ | sort -V | tail -3
|
|
18
|
+
# PowerShell: Get-ChildItem .planning/milestones/ | Sort-Object Name | Select-Object -Last 3
|
|
18
19
|
cat .planning/milestones/[VERSION]-ROADMAP.md 2>/dev/null | head -60
|
|
20
|
+
# PowerShell: Get-Content .planning/milestones/[VERSION]-ROADMAP.md -ErrorAction SilentlyContinue | Select-Object -First 60
|
|
19
21
|
```
|
|
20
22
|
|
|
21
23
|
Read all phase SUMMARY.md files from this milestone:
|
|
@@ -48,6 +48,7 @@ Follow the thread. When you have enough to write clear goals, ask for confirmati
|
|
|
48
48
|
Read the last version from `.planning/milestones/`:
|
|
49
49
|
```bash
|
|
50
50
|
ls .planning/milestones/ | grep -E "^v[0-9]" | sort -V | tail -3
|
|
51
|
+
# PowerShell: Get-ChildItem .planning/milestones/ | Where-Object { $_.Name -match '^v[0-9]' } | Sort-Object Name | Select-Object -Last 3
|
|
51
52
|
```
|
|
52
53
|
|
|
53
54
|
Propose the next version (e.g., `v1.0 → v1.1`, or `v2.0` for a major scope change). Confirm with user or let them specify.
|
|
@@ -21,14 +21,14 @@ Initialize a new project with full context gathering, optional research, require
|
|
|
21
21
|
|
|
22
22
|
## Step 1: Setup
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
You are running on **Windsurf**. Platform config directory: `.windsurf/`
|
|
25
25
|
|
|
26
26
|
> **Routing protocol suspended.** While this workflow is running, every user message is an answer to a workflow question — not a task to route. Do NOT apply the request routing protocol until `/new-project` is fully complete and `.planning/PROJECT.md` exists.
|
|
27
27
|
|
|
28
28
|
Check if `.planning/PROJECT.md` already exists:
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
|
|
31
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning/PROJECT.md') ? 'EXISTS' : 'NEW')"
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
**If EXISTS:** Stop. Project already initialized. Use the `progress` workflow to see where you are.
|
|
@@ -36,11 +36,11 @@ python3 -c "import os; print('EXISTS' if os.path.exists('.planning/PROJECT.md')
|
|
|
36
36
|
**Check for an existing codebase:**
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
node -e "
|
|
40
|
+
const fs=require('fs'),path=require('path');
|
|
41
|
+
function walk(dir,skip){let n=0;try{for(const e of fs.readdirSync(dir,{withFileTypes:true})){const f=path.join(dir,e.name);if(skip.some(s=>f.includes(s)))continue;n+=e.isDirectory()?walk(f,skip):1;}}catch(e){}return n;}
|
|
42
|
+
const n=walk('.',['/.git/','node_modules','.planning','__pycache__','.venv']);
|
|
43
|
+
console.log(n>2?'HAS_CODE':'BLANK');console.log(n+' files');
|
|
44
44
|
"
|
|
45
45
|
```
|
|
46
46
|
|
|
@@ -49,7 +49,7 @@ print(f'{len(files)} files')
|
|
|
49
49
|
Check if git is initialized:
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
|
-
|
|
52
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.git') ? 'HAS_GIT' : 'NO_GIT')"
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
**If NO_GIT:**
|
|
@@ -59,12 +59,12 @@ git init
|
|
|
59
59
|
|
|
60
60
|
Add the platform config directory to `.gitignore` so AI platform files are not tracked in the project repo:
|
|
61
61
|
```bash
|
|
62
|
-
|
|
62
|
+
grep -q '.windsurf/' .gitignore 2>/dev/null || echo '.windsurf/' >> .gitignore
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
Create the planning directory:
|
|
66
66
|
```bash
|
|
67
|
-
|
|
67
|
+
node -e "require('fs').mkdirSync('.planning/research',{recursive:true})"
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
## Step 1b: Existing Codebase Scan (only if EXISTING_CODEBASE = true)
|
|
@@ -73,6 +73,7 @@ If `EXISTING_CODEBASE = true`, do a quick structural scan before questioning so
|
|
|
73
73
|
|
|
74
74
|
```bash
|
|
75
75
|
find . -maxdepth 3 -not -path './.git/*' -not -path './node_modules/*' -not -path './.planning/*' -not -path './__pycache__/*' -not -path './.venv/*' | sort | head -40
|
|
76
|
+
# PowerShell: Get-ChildItem -Recurse -Depth 3 | Where-Object { $_.FullName -notmatch '\.git|node_modules|\.planning|__pycache__|\.venv' } | Select-Object -First 40
|
|
76
77
|
```
|
|
77
78
|
|
|
78
79
|
Note the tech stack, key directories, and any README content internally. Use this ONLY to ask sharper follow-up questions — never to infer the user's intent or skip ceremony steps.
|
|
@@ -105,7 +106,9 @@ Ask: "Which workflow agents should be enabled?"
|
|
|
105
106
|
- **Plan Check** (recommended) — Verify plans achieve their goals before execution
|
|
106
107
|
- **Verifier** (recommended) — Confirm deliverables match phase goals after execution
|
|
107
108
|
|
|
108
|
-
|
|
109
|
+
**Group D — Parallel execution:**
|
|
110
|
+
|
|
111
|
+
Windsurf does not support real subagents. Parallelization is automatically set to `false`.
|
|
109
112
|
|
|
110
113
|
Ask: "Commit planning docs to git?"
|
|
111
114
|
- **Yes** (recommended) — Planning docs tracked in version control
|
|
@@ -351,6 +354,7 @@ Fill in the placeholder sections using information gathered in this session:
|
|
|
351
354
|
**Project Structure** — derive from the project description and any existing directories:
|
|
352
355
|
```bash
|
|
353
356
|
find . -maxdepth 2 -not -path './.git/*' -not -path './node_modules/*' -not -path './.planning/*' -type d | sort | head -20
|
|
357
|
+
# PowerShell: Get-ChildItem -Directory -Recurse -Depth 2 | Where-Object { $_.FullName -notmatch '\.git|node_modules|\.planning' } | Select-Object -First 20
|
|
354
358
|
```
|
|
355
359
|
|
|
356
360
|
Populate the `## Project Structure` tree with real directories and one-line descriptions.
|
|
@@ -13,7 +13,7 @@ Reads project state and runs the right next workflow automatically. No need to r
|
|
|
13
13
|
## Step 1: Check for Project
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
|
|
16
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning/PROJECT.md') ? 'EXISTS' : 'MISSING')"
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
**If MISSING:**
|
|
@@ -12,7 +12,7 @@ Create a `.continue-here.md` handoff file that captures complete work state. Ena
|
|
|
12
12
|
|
|
13
13
|
Find the most recently active phase:
|
|
14
14
|
```bash
|
|
15
|
-
|
|
15
|
+
node -e "const fs=require('fs'),path=require('path');function find(d){let r=[];try{for(const e of fs.readdirSync(d,{withFileTypes:true})){const f=path.join(d,e.name);r=r.concat(e.isDirectory()?find(f):e.name.endsWith('-PLAN.md')?[f]:[]);}}catch(e){}return r;}const files=find('.planning/phases').map(f=>({f,t:fs.statSync(f).mtimeMs})).sort((a,b)=>b.t-a.t);if(files[0])console.log(files[0].f);"
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
Extract the phase directory name from the result.
|
|
@@ -13,6 +13,7 @@ Create all phases needed to close gaps identified by `audit-milestone`. One work
|
|
|
13
13
|
Find the most recent audit file:
|
|
14
14
|
```bash
|
|
15
15
|
ls -t .planning/*-MILESTONE-AUDIT.md 2>/dev/null | head -1
|
|
16
|
+
# PowerShell: Get-ChildItem .planning/*-MILESTONE-AUDIT.md -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
|
16
17
|
```
|
|
17
18
|
|
|
18
19
|
If no audit file exists or status is `passed`:
|
|
@@ -74,6 +75,7 @@ Gap: Flow "User stays logged in" broken
|
|
|
74
75
|
Find the highest existing phase number:
|
|
75
76
|
```bash
|
|
76
77
|
ls .planning/phases/ | grep -E "^[0-9]" | sort -V | tail -1
|
|
78
|
+
# PowerShell: Get-ChildItem .planning/phases/ | Where-Object { $_.Name -match '^[0-9]' } | Sort-Object Name | Select-Object -Last 1
|
|
77
79
|
```
|
|
78
80
|
|
|
79
81
|
Gap closure phases continue from the highest existing phase + 1.
|
|
@@ -131,7 +133,7 @@ For each unsatisfied requirement being addressed:
|
|
|
131
133
|
|
|
132
134
|
```bash
|
|
133
135
|
for each gap closure phase:
|
|
134
|
-
|
|
136
|
+
node -e "require('fs').mkdirSync('.planning/phases/[NN]-[slug]',{recursive:true})"
|
|
135
137
|
done
|
|
136
138
|
```
|
|
137
139
|
|
|
@@ -25,7 +25,7 @@ cat .planning/config.json
|
|
|
25
25
|
|
|
26
26
|
Create the phase directory if it doesn't exist:
|
|
27
27
|
```bash
|
|
28
|
-
|
|
28
|
+
node -e "require('fs').mkdirSync('.planning/phases/[padded_phase]-[phase_slug]',{recursive:true})"
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
Check what already exists:
|
|
@@ -9,7 +9,7 @@ Check where you are in the project, what's been done, and what comes next.
|
|
|
9
9
|
## Step 1: Check for Planning Structure
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
|
|
12
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning/PROJECT.md') ? 'EXISTS' : 'MISSING')"
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
If `.planning/` doesn't exist: stop — run `new-project` to initialize.
|
|
@@ -24,7 +24,7 @@ cat .planning/ROADMAP.md
|
|
|
24
24
|
|
|
25
25
|
Find the 2-3 most recent SUMMARY.md files:
|
|
26
26
|
```bash
|
|
27
|
-
|
|
27
|
+
node -e "const fs=require('fs'),path=require('path');function find(d){let r=[];try{for(const e of fs.readdirSync(d,{withFileTypes:true})){const f=path.join(d,e.name);r=r.concat(e.isDirectory()?find(f):e.name.endsWith('-SUMMARY.md')?[f]:[]);}}catch(e){}return r;}const files=find('.planning').map(f=>({f,t:fs.statSync(f).mtimeMs})).sort((a,b)=>b.t-a.t).slice(0,3).map(x=>x.f);files.forEach(f=>console.log(f));"
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
Read each to extract what was recently accomplished (one-liner per plan).
|
|
@@ -34,7 +34,7 @@ Display banner based on active flags:
|
|
|
34
34
|
|
|
35
35
|
Check that a project exists:
|
|
36
36
|
```bash
|
|
37
|
-
|
|
37
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning/PROJECT.md') ? 'OK' : 'MISSING')"
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
If PROJECT.md missing: stop — run `new-project` first. Quick tasks require an active project.
|
|
@@ -46,13 +46,15 @@ Generate a slug from the description (lowercase, hyphens, max 40 chars).
|
|
|
46
46
|
Find the next task number:
|
|
47
47
|
```bash
|
|
48
48
|
ls .planning/quick/ 2>/dev/null | grep -E "^[0-9]+" | sort -n | tail -1
|
|
49
|
+
# PowerShell: Get-ChildItem .planning/quick/ -ErrorAction SilentlyContinue | Where-Object { $_.Name -match '^[0-9]+' } | Sort-Object Name | Select-Object -Last 1
|
|
49
50
|
```
|
|
50
51
|
|
|
51
52
|
Set `NEXT_NUM` to the next available number (001, 002, etc.).
|
|
52
53
|
|
|
53
54
|
Create task directory:
|
|
54
55
|
```bash
|
|
55
|
-
|
|
56
|
+
node -e "require('fs').mkdirSync('.planning/quick/${NEXT_NUM}-${SLUG}',{recursive:true})"
|
|
57
|
+
# PowerShell: New-Item -ItemType Directory -Force -Path ".planning/quick/${NEXT_NUM}-${SLUG}"
|
|
56
58
|
```
|
|
57
59
|
|
|
58
60
|
Report: "Creating quick task ${NEXT_NUM}: ${DESCRIPTION}"
|
|
@@ -130,7 +132,7 @@ If `--full`: also include `must_haves` in plan frontmatter (truths, artifacts, k
|
|
|
130
132
|
|
|
131
133
|
Verify plan was created (substitute actual NEXT_NUM and SLUG values):
|
|
132
134
|
```bash
|
|
133
|
-
|
|
135
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning/quick/NEXT_NUM-SLUG/NEXT_NUM-PLAN.md') ? 'OK' : 'MISSING')"
|
|
134
136
|
```
|
|
135
137
|
|
|
136
138
|
## Step 5: Plan Check (only with `--full`)
|
|
@@ -168,10 +168,10 @@ curl -s -X POST \
|
|
|
168
168
|
\"tag_name\": \"vX.Y.Z\",
|
|
169
169
|
\"target_commitish\": \"main\",
|
|
170
170
|
\"name\": \"vX.Y.Z — [Short title]\",
|
|
171
|
-
\"body\": $(
|
|
171
|
+
\"body\": $(node -e "process.stdout.write(JSON.stringify(require('fs').readFileSync('/dev/stdin','utf8')))" <<< "$RELEASE_NOTES"),
|
|
172
172
|
\"draft\": false,
|
|
173
173
|
\"prerelease\": false
|
|
174
|
-
}" |
|
|
174
|
+
}" | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>{const r=JSON.parse(d);console.log(r.html_url||r.message||'ERROR');})"
|
|
175
175
|
```
|
|
176
176
|
|
|
177
177
|
If successful, the release URL is printed.
|
|
@@ -198,6 +198,7 @@ git remote -v
|
|
|
198
198
|
```bash
|
|
199
199
|
git log --oneline public-main -3 # new release commit at top
|
|
200
200
|
git tag --sort=-version:refname | head -5 # new tag at top
|
|
201
|
+
# PowerShell: git tag --sort=-version:refname | Select-Object -First 5
|
|
201
202
|
```
|
|
202
203
|
|
|
203
204
|
Open the release URL printed in Step 11 to confirm it looks correct on GitHub.
|
|
@@ -22,7 +22,7 @@ Example: remove-phase 7
|
|
|
22
22
|
|
|
23
23
|
Check roadmap exists:
|
|
24
24
|
```bash
|
|
25
|
-
|
|
25
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning/ROADMAP.md') ? 'OK' : 'MISSING')"
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
## Step 2: Verify the Phase is Future
|
|
@@ -13,7 +13,7 @@ Run standalone domain research for a phase. Useful when the domain is unfamiliar
|
|
|
13
13
|
## Step 1: Validate Phase
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
|
|
16
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning/ROADMAP.md') ? 'OK' : 'MISSING')"
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Find phase `[N]` in ROADMAP.md:
|
|
@@ -9,9 +9,9 @@ Instantly restore full project context. Use when starting a new session, returni
|
|
|
9
9
|
## Step 1: Check Planning Structure
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning/STATE.md') ? 'HAS_STATE' : 'NO_STATE')"
|
|
13
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning/PROJECT.md') ? 'HAS_PROJECT' : 'NO_PROJECT')"
|
|
14
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning/ROADMAP.md') ? 'HAS_ROADMAP' : 'NO_ROADMAP')"
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
If nothing exists: stop — run `new-project` to start a project.
|
|
@@ -51,12 +51,12 @@ Stop.
|
|
|
51
51
|
Update the `model_profile` field in `.planning/config.json`:
|
|
52
52
|
|
|
53
53
|
```bash
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
cfg
|
|
57
|
-
cfg
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
node -e "
|
|
55
|
+
const fs=require('fs');
|
|
56
|
+
const cfg=JSON.parse(fs.readFileSync('.planning/config.json','utf8'));
|
|
57
|
+
cfg.model_profile='[profile]';
|
|
58
|
+
fs.writeFileSync('.planning/config.json',JSON.stringify(cfg,null,2));
|
|
59
|
+
console.log('Updated.');
|
|
60
60
|
"
|
|
61
61
|
```
|
|
62
62
|
|
|
@@ -11,7 +11,7 @@ Interactive configuration editor for the current project. Updates `.planning/con
|
|
|
11
11
|
## Step 1: Ensure Config Exists
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
|
|
14
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning/config.json') ? 'exists' : 'missing')"
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
If missing, create from template:
|
|
@@ -97,7 +97,7 @@ Confirm both clones succeeded — `SKILL.md` must exist in `$AGENTIC_LEARN_TMP`
|
|
|
97
97
|
|
|
98
98
|
```bash
|
|
99
99
|
BACKUP_DIR="$(pwd)/.windsurf/skills/.upstream-backup-$(date +%Y%m%d-%H%M%S)"
|
|
100
|
-
|
|
100
|
+
node -e "require('fs').mkdirSync('$BACKUP_DIR',{recursive:true})"
|
|
101
101
|
|
|
102
102
|
cp -r "$(pwd)/.windsurf/skills/agentic-learning" "$BACKUP_DIR/agentic-learning"
|
|
103
103
|
cp -r "$(pwd)/.windsurf/skills/impeccable" "$BACKUP_DIR/impeccable"
|
|
@@ -27,7 +27,7 @@ find .planning/ -name "*.md" | sort
|
|
|
27
27
|
|
|
28
28
|
Read the most recent SUMMARY.md files (last 3 phases):
|
|
29
29
|
```bash
|
|
30
|
-
|
|
30
|
+
node -e "const fs=require('fs'),path=require('path');function find(d){let r=[];try{for(const e of fs.readdirSync(d,{withFileTypes:true})){const f=path.join(d,e.name);r=r.concat(e.isDirectory()?find(f):e.name.endsWith('-SUMMARY.md')?[f]:[]);}}catch(e){}return r;}const files=find('.planning/phases').map(f=>({f,t:fs.statSync(f).mtimeMs})).sort((a,b)=>b.t-a.t).slice(0,6).map(x=>x.f);files.forEach(f=>console.log(f));"
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
Check git status:
|
|
@@ -35,6 +35,7 @@ for loc in \
|
|
|
35
35
|
"$HOME/favio/learnship" \
|
|
36
36
|
"$HOME/learnship" \
|
|
37
37
|
"$(find $HOME -name "install.sh" -path "*/learnship/*" 2>/dev/null | head -1 | xargs dirname 2>/dev/null)"; do
|
|
38
|
+
# PowerShell: (Get-ChildItem $HOME -Recurse -Filter install.sh -ErrorAction SilentlyContinue | Where-Object { $_.FullName -match 'learnship' } | Select-Object -First 1).DirectoryName
|
|
38
39
|
test -d "$loc/.windsurf/workflows" && SOURCE_DIR="$loc" && break
|
|
39
40
|
done
|
|
40
41
|
```
|
|
@@ -93,7 +94,7 @@ Stop.
|
|
|
93
94
|
For any workflow file that exists in install dir AND differs from source AND differs from the current source (meaning you modified it):
|
|
94
95
|
|
|
95
96
|
```bash
|
|
96
|
-
|
|
97
|
+
node -e "require('fs').mkdirSync('$INSTALL_DIR/local-patches',{recursive:true})"
|
|
97
98
|
```
|
|
98
99
|
|
|
99
100
|
For each locally modified file:
|
|
@@ -22,7 +22,7 @@ If `nyquist_validation: false`: stop — "Validation is disabled. Enable it in `
|
|
|
22
22
|
## Step 2: Validate Phase
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
|
|
25
|
+
node -e "const fs=require('fs'); console.log(fs.existsSync('.planning/ROADMAP.md') ? 'OK' : 'MISSING')"
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Determine the phase directory:
|
|
@@ -61,6 +61,7 @@ Extract:
|
|
|
61
61
|
find . \( -name "jest.config.*" -o -name "vitest.config.*" -o -name "pytest.ini" -o -name "pyproject.toml" \) -not -path "*/node_modules/*" 2>/dev/null
|
|
62
62
|
|
|
63
63
|
find . \( -name "*.test.*" -o -name "*.spec.*" -o -name "test_*.py" \) -not -path "*/node_modules/*" 2>/dev/null | head -20
|
|
64
|
+
# PowerShell: Get-ChildItem -Recurse | Where-Object { $_.Name -match '\.test\.|spec\.|^test_.*\.py' -and $_.FullName -notmatch 'node_modules' } | Select-Object -First 20
|
|
64
65
|
```
|
|
65
66
|
|
|
66
67
|
Identify: test framework, how to run tests, existing test file patterns.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "learnship",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.22",
|
|
4
4
|
"description": "Learn as you build. Build with intent. — A multi-platform agentic engineering system for Windsurf, Claude Code, Cursor, OpenCode, Gemini CLI, and Codex: spec-driven workflows, integrated learning, and production-grade design.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agentic",
|
|
@@ -40,7 +40,7 @@ Configuration options for `.planning/` directory behavior.
|
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
42
|
# Read commit_docs from config.json
|
|
43
|
-
COMMIT_DOCS=$(
|
|
43
|
+
COMMIT_DOCS=$(node -e "try{const c=JSON.parse(require('fs').readFileSync('.planning/config.json','utf8'));process.stdout.write(String((c.planning||{}).commit_docs??'true'));}catch(e){process.stdout.write('true');}" 2>/dev/null || echo 'true')
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
**Auto-detection:** If `.planning/` is gitignored, treat `commit_docs` as `false` regardless of config.json. This prevents git errors.
|
|
@@ -139,7 +139,7 @@ To use uncommitted mode:
|
|
|
139
139
|
|
|
140
140
|
Read config directly:
|
|
141
141
|
```bash
|
|
142
|
-
|
|
142
|
+
node -e "const c=JSON.parse(require('fs').readFileSync('.planning/config.json','utf8')),g=c.git||{};console.log(g.branching_strategy||'none',g.phase_branch_template||'phase-{phase}-{slug}',g.milestone_branch_template||'{milestone}-{slug}')"
|
|
143
143
|
```
|
|
144
144
|
|
|
145
145
|
**Branch creation:**
|