@hanzlaa/rcode 3.4.4 → 3.4.6
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/AGENTS.md +1 -1
- package/CONTRIBUTING.md +63 -1
- package/README.md +9 -4
- package/cli/generate-command-skills.cjs +21 -9
- package/cli/index.js +0 -0
- package/cli/install.js +126 -7
- package/cli/lib/manifest.cjs +1 -1
- package/cli/uninstall.js +8 -0
- package/dist/rcode.js +1279 -2004
- package/package.json +16 -17
- package/rihal/agents/rihal-ahmed.md +2 -1
- package/rihal/agents/rihal-code-fixer.md +46 -0
- package/rihal/agents/rihal-code-reviewer.md +46 -1
- package/rihal/agents/rihal-deviation-analyzer.md +1 -0
- package/rihal/agents/rihal-docs-auditor.md +106 -1
- package/rihal/agents/rihal-edge-case-hunter.md +47 -1
- package/rihal/agents/rihal-executor.md +1 -1
- package/rihal/agents/rihal-khalid.md +40 -1
- package/rihal/agents/rihal-layla.md +2 -1
- package/rihal/agents/rihal-nasser.md +2 -1
- package/rihal/agents/rihal-noor.md +3 -2
- package/rihal/agents/rihal-nyquist-auditor.md +1 -1
- package/rihal/agents/rihal-phase-researcher.md +46 -1
- package/rihal/agents/rihal-planner.md +1 -1
- package/rihal/agents/rihal-profiler.md +45 -2
- package/rihal/agents/rihal-project-researcher.md +47 -0
- package/rihal/agents/rihal-remediation-planner.md +45 -0
- package/rihal/agents/rihal-roadmapper.md +46 -0
- package/rihal/agents/rihal-security-adversary.md +46 -1
- package/rihal/agents/rihal-security-auditor.md +45 -1
- package/rihal/agents/rihal-ui-auditor.md +44 -1
- package/rihal/agents/rihal-ux-designer.md +41 -1
- package/rihal/agents/rihal-zahra.md +2 -1
- package/rihal/agents/rihal-zayd.md +2 -1
- package/rihal/bin/lib/config.cjs +13 -1
- package/rihal/bin/lib/council-panel.cjs +185 -23
- package/rihal/bin/lib/roadmap.cjs +27 -2
- package/rihal/bin/rihal-tools.cjs +1837 -99
- package/rihal/commands/audit.md +2 -2
- package/rihal/commands/capture.md +12 -0
- package/rihal/commands/diagnose-issues.md +18 -0
- package/rihal/commands/discuss-phase-power.md +18 -0
- package/rihal/commands/feature-drift.md +18 -0
- package/rihal/commands/karpathy-audit.md +18 -0
- package/rihal/commands/lens-audit.md +70 -0
- package/rihal/commands/new-project-research.md +18 -0
- package/rihal/commands/new-project-roadmap.md +18 -0
- package/rihal/commands/phase.md +11 -0
- package/rihal/references/continuation-format.md +3 -3
- package/rihal/references/output-format.md +79 -0
- package/rihal/references/revision-loop.md +1 -1
- package/rihal/references/verb-dictionary.md +85 -28
- package/rihal/skills/actions/1-analysis/rihal-prfaq/SKILL.md +1 -1
- package/rihal/skills/actions/2-plan/rihal-create-epics-and-stories/SKILL.md +12 -2
- package/rihal/skills/actions/2-plan/rihal-create-epics-and-stories/steps/step-04-final-validation.md +12 -0
- package/rihal/skills/actions/2-plan/rihal-create-prd/SKILL.md +12 -2
- package/rihal/skills/actions/2-plan/rihal-create-story/SKILL.md +12 -2
- package/rihal/skills/actions/4-implementation/rihal-browser-verify/SKILL.md +1 -1
- package/rihal/skills/actions/4-implementation/rihal-checkpoint-preview/SKILL.md +1 -1
- package/rihal/skills/actions/4-implementation/rihal-ci/SKILL.md +1 -1
- package/rihal/skills/actions/4-implementation/rihal-code-review/SKILL.md +16 -4
- package/rihal/skills/actions/4-implementation/rihal-debug/SKILL.md +14 -1
- package/rihal/skills/actions/4-implementation/rihal-git-flow/SKILL.md +1 -1
- package/rihal/skills/actions/4-implementation/rihal-harden/SKILL.md +1 -1
- package/rihal/skills/actions/4-implementation/rihal-incremental/SKILL.md +1 -1
- package/rihal/skills/actions/4-implementation/rihal-migrate/SKILL.md +1 -1
- package/rihal/skills/actions/4-implementation/rihal-perf/SKILL.md +1 -1
- package/rihal/skills/actions/4-implementation/rihal-prove-it/SKILL.md +1 -1
- package/rihal/skills/actions/4-implementation/rihal-scaffold-project/steps/step-01-target.md +6 -0
- package/rihal/skills/actions/4-implementation/rihal-source-truth/SKILL.md +1 -1
- package/rihal/skills/actions/4-implementation/rihal-sprint-planning/SKILL.md +14 -3
- package/rihal/skills/actions/4-implementation/rihal-trim/SKILL.md +1 -1
- package/rihal/skills/agents/ahmed-hassani-director/SKILL.md +15 -1
- package/rihal/skills/agents/dalil-scout/SKILL.md +14 -2
- package/rihal/skills/agents/fatima-qa/SKILL.md +16 -1
- package/rihal/skills/agents/haitham-frontend/SKILL.md +13 -1
- package/rihal/skills/agents/hanzla-engineer/SKILL.md +13 -1
- package/rihal/skills/agents/hussain-pm/SKILL.md +16 -1
- package/rihal/skills/agents/hussain-sm/SKILL.md +14 -1
- package/rihal/skills/agents/layla-designer/SKILL.md +13 -1
- package/rihal/skills/agents/majlis-council/SKILL.md +16 -1
- package/rihal/skills/agents/mariam-marketing/SKILL.md +14 -1
- package/rihal/skills/agents/nasser-eng-manager/SKILL.md +16 -1
- package/rihal/skills/agents/noor-writer/SKILL.md +15 -1
- package/rihal/skills/agents/raees-orchestrator/SKILL.md +15 -1
- package/rihal/skills/agents/rihal-cross-platform-auditor/SKILL.md +162 -0
- package/rihal/skills/agents/rihal-dep-auditor/SKILL.md +151 -0
- package/rihal/skills/agents/rihal-deviation-analyzer/SKILL.md +78 -0
- package/rihal/skills/agents/rihal-i18n-auditor/SKILL.md +152 -0
- package/rihal/skills/agents/rihal-observability-auditor/SKILL.md +156 -0
- package/rihal/skills/agents/sadiq-analyst/SKILL.md +12 -2
- package/rihal/skills/agents/waleed-architect/SKILL.md +12 -2
- package/rihal/skills/agents/yousef-backend/SKILL.md +12 -2
- package/rihal/skills/agents/zahra-branding/SKILL.md +15 -1
- package/rihal/skills/agents/zayd-ml/SKILL.md +13 -1
- package/rihal/skills/core/rihal-advanced-elicitation/SKILL.md +2 -2
- package/rihal/skills/core/rihal-auth-audit/SKILL.md +1 -1
- package/rihal/skills/core/rihal-brainstorming/SKILL.md +13 -2
- package/rihal/skills/core/rihal-client-gate/SKILL.md +1 -1
- package/rihal/skills/core/rihal-clone-website/SKILL.md +11 -1
- package/rihal/skills/core/rihal-deploy-unify/SKILL.md +1 -1
- package/rihal/skills/core/rihal-distillator/SKILL.md +2 -2
- package/rihal/skills/core/rihal-editorial-review-prose/SKILL.md +1 -1
- package/rihal/skills/core/rihal-editorial-review-structure/SKILL.md +2 -2
- package/rihal/skills/core/rihal-help/SKILL.md +18 -1
- package/rihal/skills/core/rihal-incident-record/SKILL.md +1 -1
- package/rihal/skills/core/rihal-index-docs/SKILL.md +1 -1
- package/rihal/skills/core/rihal-memory-audit/SKILL.md +18 -1
- package/rihal/skills/core/rihal-memory-init/SKILL.md +13 -1
- package/rihal/skills/core/rihal-memory-update/SKILL.md +13 -1
- package/rihal/skills/core/rihal-mvp-graduate/SKILL.md +1 -1
- package/rihal/skills/core/rihal-ocr-consistency/SKILL.md +1 -1
- package/rihal/skills/core/rihal-rebrand/SKILL.md +1 -1
- package/rihal/skills/core/rihal-review-adversarial-general/SKILL.md +1 -1
- package/rihal/skills/core/rihal-review-edge-case-hunter/SKILL.md +17 -1
- package/rihal/skills/core/rihal-shard-doc/SKILL.md +1 -1
- package/rihal/skills/core/rihal-theme-system/SKILL.md +1 -1
- package/rihal/team.yaml +0 -7
- package/rihal/templates/RESEARCH.md +84 -0
- package/rihal/templates/VALIDATION.md +45 -0
- package/rihal/templates/memory/INDEX.md +1 -0
- package/rihal/templates/memory/project/design-system.md +128 -0
- package/rihal/templates/summary.md +33 -3
- package/rihal/workflows/add-tests.md +1 -1
- package/rihal/workflows/add-todo.md +6 -0
- package/rihal/workflows/analyze-dependencies.md +6 -0
- package/rihal/workflows/audit-fix.md +12 -0
- package/rihal/workflows/audit-milestone.md +2 -2
- package/rihal/workflows/audit.md +23 -14
- package/rihal/workflows/autonomous-smart-discuss.md +247 -0
- package/rihal/workflows/autonomous.md +54 -267
- package/rihal/workflows/capture.md +60 -0
- package/rihal/workflows/chain.md +1 -1
- package/rihal/workflows/code-review-fix.md +6 -3
- package/rihal/workflows/code-review.md +34 -10
- package/rihal/workflows/complete-milestone.md +17 -8
- package/rihal/workflows/correct-course.md +6 -0
- package/rihal/workflows/council.md +37 -23
- package/rihal/workflows/create-architecture.md +31 -0
- package/rihal/workflows/create-epics-and-stories.md +7 -1
- package/rihal/workflows/create-prd.md +25 -0
- package/rihal/workflows/dashboard.md +1 -1
- package/rihal/workflows/debug.md +8 -0
- package/rihal/workflows/decisions.md +1 -1
- package/rihal/workflows/diff.md +6 -0
- package/rihal/workflows/discuss-phase-discuss-areas.md +271 -0
- package/rihal/workflows/discuss-phase.md +27 -266
- package/rihal/workflows/do.md +51 -12
- package/rihal/workflows/docs-update.md +3 -0
- package/rihal/workflows/document-project.md +7 -1
- package/rihal/workflows/edit-prd.md +31 -0
- package/rihal/workflows/enable-hooks.md +1 -1
- package/rihal/workflows/execute-regression-gates.md +131 -0
- package/rihal/workflows/execute-sprint.md +31 -2
- package/rihal/workflows/execute-verify-phase-goal.md +136 -0
- package/rihal/workflows/execute-waves.md +404 -0
- package/rihal/workflows/execute.md +101 -642
- package/rihal/workflows/feature-drift.md +243 -0
- package/rihal/workflows/forensics.md +10 -2
- package/rihal/workflows/health.md +65 -16
- package/rihal/workflows/help.md +36 -9
- package/rihal/workflows/import.md +17 -3
- package/rihal/workflows/init.md +20 -10
- package/rihal/workflows/install.md +2 -10
- package/rihal/workflows/lens-audit.md +689 -0
- package/rihal/workflows/map-codebase.md +7 -1
- package/rihal/workflows/memory-audit.md +67 -5
- package/rihal/workflows/memory-distill.md +10 -0
- package/rihal/workflows/memory-init.md +4 -0
- package/rihal/workflows/memory-update.md +4 -0
- package/rihal/workflows/new-milestone.md +7 -1
- package/rihal/workflows/new-project-create-roadmap.md +176 -0
- package/rihal/workflows/new-project-define-requirements.md +160 -0
- package/rihal/workflows/new-project-research-decision.md +247 -0
- package/rihal/workflows/new-project.md +3 -557
- package/rihal/workflows/note.md +1 -1
- package/rihal/workflows/phase.md +54 -0
- package/rihal/workflows/plan-milestone-gaps.md +1 -1
- package/rihal/workflows/plan-prd-express.md +108 -0
- package/rihal/workflows/plan-research-validation.md +313 -0
- package/rihal/workflows/plan-spawn-planner.md +204 -0
- package/rihal/workflows/plan.md +91 -532
- package/rihal/workflows/plant-seed.md +1 -1
- package/rihal/workflows/pr-branch.md +1 -1
- package/rihal/workflows/profile-user.md +1 -1
- package/rihal/workflows/quick.md +3 -3
- package/rihal/workflows/remove-phase.md +6 -1
- package/rihal/workflows/remove-workspace.md +6 -0
- package/rihal/workflows/rerun.md +1 -1
- package/rihal/workflows/research-phase.md +4 -2
- package/rihal/workflows/resume-work.md +8 -3
- package/rihal/workflows/retrospective.md +31 -0
- package/rihal/workflows/review-adversarial.md +12 -0
- package/rihal/workflows/review.md +6 -0
- package/rihal/workflows/scaffold-project.md +31 -0
- package/rihal/workflows/scan.md +10 -0
- package/rihal/workflows/secure-phase.md +15 -2
- package/rihal/workflows/session-report.md +32 -7
- package/rihal/workflows/ship.md +7 -2
- package/rihal/workflows/show.md +6 -0
- package/rihal/workflows/sprint-status.md +4 -4
- package/rihal/workflows/status.md +2 -2
- package/rihal/workflows/ui-phase.md +1 -1
- package/rihal/workflows/undo.md +2 -3
- package/rihal/workflows/update.md +2 -2
- package/rihal/workflows/validate-phase.md +1 -1
- package/rihal/workflows/validate-prd.md +31 -0
- package/rihal/workflows/verify-phase.md +38 -5
- package/rihal/workflows/verify-work.md +25 -11
- package/rihal/workflows/workstream.md +20 -8
- package/server/lib/html/client.js +13 -63
- package/server/lib/html/shell.js +0 -1
- 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-
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
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-
|
|
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
|
|
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-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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)
|
|
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
|
-
// ----
|
|
817
|
-
(
|
|
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 {
|
|
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;
|
package/server/lib/html/shell.js
CHANGED
|
@@ -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">
|
package/server/lib/scanner.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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 });
|