@hanzlaa/rcode 3.4.4 → 3.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. package/AGENTS.md +1 -1
  2. package/CONTRIBUTING.md +63 -1
  3. package/README.md +9 -4
  4. package/cli/generate-command-skills.cjs +5 -5
  5. package/cli/index.js +0 -0
  6. package/cli/install.js +112 -3
  7. package/cli/lib/manifest.cjs +1 -1
  8. package/cli/uninstall.js +8 -0
  9. package/dist/rcode.js +19 -1
  10. package/package.json +16 -17
  11. package/rihal/agents/rihal-ahmed.md +2 -1
  12. package/rihal/agents/rihal-code-fixer.md +46 -0
  13. package/rihal/agents/rihal-code-reviewer.md +46 -1
  14. package/rihal/agents/rihal-deviation-analyzer.md +1 -0
  15. package/rihal/agents/rihal-docs-auditor.md +106 -1
  16. package/rihal/agents/rihal-edge-case-hunter.md +47 -1
  17. package/rihal/agents/rihal-executor.md +1 -1
  18. package/rihal/agents/rihal-khalid.md +40 -1
  19. package/rihal/agents/rihal-layla.md +2 -1
  20. package/rihal/agents/rihal-nasser.md +2 -1
  21. package/rihal/agents/rihal-noor.md +3 -2
  22. package/rihal/agents/rihal-nyquist-auditor.md +1 -1
  23. package/rihal/agents/rihal-phase-researcher.md +46 -1
  24. package/rihal/agents/rihal-planner.md +1 -1
  25. package/rihal/agents/rihal-profiler.md +45 -2
  26. package/rihal/agents/rihal-project-researcher.md +47 -0
  27. package/rihal/agents/rihal-remediation-planner.md +45 -0
  28. package/rihal/agents/rihal-roadmapper.md +46 -0
  29. package/rihal/agents/rihal-security-adversary.md +46 -1
  30. package/rihal/agents/rihal-security-auditor.md +45 -1
  31. package/rihal/agents/rihal-ui-auditor.md +44 -1
  32. package/rihal/agents/rihal-ux-designer.md +41 -1
  33. package/rihal/agents/rihal-zahra.md +2 -1
  34. package/rihal/agents/rihal-zayd.md +2 -1
  35. package/rihal/bin/lib/config.cjs +13 -1
  36. package/rihal/bin/lib/council-panel.cjs +185 -23
  37. package/rihal/bin/lib/roadmap.cjs +27 -2
  38. package/rihal/bin/rihal-tools.cjs +1837 -99
  39. package/rihal/commands/audit.md +2 -2
  40. package/rihal/commands/capture.md +12 -0
  41. package/rihal/commands/diagnose-issues.md +18 -0
  42. package/rihal/commands/discuss-phase-power.md +18 -0
  43. package/rihal/commands/feature-drift.md +18 -0
  44. package/rihal/commands/karpathy-audit.md +18 -0
  45. package/rihal/commands/lens-audit.md +70 -0
  46. package/rihal/commands/new-project-research.md +18 -0
  47. package/rihal/commands/new-project-roadmap.md +18 -0
  48. package/rihal/commands/phase.md +11 -0
  49. package/rihal/references/continuation-format.md +3 -3
  50. package/rihal/references/output-format.md +79 -0
  51. package/rihal/references/revision-loop.md +1 -1
  52. package/rihal/references/verb-dictionary.md +85 -28
  53. package/rihal/skills/actions/1-analysis/rihal-prfaq/SKILL.md +1 -1
  54. package/rihal/skills/actions/2-plan/rihal-create-epics-and-stories/SKILL.md +12 -2
  55. package/rihal/skills/actions/2-plan/rihal-create-epics-and-stories/steps/step-04-final-validation.md +12 -0
  56. package/rihal/skills/actions/2-plan/rihal-create-prd/SKILL.md +12 -2
  57. package/rihal/skills/actions/2-plan/rihal-create-story/SKILL.md +12 -2
  58. package/rihal/skills/actions/4-implementation/rihal-browser-verify/SKILL.md +1 -1
  59. package/rihal/skills/actions/4-implementation/rihal-checkpoint-preview/SKILL.md +1 -1
  60. package/rihal/skills/actions/4-implementation/rihal-ci/SKILL.md +1 -1
  61. package/rihal/skills/actions/4-implementation/rihal-code-review/SKILL.md +16 -4
  62. package/rihal/skills/actions/4-implementation/rihal-debug/SKILL.md +14 -1
  63. package/rihal/skills/actions/4-implementation/rihal-git-flow/SKILL.md +1 -1
  64. package/rihal/skills/actions/4-implementation/rihal-harden/SKILL.md +1 -1
  65. package/rihal/skills/actions/4-implementation/rihal-incremental/SKILL.md +1 -1
  66. package/rihal/skills/actions/4-implementation/rihal-migrate/SKILL.md +1 -1
  67. package/rihal/skills/actions/4-implementation/rihal-perf/SKILL.md +1 -1
  68. package/rihal/skills/actions/4-implementation/rihal-prove-it/SKILL.md +1 -1
  69. package/rihal/skills/actions/4-implementation/rihal-scaffold-project/steps/step-01-target.md +6 -0
  70. package/rihal/skills/actions/4-implementation/rihal-source-truth/SKILL.md +1 -1
  71. package/rihal/skills/actions/4-implementation/rihal-sprint-planning/SKILL.md +14 -3
  72. package/rihal/skills/actions/4-implementation/rihal-trim/SKILL.md +1 -1
  73. package/rihal/skills/agents/ahmed-hassani-director/SKILL.md +15 -1
  74. package/rihal/skills/agents/dalil-scout/SKILL.md +14 -2
  75. package/rihal/skills/agents/fatima-qa/SKILL.md +16 -1
  76. package/rihal/skills/agents/haitham-frontend/SKILL.md +13 -1
  77. package/rihal/skills/agents/hanzla-engineer/SKILL.md +13 -1
  78. package/rihal/skills/agents/hussain-pm/SKILL.md +16 -1
  79. package/rihal/skills/agents/hussain-sm/SKILL.md +14 -1
  80. package/rihal/skills/agents/layla-designer/SKILL.md +13 -1
  81. package/rihal/skills/agents/majlis-council/SKILL.md +16 -1
  82. package/rihal/skills/agents/mariam-marketing/SKILL.md +14 -1
  83. package/rihal/skills/agents/nasser-eng-manager/SKILL.md +16 -1
  84. package/rihal/skills/agents/noor-writer/SKILL.md +15 -1
  85. package/rihal/skills/agents/raees-orchestrator/SKILL.md +15 -1
  86. package/rihal/skills/agents/rihal-cross-platform-auditor/SKILL.md +162 -0
  87. package/rihal/skills/agents/rihal-dep-auditor/SKILL.md +151 -0
  88. package/rihal/skills/agents/rihal-deviation-analyzer/SKILL.md +78 -0
  89. package/rihal/skills/agents/rihal-i18n-auditor/SKILL.md +152 -0
  90. package/rihal/skills/agents/rihal-observability-auditor/SKILL.md +156 -0
  91. package/rihal/skills/agents/sadiq-analyst/SKILL.md +12 -2
  92. package/rihal/skills/agents/waleed-architect/SKILL.md +12 -2
  93. package/rihal/skills/agents/yousef-backend/SKILL.md +12 -2
  94. package/rihal/skills/agents/zahra-branding/SKILL.md +15 -1
  95. package/rihal/skills/agents/zayd-ml/SKILL.md +13 -1
  96. package/rihal/skills/core/rihal-advanced-elicitation/SKILL.md +2 -2
  97. package/rihal/skills/core/rihal-auth-audit/SKILL.md +1 -1
  98. package/rihal/skills/core/rihal-brainstorming/SKILL.md +13 -2
  99. package/rihal/skills/core/rihal-client-gate/SKILL.md +1 -1
  100. package/rihal/skills/core/rihal-clone-website/SKILL.md +11 -1
  101. package/rihal/skills/core/rihal-deploy-unify/SKILL.md +1 -1
  102. package/rihal/skills/core/rihal-distillator/SKILL.md +2 -2
  103. package/rihal/skills/core/rihal-editorial-review-prose/SKILL.md +1 -1
  104. package/rihal/skills/core/rihal-editorial-review-structure/SKILL.md +2 -2
  105. package/rihal/skills/core/rihal-help/SKILL.md +18 -1
  106. package/rihal/skills/core/rihal-incident-record/SKILL.md +1 -1
  107. package/rihal/skills/core/rihal-index-docs/SKILL.md +1 -1
  108. package/rihal/skills/core/rihal-memory-audit/SKILL.md +18 -1
  109. package/rihal/skills/core/rihal-memory-init/SKILL.md +13 -1
  110. package/rihal/skills/core/rihal-memory-update/SKILL.md +13 -1
  111. package/rihal/skills/core/rihal-mvp-graduate/SKILL.md +1 -1
  112. package/rihal/skills/core/rihal-ocr-consistency/SKILL.md +1 -1
  113. package/rihal/skills/core/rihal-rebrand/SKILL.md +1 -1
  114. package/rihal/skills/core/rihal-review-adversarial-general/SKILL.md +1 -1
  115. package/rihal/skills/core/rihal-review-edge-case-hunter/SKILL.md +17 -1
  116. package/rihal/skills/core/rihal-shard-doc/SKILL.md +1 -1
  117. package/rihal/skills/core/rihal-theme-system/SKILL.md +1 -1
  118. package/rihal/team.yaml +0 -7
  119. package/rihal/templates/RESEARCH.md +84 -0
  120. package/rihal/templates/VALIDATION.md +45 -0
  121. package/rihal/templates/memory/INDEX.md +1 -0
  122. package/rihal/templates/memory/project/design-system.md +128 -0
  123. package/rihal/templates/summary.md +33 -3
  124. package/rihal/workflows/add-tests.md +1 -1
  125. package/rihal/workflows/add-todo.md +6 -0
  126. package/rihal/workflows/analyze-dependencies.md +6 -0
  127. package/rihal/workflows/audit-fix.md +12 -0
  128. package/rihal/workflows/audit-milestone.md +2 -2
  129. package/rihal/workflows/audit.md +23 -14
  130. package/rihal/workflows/autonomous-smart-discuss.md +247 -0
  131. package/rihal/workflows/autonomous.md +54 -267
  132. package/rihal/workflows/capture.md +60 -0
  133. package/rihal/workflows/chain.md +1 -1
  134. package/rihal/workflows/code-review-fix.md +6 -3
  135. package/rihal/workflows/code-review.md +34 -10
  136. package/rihal/workflows/complete-milestone.md +17 -8
  137. package/rihal/workflows/correct-course.md +6 -0
  138. package/rihal/workflows/council.md +37 -23
  139. package/rihal/workflows/create-architecture.md +31 -0
  140. package/rihal/workflows/create-epics-and-stories.md +7 -1
  141. package/rihal/workflows/create-prd.md +25 -0
  142. package/rihal/workflows/dashboard.md +1 -1
  143. package/rihal/workflows/debug.md +8 -0
  144. package/rihal/workflows/decisions.md +1 -1
  145. package/rihal/workflows/diff.md +6 -0
  146. package/rihal/workflows/discuss-phase-discuss-areas.md +271 -0
  147. package/rihal/workflows/discuss-phase.md +27 -266
  148. package/rihal/workflows/do.md +51 -12
  149. package/rihal/workflows/docs-update.md +3 -0
  150. package/rihal/workflows/document-project.md +7 -1
  151. package/rihal/workflows/edit-prd.md +31 -0
  152. package/rihal/workflows/enable-hooks.md +1 -1
  153. package/rihal/workflows/execute-regression-gates.md +131 -0
  154. package/rihal/workflows/execute-sprint.md +31 -2
  155. package/rihal/workflows/execute-verify-phase-goal.md +136 -0
  156. package/rihal/workflows/execute-waves.md +404 -0
  157. package/rihal/workflows/execute.md +101 -642
  158. package/rihal/workflows/feature-drift.md +243 -0
  159. package/rihal/workflows/forensics.md +10 -2
  160. package/rihal/workflows/health.md +65 -16
  161. package/rihal/workflows/help.md +36 -9
  162. package/rihal/workflows/import.md +17 -3
  163. package/rihal/workflows/init.md +20 -10
  164. package/rihal/workflows/install.md +2 -10
  165. package/rihal/workflows/lens-audit.md +689 -0
  166. package/rihal/workflows/map-codebase.md +7 -1
  167. package/rihal/workflows/memory-audit.md +67 -5
  168. package/rihal/workflows/memory-distill.md +10 -0
  169. package/rihal/workflows/memory-init.md +4 -0
  170. package/rihal/workflows/memory-update.md +4 -0
  171. package/rihal/workflows/new-milestone.md +7 -1
  172. package/rihal/workflows/new-project-create-roadmap.md +176 -0
  173. package/rihal/workflows/new-project-define-requirements.md +160 -0
  174. package/rihal/workflows/new-project-research-decision.md +247 -0
  175. package/rihal/workflows/new-project.md +3 -557
  176. package/rihal/workflows/note.md +1 -1
  177. package/rihal/workflows/phase.md +54 -0
  178. package/rihal/workflows/plan-milestone-gaps.md +1 -1
  179. package/rihal/workflows/plan-prd-express.md +108 -0
  180. package/rihal/workflows/plan-research-validation.md +313 -0
  181. package/rihal/workflows/plan-spawn-planner.md +204 -0
  182. package/rihal/workflows/plan.md +91 -532
  183. package/rihal/workflows/plant-seed.md +1 -1
  184. package/rihal/workflows/pr-branch.md +1 -1
  185. package/rihal/workflows/profile-user.md +1 -1
  186. package/rihal/workflows/quick.md +3 -3
  187. package/rihal/workflows/remove-phase.md +6 -1
  188. package/rihal/workflows/remove-workspace.md +6 -0
  189. package/rihal/workflows/rerun.md +1 -1
  190. package/rihal/workflows/research-phase.md +4 -2
  191. package/rihal/workflows/resume-work.md +8 -3
  192. package/rihal/workflows/retrospective.md +31 -0
  193. package/rihal/workflows/review-adversarial.md +12 -0
  194. package/rihal/workflows/review.md +6 -0
  195. package/rihal/workflows/scaffold-project.md +31 -0
  196. package/rihal/workflows/scan.md +10 -0
  197. package/rihal/workflows/secure-phase.md +15 -2
  198. package/rihal/workflows/session-report.md +32 -7
  199. package/rihal/workflows/ship.md +7 -2
  200. package/rihal/workflows/show.md +6 -0
  201. package/rihal/workflows/sprint-status.md +4 -4
  202. package/rihal/workflows/status.md +2 -2
  203. package/rihal/workflows/ui-phase.md +1 -1
  204. package/rihal/workflows/undo.md +2 -3
  205. package/rihal/workflows/update.md +2 -2
  206. package/rihal/workflows/validate-phase.md +1 -1
  207. package/rihal/workflows/validate-prd.md +31 -0
  208. package/rihal/workflows/verify-phase.md +38 -5
  209. package/rihal/workflows/verify-work.md +25 -11
  210. package/rihal/workflows/workstream.md +20 -8
  211. package/server/lib/html/client.js +13 -63
  212. package/server/lib/html/shell.js +0 -1
  213. package/server/lib/scanner.js +33 -2
