@hanzlaa/rcode 3.6.8 → 3.6.15

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 (142) hide show
  1. package/AGENTS.md +1 -1
  2. package/CONTRIBUTING.md +1 -1
  3. package/README.md +3 -3
  4. package/cli/generate-command-skills.cjs +5 -12
  5. package/cli/index.js +5 -1
  6. package/cli/lib/manifest.cjs +51 -43
  7. package/dist/rcode.js +32 -35
  8. package/package.json +3 -2
  9. package/rihal/bin/rihal-tools.cjs +45 -24
  10. package/rihal/commands/add-todo.md +1 -1
  11. package/rihal/commands/check-implementation-readiness.md +18 -0
  12. package/rihal/commands/create-architecture.md +18 -0
  13. package/rihal/commands/debug.md +1 -1
  14. package/rihal/commands/edit-prd.md +18 -0
  15. package/rihal/commands/memory-audit.md +1 -1
  16. package/rihal/commands/memory-distill.md +1 -1
  17. package/rihal/commands/memory-init.md +1 -1
  18. package/rihal/commands/memory-update.md +1 -1
  19. package/rihal/commands/progress.md +1 -1
  20. package/rihal/commands/resume-work.md +1 -1
  21. package/rihal/commands/retrospective.md +18 -0
  22. package/rihal/commands/review-edge-case-hunter.md +18 -0
  23. package/rihal/commands/scaffold-project.md +18 -0
  24. package/rihal/commands/validate-prd.md +18 -0
  25. package/rihal/references/agent-contracts.md +46 -20
  26. package/rihal/references/continuation-format.md +5 -6
  27. package/rihal/references/model-profile-resolution.md +41 -5
  28. package/rihal/references/phase-argument-parsing.md +31 -7
  29. package/rihal/references/research-synthesis-playbook.md +1 -1
  30. package/rihal/references/revision-loop.md +36 -9
  31. package/rihal/references/universal-anti-patterns.md +56 -12
  32. package/rihal/skills/SKILLS_INDEX.md +34 -5
  33. package/rihal/skills/actions/1-analysis/research/rihal-domain-research/SKILL.md +1 -0
  34. package/rihal/skills/actions/1-analysis/research/rihal-market-research/SKILL.md +1 -0
  35. package/rihal/skills/actions/1-analysis/research/rihal-technical-research/SKILL.md +1 -0
  36. package/rihal/skills/actions/1-analysis/rihal-document-project/SKILL.md +1 -0
  37. package/rihal/skills/actions/1-analysis/rihal-prfaq/SKILL.md +1 -0
  38. package/rihal/skills/actions/1-analysis/rihal-product-brief/SKILL.md +1 -0
  39. package/rihal/skills/actions/2-plan/rihal-create-epics-and-stories/SKILL.md +1 -0
  40. package/rihal/skills/actions/2-plan/rihal-create-epics-and-stories/workflow.md +12 -0
  41. package/rihal/skills/actions/2-plan/rihal-create-milestone/SKILL.md +1 -0
  42. package/rihal/skills/actions/2-plan/rihal-create-milestone/steps/step-06-phase-stubs.md +1 -1
  43. package/rihal/skills/actions/2-plan/rihal-create-milestone/steps/step-10-complete.md +1 -1
  44. package/rihal/skills/actions/2-plan/rihal-create-prd/SKILL.md +1 -0
  45. package/rihal/skills/actions/2-plan/rihal-create-story/SKILL.md +1 -0
  46. package/rihal/skills/actions/2-plan/rihal-create-ux-design/SKILL.md +1 -0
  47. package/rihal/skills/actions/2-plan/rihal-edit-prd/SKILL.md +1 -0
  48. package/rihal/skills/actions/2-plan/rihal-frontend-design/SKILL.md +1 -0
  49. package/rihal/skills/actions/2-plan/rihal-validate-prd/SKILL.md +1 -0
  50. package/rihal/skills/actions/3-solutioning/rihal-check-implementation-readiness/SKILL.md +1 -0
  51. package/rihal/skills/actions/3-solutioning/rihal-create-architecture/SKILL.md +1 -0
  52. package/rihal/skills/actions/3-solutioning/rihal-generate-project-context/SKILL.md +1 -0
  53. package/rihal/skills/actions/4-implementation/rihal-checkpoint-preview/SKILL.md +1 -0
  54. package/rihal/skills/actions/4-implementation/rihal-code-review/SKILL.md +1 -0
  55. package/rihal/skills/actions/4-implementation/rihal-correct-course/SKILL.md +1 -0
  56. package/rihal/skills/actions/4-implementation/rihal-debug/SKILL.md +4 -16
  57. package/rihal/skills/actions/4-implementation/rihal-dev-story/SKILL.md +1 -0
  58. package/rihal/skills/actions/4-implementation/rihal-dev-story/workflow.md +13 -0
  59. package/rihal/skills/actions/4-implementation/rihal-qa-generate-e2e-tests/SKILL.md +1 -0
  60. package/rihal/skills/actions/4-implementation/rihal-retrospective/SKILL.md +1 -0
  61. package/rihal/skills/actions/4-implementation/rihal-retrospective/workflow.md +12 -0
  62. package/rihal/skills/actions/4-implementation/rihal-scaffold-project/SKILL.md +1 -0
  63. package/rihal/skills/actions/4-implementation/rihal-sprint-planning/SKILL.md +1 -0
  64. package/rihal/skills/actions/4-implementation/rihal-sprint-planning/workflow.md +12 -0
  65. package/rihal/skills/actions/4-implementation/rihal-sprint-status/SKILL.md +1 -0
  66. package/rihal/skills/agents/ahmed-hassani-director/SKILL.md +1 -0
  67. package/rihal/skills/agents/dalil-scout/SKILL.md +1 -0
  68. package/rihal/skills/agents/fatima-qa/SKILL.md +1 -0
  69. package/rihal/skills/agents/haitham-frontend/SKILL.md +1 -0
  70. package/rihal/skills/agents/hanzla-engineer/SKILL.md +1 -0
  71. package/rihal/skills/agents/hussain-pm/SKILL.md +1 -0
  72. package/rihal/skills/agents/hussain-sm/SKILL.md +1 -0
  73. package/rihal/skills/agents/layla-designer/SKILL.md +1 -0
  74. package/rihal/skills/agents/majlis-council/SKILL.md +1 -0
  75. package/rihal/skills/agents/mariam-marketing/SKILL.md +1 -0
  76. package/rihal/skills/agents/nasser-eng-manager/SKILL.md +1 -0
  77. package/rihal/skills/agents/noor-writer/SKILL.md +1 -0
  78. package/rihal/skills/agents/raees-orchestrator/SKILL.md +1 -0
  79. package/rihal/skills/agents/rihal-cross-platform-auditor/SKILL.md +1 -0
  80. package/rihal/skills/agents/rihal-dep-auditor/SKILL.md +1 -0
  81. package/rihal/skills/agents/rihal-deviation-analyzer/SKILL.md +1 -0
  82. package/rihal/skills/agents/rihal-i18n-auditor/SKILL.md +1 -0
  83. package/rihal/skills/agents/rihal-observability-auditor/SKILL.md +1 -0
  84. package/rihal/skills/agents/sadiq-analyst/SKILL.md +1 -0
  85. package/rihal/skills/agents/waleed-architect/SKILL.md +1 -0
  86. package/rihal/skills/agents/yousef-backend/SKILL.md +1 -0
  87. package/rihal/skills/agents/zahra-branding/SKILL.md +1 -0
  88. package/rihal/skills/agents/zayd-ml/SKILL.md +1 -0
  89. package/rihal/skills/core/rihal-init/SKILL.md +1 -1
  90. package/rihal/skills/core/rihal-memory-audit/SKILL.md +5 -5
  91. package/rihal/skills/core/rihal-memory-distill/SKILL.md +5 -5
  92. package/rihal/skills/core/rihal-memory-init/SKILL.md +7 -7
  93. package/rihal/skills/core/rihal-memory-update/SKILL.md +4 -4
  94. package/rihal/team.yaml +56 -0
  95. package/rihal/templates/UAT.md +69 -18
  96. package/rihal/templates/memory/INDEX.md +2 -2
  97. package/rihal/templates/memory/distillates/project.distillate.md +2 -2
  98. package/rihal/templates/memory/distillates/stack.distillate.md +2 -2
  99. package/rihal/templates/memory/project/stack.md +1 -1
  100. package/rihal/templates/summary.md +54 -37
  101. package/rihal/templates/verification-report.md +72 -17
  102. package/rihal/workflows/analyze-dependencies.md +4 -4
  103. package/rihal/workflows/audit-fix.md +3 -3
  104. package/rihal/workflows/audit-milestone.md +12 -11
  105. package/rihal/workflows/audit-worktrees.md +163 -0
  106. package/rihal/workflows/audit.md +18 -3
  107. package/rihal/workflows/autonomous.md +2 -2
  108. package/rihal/workflows/correct-course.md +3 -3
  109. package/rihal/workflows/create-architecture.md +3 -3
  110. package/rihal/workflows/create-epics-and-stories.md +3 -3
  111. package/rihal/workflows/create-prd.md +1 -1
  112. package/rihal/workflows/diagnose-issues.md +75 -22
  113. package/rihal/workflows/discuss-phase-power.md +1 -1
  114. package/rihal/workflows/discuss-phase.md +1 -1
  115. package/rihal/workflows/document-project.md +3 -3
  116. package/rihal/workflows/edit-prd.md +3 -3
  117. package/rihal/workflows/execute-milestone.md +3 -3
  118. package/rihal/workflows/execute-sprint.md +1 -1
  119. package/rihal/workflows/execute-waves.md +27 -2
  120. package/rihal/workflows/forensics.md +3 -3
  121. package/rihal/workflows/health.md +19 -4
  122. package/rihal/workflows/help.md +0 -2
  123. package/rihal/workflows/memory-audit.md +2 -2
  124. package/rihal/workflows/memory-distill.md +2 -2
  125. package/rihal/workflows/memory-init.md +2 -2
  126. package/rihal/workflows/memory-update.md +2 -2
  127. package/rihal/workflows/new-project-roadmap.md +2 -2
  128. package/rihal/workflows/plan-research-validation.md +2 -2
  129. package/rihal/workflows/plan.md +7 -7
  130. package/rihal/workflows/research-phase.md +1 -1
  131. package/rihal/workflows/retrospective.md +3 -3
  132. package/rihal/workflows/review-adversarial.md +8 -6
  133. package/rihal/workflows/review.md +2 -2
  134. package/rihal/workflows/scaffold-project.md +3 -3
  135. package/rihal/workflows/secure-phase.md +4 -4
  136. package/rihal/workflows/session-report.md +1 -1
  137. package/rihal/workflows/status.md +6 -10
  138. package/rihal/workflows/validate-prd.md +4 -4
  139. package/rihal/workflows/verify-phase.md +3 -3
  140. package/rihal/workflows/verify-work.md +1 -1
  141. package/rihal/workflows/workstream.md +3 -3
  142. package/server/lib/html/client/views/MemoryView.js +6 -6
