@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.
- package/AGENTS.md +1 -1
- package/CONTRIBUTING.md +1 -1
- package/README.md +3 -3
- package/cli/generate-command-skills.cjs +5 -12
- package/cli/index.js +5 -1
- package/cli/lib/manifest.cjs +51 -43
- package/dist/rcode.js +32 -35
- package/package.json +3 -2
- package/rihal/bin/rihal-tools.cjs +45 -24
- package/rihal/commands/add-todo.md +1 -1
- package/rihal/commands/check-implementation-readiness.md +18 -0
- package/rihal/commands/create-architecture.md +18 -0
- package/rihal/commands/debug.md +1 -1
- package/rihal/commands/edit-prd.md +18 -0
- package/rihal/commands/memory-audit.md +1 -1
- package/rihal/commands/memory-distill.md +1 -1
- package/rihal/commands/memory-init.md +1 -1
- package/rihal/commands/memory-update.md +1 -1
- package/rihal/commands/progress.md +1 -1
- package/rihal/commands/resume-work.md +1 -1
- package/rihal/commands/retrospective.md +18 -0
- package/rihal/commands/review-edge-case-hunter.md +18 -0
- package/rihal/commands/scaffold-project.md +18 -0
- package/rihal/commands/validate-prd.md +18 -0
- package/rihal/references/agent-contracts.md +46 -20
- package/rihal/references/continuation-format.md +5 -6
- package/rihal/references/model-profile-resolution.md +41 -5
- package/rihal/references/phase-argument-parsing.md +31 -7
- package/rihal/references/research-synthesis-playbook.md +1 -1
- package/rihal/references/revision-loop.md +36 -9
- package/rihal/references/universal-anti-patterns.md +56 -12
- package/rihal/skills/SKILLS_INDEX.md +34 -5
- package/rihal/skills/actions/1-analysis/research/rihal-domain-research/SKILL.md +1 -0
- package/rihal/skills/actions/1-analysis/research/rihal-market-research/SKILL.md +1 -0
- package/rihal/skills/actions/1-analysis/research/rihal-technical-research/SKILL.md +1 -0
- package/rihal/skills/actions/1-analysis/rihal-document-project/SKILL.md +1 -0
- package/rihal/skills/actions/1-analysis/rihal-prfaq/SKILL.md +1 -0
- package/rihal/skills/actions/1-analysis/rihal-product-brief/SKILL.md +1 -0
- package/rihal/skills/actions/2-plan/rihal-create-epics-and-stories/SKILL.md +1 -0
- package/rihal/skills/actions/2-plan/rihal-create-epics-and-stories/workflow.md +12 -0
- package/rihal/skills/actions/2-plan/rihal-create-milestone/SKILL.md +1 -0
- package/rihal/skills/actions/2-plan/rihal-create-milestone/steps/step-06-phase-stubs.md +1 -1
- package/rihal/skills/actions/2-plan/rihal-create-milestone/steps/step-10-complete.md +1 -1
- package/rihal/skills/actions/2-plan/rihal-create-prd/SKILL.md +1 -0
- package/rihal/skills/actions/2-plan/rihal-create-story/SKILL.md +1 -0
- package/rihal/skills/actions/2-plan/rihal-create-ux-design/SKILL.md +1 -0
- package/rihal/skills/actions/2-plan/rihal-edit-prd/SKILL.md +1 -0
- package/rihal/skills/actions/2-plan/rihal-frontend-design/SKILL.md +1 -0
- package/rihal/skills/actions/2-plan/rihal-validate-prd/SKILL.md +1 -0
- package/rihal/skills/actions/3-solutioning/rihal-check-implementation-readiness/SKILL.md +1 -0
- package/rihal/skills/actions/3-solutioning/rihal-create-architecture/SKILL.md +1 -0
- package/rihal/skills/actions/3-solutioning/rihal-generate-project-context/SKILL.md +1 -0
- package/rihal/skills/actions/4-implementation/rihal-checkpoint-preview/SKILL.md +1 -0
- package/rihal/skills/actions/4-implementation/rihal-code-review/SKILL.md +1 -0
- package/rihal/skills/actions/4-implementation/rihal-correct-course/SKILL.md +1 -0
- package/rihal/skills/actions/4-implementation/rihal-debug/SKILL.md +4 -16
- package/rihal/skills/actions/4-implementation/rihal-dev-story/SKILL.md +1 -0
- package/rihal/skills/actions/4-implementation/rihal-dev-story/workflow.md +13 -0
- package/rihal/skills/actions/4-implementation/rihal-qa-generate-e2e-tests/SKILL.md +1 -0
- package/rihal/skills/actions/4-implementation/rihal-retrospective/SKILL.md +1 -0
- package/rihal/skills/actions/4-implementation/rihal-retrospective/workflow.md +12 -0
- package/rihal/skills/actions/4-implementation/rihal-scaffold-project/SKILL.md +1 -0
- package/rihal/skills/actions/4-implementation/rihal-sprint-planning/SKILL.md +1 -0
- package/rihal/skills/actions/4-implementation/rihal-sprint-planning/workflow.md +12 -0
- package/rihal/skills/actions/4-implementation/rihal-sprint-status/SKILL.md +1 -0
- package/rihal/skills/agents/ahmed-hassani-director/SKILL.md +1 -0
- package/rihal/skills/agents/dalil-scout/SKILL.md +1 -0
- package/rihal/skills/agents/fatima-qa/SKILL.md +1 -0
- package/rihal/skills/agents/haitham-frontend/SKILL.md +1 -0
- package/rihal/skills/agents/hanzla-engineer/SKILL.md +1 -0
- package/rihal/skills/agents/hussain-pm/SKILL.md +1 -0
- package/rihal/skills/agents/hussain-sm/SKILL.md +1 -0
- package/rihal/skills/agents/layla-designer/SKILL.md +1 -0
- package/rihal/skills/agents/majlis-council/SKILL.md +1 -0
- package/rihal/skills/agents/mariam-marketing/SKILL.md +1 -0
- package/rihal/skills/agents/nasser-eng-manager/SKILL.md +1 -0
- package/rihal/skills/agents/noor-writer/SKILL.md +1 -0
- package/rihal/skills/agents/raees-orchestrator/SKILL.md +1 -0
- package/rihal/skills/agents/rihal-cross-platform-auditor/SKILL.md +1 -0
- package/rihal/skills/agents/rihal-dep-auditor/SKILL.md +1 -0
- package/rihal/skills/agents/rihal-deviation-analyzer/SKILL.md +1 -0
- package/rihal/skills/agents/rihal-i18n-auditor/SKILL.md +1 -0
- package/rihal/skills/agents/rihal-observability-auditor/SKILL.md +1 -0
- package/rihal/skills/agents/sadiq-analyst/SKILL.md +1 -0
- package/rihal/skills/agents/waleed-architect/SKILL.md +1 -0
- package/rihal/skills/agents/yousef-backend/SKILL.md +1 -0
- package/rihal/skills/agents/zahra-branding/SKILL.md +1 -0
- package/rihal/skills/agents/zayd-ml/SKILL.md +1 -0
- package/rihal/skills/core/rihal-init/SKILL.md +1 -1
- package/rihal/skills/core/rihal-memory-audit/SKILL.md +5 -5
- package/rihal/skills/core/rihal-memory-distill/SKILL.md +5 -5
- package/rihal/skills/core/rihal-memory-init/SKILL.md +7 -7
- package/rihal/skills/core/rihal-memory-update/SKILL.md +4 -4
- package/rihal/team.yaml +56 -0
- package/rihal/templates/UAT.md +69 -18
- package/rihal/templates/memory/INDEX.md +2 -2
- package/rihal/templates/memory/distillates/project.distillate.md +2 -2
- package/rihal/templates/memory/distillates/stack.distillate.md +2 -2
- package/rihal/templates/memory/project/stack.md +1 -1
- package/rihal/templates/summary.md +54 -37
- package/rihal/templates/verification-report.md +72 -17
- package/rihal/workflows/analyze-dependencies.md +4 -4
- package/rihal/workflows/audit-fix.md +3 -3
- package/rihal/workflows/audit-milestone.md +12 -11
- package/rihal/workflows/audit-worktrees.md +163 -0
- package/rihal/workflows/audit.md +18 -3
- package/rihal/workflows/autonomous.md +2 -2
- package/rihal/workflows/correct-course.md +3 -3
- package/rihal/workflows/create-architecture.md +3 -3
- package/rihal/workflows/create-epics-and-stories.md +3 -3
- package/rihal/workflows/create-prd.md +1 -1
- package/rihal/workflows/diagnose-issues.md +75 -22
- package/rihal/workflows/discuss-phase-power.md +1 -1
- package/rihal/workflows/discuss-phase.md +1 -1
- package/rihal/workflows/document-project.md +3 -3
- package/rihal/workflows/edit-prd.md +3 -3
- package/rihal/workflows/execute-milestone.md +3 -3
- package/rihal/workflows/execute-sprint.md +1 -1
- package/rihal/workflows/execute-waves.md +27 -2
- package/rihal/workflows/forensics.md +3 -3
- package/rihal/workflows/health.md +19 -4
- package/rihal/workflows/help.md +0 -2
- package/rihal/workflows/memory-audit.md +2 -2
- package/rihal/workflows/memory-distill.md +2 -2
- package/rihal/workflows/memory-init.md +2 -2
- package/rihal/workflows/memory-update.md +2 -2
- package/rihal/workflows/new-project-roadmap.md +2 -2
- package/rihal/workflows/plan-research-validation.md +2 -2
- package/rihal/workflows/plan.md +7 -7
- package/rihal/workflows/research-phase.md +1 -1
- package/rihal/workflows/retrospective.md +3 -3
- package/rihal/workflows/review-adversarial.md +8 -6
- package/rihal/workflows/review.md +2 -2
- package/rihal/workflows/scaffold-project.md +3 -3
- package/rihal/workflows/secure-phase.md +4 -4
- package/rihal/workflows/session-report.md +1 -1
- package/rihal/workflows/status.md +6 -10
- package/rihal/workflows/validate-prd.md +4 -4
- package/rihal/workflows/verify-phase.md +3 -3
- package/rihal/workflows/verify-work.md +1 -1
- package/rihal/workflows/workstream.md +3 -3
- 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/
|
|
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
|
[](https://www.npmjs.com/package/@hanzlaa/rcode)
|
|
12
12
|
[](https://www.npmjs.com/package/@hanzlaa/rcode)
|
|
13
13
|
|
|
14
|
-
Status: actively developed — published on npm as `@hanzlaa/rcode` v3.
|
|
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,
|
|
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-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
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.
|
package/cli/lib/manifest.cjs
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
167
|
-
* .mdc
|
|
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
|
|
172
|
-
|
|
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(
|
|
178
|
-
for (const
|
|
179
|
-
if (!
|
|
180
|
-
if (
|
|
181
|
-
installed.add(
|
|
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, '
|
|
210
|
+
return [diffSet(editor, 'agents', pkg.agents, installed)];
|
|
197
211
|
}
|
|
198
212
|
|
|
199
213
|
/**
|
|
200
|
-
* Verify an Antigravity install:
|
|
201
|
-
*
|
|
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
|
|
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
|
|
208
|
-
if (!
|
|
209
|
-
|
|
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',
|
|
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(
|
|
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.
|
|
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
|
-
|
|
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
|
|
15113
|
-
|
|
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(
|
|
15118
|
-
for (const
|
|
15119
|
-
if (!
|
|
15120
|
-
if (
|
|
15121
|
-
installed.add(
|
|
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, "
|
|
15133
|
+
return [diffSet(editor, "agents", pkg.agents, installed)];
|
|
15133
15134
|
}
|
|
15134
15135
|
function verifyAntigravityInstall(cwd, packageRoot) {
|
|
15135
|
-
const
|
|
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
|
|
15139
|
-
if (!
|
|
15140
|
-
|
|
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",
|
|
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
|
-
|
|
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.
|
|
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
|
|
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
|
|
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
|
-
|
|
6135
|
-
|
|
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: '
|
|
6141
|
-
routes.push({ letter: 'B', label: '
|
|
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
|
-
|
|
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 {
|
|
@@ -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>
|
package/rihal/commands/debug.md
CHANGED
|
@@ -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>
|
|
@@ -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>
|