mindsystem-cc 3.19.0 → 3.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +5 -6
  2. package/agents/ms-designer.md +5 -2
  3. package/agents/ms-mockup-designer.md +1 -1
  4. package/agents/ms-plan-writer.md +8 -1
  5. package/agents/ms-product-researcher.md +69 -0
  6. package/agents/ms-research-synthesizer.md +1 -1
  7. package/agents/ms-researcher.md +8 -8
  8. package/agents/ms-roadmapper.md +9 -13
  9. package/bin/install.js +68 -5
  10. package/commands/ms/add-phase.md +30 -18
  11. package/commands/ms/adhoc.md +1 -1
  12. package/commands/ms/audit-milestone.md +12 -12
  13. package/commands/ms/complete-milestone.md +25 -22
  14. package/commands/ms/config.md +202 -0
  15. package/commands/ms/design-phase.md +34 -29
  16. package/commands/ms/discuss-phase.md +26 -22
  17. package/commands/ms/doctor.md +22 -202
  18. package/commands/ms/execute-phase.md +18 -7
  19. package/commands/ms/help.md +46 -39
  20. package/commands/ms/insert-phase.md +29 -17
  21. package/commands/ms/new-milestone.md +42 -19
  22. package/commands/ms/new-project.md +88 -103
  23. package/commands/ms/plan-milestone-gaps.md +4 -5
  24. package/commands/ms/plan-phase.md +5 -3
  25. package/commands/ms/progress.md +2 -4
  26. package/commands/ms/research-phase.md +7 -12
  27. package/commands/ms/research-project.md +12 -12
  28. package/mindsystem/references/continuation-format.md +3 -3
  29. package/mindsystem/references/plan-format.md +11 -1
  30. package/mindsystem/references/principles.md +1 -1
  31. package/mindsystem/references/questioning.md +50 -8
  32. package/mindsystem/references/routing/audit-result-routing.md +12 -11
  33. package/mindsystem/references/routing/between-milestones-routing.md +2 -2
  34. package/mindsystem/references/routing/milestone-complete-routing.md +1 -1
  35. package/mindsystem/references/routing/next-phase-routing.md +4 -2
  36. package/mindsystem/templates/context.md +7 -6
  37. package/mindsystem/templates/milestone-archive.md +5 -5
  38. package/mindsystem/templates/milestone-context.md +1 -1
  39. package/mindsystem/templates/milestone.md +9 -9
  40. package/mindsystem/templates/project.md +70 -64
  41. package/mindsystem/templates/research-subagent-prompt.md +3 -3
  42. package/mindsystem/templates/roadmap-milestone.md +14 -14
  43. package/mindsystem/templates/roadmap.md +9 -7
  44. package/mindsystem/workflows/adhoc.md +1 -1
  45. package/mindsystem/workflows/complete-milestone.md +66 -107
  46. package/mindsystem/workflows/discuss-phase.md +137 -65
  47. package/mindsystem/workflows/doctor-fixes.md +273 -0
  48. package/mindsystem/workflows/execute-phase.md +7 -3
  49. package/mindsystem/workflows/execute-plan.md +6 -5
  50. package/mindsystem/workflows/map-codebase.md +2 -2
  51. package/mindsystem/workflows/mockup-generation.md +1 -1
  52. package/mindsystem/workflows/plan-phase.md +28 -3
  53. package/mindsystem/workflows/transition.md +20 -25
  54. package/mindsystem/workflows/verify-work.md +1 -1
  55. package/package.json +1 -1
  56. package/scripts/__pycache__/ms-tools.cpython-314.pyc +0 -0
  57. package/scripts/__pycache__/test_ms_tools.cpython-314-pytest-9.0.2.pyc +0 -0
  58. package/scripts/fixtures/scan-context/.planning/ROADMAP.md +16 -0
  59. package/scripts/fixtures/scan-context/.planning/adhoc/20260220-fix-token-SUMMARY.md +12 -0
  60. package/scripts/fixtures/scan-context/.planning/config.json +3 -0
  61. package/scripts/fixtures/scan-context/.planning/debug/resolved/token-bug.md +11 -0
  62. package/scripts/fixtures/scan-context/.planning/knowledge/auth.md +11 -0
  63. package/scripts/fixtures/scan-context/.planning/phases/02-infra/02-1-SUMMARY.md +20 -0
  64. package/scripts/fixtures/scan-context/.planning/phases/04-setup/04-1-SUMMARY.md +21 -0
  65. package/scripts/fixtures/scan-context/.planning/phases/05-auth/05-1-SUMMARY.md +28 -0
  66. package/scripts/fixtures/scan-context/.planning/todos/done/setup-db.md +10 -0
  67. package/scripts/fixtures/scan-context/.planning/todos/pending/add-logout.md +10 -0
  68. package/scripts/fixtures/scan-context/expected-output.json +257 -0
  69. package/scripts/ms-tools.py +2139 -0
  70. package/scripts/test_ms_tools.py +836 -0
  71. package/commands/ms/list-phase-assumptions.md +0 -56
  72. package/mindsystem/workflows/list-phase-assumptions.md +0 -178
  73. package/scripts/__pycache__/compare_mockups.cpython-314.pyc +0 -0
  74. package/scripts/archive-milestone-files.sh +0 -68
  75. package/scripts/archive-milestone-phases.sh +0 -138
  76. package/scripts/doctor-scan.sh +0 -379
  77. package/scripts/gather-milestone-stats.sh +0 -179
  78. package/scripts/generate-adhoc-patch.sh +0 -79
  79. package/scripts/generate-phase-patch.sh +0 -169
  80. package/scripts/scan-artifact-subsystems.sh +0 -55
  81. package/scripts/scan-planning-context.py +0 -839
  82. package/scripts/update-state.sh +0 -59
  83. package/scripts/validate-execution-order.sh +0 -104