@@ -24,7 +24,7 @@ If all pass: `RIHAL ► SPRINT {NN.S} VERIFIED ✓` + Next Up: `/rihal-next`.
24
24
  <available_agent_types>
25
25
  Valid Rihal subagent types (use exact names — do not fall back to 'general-purpose'):
26
26
  - rihal-planner — Creates detailed plans from phase scope
27
- - rihal-plan-checker — Reviews plan quality before execution
27
+ - rihal-sprint-checker — Reviews plan quality before execution
28
28
  </available_agent_types>
29
29
 
30
30
  <philosophy>
@@ -47,7 +47,7 @@ No Pass/Fail buttons. No severity questions. Just: "Here's what should happen. D
47
47
  If $ARGUMENTS contains a phase number, load context:
48
48
 
49
49
  ```bash
50
- INIT=$(node ".rihal/bin/rihal-tools.cjs" init verify-work "${PHASE_ARG}")
50
+ INIT=$(node ".rihal/bin/rihal-tools.cjs" init verify-work "${PHASE_ARG}" 2>/dev/null)
51
51
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
52
52
  AGENT_SKILLS_PLANNER=$(node ".rihal/bin/rihal-tools.cjs" agent-skills rihal-planner 2>/dev/null)
53
53
  AGENT_SKILLS_CHECKER=$(node ".rihal/bin/rihal-tools.cjs" agent-skills rihal-checker 2>/dev/null)
@@ -250,7 +250,7 @@ Proceed to `present_test`.
250
250
  Render the checkpoint from the structured UAT file instead of composing it freehand:
251
251
 
252
252
  ```bash
