@hanzlaa/rcode 3.4.17 ā 3.4.18
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/cli/index.js +47 -0
- package/cli/install.js +7 -0
- package/dist/rcode.js +41 -0
- package/package.json +1 -1
- package/rihal/bin/rihal-tools.cjs +5 -2
- package/rihal/workflows/execute.md +2 -1
- package/rihal/workflows/plan.md +3 -2
package/cli/index.js
CHANGED
|
@@ -91,9 +91,56 @@ Documentation: https://github.com/hanzlahabib/rihal-code
|
|
|
91
91
|
`.trim());
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
/**
|
|
95
|
+
* npm 10+ suppresses postinstall script output during global installs, so users
|
|
96
|
+
* who run `npm install -g @hanzlaa/rcode` see only "added 1 package" with no
|
|
97
|
+
* confirmation that 100+ commands and skills were installed. We detect a fresh
|
|
98
|
+
* install on the first `rcode <anything>` invocation by checking for a marker
|
|
99
|
+
* file under ~/.rihal/, print a one-time welcome banner, then drop the marker.
|
|
100
|
+
*/
|
|
101
|
+
function maybeShowFirstRunBanner() {
|
|
102
|
+
const os = require('os');
|
|
103
|
+
const home = os.homedir();
|
|
104
|
+
const markerDir = path.join(home, '.rihal');
|
|
105
|
+
const marker = path.join(markerDir, '.welcome-shown');
|
|
106
|
+
if (fs.existsSync(marker)) return;
|
|
107
|
+
|
|
108
|
+
// Only show banner if global install actually ran ā i.e. ~/.claude/commands/
|
|
109
|
+
// has rihal-*.md files. Otherwise this is a developer running from source.
|
|
110
|
+
const globalCommands = path.join(home, '.claude', 'commands');
|
|
111
|
+
let hasGlobalRihal = false;
|
|
112
|
+
try {
|
|
113
|
+
hasGlobalRihal = fs.existsSync(globalCommands) &&
|
|
114
|
+
fs.readdirSync(globalCommands).some(f => f.startsWith('rihal-') && f.endsWith('.md'));
|
|
115
|
+
} catch { /* unreadable */ }
|
|
116
|
+
if (!hasGlobalRihal) return;
|
|
117
|
+
|
|
118
|
+
console.log(`\nš Rihal Code v${PACKAGE_JSON.version} ā first run detected.\n`);
|
|
119
|
+
console.log(` ā ${countGlobalRihal(globalCommands)} slash commands installed ā ~/.claude/commands/`);
|
|
120
|
+
console.log(` ā All /rihal-* commands available in every Claude Code project.`);
|
|
121
|
+
console.log(`\n To set up a project: cd my-project && rcode install`);
|
|
122
|
+
console.log(` Show all commands: rcode help`);
|
|
123
|
+
console.log(` Diagnose issues: rcode doctor\n`);
|
|
124
|
+
|
|
125
|
+
try {
|
|
126
|
+
fs.mkdirSync(markerDir, { recursive: true });
|
|
127
|
+
fs.writeFileSync(marker, `installed ${PACKAGE_JSON.version} at ${new Date().toISOString()}\n`);
|
|
128
|
+
} catch { /* if we can't write the marker, banner shows again next time ā annoying but not broken */ }
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function countGlobalRihal(dir) {
|
|
132
|
+
try {
|
|
133
|
+
return fs.readdirSync(dir).filter(f => f.startsWith('rihal-') && f.endsWith('.md')).length;
|
|
134
|
+
} catch { return 0; }
|
|
135
|
+
}
|
|
136
|
+
|
|
94
137
|
async function main() {
|
|
95
138
|
const [, , command = 'help', ...args] = process.argv;
|
|
96
139
|
|
|
140
|
+
// Show first-run banner before dispatching ā npm hides postinstall output,
|
|
141
|
+
// so this is the user's first visible confirmation that the install worked.
|
|
142
|
+
maybeShowFirstRunBanner();
|
|
143
|
+
|
|
97
144
|
const handler = COMMANDS[command];
|
|
98
145
|
if (!handler) {
|
|
99
146
|
console.error(`Unknown command: ${command}`);
|
package/cli/install.js
CHANGED
|
@@ -177,6 +177,13 @@ function parseArgs(argv) {
|
|
|
177
177
|
opts.target = path.resolve(positional[0]);
|
|
178
178
|
opts.targetProvided = true;
|
|
179
179
|
}
|
|
180
|
+
// --global without an explicit target means "install to ~/.claude/" ā i.e.
|
|
181
|
+
// home dir. Without this, running `rcode install --global` from inside a
|
|
182
|
+
// project directory wrote rihal artifacts to that project, not to the user's
|
|
183
|
+
// home where Claude Code reads global commands from.
|
|
184
|
+
if (opts.global && !opts.targetProvided) {
|
|
185
|
+
opts.target = os.homedir();
|
|
186
|
+
}
|
|
180
187
|
if (!opts.projectName) opts.projectName = path.basename(opts.target);
|
|
181
188
|
return opts;
|
|
182
189
|
}
|
package/dist/rcode.js
CHANGED
|
@@ -15063,6 +15063,9 @@ var require_install = __commonJS({
|
|
|
15063
15063
|
opts.target = path2.resolve(positional[0]);
|
|
15064
15064
|
opts.targetProvided = true;
|
|
15065
15065
|
}
|
|
15066
|
+
if (opts.global && !opts.targetProvided) {
|
|
15067
|
+
opts.target = os.homedir();
|
|
15068
|
+
}
|
|
15066
15069
|
if (!opts.projectName) opts.projectName = path2.basename(opts.target);
|
|
15067
15070
|
return opts;
|
|
15068
15071
|
}
|
|
@@ -20945,8 +20948,46 @@ Getting started:
|
|
|
20945
20948
|
Documentation: https://github.com/hanzlahabib/rihal-code
|
|
20946
20949
|
`.trim());
|
|
20947
20950
|
}
|
|
20951
|
+
function maybeShowFirstRunBanner() {
|
|
20952
|
+
const os = require("os");
|
|
20953
|
+
const home = os.homedir();
|
|
20954
|
+
const markerDir = path.join(home, ".rihal");
|
|
20955
|
+
const marker = path.join(markerDir, ".welcome-shown");
|
|
20956
|
+
if (fs.existsSync(marker)) return;
|
|
20957
|
+
const globalCommands = path.join(home, ".claude", "commands");
|
|
20958
|
+
let hasGlobalRihal = false;
|
|
20959
|
+
try {
|
|
20960
|
+
hasGlobalRihal = fs.existsSync(globalCommands) && fs.readdirSync(globalCommands).some((f) => f.startsWith("rihal-") && f.endsWith(".md"));
|
|
20961
|
+
} catch {
|
|
20962
|
+
}
|
|
20963
|
+
if (!hasGlobalRihal) return;
|
|
20964
|
+
console.log(`
|
|
20965
|
+
\u{1F54C} Rihal Code v${PACKAGE_JSON.version} \u2014 first run detected.
|
|
20966
|
+
`);
|
|
20967
|
+
console.log(` \u2713 ${countGlobalRihal(globalCommands)} slash commands installed \u2192 ~/.claude/commands/`);
|
|
20968
|
+
console.log(` \u2713 All /rihal-* commands available in every Claude Code project.`);
|
|
20969
|
+
console.log(`
|
|
20970
|
+
To set up a project: cd my-project && rcode install`);
|
|
20971
|
+
console.log(` Show all commands: rcode help`);
|
|
20972
|
+
console.log(` Diagnose issues: rcode doctor
|
|
20973
|
+
`);
|
|
20974
|
+
try {
|
|
20975
|
+
fs.mkdirSync(markerDir, { recursive: true });
|
|
20976
|
+
fs.writeFileSync(marker, `installed ${PACKAGE_JSON.version} at ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
20977
|
+
`);
|
|
20978
|
+
} catch {
|
|
20979
|
+
}
|
|
20980
|
+
}
|
|
20981
|
+
function countGlobalRihal(dir) {
|
|
20982
|
+
try {
|
|
20983
|
+
return fs.readdirSync(dir).filter((f) => f.startsWith("rihal-") && f.endsWith(".md")).length;
|
|
20984
|
+
} catch {
|
|
20985
|
+
return 0;
|
|
20986
|
+
}
|
|
20987
|
+
}
|
|
20948
20988
|
async function main() {
|
|
20949
20989
|
const [, , command = "help", ...args] = process.argv;
|
|
20990
|
+
maybeShowFirstRunBanner();
|
|
20950
20991
|
const handler = COMMANDS[command];
|
|
20951
20992
|
if (!handler) {
|
|
20952
20993
|
console.error(`Unknown command: ${command}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzlaa/rcode",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.18",
|
|
4
4
|
"description": "rcode ā the memory bank for AI-driven SaaS teams. Persistent project context, distinctive engineering personas, and phase-based workflows. Built by Rihal. Works in Claude Code, Cursor, Gemini, VS Code, and Antigravity.",
|
|
5
5
|
"main": "cli/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -2390,6 +2390,11 @@ function cmdState(subArgs) {
|
|
|
2390
2390
|
// Format B ā heading style: ## Phase 01 ā Name / ### Phase 01: Name
|
|
2391
2391
|
// Milestone heading is also matched in any of: "## Milestone M1", "## Milestone v1.0 ā Name",
|
|
2392
2392
|
// "**Milestone: v1.0 ā Name**".
|
|
2393
|
+
|
|
2394
|
+
// Issue #651 ā must be declared in outer scope. The prune step at end of
|
|
2395
|
+
// sync references seenNums even when roadmap_exists is false (no-op prune
|
|
2396
|
+
// path), causing 'seenNums is not defined' crash.
|
|
2397
|
+
const seenNums = new Set();
|
|
2393
2398
|
if (parsed.roadmap_exists) {
|
|
2394
2399
|
const roadmap = fs.readFileSync(roadmapPath, 'utf8');
|
|
2395
2400
|
const milestoneMatches = [
|
|
@@ -2425,8 +2430,6 @@ function cmdState(subArgs) {
|
|
|
2425
2430
|
parsed.phases_normalized = beforeClean - cleaned.length;
|
|
2426
2431
|
state.phases = cleaned;
|
|
2427
2432
|
|
|
2428
|
-
const seenNums = new Set();
|
|
2429
|
-
|
|
2430
2433
|
const upsertPhase = (phaseNum, phaseName, phaseGoal) => {
|
|
2431
2434
|
if (!/^\d/.test(phaseNum)) return;
|
|
2432
2435
|
if (phaseName.toLowerCase() === 'phase') return;
|
|
@@ -573,7 +573,8 @@ If `CODE_REVIEW_ENABLED` is `"false"`: display "Code review skipped (workflow.co
|
|
|
573
573
|
REVIEWER_MODEL=$(node ".rihal/bin/rihal-tools.cjs" resolve-model code-reviewer 2>/dev/null | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>{try{console.log(JSON.parse(d).model)}catch{console.log('')}})" || echo "sonnet")
|
|
574
574
|
REVIEWER_MODEL=${REVIEWER_MODEL:-sonnet}
|
|
575
575
|
REVIEWER_SKILLS=$(node ".rihal/bin/rihal-tools.cjs" agent-skills rihal-code-reviewer 2>/dev/null || echo "")
|
|
576
|
-
|
|
576
|
+
# Issue #652 ā no leading zeros. Variable name kept for backward compat in this workflow.
|
|
577
|
+
PADDED="${PHASE_NUMBER}"
|
|
577
578
|
REVIEW_FILE="${PHASE_DIR}/${PADDED}-REVIEW.md"
|
|
578
579
|
```
|
|
579
580
|
|
package/rihal/workflows/plan.md
CHANGED
|
@@ -209,8 +209,9 @@ Exit workflow.
|
|
|
209
209
|
|
|
210
210
|
```bash
|
|
211
211
|
EXISTING_PLAN_COUNT=$(ls "${PHASE_DIR}"/*-SPRINT.md 2>/dev/null | wc -l | tr -d ' ')
|
|
212
|
-
|
|
213
|
-
|
|
212
|
+
# Issue #652 ā no leading zeros in planning artifacts. Phase 8 not 08, plan 2 not 02.
|
|
213
|
+
NEXT_PLAN_NUMBER=$((EXISTING_PLAN_COUNT + 1))
|
|
214
|
+
PADDED_PHASE="${PHASE}"
|
|
214
215
|
GAP_PLAN_FILENAME="${PADDED_PHASE}-${NEXT_PLAN_NUMBER}-SPRINT.md"
|
|
215
216
|
GAP_PLAN_PATH="${PHASE_DIR}/${GAP_PLAN_FILENAME}"
|
|
216
217
|
```
|