@hanzlaa/rcode 2.6.1 → 2.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzlaa/rcode",
3
- "version": "2.6.1",
3
+ "version": "2.6.2",
4
4
  "description": "Rihal Code (rcode) — installable context-brain for Rihalians. 43 agents, 99 slash commands, 56 skills, pullable Rihal standards. Unified install for Claude Code, Cursor, and Gemini.",
5
5
  "main": "cli/index.js",
6
6
  "bin": {
@@ -54,9 +54,9 @@ Read all files referenced by the invoking prompt's execution_context before star
54
54
  Before any phase work, verify the methodology chain has run:
55
55
 
56
56
  ```bash
57
- HAS_PRD=$([ -f .planning/prd.md ] && echo true || echo false)
57
+ HAS_PRD=$( ( ls .planning/prd.md .planning/PRD.md .planning/prds/*.md .planning/milestones/*/PRD.md 2>/dev/null | head -1 ) && echo true || echo false)
58
58
  HAS_ROADMAP_MILESTONES=$(grep -qE "^## Milestone\s+M[0-9]+" .planning/ROADMAP.md 2>/dev/null && echo true || echo false)
59
- HAS_EPICS=$([ -f .planning/epics.md ] && echo true || echo false)
59
+ HAS_EPICS=$( ( ls .planning/epics.md .planning/EPICS.md .planning/epics/*.md .planning/milestones/*/EPICS.md 2>/dev/null | head -1 ) && echo true || echo false)
60
60
  SKIP_FLAG=$(echo "$ARGUMENTS" | grep -qE "\-\-skip-prerequisites" && echo true || echo false)
61
61
  ```
62
62
 
@@ -59,15 +59,21 @@ If user picks 1-15, invoke that command. If 16, capture text and continue.
59
59
  <step name="check_project">
60
60
  **Check if project exists + state survey.**
61
61
 
62
+ Detect PRD / epics with glob — projects use either singular files (`.planning/prd.md`) OR per-milestone directories (`.planning/prds/v1.8.md`). Closes #377 — false 'create-prd first' redirects on multi-milestone repos.
63
+
62
64
  ```bash
63
65
  INIT=$(node ".rihal/bin/rihal-tools.cjs" state load 2>/dev/null)
64
- HAS_PRD=$([ -f .planning/prd.md ] && echo true || echo false)
65
- HAS_EPICS=$([ -f .planning/epics.md ] && echo true || echo false)
66
+ HAS_PRD=$( ( ls .planning/prd.md .planning/PRD.md .planning/prds/*.md .planning/milestones/*/PRD.md 2>/dev/null | head -1 ) && echo true || echo false)
67
+ HAS_EPICS=$( ( ls .planning/epics.md .planning/EPICS.md .planning/epics/*.md .planning/milestones/*/EPICS.md 2>/dev/null | head -1 ) && echo true || echo false)
66
68
  PHASE_COUNT=$(node ".rihal/bin/rihal-tools.cjs" progress init 2>/dev/null | python3 -c "import sys,json;print(json.load(sys.stdin).get('phase_count',0))" 2>/dev/null || echo 0)
67
69
  HAS_PHASES=$([ "$PHASE_COUNT" -gt 0 ] && echo true || echo false)
70
+
71
+ # State-aware milestone detection (#374) — used by explicit_intent_check
72
+ ACTIVE_MILESTONE=$(grep -m1 '^## Current Milestone' .planning/PROJECT.md 2>/dev/null | sed 's/^## Current Milestone[: ]*//' | xargs)
73
+ LAST_SHIPPED_VERSION=$(grep -m1 -oE 'v[0-9]+\.[0-9]+' .planning/MILESTONES.md 2>/dev/null | head -1)
68
74
  ```
69
75
 
70
- These flags drive the greenfield guard in the next step. `.planning/` existing alone is not enough — we need to know whether the methodology chain has actually run (PRD → milestone → epics → phases).
76
+ These flags drive the greenfield guard AND the explicit_intent_check below. `.planning/` existing alone is not enough — we need to know whether the methodology chain has actually run (PRD → milestone → epics → phases) AND which milestone is currently open.
71
77
  </step>
72
78
 
73
79
  <step name="greenfield_guard" priority="first-match">
@@ -166,13 +172,42 @@ This was a real bug: `/rihal:do "milestone bnao aur ... list down karo"` trigger
166
172
  **Behavior:**
167
173
  1. If both a verb AND a scope-noun match, fire this step.
168
174
  2. Skip the ambiguity-handling logic in the `route` step entirely.
169
- 3. Print the routing banner with `Reason: explicit user verb — "{matched verb}" + "{matched noun}"`.
170
- 4. Dispatch immediately.
175
+ 3. Apply the state-aware redirect rules below.
176
+ 4. Print the routing banner with `Reason: explicit user verb — "{matched verb}" + "{matched noun}"` plus any state-redirect explanation.
177
+ 5. Dispatch immediately.
178
+
179
+ **State-aware redirects (closes #374):**
180
+
181
+ The naive route is "user said milestone bnao → dispatch new-milestone". But if a milestone is already active, that violates the one-active-milestone convention and triggers a second prompt downstream. Apply these state-aware overrides BEFORE dispatching:
182
+
183
+ | Verb + scope | State signal | Redirect | Banner message |
184
+ |---|---|---|---|
185
+ | create + milestone | `$ACTIVE_MILESTONE` is non-empty AND user did NOT pass `--force-new-milestone` | `/rihal:add-phase` | `$ACTIVE_MILESTONE is active — adding as a phase to it instead of opening a new milestone. Override: add `--force-new-milestone` to the original input.` |
186
+ | create + milestone | No active milestone | `/rihal:new-milestone $NEXT_VERSION` (auto-derived from `$LAST_SHIPPED_VERSION` + 0.1) | `Auto-versioned $NEXT_VERSION based on last shipped $LAST_SHIPPED_VERSION.` |
187
+ | create + phase | `$HAS_PHASES=false` AND `$HAS_PRD=false` | `/rihal:create-prd` | greenfield_guard already covers this; this row is for completeness. |
188
+ | create + story | `$HAS_EPICS=false` | `/rihal:create-epics-and-stories` (greenfield_guard) | likewise. |
189
+
190
+ **Auto-version computation when no milestone is active:**
171
191
 
172
- **Edge case — multiple scope-nouns in one input** (e.g. "milestone bnao aur usmy phase 1 banao"): take the OUTER/PARENT scope. "Milestone bnao aur usmy phase X" → `/rihal:new-milestone` (parent = milestone). The dispatched command will handle the nested phase 1 internally.
192
+ ```bash
193
+ # Parse last shipped version (e.g. "v1.7"), bump minor by default
194
+ if [ -n "$LAST_SHIPPED_VERSION" ]; then
195
+ MAJOR=$(echo "$LAST_SHIPPED_VERSION" | sed -E 's/v([0-9]+)\.[0-9]+/\1/')
196
+ MINOR=$(echo "$LAST_SHIPPED_VERSION" | sed -E 's/v[0-9]+\.([0-9]+)/\1/')
197
+ NEXT_VERSION="v${MAJOR}.$((MINOR + 1))"
198
+ else
199
+ NEXT_VERSION="v1.0"
200
+ fi
201
+ ```
202
+
203
+ Pass `$NEXT_VERSION` as the dispatch arg. The user is NOT prompted to pick a version — the workflow just chose the right one based on history.
204
+
205
+ **Edge case — multiple scope-nouns in one input** (e.g. "milestone bnao aur usmy phase 1 banao"): take the OUTER/PARENT scope. "Milestone bnao aur usmy phase X" → state-aware-redirect kicks in. If active milestone exists → `/rihal:add-phase` (the inner phase becomes the dispatched action directly). If not → `/rihal:new-milestone $NEXT_VERSION` (the dispatched workflow will create phase 1 internally).
173
206
 
174
207
  **Edge case — verb without scope-noun** (e.g. "kuch karo", "do something"): do NOT fire this step. Fall through to the normal routing table which can ask for clarification.
175
208
 
209
+ **Edge case — explicit override via flag** (`--force-new-milestone`, `--force-new`): bypasses the active-milestone redirect. Use sparingly — usually for emergency hotfix tracks that genuinely need a parallel milestone.
210
+
176
211
  If this step fires, skip the route-step's ambiguity prompt entirely and proceed to display + dispatch.
177
212
  </step>
178
213