253
- CHECKPOINT=$(node ".rihal/bin/rihal-tools.cjs" uat render-checkpoint --file "$uat_path" --raw)
253
+ CHECKPOINT=$(node ".rihal/bin/rihal-tools.cjs" uat render-checkpoint --file "$uat_path" --raw 2>/dev/null || echo "")
254
254
  if [[ "$CHECKPOINT" == @file:* ]]; then CHECKPOINT=$(cat "${CHECKPOINT#@file:}"); fi
255
255
  ```
256
256
 
@@ -443,7 +443,7 @@ All tests passed. Ready to continue.
443
443
 
444
444
  - `/rihal-secure-phase {phase}` — security review (required before advancing)
445
445
  - `/rihal-plan {next}` — Plan next phase
446
- - `/rihal-execute-phase {next}` — Execute next phase
446
+ - `/rihal-execute {next}` — Execute next phase
447
447
  - `/rihal-ui-review {phase}` — visual quality audit (if frontend files were modified)
448
448
  ```
449
449
 
@@ -458,7 +458,7 @@ If `SECURITY_CFG` is `false` OR (`SECURITY_FILE` exists AND `threats_open` is `0
458
458
  All tests passed. Ready to continue.
459
459
 
460
460
  - `/rihal-plan {next}` — Plan next phase
461
- - `/rihal-execute-phase {next}` — Execute next phase
461
+ - `/rihal-execute {next}` — Execute next phase
462
462
  - `/rihal-secure-phase {phase}` — security review
463
463
  - `/rihal-ui-review {phase}` — visual quality audit (if frontend files were modified)
464
464
  ```
@@ -518,11 +518,12 @@ ${AGENT_SKILLS_PLANNER}
518
518
  </planning_context>
519
519
 
520
520
  <downstream_consumer>
521
- Output consumed by /rihal-execute-phase
521
+ Output consumed by /rihal-execute
522
522
  Plans must be executable prompts.
523
523
  </downstream_consumer>
524
524
  """,
525
525
  subagent_type="rihal-planner",
526
+ model="sonnet",
526
527
  model="{planner_model}",
527
528
  description="Plan gap fixes for Phase {phase}"
528
529
  )
@@ -547,7 +548,7 @@ Display:
547
548
 
548
549
  Initialize: `iteration_count = 1`
549
550
 
550
- Spawn rihal-plan-checker:
551
+ Spawn rihal-sprint-checker:
551
552
 
552
553
  ```
553
554
  Task(
@@ -571,7 +572,8 @@ Return one of:
571
572
  - ## ISSUES FOUND — structured issue list
572
573
  </expected_output>
573
574
  """,
574
- subagent_type="rihal-plan-checker",
575
+ subagent_type="rihal-sprint-checker",
576
+ model="sonnet",
575
577
  model="{checker_model}",
576
578
  description="Verify Phase {phase} fix plans"
577
579
  )