package/AGENTS.md CHANGED
@@ -24,7 +24,7 @@ If a user says "just keep going" or "don't stop until done", that authorization
24
24
 
25
25
  - Follow [Conventional Commits](https://www.conventionalcommits.org/) format: `type(scope): subject`
26
26
  - Types allowed: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`, `perf`, `revert`
27
- - Scopes allowed: `agents`, `skills`, `workflows`, `templates`, `dashboard`, `docs`, `config`, `github`, `commands`, `memory`, `brand`, `cli`, `ci`, `release`, `meta`, `tasks`, `migrations`, `refs`, `state`, `hooks`, `install`, `parity`, `triggers`, `dogfood`, `namespace`, `planning`, `insights`, `help`, `roadmap`, `session`, `audits`, `execute`, `executor`, `plan`, `planner`, `readme`, `sync`, `sprint`, `agent-exp`, `extensibility`, `lens-audit`, `tiers`, `build`, `council`, `doctor`, `postinstall`, `progress`, `security`, `tools`, `uninstall`, `update`, `test`, `changelog`, `scopes`, `phases`, `references`, `kanban`, `orchestrator`, plus numeric phase/sprint scopes (e.g. `docs(15)`, `feat(8.3)`)
27
+ - Scopes allowed: `agents`, `skills`, `workflows`, `templates`, `dashboard`, `docs`, `config`, `github`, `commands`, `memory`, `brand`, `cli`, `ci`, `release`, `meta`, `tasks`, `migrations`, `refs`, `state`, `hooks`, `install`, `parity`, `triggers`, `dogfood`, `namespace`, `planning`, `insights`, `help`, `roadmap`, `session`, `audits`, `execute`, `executor`, `plan`, `planner`, `readme`, `sync`, `sprint`, `agent-exp`, `extensibility`, `lens-audit`, `tiers`, `build`, `council`, `doctor`, `postinstall`, `progress`, `security`, `tools`, `uninstall`, `update`, `test`, `changelog`, `scopes`, `phases`, `references`, `kanban`, `orchestrator`, `orchpanel`, `status`, plus numeric phase/sprint scopes (e.g. `docs(15)`, `feat(8.3)`)
28
28
  - Subject: lowercase first letter, imperative mood, no trailing period, under 72 chars
29
29
  - **NEVER add Claude/AI attribution to commit messages.** No "Generated with Claude Code", no "Co-Authored-By: Claude", no "🤖 Generated". The user does not want this.
30
30
  - **NEVER use `--no-verify`** to bypass hooks. If hooks fail, fix the underlying issue.
package/CONTRIBUTING.md CHANGED
@@ -131,7 +131,7 @@ User types: /rihal-prfaq
131
131
  | Add a new `/rihal-something` slash command | Create `rihal/commands/something.md` pointing to a workflow or skill |
132
132
  | Change the steps in an existing command | Edit the workflow it points to |
133
133
  | Improve how a persona thinks (Hanzla, Waleed, etc.) | Edit `rihal/skills/agents/<name>/SKILL.md` or `rihal/agents/<name>.md` |
134
- | Add a new agent to `/rihal-council` | Edit `rihal/agents/team.yaml` + add agent file |
134
+ | Add a new agent to `/rihal-council` | Edit `rihal/team.yaml` + add agent file |
135
135
  | Improve a complex multi-stage task (PRFAQ, code review, etc.) | Edit the skill's stage reference files |
136
136
  | Add a new skill triggered by natural language | Create `rihal/skills/actions/<category>/<name>/SKILL.md` — no command file needed if slash is not required |
137
137
  | Fix a broken `@-include` reference | Check that the target file exists at `.rihal/<path>` after install |
package/README.md CHANGED
@@ -11,7 +11,7 @@ npx @hanzlaa/rcode install # one command, zero dependencies
11
11
  [![npm version](https://img.shields.io/npm/v/@hanzlaa/rcode)](https://www.npmjs.com/package/@hanzlaa/rcode)
12
12
  [![downloads](https://img.shields.io/npm/dw/@hanzlaa/rcode)](https://www.npmjs.com/package/@hanzlaa/rcode)
13
13
 
14
- Status: actively developed — published on npm as `@hanzlaa/rcode` v3.5.x, with an automated test suite covered by `node --test`.
14
+ Status: actively developed — published on npm as `@hanzlaa/rcode` v3.6.x, with an automated test suite covered by `node --test`.
15
15
 
16
16
  ---
17
17
 
@@ -81,7 +81,7 @@ See [`docs/install.md`](docs/install.md) for flavors (module subsets, IDE option
81
81
 
82
82
  ```
83
83
  /rihal-council should I rewrite auth? → 5 agents debate in parallel, 2 rounds
84
- /rihal-plan --research build a rental app → researcher grounds, plan-checker verifies
84
+ /rihal-plan --research build a rental app → researcher grounds, sprint-checker verifies
85
85
  /rihal-execute .planning/plans/01/PLAN.md → atomic commits + post-gates
86
86
  /rihal-status → phases, decisions, blockers, sessions
87
87
  ```
@@ -141,7 +141,7 @@ The design rule: **markdown owns the logic, scripts own the boundaries.** Heavy
141
141
 
142
142
  ### Verification built in
143
143
 
144
- `/rihal-plan` runs `rihal-plan-checker` to validate file/symbol references before execution. `/rihal-execute` runs `rihal-integration-checker` (cross-phase E2E) and `rihal-nyquist-auditor` (test coverage) after completion.
144
+ `/rihal-plan` runs `rihal-sprint-checker` to validate file/symbol references before execution. `/rihal-execute` runs `rihal-integration-checker` (cross-phase E2E) and `rihal-nyquist-auditor` (test coverage) after completion.
145
145
 
146
146
  ---
147
147
 
@@ -40,18 +40,11 @@ const path = require('path');
40
40
  * functional). Power users running niche commands like /rihal-prfaq or
41
41
  * /rihal-ui-phase still get them — they just don't show up in the sidebar.
42
42
  */
43
- const SIDEBAR_COMMANDS = new Set([
44
- // Navigation & status (the daily check-in)
45
- 'do', 'status', 'next',
46
- // Core lifecycle (the workflow loop)
47
- 'plan', 'execute', 'ship',
48
- // Strategic
49
- 'council',
50
- // Quality gate
51
- 'audit', 'verify-phase',
52
- // Utility
53
- 'note',
54
- ]);
43
+ // Empty sidebar stubs with user-invocable:false block direct /rihal-* invocation
44
+ // in Claude Code 2.x. Commands in .claude/commands/ already appear in slash autocomplete.
45
+ // The VS Code sidebar also shows commands directly in CC 2.x, so stubs are redundant.
46
+ // Issue #710: sidebar stubs caused "can only be invoked by Claude" error for users.
47
+ const SIDEBAR_COMMANDS = new Set([]);
55
48
 
56
49
  function parseFrontmatter(text) {
57
50
  if (!text.startsWith('---\n')) return {};
package/cli/index.js CHANGED
@@ -139,7 +139,11 @@ function countGlobalRihal(dir) {
139
139
  }
140
140
 
141
141
  async function main() {
142
- const [, , command = 'help', ...args] = process.argv;
142
+ let [, , command = 'help', ...args] = process.argv;
143
+
144
+ // Normalise flag aliases → bare-word commands
145
+ if (command === '--help' || command === '-h') command = 'help';
146
+ if (command === '--version' || command === '-v') command = 'version';
143
147
 
144
148
  // Show first-run banner before dispatching — npm hides postinstall output,
145
149
  // so this is the user's first visible confirmation that the install worked.
@@ -19,7 +19,10 @@ const path = require('path');
19
19
  * Read the expected skill set from the package source.
20
20
  * Returns { agents: Set<string>, actions: Set<string> }.
21
21
  *
22
- * `agents` are the directory names under rihal/skills/agents/ (e.g. "waleed-cto").
22
+ * `agents` are the bare names (no rihal- prefix, no .md) of the agent files
23
+ * under rihal/agents/*.md — these are what install ships to
24
+ * .claude/agents/rihal-<name>.md, .cursor/rules/rihal/agents/, etc.
25
+ * NOT the phrase-activated agent skills under rihal/skills/agents/.
23
26
  * `actions` are the skill dir names under rihal/skills/actions/, plus the
24
27
  * nested rihal/skills/actions/research/ children (flattened — matches how
25
28
  * installSkills() copies them).
@@ -28,10 +31,16 @@ function readPackageManifest(packageRoot) {
28
31
  const skillsRoot = path.join(packageRoot, 'rihal/skills');
29
32
  const manifest = { agents: new Set(), actions: new Set() };
30
33
 
31
- const agentsDir = path.join(skillsRoot, 'agents');
34
+ // Issue #783 — agents are file-based (rihal/agents/*.md), not the skill
35
+ // directories under rihal/skills/agents/. The installer ships rihal/agents/
36
+ // to every editor target; the old skill-dir source produced a different
37
+ // namespace ("fatima-qa" vs "fatima") and made doctor report constant drift.
38
+ const agentsDir = path.join(packageRoot, 'rihal/agents');
32
39
  if (fs.existsSync(agentsDir)) {
33
40
  for (const entry of fs.readdirSync(agentsDir, { withFileTypes: true })) {
34
- if (entry.isDirectory()) manifest.agents.add(entry.name);
41
+ if (!entry.isFile()) continue;
42
+ if (!entry.name.startsWith('rihal-') || !entry.name.endsWith('.md')) continue;
43
+ manifest.agents.add(entry.name.replace(/^rihal-/, '').replace(/\.md$/, ''));
35
44
  }
36
45
  }
37
46
 
@@ -154,7 +163,21 @@ function verifyClaudeInstall(cwd, packageRoot, options = {}) {
154
163
  // rihal-* dirs which excluded ALL real actions and made the diff always
155
164
  // report "everything missing." Compare directly against the prefixed set.
156
165
  const allInstalled = readInstalledDirs(skillsDir);
157
- const actionsInstalled = new Set([...allInstalled].filter((n) => pkg.actions.has(n)));
166
+ let actionsInstalled = new Set([...allInstalled].filter((n) => pkg.actions.has(n)));
167
+
168
+ // Issue #783 — global precedence fallback for action skills, mirroring the
169
+ // agent fallback above. installSkills() skips project-level skills when
170
+ // ~/.claude/skills/ already has them (#679), leaving the project skills dir
171
+ // with only command stubs. Without this fallback the verifier reports
172
+ // "actions 0/37" on every successful install in that scenario.
173
+ if (actionsInstalled.size === 0 && globalFallback) {
174
+ try {
175
+ const os = require('os');
176
+ const globalSkillsDir = path.join(os.homedir(), '.claude/skills');
177
+ const globalInstalled = readInstalledDirs(globalSkillsDir);
178
+ actionsInstalled = new Set([...globalInstalled].filter((n) => pkg.actions.has(n)));
179
+ } catch { /* non-fatal — permission errors etc. */ }
180
+ }
158
181
 
159
182
  return [
160
183
  diffSet('claude', 'agents', pkg.agents, installedAgents),
@@ -163,63 +186,48 @@ function verifyClaudeInstall(cwd, packageRoot, options = {}) {
163
186
  }
164
187
 
165
188
  /**
166
- * Verify a Cursor or Windsurf install. Both install 19 digest-based
167
- * .mdc rules (one per agent) + a rihal-code.mdc overview rule.
189
+ * Verify a Cursor or Windsurf install. Issue #783: the installer ships one
190
+ * .mdc agent rule per rihal/agents/*.md into the NESTED directory
191
+ * .cursor/rules/rihal/agents/rihal-<name>.mdc (cursor)
192
+ * .windsurf/rules/rihal/agents/rihal-<name>.mdc (windsurf)
193
+ * — not flat digest-based rules at .<ide>/rules/. Compare against the same
194
+ * agent set the Claude install uses.
168
195
  */
169
196
  function verifyRulesInstall(editor, cwd, packageRoot) {
170
197
  const pkg = readPackageManifest(packageRoot);
171
- const rulesDir = path.join(
172
- cwd,
173
- editor === 'cursor' ? '.cursor/rules' : '.windsurf/rules'
174
- );
198
+ const base = editor === 'cursor' ? '.cursor/rules' : '.windsurf/rules';
199
+ const agentsDir = path.join(cwd, base, 'rihal', 'agents');
175
200
 
176
201
  const installed = new Set();
177
- if (fs.existsSync(rulesDir)) {
178
- for (const file of fs.readdirSync(rulesDir)) {
179
- if (!file.startsWith('rihal-') || !file.endsWith('.mdc')) continue;
180
- if (file === 'rihal-code.mdc') continue; // overview meta-rule, not per-agent
181
- installed.add(file.replace(/^rihal-/, '').replace(/\.mdc$/, ''));
182
- }
183
- }
184
-
185
- // Rules are generated from digests, not agent skill dirs. Build expected
186
- // set from rihal/digests/*.md.
187
- const digestsDir = path.join(packageRoot, 'rihal/digests');
188
- const expected = new Set();
189
- if (fs.existsSync(digestsDir)) {
190
- for (const file of fs.readdirSync(digestsDir)) {
191
- if (!file.endsWith('.md') || file === 'README.md') continue;
192
- expected.add(file.replace(/\.md$/, ''));
202
+ if (fs.existsSync(agentsDir)) {
203
+ for (const entry of fs.readdirSync(agentsDir, { withFileTypes: true })) {
204
+ if (!entry.isFile()) continue; // skip the nested rules/ subdir
205
+ if (!entry.name.startsWith('rihal-') || !entry.name.endsWith('.mdc')) continue;
206
+ installed.add(entry.name.replace(/^rihal-/, '').replace(/\.mdc$/, ''));
193
207
  }
194
208
  }
195
209
 
196
- return [diffSet(editor, 'rules', expected, installed)];
210
+ return [diffSet(editor, 'agents', pkg.agents, installed)];
197
211
  }
198
212
 
199
213
  /**
200
- * Verify an Antigravity install: .antigravity/agents/rihal-<agent>.md files.
201
- * One per digest.
214
+ * Verify an Antigravity install. Issue #783: the installer ships agent files
215
+ * to the NESTED .antigravity/rihal/agents/rihal-<name>.md — not
216
+ * .antigravity/agents/. Compare against the package agent set.
202
217
  */
203
218
  function verifyAntigravityInstall(cwd, packageRoot) {
204
- const agentsDir = path.join(cwd, '.antigravity/agents');
219
+ const pkg = readPackageManifest(packageRoot);
220
+ const agentsDir = path.join(cwd, '.antigravity/rihal/agents');
205
221
  const installed = new Set();
206
222
  if (fs.existsSync(agentsDir)) {
207
- for (const file of fs.readdirSync(agentsDir)) {
208
- if (!file.startsWith('rihal-') || !file.endsWith('.md')) continue;
209
- installed.add(file.replace(/^rihal-/, '').replace(/\.md$/, ''));
210
- }
211
- }
212
-
213
- const digestsDir = path.join(packageRoot, 'rihal/digests');
214
- const expected = new Set();
215
- if (fs.existsSync(digestsDir)) {
216
- for (const file of fs.readdirSync(digestsDir)) {
217
- if (!file.endsWith('.md') || file === 'README.md') continue;
218
- expected.add(file.replace(/\.md$/, ''));
223
+ for (const entry of fs.readdirSync(agentsDir, { withFileTypes: true })) {
224
+ if (!entry.isFile()) continue;
225
+ if (!entry.name.startsWith('rihal-') || !entry.name.endsWith('.md')) continue;
226
+ installed.add(entry.name.replace(/^rihal-/, '').replace(/\.md$/, ''));
219
227
  }
220
228
  }
221
229
 
222
- return [diffSet('antigravity', 'agents', expected, installed)];
230
+ return [diffSet('antigravity', 'agents', pkg.agents, installed)];
223
231
  }
224
232
 
225
233
  /**
package/dist/rcode.js CHANGED
@@ -15029,10 +15029,12 @@ var require_manifest = __commonJS({
15029
15029
  function readPackageManifest(packageRoot) {
15030
15030
  const skillsRoot = path2.join(packageRoot, "rihal/skills");
15031
15031
  const manifest = { agents: /* @__PURE__ */ new Set(), actions: /* @__PURE__ */ new Set() };
15032
- const agentsDir = path2.join(skillsRoot, "agents");
15032
+ const agentsDir = path2.join(packageRoot, "rihal/agents");
15033
15033
  if (fs2.existsSync(agentsDir)) {
15034
15034
  for (const entry of fs2.readdirSync(agentsDir, { withFileTypes: true })) {
15035
- if (entry.isDirectory()) manifest.agents.add(entry.name);
15035
+ if (!entry.isFile()) continue;
15036
+ if (!entry.name.startsWith("rihal-") || !entry.name.endsWith(".md")) continue;
15037
+ manifest.agents.add(entry.name.replace(/^rihal-/, "").replace(/\.md$/, ""));
15036
15038
  }
15037
15039
  }
15038
15040
  function walkActions(dir) {
@@ -15101,7 +15103,16 @@ var require_manifest = __commonJS({
15101
15103
  }
15102
15104
  }
15103
15105
  const allInstalled = readInstalledDirs(skillsDir);
15104
- const actionsInstalled = new Set([...allInstalled].filter((n) => pkg.actions.has(n)));
15106
+ let actionsInstalled = new Set([...allInstalled].filter((n) => pkg.actions.has(n)));
15107
+ if (actionsInstalled.size === 0 && globalFallback) {
15108
+ try {
15109
+ const os = require("os");
15110
+ const globalSkillsDir = path2.join(os.homedir(), ".claude/skills");
15111
+ const globalInstalled = readInstalledDirs(globalSkillsDir);
15112
+ actionsInstalled = new Set([...globalInstalled].filter((n) => pkg.actions.has(n)));
15113
+ } catch {
15114
+ }
15115
+ }
15105
15116
  return [
15106
15117
  diffSet("claude", "agents", pkg.agents, installedAgents),
15107
15118
  diffSet("claude", "actions", pkg.actions, actionsInstalled)
@@ -15109,46 +15120,30 @@ var require_manifest = __commonJS({
15109
15120
  }
15110
15121
  function verifyRulesInstall(editor, cwd, packageRoot) {
15111
15122
  const pkg = readPackageManifest(packageRoot);
15112
- const rulesDir = path2.join(
15113
- cwd,
15114
- editor === "cursor" ? ".cursor/rules" : ".windsurf/rules"
15115
- );
15123
+ const base = editor === "cursor" ? ".cursor/rules" : ".windsurf/rules";
15124
+ const agentsDir = path2.join(cwd, base, "rihal", "agents");
15116
15125
  const installed = /* @__PURE__ */ new Set();
15117
- if (fs2.existsSync(rulesDir)) {
15118
- for (const file of fs2.readdirSync(rulesDir)) {
15119
- if (!file.startsWith("rihal-") || !file.endsWith(".mdc")) continue;
15120
- if (file === "rihal-code.mdc") continue;
15121
- installed.add(file.replace(/^rihal-/, "").replace(/\.mdc$/, ""));
15122
- }
15123
- }
15124
- const digestsDir = path2.join(packageRoot, "rihal/digests");
15125
- const expected = /* @__PURE__ */ new Set();
15126
- if (fs2.existsSync(digestsDir)) {
15127
- for (const file of fs2.readdirSync(digestsDir)) {
15128
- if (!file.endsWith(".md") || file === "README.md") continue;
15129
- expected.add(file.replace(/\.md$/, ""));
15126
+ if (fs2.existsSync(agentsDir)) {
15127
+ for (const entry of fs2.readdirSync(agentsDir, { withFileTypes: true })) {
15128
+ if (!entry.isFile()) continue;
15129
+ if (!entry.name.startsWith("rihal-") || !entry.name.endsWith(".mdc")) continue;
15130
+ installed.add(entry.name.replace(/^rihal-/, "").replace(/\.mdc$/, ""));
15130
15131
  }
15131
15132
  }
15132
- return [diffSet(editor, "rules", expected, installed)];
15133
+ return [diffSet(editor, "agents", pkg.agents, installed)];
15133
15134
  }
15134
15135
  function verifyAntigravityInstall(cwd, packageRoot) {
15135
- const agentsDir = path2.join(cwd, ".antigravity/agents");
15136
+ const pkg = readPackageManifest(packageRoot);
15137
+ const agentsDir = path2.join(cwd, ".antigravity/rihal/agents");
15136
15138
  const installed = /* @__PURE__ */ new Set();
15137
15139
  if (fs2.existsSync(agentsDir)) {
15138
- for (const file of fs2.readdirSync(agentsDir)) {
15139
- if (!file.startsWith("rihal-") || !file.endsWith(".md")) continue;
15140
- installed.add(file.replace(/^rihal-/, "").replace(/\.md$/, ""));
15141
- }
15142
- }
15143
- const digestsDir = path2.join(packageRoot, "rihal/digests");
15144
- const expected = /* @__PURE__ */ new Set();
15145
- if (fs2.existsSync(digestsDir)) {
15146
- for (const file of fs2.readdirSync(digestsDir)) {
15147
- if (!file.endsWith(".md") || file === "README.md") continue;
15148
- expected.add(file.replace(/\.md$/, ""));
15140
+ for (const entry of fs2.readdirSync(agentsDir, { withFileTypes: true })) {
15141
+ if (!entry.isFile()) continue;
15142
+ if (!entry.name.startsWith("rihal-") || !entry.name.endsWith(".md")) continue;
15143
+ installed.add(entry.name.replace(/^rihal-/, "").replace(/\.md$/, ""));
15149
15144
  }
15150
15145
  }
15151
- return [diffSet("antigravity", "agents", expected, installed)];
15146
+ return [diffSet("antigravity", "agents", pkg.agents, installed)];
15152
15147
  }
15153
15148
  function verifyInstall(cwd, packageRoot, editors) {
15154
15149
  const reports = [];
@@ -21764,7 +21759,9 @@ function countGlobalRihal(dir) {
21764
21759
  }
21765
21760
  }
21766
21761
  async function main() {
21767
- const [, , command = "help", ...args] = process.argv;
21762
+ let [, , command = "help", ...args] = process.argv;
21763
+ if (command === "--help" || command === "-h") command = "help";
21764
+ if (command === "--version" || command === "-v") command = "version";
21768
21765
  maybeShowFirstRunBanner();
21769
21766
  const handler = COMMANDS[command];
21770
21767
  if (!handler) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzlaa/rcode",
3
- "version": "3.6.8",
3
+ "version": "3.6.15",
4
4
  "description": "rcode — the AI team that never forgets. Persistent memory, specialist agents, and slash commands for AI IDEs. Works in Claude Code, Cursor, Gemini, VS Code, and Antigravity.",
5
5
  "main": "cli/index.js",
6
6
  "bin": {
@@ -29,6 +29,7 @@
29
29
  "CONTRIBUTING.md"
30
30
  ],
31
31
  "keywords": [
32
+ "rcode",
32
33
  "claude-code",
33
34
  "claude",
34
35
  "ai-agents",
@@ -53,7 +54,7 @@
53
54
  "license": "MIT",
54
55
  "repository": {
55
56
  "type": "git",
56
- "url": "https://github.com/hanzlahabib/rihal-code.git"
57
+ "url": "git+https://github.com/hanzlahabib/rihal-code.git"
57
58
  },
58
59
  "bugs": {
59
60
  "url": "https://github.com/hanzlahabib/rihal-code/issues"
@@ -1020,6 +1020,26 @@ function cmdState(subArgs) {
1020
1020
  }
1021
1021
  }
1022
1022
 
1023
+ // Issue #681: auto-clear the install-time _seeded_stub marker once the
1024
+ // state has graduated to a real project (project field set + at least one
1025
+ // real phase OR REQUIREMENTS.md present). project-status (#675) reads
1026
+ // _seeded_stub; if no writer ever clears it, every project stays "stub"
1027
+ // forever and downstream workflows misroute.
1028
+ if (state._seeded_stub === true) {
1029
+ const phases = Array.isArray(state.phases) ? state.phases : [];
1030
+ const firstPhaseName = phases[0]?.name || '';
1031
+ const hasRealPhase = phases.length > 1 ||
1032
+ (firstPhaseName && firstPhaseName !== 'Setup & Scaffolding');
1033
+ const hasRequirements = (() => {
1034
+ try {
1035
+ return fs.existsSync(path.join(PROJECT_ROOT, '.planning', 'REQUIREMENTS.md'));
1036
+ } catch { return false; }
1037
+ })();
1038
+ if ((state.project && hasRealPhase) || hasRequirements) {
1039
+ delete state._seeded_stub;
1040
+ }
1041
+ }
1042
+
1023
1043
  state.updated = new Date().toISOString();
1024
1044
  fs.mkdirSync(RIHAL_DIR, { recursive: true });
1025
1045
  const lockPath = statePath + '.lock';
@@ -6070,7 +6090,7 @@ function cmdProgress(args) {
6070
6090
  return insights;
6071
6091
  }
6072
6092
 
6073
- function deriveRoutes(state, roadmapPhases, diskByNum) {
6093
+ function deriveRoutes(state, roadmapPhases, diskByNum, insights) {
6074
6094
  const routes = [];
6075
6095
  const statePhases = (state && (state.state?.phases || state.phases)) || [];
6076
6096
 
@@ -6092,26 +6112,18 @@ function cmdProgress(args) {
6092
6112
  }).slice(0, 3);
6093
6113
  for (const p of pendingExec) {
6094
6114
  const k = phaseKey(p);
6095
- routes.push({
6096
- letter: 'A',
6097
- label: `Execute phase ${k} — unfinished plans`,
6098
- command: `/rihal-execute ${k}`,
6099
- });
6115
+ routes.push({ letter: 'A', label: '', command: `/rihal-execute ${k}` });
6100
6116
  }
6101
6117
 
6102
6118
  // Route B — phases with research but no plans
6103
6119
  const researchOnly = Object.entries(diskByNum)
6104
6120
  .filter(([num, d]) => d.has_research && d.plan_count === 0)
6105
6121
  .slice(0, 3);
6106
- for (const [num, d] of researchOnly) {
6107
- routes.push({
6108
- letter: 'B',
6109
- label: `Plan phase ${num} — researched, awaiting plan`,
6110
- command: `/rihal-plan-phase ${num}`,
6111
- });
6122
+ for (const [num] of researchOnly) {
6123
+ routes.push({ letter: 'B', label: '', command: `/rihal-plan ${num}` });
6112
6124
  }
6113
6125
 
6114
- // Route B' — in-progress phases without plans (the user is actively working but no SPRINT.md exists yet)
6126
+ // Route B' — in-progress phases without plans
6115
6127
  const inProgressNoPlan = statePhases
6116
6128
  .filter(p => (p.status === 'in_progress' || p.status === 'in-progress'))
6117
6129
  .filter(p => {
@@ -6121,24 +6133,32 @@ function cmdProgress(args) {
6121
6133
  .slice(0, 2);
6122
6134
  for (const p of inProgressNoPlan) {
6123
6135
  const k = phaseKey(p);
6124
- routes.push({
6125
- letter: 'B',
6126
- label: `Plan phase ${k} — in progress without SPRINT.md`,
6127
- command: `/rihal-plan ${k}`,
6128
- });
6136
+ routes.push({ letter: 'B', label: '', command: `/rihal-plan ${k}` });
6129
6137
  }
6130
6138
 
6131
6139
  // Route C — close out milestone if everything seems done
6132
6140
  const allDone = statePhases.length > 0 && statePhases.every(p => p.status === 'complete' || p.completed);
6133
6141
  if (allDone) {
6134
- routes.push({ letter: 'C', label: 'Audit current milestone', command: '/rihal-audit-milestone' });
6135
- routes.push({ letter: 'C', label: 'Complete current milestone', command: '/rihal-complete-milestone' });
6142
+ // Count unverified phases (complete but no VERIFICATION.md on disk)
6143
+ const unverifiedCount = statePhases.filter(p => {
6144
+ const disk = diskByNum[phaseKey(p)];
6145
+ return (p.status === 'complete' || p.completed) && disk && !disk.has_verification;
6146
+ }).length;
6147
+ const hasDrift = (insights || []).some(i => i.kind === 'roadmap-drift' || (i.message && i.message.includes('ROADMAP')));
6148
+ const auditArgs = [];
6149
+ if (unverifiedCount > 0) auditArgs.push(String(unverifiedCount));
6150
+ if (hasDrift) auditArgs.push('--fix-drift');
6151
+ const auditCmd = auditArgs.length > 0
6152
+ ? `/rihal-audit-milestone ${auditArgs.join(' ')}`
6153
+ : '/rihal-audit-milestone';
6154
+ routes.push({ letter: 'C', label: '', command: auditCmd });
6155
+ routes.push({ letter: 'C', label: '', command: '/rihal-complete-milestone' });
6136
6156
  }
6137
6157
 
6138
6158
  // Fallback — nothing obvious: offer status
6139
6159
  if (routes.length === 0) {
6140
- routes.push({ letter: 'A', label: 'Check progress detail', command: '/rihal-progress' });
6141
- routes.push({ letter: 'B', label: 'Start a council on what to do next', command: '/rihal-council' });
6160
+ routes.push({ letter: 'A', label: '', command: '/rihal-progress' });
6161
+ routes.push({ letter: 'B', label: '', command: '/rihal-council' });
6142
6162
  }
6143
6163
 
6144
6164
  return routes;
@@ -6208,14 +6228,15 @@ function cmdProgress(args) {
6208
6228
  }
6209
6229
 
6210
6230
  if (sub === 'routes') {
6211
- return { ok: true, routes: deriveRoutes(state, roadmapPhases, diskByNum) };
6231
+ const routeInsights = detectInsights(state, roadmapPhases, diskByNum);
6232
+ return { ok: true, routes: deriveRoutes(state, roadmapPhases, diskByNum, routeInsights) };
6212
6233
  }
6213
6234
 
6214
6235
  // sub === 'init' (default) — full snapshot
6215
6236
  const currentPhase = state && state.current_phase;
6216
6237
  const insights = detectInsights(state, roadmapPhases, diskByNum);
6217
6238
  enforceStrictGate(insights);
6218
- const routes = deriveRoutes(state, roadmapPhases, diskByNum);
6239
+ const routes = deriveRoutes(state, roadmapPhases, diskByNum, insights);
6219
6240
  const { weighted: weightedCompleted, pct: weightedPct } = computeWeightedProgress(statePhases, diskByNum);
6220
6241
 
6221
6242
  return {
@@ -2,7 +2,7 @@
2
2
  name: rihal-add-todo
3
3
  description: Capture an idea or task for later work
4
4
  argument-hint: "<todo-title>"
5
- allowed-tools: bash, read, write
5
+ allowed-tools: Bash, Read, Write
6
6
  ---
7
7
 
8
8
  @.rihal/workflows/add-todo.md
@@ -0,0 +1,18 @@
1
+ ---
2
+ name: rihal-check-implementation-readiness
3
+ description: "Verify a feature is fully ready to implement — PRD approved, architecture approved, dependencies identified — before writing code."
4
+ argument-hint: "[--phase <n>]"
5
+ allowed-tools: Read, Write, Bash, Glob, Grep, Agent
6
+ ---
7
+
8
+ <objective>
9
+ Execute check-implementation-readiness workflow
10
+ </objective>
11
+
12
+ <execution_context>
13
+ @.rihal/workflows/check-implementation-readiness.md
14
+ </execution_context>
15
+
16
+ <process>
17
+ Execute the check-implementation-readiness workflow from @.rihal/workflows/check-implementation-readiness.md end-to-end.
18
+ </process>
@@ -0,0 +1,18 @@
1
+ ---
2
+ name: rihal-create-architecture
3
+ description: "Write an Architecture Decision Record (ADR) or system design document that informs implementation."
4
+ argument-hint: "[topic]"
5
+ allowed-tools: Read, Write, Bash, Glob, Grep, AskUserQuestion, Agent
6
+ ---
7
+
8
+ <objective>
9
+ Execute create-architecture workflow
10
+ </objective>
11
+
12
+ <execution_context>
13
+ @.rihal/workflows/create-architecture.md
14
+ </execution_context>
15
+
16
+ <process>
17
+ Execute the create-architecture workflow from @.rihal/workflows/create-architecture.md end-to-end.
18
+ </process>
@@ -2,7 +2,7 @@
2
2
  name: rihal-debug
3
3
  description: Systematically investigate and diagnose issues
4
4
  argument-hint: "<issue-description>"
5
- allowed-tools: task, bash, read, grep, glob
5
+ allowed-tools: Task, Bash, Read, Grep, Glob
6
6
  ---
7
7
 
8
8
  @.rihal/workflows/debug.md
@@ -0,0 +1,18 @@
1
+ ---
2
+ name: rihal-edit-prd
3
+ description: "Update an existing PRD with revisions or clarifications. Use after validation findings or scope changes."
4
+ argument-hint: "[prd-path]"
5
+ allowed-tools: Read, Write, Bash, Glob, Grep, AskUserQuestion
6
+ ---
7
+
8
+ <objective>
9
+ Execute edit-prd workflow
10
+ </objective>
11
+
12
+ <execution_context>
13
+ @.rihal/workflows/edit-prd.md
14
+ </execution_context>
15
+
16
+ <process>
17
+ Execute the edit-prd workflow from @.rihal/workflows/edit-prd.md end-to-end.
18
+ </process>
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: rcode:memory-audit
2
+ name: rihal-memory-audit
3
3
  description: Audit the Memory Bank for stale entries, contradictions, and unfilled placeholders — read-only report
4
4
  argument-hint: "[--severity {critical|warn|info}]"
5
5
  allowed-tools:
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: rcode:memory-distill
2
+ name: rihal-memory-distill
3
3
  description: Regenerate Memory Bank distillates — token-optimised lossless compressions for fast LLM context loading
4
4
  argument-hint: "[--force] [--target {project|stack|all}]"
5
5
  allowed-tools:
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: rcode:memory-init
2
+ name: rihal-memory-init
3
3
  description: Bootstrap the rcode Memory Bank for this project — copies templates, asks 5 questions, populates seed files
4
4
  argument-hint: ""
5
5
  allowed-tools:
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: rcode:memory-update
2
+ name: rihal-memory-update
3
3
  description: Append a decision, known issue, stakeholder, or milestone update to the Memory Bank from conversation context
4
4
  argument-hint: "<content>"
5
5
  allowed-tools:
@@ -2,7 +2,7 @@
2
2
  name: rihal-progress
3
3
  description: Alias of /rihal-status --verbose — full project state dashboard with decisions, blockers, and next-step routes
4
4
  argument-hint: ""
5
- allowed-tools: bash, read, grep
5
+ allowed-tools: Bash, Read, Grep
6
6
  ---
7
7
 
8
8
  <objective>
@@ -2,7 +2,7 @@
2
2
  name: rihal-resume-work
3
3
  description: Restore project context and resume work
4
4
  argument-hint: ""
5
- allowed-tools: bash, read
5
+ allowed-tools: Bash, Read
6
6
  ---
7
7
 
8
8
  @.rihal/workflows/resume-work.md
@@ -0,0 +1,18 @@
1
+ ---
2
+ name: rihal-retrospective
3
+ description: "Run an epic retrospective and produce owned action items."
4
+ argument-hint: "[epic]"
5
+ allowed-tools: Read, Write, Bash, Glob, Grep, AskUserQuestion
6
+ ---
7
+
8
+ <objective>
9
+ Execute retrospective workflow
10
+ </objective>
11
+
12
+ <execution_context>
13
+ @.rihal/workflows/retrospective.md
14
+ </execution_context>
15
+
16
+ <process>
17
+ Execute the retrospective workflow from @.rihal/workflows/retrospective.md end-to-end.
18
+ </process>