@@ -1,379 +0,0 @@
1
- #!/bin/bash
2
- #
3
- # doctor-scan.sh
4
- # Single-pass diagnostic scan of the .planning/ tree.
5
- # Reports on 6 health check categories with structured output.
6
- #
7
- # Usage: ./scripts/doctor-scan.sh
8
- #
9
- # Exit codes:
10
- # 0 — all checks pass
11
- # 1 — one or more checks failed
12
- # 2 — .planning/ or config.json missing (cannot scan)
13
-
14
- set -e
15
-
16
- # --- Find .planning from git root ---
17
- GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
18
- if [ -z "$GIT_ROOT" ]; then
19
- echo "Error: Not in a git repository"
20
- exit 2
21
- fi
22
-
23
- PLANNING="$GIT_ROOT/.planning"
24
- if [ ! -d "$PLANNING" ]; then
25
- echo "Error: No .planning/ directory found"
26
- exit 2
27
- fi
28
-
29
- CONFIG="$PLANNING/config.json"
30
- if [ ! -f "$CONFIG" ]; then
31
- echo "Error: No config.json found at $CONFIG"
32
- exit 2
33
- fi
34
-
35
- MILESTONES_FILE="$PLANNING/MILESTONES.md"
36
- PHASES_DIR="$PLANNING/phases"
37
- MILESTONES_DIR="$PLANNING/milestones"
38
- KNOWLEDGE_DIR="$PLANNING/knowledge"
39
-
40
- PASS_COUNT=0
41
- FAIL_COUNT=0
42
- SKIP_COUNT=0
43
- FAILED_CHECKS=""
44
-
45
- # --- Helper: record check result ---
46
- record_result() {
47
- local status="$1"
48
- local name="$2"
49
- case "$status" in
50
- PASS) PASS_COUNT=$((PASS_COUNT + 1)) ;;
51
- FAIL) FAIL_COUNT=$((FAIL_COUNT + 1)); FAILED_CHECKS="$FAILED_CHECKS $name" ;;
52
- SKIP) SKIP_COUNT=$((SKIP_COUNT + 1)) ;;
53
- esac
54
- }
55
-
56
- # ============================================================
57
- # CHECK 1: Subsystem Vocabulary
58
- # ============================================================
59
- echo "=== Subsystem Vocabulary ==="
60
-
61
- SUBSYSTEM_COUNT=$(jq -r '.subsystems // [] | length' "$CONFIG" 2>/dev/null || echo "0")
62
-
63
- if [ "$SUBSYSTEM_COUNT" -eq 0 ]; then
64
- echo "Status: FAIL"
65
- echo "No subsystems array in config.json (or empty)"
66
- record_result "FAIL" "Subsystem Vocabulary"
67
- else
68
- echo "Subsystems: $SUBSYSTEM_COUNT configured"
69
- jq -r '.subsystems[]' "$CONFIG" 2>/dev/null | sed 's/^/ - /'
70
-
71
- # Run artifact scan to check for mismatches
72
- SCAN_SCRIPT="$(dirname "$0")/scan-artifact-subsystems.sh"
73
- if [ -x "$SCAN_SCRIPT" ]; then
74
- CANONICAL=$(jq -r '.subsystems[]' "$CONFIG" 2>/dev/null)
75
- ARTIFACT_VALUES=$("$SCAN_SCRIPT" --values-only 2>/dev/null | grep -v '^===' | sort -u)
76
- MISMATCHES=""
77
- while IFS= read -r val; do
78
- [ -z "$val" ] && continue
79
- if ! echo "$CANONICAL" | grep -qx "$val"; then
80
- MISMATCHES="$MISMATCHES $val"
81
- fi
82
- done <<< "$ARTIFACT_VALUES"
83
-
84
- if [ -n "$MISMATCHES" ]; then
85
- echo "Status: FAIL"
86
- echo "Artifact values not in canonical list:$MISMATCHES"
87
- record_result "FAIL" "Subsystem Vocabulary"
88
- else
89
- ARTIFACT_COUNT=$("$SCAN_SCRIPT" --values-only 2>/dev/null | grep -v '^===' | wc -l | tr -d ' ')
90
- echo "Artifacts scanned: $ARTIFACT_COUNT (all OK)"
91
- echo "Status: PASS"
92
- record_result "PASS" "Subsystem Vocabulary"
93
- fi
94
- else
95
- echo "Status: PASS"
96
- echo "(scan-artifact-subsystems.sh not found — skipped artifact validation)"
97
- record_result "PASS" "Subsystem Vocabulary"
98
- fi
99
- fi
100
- echo ""
101
-
102
- # ============================================================
103
- # CHECK 2: Milestone Directory Structure
104
- # ============================================================
105
- echo "=== Milestone Directory Structure ==="
106
-
107
- if [ ! -d "$MILESTONES_DIR" ]; then
108
- # No milestones directory at all — check if MILESTONES.md has entries
109
- if [ -f "$MILESTONES_FILE" ] && grep -q "^## " "$MILESTONES_FILE" 2>/dev/null; then
110
- echo "Status: FAIL"
111
- echo "MILESTONES.md has entries but no milestones/ directory"
112
- record_result "FAIL" "Milestone Directory Structure"
113
- else
114
- echo "Status: SKIP"
115
- echo "No completed milestones"
116
- record_result "SKIP" "Milestone Directory Structure"
117
- fi
118
- else
119
- # Look for flat files matching v*-*.md directly in milestones/
120
- FLAT_FILES=""
121
- FLAT_COUNT=0
122
- for f in "$MILESTONES_DIR"/v*-*.md; do
123
- [ -f "$f" ] || continue
124
- FLAT_FILES="$FLAT_FILES $(basename "$f")"$'\n'
125
- FLAT_COUNT=$((FLAT_COUNT + 1))
126
- done
127
-
128
- if [ "$FLAT_COUNT" -gt 0 ]; then
129
- echo "Status: FAIL"
130
- echo "Found $FLAT_COUNT flat file(s) in milestones/ (old format):"
131
- echo "$FLAT_FILES"
132
- # Check if corresponding versioned directories exist
133
- for f in "$MILESTONES_DIR"/v*-*.md; do
134
- [ -f "$f" ] || continue
135
- fname=$(basename "$f")
136
- # Extract version prefix: v0.1-ROADMAP.md -> v0.1
137
- version=$(echo "$fname" | sed 's/^\(v[0-9.]*\)-.*/\1/')
138
- if [ -d "$MILESTONES_DIR/$version" ]; then
139
- echo " $fname → directory $version/ exists (can restructure)"
140
- else
141
- echo " $fname → directory $version/ missing (need to create)"
142
- fi
143
- done
144
- record_result "FAIL" "Milestone Directory Structure"
145
- else
146
- # Count versioned directories
147
- DIR_COUNT=0
148
- for d in "$MILESTONES_DIR"/v*/; do
149
- [ -d "$d" ] || continue
150
- DIR_COUNT=$((DIR_COUNT + 1))
151
- done
152
-
153
- if [ "$DIR_COUNT" -eq 0 ]; then
154
- echo "Status: SKIP"
155
- echo "No completed milestones"
156
- record_result "SKIP" "Milestone Directory Structure"
157
- else
158
- echo "Status: PASS"
159
- echo "$DIR_COUNT versioned milestone directories"
160
- record_result "PASS" "Milestone Directory Structure"
161
- fi
162
- fi
163
- fi
164
- echo ""
165
-
166
- # ============================================================
167
- # CHECK 3: Phase Archival
168
- # ============================================================
169
- echo "=== Phase Archival ==="
170
-
171
- if [ ! -f "$MILESTONES_FILE" ] || ! grep -q "Phases completed" "$MILESTONES_FILE" 2>/dev/null; then
172
- echo "Status: SKIP"
173
- echo "No completed milestones with phase ranges in MILESTONES.md"
174
- record_result "SKIP" "Phase Archival"
175
- else
176
- ORPHAN_COUNT=0
177
- ORPHAN_LIST=""
178
-
179
- # Parse each milestone's phase range from MILESTONES.md
180
- while IFS= read -r line; do
181
- # Extract range like "1-6" or "7-8"
182
- range=$(echo "$line" | grep -o '[0-9]\+-[0-9]\+')
183
- [ -z "$range" ] && continue
184
- range_start=$(echo "$range" | cut -d'-' -f1)
185
- range_end=$(echo "$range" | cut -d'-' -f2)
186
-
187
- # Check if any phase directories in this range still exist in phases/
188
- for i in $(seq "$range_start" "$range_end"); do
189
- phase_prefix=$(printf "%02d" "$i")
190
- for dir in "$PHASES_DIR"/${phase_prefix}-*/; do
191
- [ -d "$dir" ] || continue
192
- dirname=$(basename "$dir")
193
- ORPHAN_COUNT=$((ORPHAN_COUNT + 1))
194
- ORPHAN_LIST="$ORPHAN_LIST $dirname (should be archived)"$'\n'
195
- done
196
- done
197
- done < <(grep "Phases completed" "$MILESTONES_FILE")
198
-
199
- if [ "$ORPHAN_COUNT" -gt 0 ]; then
200
- echo "Status: FAIL"
201
- echo "Found $ORPHAN_COUNT orphaned phase directories from completed milestones:"
202
- echo "$ORPHAN_LIST"
203
- record_result "FAIL" "Phase Archival"
204
- else
205
- echo "Status: PASS"
206
- echo "All completed milestone phases are archived"
207
- record_result "PASS" "Phase Archival"
208
- fi
209
- fi
210
- echo ""
211
-
212
- # ============================================================
213
- # CHECK 4: Knowledge Files
214
- # ============================================================
215
- echo "=== Knowledge Files ==="
216
-
217
- if [ "$SUBSYSTEM_COUNT" -eq 0 ]; then
218
- echo "Status: SKIP"
219
- echo "No subsystems configured — knowledge check requires subsystem vocabulary"
220
- record_result "SKIP" "Knowledge Files"
221
- elif [ ! -d "$KNOWLEDGE_DIR" ]; then
222
- echo "Status: FAIL"
223
- echo "Knowledge directory missing: .planning/knowledge/"
224
- echo "Expected files for $SUBSYSTEM_COUNT subsystems"
225
- record_result "FAIL" "Knowledge Files"
226
- else
227
- MISSING_KNOWLEDGE=""
228
- MISSING_COUNT=0
229
- PRESENT_COUNT=0
230
- while IFS= read -r subsystem; do
231
- [ -z "$subsystem" ] && continue
232
- if [ -f "$KNOWLEDGE_DIR/$subsystem.md" ]; then
233
- PRESENT_COUNT=$((PRESENT_COUNT + 1))
234
- else
235
- MISSING_COUNT=$((MISSING_COUNT + 1))
236
- MISSING_KNOWLEDGE="$MISSING_KNOWLEDGE $subsystem.md"$'\n'
237
- fi
238
- done < <(jq -r '.subsystems[]' "$CONFIG" 2>/dev/null)
239
-
240
- # Check for orphaned knowledge files (not in subsystem list)
241
- ORPHAN_KNOWLEDGE=""
242
- ORPHAN_K_COUNT=0
243
- for f in "$KNOWLEDGE_DIR"/*.md; do
244
- [ -f "$f" ] || continue
245
- fname=$(basename "$f" .md)
246
- if ! jq -r '.subsystems[]' "$CONFIG" 2>/dev/null | grep -qx "$fname"; then
247
- ORPHAN_K_COUNT=$((ORPHAN_K_COUNT + 1))
248
- ORPHAN_KNOWLEDGE="$ORPHAN_KNOWLEDGE $fname.md (not in subsystems list)"$'\n'
249
- fi
250
- done
251
-
252
- if [ "$MISSING_COUNT" -gt 0 ] || [ "$ORPHAN_K_COUNT" -gt 0 ]; then
253
- echo "Status: FAIL"
254
- echo "Coverage: $PRESENT_COUNT/$SUBSYSTEM_COUNT subsystems have knowledge files"
255
- if [ "$MISSING_COUNT" -gt 0 ]; then
256
- echo "Missing:"
257
- echo "$MISSING_KNOWLEDGE"
258
- fi
259
- if [ "$ORPHAN_K_COUNT" -gt 0 ]; then
260
- echo "Orphaned:"
261
- echo "$ORPHAN_KNOWLEDGE"
262
- fi
263
- record_result "FAIL" "Knowledge Files"
264
- else
265
- echo "Status: PASS"
266
- echo "All $SUBSYSTEM_COUNT subsystems have knowledge files"
267
- record_result "PASS" "Knowledge Files"
268
- fi
269
- fi
270
- echo ""
271
-
272
- # ============================================================
273
- # CHECK 5: Phase Summaries
274
- # ============================================================
275
- echo "=== Phase Summaries ==="
276
-
277
- if [ ! -d "$MILESTONES_DIR" ]; then
278
- echo "Status: SKIP"
279
- echo "No milestones directory"
280
- record_result "SKIP" "Phase Summaries"
281
- else
282
- MISSING_SUMMARIES=""
283
- MISSING_S_COUNT=0
284
- CHECKED=0
285
-
286
- for d in "$MILESTONES_DIR"/v*/; do
287
- [ -d "$d" ] || continue
288
- CHECKED=$((CHECKED + 1))
289
- version=$(basename "$d")
290
- if [ ! -f "$d/PHASE-SUMMARIES.md" ]; then
291
- MISSING_S_COUNT=$((MISSING_S_COUNT + 1))
292
- MISSING_SUMMARIES="$MISSING_SUMMARIES $version/PHASE-SUMMARIES.md"$'\n'
293
- fi
294
- done
295
-
296
- if [ "$CHECKED" -eq 0 ]; then
297
- echo "Status: SKIP"
298
- echo "No versioned milestone directories"
299
- record_result "SKIP" "Phase Summaries"
300
- elif [ "$MISSING_S_COUNT" -gt 0 ]; then
301
- echo "Status: FAIL"
302
- echo "Missing PHASE-SUMMARIES.md in $MISSING_S_COUNT milestone(s):"
303
- echo "$MISSING_SUMMARIES"
304
- record_result "FAIL" "Phase Summaries"
305
- else
306
- echo "Status: PASS"
307
- echo "All $CHECKED milestones have PHASE-SUMMARIES.md"
308
- record_result "PASS" "Phase Summaries"
309
- fi
310
- fi
311
- echo ""
312
-
313
- # ============================================================
314
- # CHECK 6: PLAN Cleanup
315
- # ============================================================
316
- echo "=== PLAN Cleanup ==="
317
-
318
- if [ ! -f "$MILESTONES_FILE" ] || ! grep -q "Phases completed" "$MILESTONES_FILE" 2>/dev/null; then
319
- echo "Status: SKIP"
320
- echo "No completed milestones — active phase PLANs are expected"
321
- record_result "SKIP" "PLAN Cleanup"
322
- else
323
- LEFTOVER_PLANS=""
324
- LEFTOVER_COUNT=0
325
-
326
- # Check phases/ for PLANs belonging to completed milestones
327
- while IFS= read -r line; do
328
- range=$(echo "$line" | grep -o '[0-9]\+-[0-9]\+')
329
- [ -z "$range" ] && continue
330
- range_start=$(echo "$range" | cut -d'-' -f1)
331
- range_end=$(echo "$range" | cut -d'-' -f2)
332
-
333
- for i in $(seq "$range_start" "$range_end"); do
334
- phase_prefix=$(printf "%02d" "$i")
335
- for plan in "$PHASES_DIR"/${phase_prefix}-*/*-PLAN.md; do
336
- [ -f "$plan" ] || continue
337
- LEFTOVER_COUNT=$((LEFTOVER_COUNT + 1))
338
- LEFTOVER_PLANS="$LEFTOVER_PLANS $(echo "$plan" | sed "s|$GIT_ROOT/.planning/||")"$'\n'
339
- done
340
- done
341
- done < <(grep "Phases completed" "$MILESTONES_FILE")
342
-
343
- # Check archived milestone phase directories for leftover PLANs
344
- for d in "$MILESTONES_DIR"/v*/phases/*/; do
345
- [ -d "$d" ] || continue
346
- for plan in "$d"*-PLAN.md; do
347
- [ -f "$plan" ] || continue
348
- LEFTOVER_COUNT=$((LEFTOVER_COUNT + 1))
349
- LEFTOVER_PLANS="$LEFTOVER_PLANS $(echo "$plan" | sed "s|$GIT_ROOT/.planning/||")"$'\n'
350
- done
351
- done
352
-
353
- if [ "$LEFTOVER_COUNT" -gt 0 ]; then
354
- echo "Status: FAIL"
355
- echo "Found $LEFTOVER_COUNT leftover PLAN file(s) in completed phases:"
356
- echo "$LEFTOVER_PLANS"
357
- record_result "FAIL" "PLAN Cleanup"
358
- else
359
- echo "Status: PASS"
360
- echo "No leftover PLAN files in completed phases"
361
- record_result "PASS" "PLAN Cleanup"
362
- fi
363
- fi
364
- echo ""
365
-
366
- # ============================================================
367
- # SUMMARY
368
- # ============================================================
369
- TOTAL=$((PASS_COUNT + FAIL_COUNT + SKIP_COUNT))
370
- echo "=== Summary ==="
371
- echo "Checks: $TOTAL total, $PASS_COUNT passed, $FAIL_COUNT failed, $SKIP_COUNT skipped"
372
-
373
- if [ "$FAIL_COUNT" -gt 0 ]; then
374
- echo "Issues:$FAILED_CHECKS"
375
- exit 1
376
- else
377
- echo "All checks passed"
378
- exit 0
379
- fi
@@ -1,179 +0,0 @@
1
- #!/bin/bash
2
- #
3
- # gather-milestone-stats.sh
4
- # Gathers milestone readiness status and statistics from the filesystem
5
- # and git history. Outputs structured text for the LLM to present.
6
- #
7
- # Usage: ./scripts/gather-milestone-stats.sh <start_phase> <end_phase>
8
- # Example: ./scripts/gather-milestone-stats.sh 1 6
9
-
10
- set -e
11
-
12
- # --- Validation ---
13
- if [ -z "$1" ] || [ -z "$2" ]; then
14
- echo "Error: Two arguments required"
15
- echo "Usage: $0 <start_phase> <end_phase>"
16
- exit 1
17
- fi
18
-
19
- START="$1"
20
- END="$2"
21
-
22
- if ! [[ "$START" =~ ^[0-9]+$ ]] || ! [[ "$END" =~ ^[0-9]+$ ]]; then
23
- echo "Error: Both arguments must be numeric"
24
- echo "Usage: $0 <start_phase> <end_phase>"
25
- exit 1
26
- fi
27
-
28
- if [ "$START" -gt "$END" ]; then
29
- echo "Error: Start phase ($START) cannot exceed end phase ($END)"
30
- exit 1
31
- fi
32
-
33
- # --- Find .planning from git root ---
34
- GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
35
- if [ -z "$GIT_ROOT" ]; then
36
- echo "Error: Not in a git repository"
37
- exit 1
38
- fi
39
-
40
- PHASES_DIR="$GIT_ROOT/.planning/phases"
41
- if [ ! -d "$PHASES_DIR" ]; then
42
- echo "Error: Phases directory not found at $PHASES_DIR"
43
- exit 1
44
- fi
45
-
46
- # --- Helper: check if phase number is in range (supports decimals like 02.1) ---
47
- in_range() {
48
- local phase_num="$1"
49
- echo "$phase_num" | awk -v s="$START" -v e="$END" '{
50
- val = $1 + 0
51
- if (val >= s && val <= e + 0.999) exit 0
52
- else exit 1
53
- }'
54
- }
55
-
56
- # ============================================================
57
- # READINESS
58
- # ============================================================
59
- echo "=== Readiness ==="
60
- echo ""
61
-
62
- PHASE_COUNT=0
63
- PLAN_COUNT=0
64
- COMPLETE=0
65
- INCOMPLETE_LIST=""
66
- PHASE_DETAILS=""
67
-
68
- for dir in "$PHASES_DIR"/*/; do
69
- [ -d "$dir" ] || continue
70
- dirname=$(basename "$dir")
71
- phase_num="${dirname%%-*}"
72
- phase_name="${dirname#*-}"
73
-
74
- if in_range "$phase_num"; then
75
- PHASE_COUNT=$((PHASE_COUNT + 1))
76
- phase_plans=0
77
- phase_complete=0
78
-
79
- for plan in "$dir"/*-PLAN.md; do
80
- [ -f "$plan" ] || continue
81
- PLAN_COUNT=$((PLAN_COUNT + 1))
82
- phase_plans=$((phase_plans + 1))
83
- plan_base=$(basename "$plan" -PLAN.md)
84
- summary="$dir/${plan_base}-SUMMARY.md"
85
- if [ -f "$summary" ]; then
86
- COMPLETE=$((COMPLETE + 1))
87
- phase_complete=$((phase_complete + 1))
88
- else
89
- INCOMPLETE_LIST+=" $(basename "$dir")/$(basename "$plan")"$'\n'
90
- fi
91
- done
92
-
93
- PHASE_DETAILS+="- Phase $phase_num: $phase_name ($phase_complete/$phase_plans plans)"$'\n'
94
- fi
95
- done
96
-
97
- echo "Phases: $PHASE_COUNT (range $START-$END)"
98
- echo "Plans: $PLAN_COUNT total, $COMPLETE complete"
99
- echo ""
100
- echo "$PHASE_DETAILS"
101
-
102
- if [ "$COMPLETE" -eq "$PLAN_COUNT" ] && [ "$PLAN_COUNT" -gt 0 ]; then
103
- echo "Status: READY"
104
- else
105
- INCOMPLETE=$((PLAN_COUNT - COMPLETE))
106
- echo "Incomplete ($INCOMPLETE):"
107
- echo "$INCOMPLETE_LIST"
108
- echo "Status: NOT READY"
109
- fi
110
-
111
- # ============================================================
112
- # GIT STATS
113
- # ============================================================
114
- echo ""
115
- echo "=== Git Stats ==="
116
- echo ""
117
-
118
- # Collect commits matching Mindsystem phase convention: feat(XX-YY), fix(XX-YY), etc.
119
- ALL_COMMITS=""
120
- for i in $(seq "$START" "$END"); do
121
- phase=$(printf "%02d" "$i")
122
- commits=$(git log --all --format="%H %ai %s" --grep="($phase-" 2>/dev/null || true)
123
- if [ -n "$commits" ]; then
124
- ALL_COMMITS+="$commits"$'\n'
125
- fi
126
- done
127
-
128
- # Also capture decimal phase commits (e.g., 02.1 inserted phases)
129
- for dir in "$PHASES_DIR"/*/; do
130
- [ -d "$dir" ] || continue
131
- dirname=$(basename "$dir")
132
- phase_num="${dirname%%-*}"
133
- case "$phase_num" in
134
- *.*) # Decimal phase — not captured by seq
135
- if in_range "$phase_num"; then
136
- commits=$(git log --all --format="%H %ai %s" --grep="($phase_num-" 2>/dev/null || true)
137
- if [ -n "$commits" ]; then
138
- ALL_COMMITS+="$commits"$'\n'
139
- fi
140
- fi
141
- ;;
142
- esac
143
- done
144
-
145
- # Remove empty lines, deduplicate, sort by date
146
- ALL_COMMITS=$(echo "$ALL_COMMITS" | grep -v '^$' | sort -u -k2,3)
147
-
148
- if [ -n "$ALL_COMMITS" ]; then
149
- COMMIT_COUNT=$(echo "$ALL_COMMITS" | wc -l | tr -d ' ')
150
- FIRST_LINE=$(echo "$ALL_COMMITS" | head -1)
151
- LAST_LINE=$(echo "$ALL_COMMITS" | tail -1)
152
- FIRST_HASH=$(echo "$FIRST_LINE" | awk '{print $1}')
153
- LAST_HASH=$(echo "$LAST_LINE" | awk '{print $1}')
154
- FIRST_DATE=$(echo "$FIRST_LINE" | awk '{print $2}')
155
- LAST_DATE=$(echo "$LAST_LINE" | awk '{print $2}')
156
- FIRST_MSG=$(echo "$FIRST_LINE" | cut -d' ' -f4-)
157
- LAST_MSG=$(echo "$LAST_LINE" | cut -d' ' -f4-)
158
-
159
- # Calculate days
160
- DAYS=$(python3 -c "from datetime import date; print((date.fromisoformat('$LAST_DATE') - date.fromisoformat('$FIRST_DATE')).days)" 2>/dev/null || echo "?")
161
-
162
- echo "Commits: $COMMIT_COUNT"
163
- echo "Git range: ${FIRST_HASH:0:7}..${LAST_HASH:0:7}"
164
- echo "First: $FIRST_DATE — $FIRST_MSG"
165
- echo "Last: $LAST_DATE — $LAST_MSG"
166
- echo "Timeline: $DAYS days ($FIRST_DATE → $LAST_DATE)"
167
-
168
- # Diff stats for the range
169
- DIFFSTAT=$(git diff --shortstat "${FIRST_HASH}^..${LAST_HASH}" 2>/dev/null || true)
170
- if [ -n "$DIFFSTAT" ]; then
171
- echo "Changes:$DIFFSTAT"
172
- fi
173
- else
174
- echo "No commits found matching phase patterns (expected 'feat(XX-YY): ...')"
175
- echo "Determine git range manually from git log"
176
- fi
177
-
178
- echo ""
179
- exit 0
@@ -1,79 +0,0 @@
1
- #!/bin/bash
2
- #
3
- # generate-adhoc-patch.sh
4
- # Generates a patch file from an adhoc commit, excluding documentation and generated files.
5
- #
6
- # Usage: ./scripts/generate-adhoc-patch.sh <commit-hash> <output-path>
7
- # Example: ./scripts/generate-adhoc-patch.sh abc123f .planning/adhoc/2026-01-26-fix-bug.patch
8
-
9
- set -e
10
-
11
- # --- Configuration ---
12
- # Same exclusions as generate-phase-patch.sh
13
- EXCLUSIONS=(
14
- # Documentation
15
- '.planning'
16
-
17
- # Flutter/Dart generated
18
- '*.g.dart'
19
- '*.freezed.dart'
20
- '*.gr.dart'
21
- 'generated'
22
- '.dart_tool'
23
-
24
- # Next.js/TypeScript generated
25
- 'node_modules'
26
- '.next'
27
- 'dist'
28
- 'build'
29
- '*.d.ts'
30
- '.turbo'
31
-
32
- # Common build artifacts
33
- '*.lock'
34
- )
35
-
36
- # --- Parse arguments ---
37
- COMMIT_HASH="$1"
38
- OUTPUT_PATH="$2"
39
-
40
- # --- Validation ---
41
- if [ -z "$COMMIT_HASH" ] || [ -z "$OUTPUT_PATH" ]; then
42
- echo "Error: Commit hash and output path required"
43
- echo "Usage: $0 <commit-hash> <output-path>"
44
- exit 1
45
- fi
46
-
47
- # --- Find git root ---
48
- GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
49
- if [ -z "$GIT_ROOT" ]; then
50
- echo "Error: Not in a git repository"
51
- exit 1
52
- fi
53
- cd "$GIT_ROOT"
54
-
55
- # --- Verify commit exists ---
56
- if ! git rev-parse "$COMMIT_HASH" >/dev/null 2>&1; then
57
- echo "Error: Commit $COMMIT_HASH not found"
58
- exit 1
59
- fi
60
-
61
- # --- Build exclusion arguments ---
62
- EXCLUDE_ARGS=""
63
- for pattern in "${EXCLUSIONS[@]}"; do
64
- EXCLUDE_ARGS="$EXCLUDE_ARGS ':!$pattern'"
65
- done
66
-
67
- # --- Generate diff from parent commit to specified commit ---
68
- eval "git diff \"${COMMIT_HASH}^\" \"$COMMIT_HASH\" -- . $EXCLUDE_ARGS" > "$OUTPUT_PATH"
69
-
70
- # --- Check result ---
71
- if [ ! -s "$OUTPUT_PATH" ]; then
72
- rm -f "$OUTPUT_PATH"
73
- echo "No implementation changes outside excluded patterns"
74
- echo "Patch skipped"
75
- exit 0
76
- fi
77
-
78
- PATCH_LINES=$(wc -l < "$OUTPUT_PATH" | tr -d ' ')
79
- echo "Generated: $OUTPUT_PATH ($PATCH_LINES lines)"