@@ -616,6 +618,7 @@ Do NOT replan from scratch unless issues are fundamental.
616
618
  </instructions>
617
619
  """,
618
620
  subagent_type="rihal-planner",
621
+ model="sonnet",
619
622
  model="{planner_model}",
620
623
  description="Revise Phase {phase} plans"
621
624
  )
@@ -659,7 +662,7 @@ Plans verified and ready for execution.
659
662
 
660
663
  **Execute fixes** — run fix plans
661
664
 
662
- `/clear` then `/rihal-execute-phase {phase} --gaps-only`
665
+ `/clear` then `/rihal-execute {phase} --gaps-only`
663
666
 
664
667
  ───────────────────────────────────────────────────────────────
665
668
  ```
@@ -711,7 +714,18 @@ Default to **major** if unclear. User can correct if needed.
711
714
  - [ ] Committed on completion
712
715
  - [ ] If issues: parallel debug agents diagnose root causes
713
716
  - [ ] If issues: rihal-planner creates fix plans (gap_closure mode)
714
- - [ ] If issues: rihal-plan-checker verifies fix plans
717
+ - [ ] If issues: rihal-sprint-checker verifies fix plans
715
718
  - [ ] If issues: revision loop until plans pass (max 3 iterations)
716
- - [ ] Ready for `/rihal-execute-phase --gaps-only` when complete
719
+ - [ ] Ready for `/rihal-execute --gaps-only` when complete
717
720
  </success_criteria>
721
+
722
+ ## On Completion
723
+
724
+ When gaps found and fix plans generated:
725
+ /rihal-execute {phase} --gaps-only — re-execute just the gap plans
726
+ /rihal-progress — see updated phase status
727
+
728
+ When all tests pass:
729
+ /rihal-add-tests {phase} — generate unit + E2E tests for this phase
730
+ /rihal-next — advance to next phase
731
+ /rihal-plan {next} — plan the next phase
@@ -55,12 +55,12 @@ If validation fails, print error and STOP.
55
55
 
56
56
  **Execute:**
57
57
  ```bash
58
- node .rihal/bin/rihal-tools.cjs state workstream-create --name "$NAME"
58
+ node .rihal/bin/rihal-tools.cjs state workstream-create --name "$NAME" 2>/dev/null || echo '{"ok":false,"error":"workstream-create failed"}'
59
59
  ```
60
60
 
61
61
  **Output:**
62
62
  ```
63
- Workstream created: {name}
63
+ Workstream created: {name}
64
64
  ID: {id}
65
65
  Active: false
66
66
  Phases: 0
@@ -74,12 +74,12 @@ Set it as active unless user specifies `--no-activate` (not currently supported
74
74
 
75
75
  **Execute:**
76
76
  ```bash
77
- node .rihal/bin/rihal-tools.cjs state workstream-switch --name "$NAME"
77
+ node .rihal/bin/rihal-tools.cjs state workstream-switch --name "$NAME" 2>/dev/null || echo '{"ok":false,"error":"workstream-switch failed"}'
78
78
  ```
79
79
 
80
80
  **Output:**
81
81
  ```
82
- Switched to workstream: {name}
82
+ Switched to workstream: {name}
83
83
  Previous: {old_name}
84
84
  Phases in this workstream: {count}
85
85
  ```
@@ -88,7 +88,7 @@ node .rihal/bin/rihal-tools.cjs state workstream-switch --name "$NAME"
88
88
 
89
89
  **Execute:**
90
90
  ```bash
91
- node .rihal/bin/rihal-tools.cjs state workstream-list
91
+ node .rihal/bin/rihal-tools.cjs state workstream-list 2>/dev/null || echo '[]'
92
92
  ```
93
93
 
94
94
  **Output (formatted table):**
@@ -104,7 +104,7 @@ API Refactor ✗ ✗ 1 2026-04-09
104
104
 
105
105
  **Execute:**
106
106
  ```bash
107
- node .rihal/bin/rihal-tools.cjs state workstream-status
107
+ node .rihal/bin/rihal-tools.cjs state workstream-status 2>/dev/null || echo '{"ok":false,"error":"no active workstream"}'
108
108
  ```
109
109
 
110
110
  **Output:**
@@ -128,12 +128,12 @@ Recent phases:
128
128
 
129
129
  **Execute:**
130
130
  ```bash
131
- node .rihal/bin/rihal-tools.cjs state workstream-complete --name "$NAME"
131
+ node .rihal/bin/rihal-tools.cjs state workstream-complete --name "$NAME" 2>/dev/null || echo '{"ok":false,"error":"workstream-complete failed"}'
132
132
  ```
133
133
 
134
134
  **Output:**
135
135
  ```
136
- Marked workstream complete: {name}
136
+ Marked workstream complete: {name}
137
137
  Completed at: {ISO date}
138
138
  All phases: {count}
139
139
  Commits in this workstream: {count}
@@ -195,3 +195,15 @@ If arguments are invalid, missing files, or subagent fails:
195
195
  - Check that required files exist
196
196
  - Retry with clearer arguments or report the specific error to the user
197
197
 
198
+
199
+ ## On Completion
200
+
201
+ /rihal-plan {next_phase} — plan next phase in this workstream
202
+ /rihal-next — get suggested next action
203
+ /rihal-progress — see all workstreams and phases
204
+
205
+ ## ▶ Next Up
206
+
207
+ - **Workstream created:** `/rihal-execute {workstream-phase}` — begin execution
208
+ - **View all workstreams:** `/rihal-progress` — see parallel workstream status
209
+ - **Stuck:** `/rihal-forensics` — diagnose any blocked workstream
@@ -161,7 +161,7 @@ function phaseCard(p) {
161
161
  const sps = p.sprints || [];
162
162
  const stories = sps.flatMap(s => s.stories || []);
163
163
  const done = stories.filter(t => t.status === 'done' || t.status === 'completed').length;
164
- const isCur = p.id === S.currentPhase;
164
+ const isCur = String(p.id) === String(S.currentPhase);
165
165
  return '<div class="item item-clickable" onclick="navTo(\\'phases/' + p.id + '\\')"' +
166
166
  (isCur ? ' style="border-left-color:var(--accent-amber)"' : '') + '>' +
167
167
  '<div class="item-title">Phase ' + esc(p.id) + ' — ' + esc(p.name) +
@@ -180,6 +180,7 @@ function sprintCard(s) {
180
180
  const stories = s.stories || [];
181
181
  const done = stories.filter(t => t.status === 'done' || t.status === 'completed').length;
182
182
  const isCur = s.id === S.currentSprint;
183
+ const phaseId = s.phaseId || s.id || '';
183
184
  return '<div class="item item-clickable' + (isCur ? ' sprint-current' : '') + '" onclick="navTo(\\'sprints/' + s.id + '\\')"' +
184
185
  (isCur ? ' style="border-left-color:var(--accent-amber);background:rgba(245,158,11,0.04)"' : '') + '>' +
185
186
  '<div class="item-title">Sprint ' + esc(s.id) + ' — ' + esc(s.goal || 'No goal') +
@@ -190,6 +191,7 @@ function sprintCard(s) {
190
191
  (s.velocity_target != null ? tag('Target: ' + s.velocity_target + 'pts') : '') +
191
192
  (s.velocity_actual != null ? tag('Actual: ' + s.velocity_actual + 'pts') : '') + '</div>' +
192
193
  '<div style="margin-top:6px;">' + progressBar(done, stories.length) + '</div>' +
194
+ (stories.length === 0 ? '<div class="empty-action" style="margin-top:var(--space-2);font-size:var(--text-xs);">No tasks — run <code>/rihal-plan ' + esc(phaseId) + '</code> to populate</div>' : '') +
193
195
  (s.started_at ? '<div style="color:var(--text-muted);font-size:var(--text-xs);margin-top:4px;">' +
194
196
  humanDate(s.started_at) + (s.completed_at ? ' → ' + humanDate(s.completed_at) : ' → ongoing') + '</div>' : '') +
195
197
  '</div>';
@@ -451,7 +453,7 @@ function renderMilestones(subId) {
451
453
  function renderPhases(subId) {
452
454
  const el = document.getElementById('view-phases');
453
455
  if (subId) {
454
- const p = _phases.find(ph => ph.id === subId || ph.number === subId);
456
+ const p = _phases.find(ph => String(ph.id) === String(subId) || String(ph.number) === String(subId));
455
457
  // Fix #319: guard against missing sprints key
456
458
  if (!p) { el.innerHTML = breadcrumb('Phases','phases') + '<div class="empty">Phase not found.</div>'; return; }
457
459
  const sps = Array.isArray(p.sprints) ? p.sprints : [];
@@ -501,7 +503,7 @@ function renderSprints(subId) {
501
503
  const el = document.getElementById('view-sprints');
502
504
  const sprints = allSprints();
503
505
  if (subId) {
504
- const s = sprints.find(sp => sp.id === subId);
506
+ const s = sprints.find(sp => String(sp.id) === String(subId));
505
507
  if (!s) { el.innerHTML = breadcrumb('All Sprints','sprints') + '<div class="empty">Sprint not found.</div>'; return; }
506
508
  const rawStories = Array.isArray(s.stories) ? s.stories : [];
507
509
  const stories = rawStories.map(function(t) { return Object.assign({}, t, {sprintId: s.id, sprintGoal: s.goal || '', phaseId: s.phaseId, phaseName: s.phaseName}); });
@@ -578,7 +580,11 @@ function renderTasks() {
578
580
  }
579
581
 
580
582
  function renderTasksGrouped(tasks) {
581
- if (!tasks.length) return '<div class="empty">No tasks yet.<div class="empty-action">Run /rihal-create-story to add tasks</div></div>';
583
+ if (!tasks.length) {
584
+ var phaseHint = S.currentPhase ? ' ' + S.currentPhase : '';
585
+ return '<div class="empty">No tasks yet.' +
586
+ '<div class="empty-action">Run <code>/rihal-plan' + phaseHint + '</code> to generate tasks for this project.</div></div>';
587
+ }
582
588
  const groups = {};
583
589
  for (const t of tasks) {
584
590
  const key = t.sprintId || 'unassigned';
@@ -813,61 +819,13 @@ function filterItems(input, listId) {
813
819
  });
814
820
  }
815
821
 
816
- // ---- File tree (sidebar) ----
817
- (async function() {
818
- let groups = [];
819
- try { const r = await fetch('/api/files'); groups = await r.json(); } catch { return; }
820
- const tree = document.getElementById('sidebar-file-tree');
821
- if (!tree) return;
822
- // #301: search input
823
- let h = '<div style="padding:0 var(--space-2) var(--space-2);"><input class="filter-input" style="width:100%;max-width:none;" type="text" placeholder="Search files…" id="file-tree-search" oninput="filterFileTree(this.value)"></div>';
824
- h += '<div class="file-tree" id="file-tree-items">';
825
- h += groups.map(function(g) {
826
- // Support sub-groups (e.g. Phases with per-phase sub-groups)
827
- if (g.subGroups) {
828
- return '<details class="file-tree-group" open><summary>' + g.group + '</summary>' +
829
- g.subGroups.map(function(sg) {
830
- return '<details class="file-tree-subgroup" open style="margin-left:var(--space-2);margin-bottom:var(--space-1);">' +
831
- '<summary style="font-size:var(--text-xs);font-weight:500;color:var(--text-secondary);cursor:pointer;padding:var(--space-1) 0;user-select:none;">' + sg.subGroup + ' <span style="color:var(--text-muted);font-weight:400;">(' + sg.files.length + ')</span></summary>' +
832
- sg.files.map(function(f) {
833
- return '<span class="file-tree-item" data-path="' + esc(f.path) + '" data-filter-text="' + esc(f.label + ' ' + f.path + ' ' + sg.subGroup).toLowerCase() + '" style="padding-left:var(--space-4);">' + esc(f.label) + '</span>';
834
- }).join('') + '</details>';
835
- }).join('') + '</details>';
836
- }
837
- return '<details class="file-tree-group" open><summary>' + g.group + '</summary>' +
838
- g.files.map(function(f) {
839
- return '<span class="file-tree-item" data-path="' + esc(f.path) + '" data-filter-text="' + esc(f.label + ' ' + f.path).toLowerCase() + '">' + esc(f.label) + '</span>';
840
- }).join('') + '</details>';
841
- }).join('');
842
- h += '</div>';
843
- tree.innerHTML = h;
844
- tree.addEventListener('click', async function(e) {
845
- var item = e.target.closest('.file-tree-item');
846
- if (!item) return;
847
- tree.querySelectorAll('.file-tree-item').forEach(function(el) { el.classList.remove('selected'); });
848
- item.classList.add('selected');
849
- navTo('files');
850
- var fv = document.getElementById('file-view');
851
- // #315: loading skeleton
852
- fv.innerHTML = '<div class="skeleton"></div><div class="skeleton" style="height:200px;"></div>';
853
- // Scroll file content into view
854
- fv.scrollIntoView({ behavior: 'smooth', block: 'start' });
855
- try {
856
- var resp = await fetch('/api/file?path=' + encodeURIComponent(item.dataset.path));
857
- if (!resp.ok) { fv.innerHTML = '<div style="color:var(--accent-red);padding:16px;">Failed to load file.</div>'; return; }
858
- var text = await resp.text();
859
- // #298: show file path + #299: copy path button
860
- fv.innerHTML = '<div class="file-path-header"><span>' + esc(item.dataset.path) + '</span>' +
861
- '<button class="copy-btn" onclick="navigator.clipboard.writeText(\\'' + item.dataset.path.replace(/'/g, "\\\\'") + '\\');showToast(\\'Path copied!\\')">📋 Copy</button></div>' +
862
- '<div class="md-render">' + renderMd(text) + '</div>';
863
- } catch { fv.innerHTML = '<div style="color:var(--accent-red);padding:16px;">Network error.</div>'; }
864
- });
865
- })();
822
+ // ---- Shared file-list fetch (single request for all consumers) ----
823
+ const _filesPromise = fetch('/api/files').then(function(r) { return r.json(); }).catch(function() { return []; });
866
824
 
867
825
  // Inline file list inside Files view
868
826
  (async function() {
869
827
  let groups = [];
870
- try { const r = await fetch('/api/files'); groups = await r.json(); } catch { return; }
828
+ try { groups = await _filesPromise; } catch { return; }
871
829
  const el = document.getElementById('file-list-inline');
872
830
  if (!el) return;
873
831
  let h = '<div class="filter-bar"><input class="filter-input" type="text" placeholder="Search files…" oninput="filterInlineFiles(this.value)"></div>';
@@ -929,14 +887,6 @@ async function loadInlineFile(el) {
929
887
  } catch { fv.innerHTML = '<div style="color:var(--accent-red);padding:16px;">Network error.</div>'; }
930
888
  }
931
889
 
932
- // #301: filter file tree
933
- function filterFileTree(q) {
934
- q = q.toLowerCase().trim();
935
- document.querySelectorAll('#file-tree-items .file-tree-item').forEach(function(item) {
936
- item.style.display = !q || (item.dataset.filterText || '').includes(q) ? '' : 'none';
937
- });
938
- }
939
-
940
890
  // ---- Markdown + frontmatter ----
941
891
  function stripFrontmatter(md) {
942
892
  if (!md.startsWith('---')) return md;
@@ -83,7 +83,6 @@ ${renderCss()}
83
83
  <button class="nav-link" data-view="decisions">⚖ Decisions</button>
84
84
  <button class="nav-link" data-view="memory">🧠 Memory Bank</button>
85
85
  </nav>
86
- <div id="sidebar-file-tree" style="margin-top:var(--space-4);padding:0 var(--space-2);"></div>
87
86
  </aside>
88
87
  <div id="sidebar-backdrop" onclick="closeSidebar()"></div>
89
88
  <div class="content-area" id="main-content">
@@ -78,11 +78,42 @@ function scanState(rihalDir) {
78
78
  const phasesDir = path.join(projectDir, '.planning', 'phases');
79
79
  state.phases = state.raw.phases.map(p => {
80
80
  const sprints = Array.isArray(p.sprints) ? p.sprints : [];
81
- const allStories = sprints.flatMap(s => Array.isArray(s.stories) ? s.stories : []);
81
+ let allStories = sprints.flatMap(s => Array.isArray(s.stories) ? s.stories : []);
82
+
83
+ // #590 fallback: when state.json has no stories but a SPRINT.md exists, parse task lines
84
+ // so the Tasks view is not empty. Synthetic entries carry _source:'sprint-md-fallback'.
85
+ if (allStories.length === 0) {
86
+ const phasesDir2 = path.join(projectDir, '.planning', 'phases');
87
+ try {
88
+ const intIdFb = String(p.id || p.number || '').split('.')[0];
89
+ const paddedFb = intIdFb.padStart(2, '0');
90
+ const dirsFb = fs.readdirSync(phasesDir2, { withFileTypes: true });
91
+ const matchFb = dirsFb.find(d => d.isDirectory() && d.name.startsWith(paddedFb + '-'));
92
+ if (matchFb) {
93
+ const allMdFb = fs.readdirSync(path.join(phasesDir2, matchFb.name)).filter(f => f.endsWith('.md'));
94
+ const numberedFb = allMdFb.filter(f => /^\d{2}-\d{2}-/.test(f)).sort().reverse();
95
+ const chosenFb = numberedFb.length ? numberedFb[0] : allMdFb.sort().reverse()[0];
96
+ if (chosenFb) {
97
+ const mdText = safeReadText(path.join(phasesDir2, matchFb.name, chosenFb));
98
+ if (mdText) {
99
+ const taskLines = mdText.split('\n').filter(l => /^[-*]\s+\[[ xX]\]/.test(l.trim()));
100
+ allStories = taskLines.map((l, i) => ({
101
+ id: (p.id || p.number || 'p') + '-task-' + (i + 1),
102
+ title: l.replace(/^[-*]\s+\[[ xX]\]\s*/, '').trim() || ('Task ' + (i + 1)),
103
+ status: /\[[xX]\]/.test(l) ? 'done' : 'todo',
104
+ _source: 'sprint-md-fallback',
105
+ }));
106
+ }
107
+ }
108
+ }
109
+ } catch { /* phasesDir missing or unreadable */ }
110
+ }
111
+
82
112
  const done = allStories.filter(s => s.status === 'done' || s.status === 'completed').length;
83
113
  const total = allStories.length;
84
114
 
85
- const padded = String(p.id || p.number || '').padStart(2, '0');
115
+ const intId = String(p.id || p.number || '').split('.')[0];
116
+ const padded = intId.padStart(2, '0');
86
117
  let phaseDir = null, sprintFile = null;
87
118
  try {
88
119
  const dirs = fs.readdirSync(phasesDir, { withFileTypes: true });