@hanzlaa/rcode 3.4.5 → 3.4.7
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/generate-command-skills.cjs +16 -4
- package/cli/install.js +46 -4
- package/cli/postinstall.js +67 -7
- package/dist/rcode.js +1287 -2003
- package/package.json +1 -1
- package/rihal/agents/rules/executor/task-commit-protocol.md +26 -2
|
@@ -32,11 +32,23 @@ const path = require('path');
|
|
|
32
32
|
* lifecycle verbs. Internal sub-commands stay slash-only.
|
|
33
33
|
*/
|
|
34
34
|
const SIDEBAR_COMMANDS = new Set([
|
|
35
|
-
|
|
36
|
-
'
|
|
37
|
-
|
|
38
|
-
'
|
|
35
|
+
// Navigation & status
|
|
36
|
+
'do', 'status', 'progress', 'next', 'health',
|
|
37
|
+
// Core planning & execution
|
|
38
|
+
'plan', 'execute', 'add-phase', 'discuss-phase', 'complete-milestone',
|
|
39
|
+
'plan-milestone-gaps', 'autonomous',
|
|
40
|
+
// Project setup
|
|
39
41
|
'new-project', 'new-milestone', 'milestone-summary',
|
|
42
|
+
// Sprint workflow
|
|
43
|
+
'sprint-planning', 'sprint-status', 'execute-sprint', 'dev-story',
|
|
44
|
+
'create-story', 'create-epics-and-stories',
|
|
45
|
+
// Discussion & council
|
|
46
|
+
'council', 'discuss', 'prfaq',
|
|
47
|
+
// Quality & review
|
|
48
|
+
'ship', 'audit', 'verify-phase', 'verify-work', 'review', 'code-review',
|
|
49
|
+
'feature-drift', 'ui-phase', 'ui-review',
|
|
50
|
+
// Utility
|
|
51
|
+
'debug', 'session-report', 'forensics', 'map-codebase', 'quick',
|
|
40
52
|
'note', 'add-todo', 'check-todos', 'pause-work', 'resume-work',
|
|
41
53
|
]);
|
|
42
54
|
|
package/cli/install.js
CHANGED
|
@@ -137,6 +137,12 @@ function parseArgs(argv) {
|
|
|
137
137
|
// #199 — git pre-commit hook. null = install if .git/ present (default).
|
|
138
138
|
// Set false by --no-git-hooks, true by --git-hooks.
|
|
139
139
|
gitHooks: null,
|
|
140
|
+
// global install mode — targets ~/.claude/, skips per-project artifacts
|
|
141
|
+
global: false,
|
|
142
|
+
// silent — suppress non-error output (used by postinstall auto-run)
|
|
143
|
+
silent: false,
|
|
144
|
+
// noPrompt — skip all interactive prompts (used by postinstall auto-run)
|
|
145
|
+
noPrompt: false,
|
|
140
146
|
};
|
|
141
147
|
const positional = [];
|
|
142
148
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -162,6 +168,9 @@ function parseArgs(argv) {
|
|
|
162
168
|
else if (arg === '--no-backup') opts.noBackup = true; // #381
|
|
163
169
|
else if (arg === '--no-git-hooks') opts.gitHooks = false; // #199
|
|
164
170
|
else if (arg === '--git-hooks') opts.gitHooks = true; // #199
|
|
171
|
+
else if (arg === '--global') opts.global = true;
|
|
172
|
+
else if (arg === '--silent') opts.silent = true;
|
|
173
|
+
else if (arg === '--no-prompt') opts.noPrompt = true;
|
|
165
174
|
else if (!arg.startsWith('--')) positional.push(arg);
|
|
166
175
|
}
|
|
167
176
|
if (positional[0]) {
|
|
@@ -305,6 +314,7 @@ function detectIdeSignals(target) {
|
|
|
305
314
|
*/
|
|
306
315
|
async function resolveIde(opts) {
|
|
307
316
|
if (opts.ideProvided) return [opts.ide]; // user passed --ide, respect it
|
|
317
|
+
if (opts.noPrompt || opts.global) return ['claude']; // auto-install: always claude
|
|
308
318
|
if (opts.yes || !process.stdin.isTTY) {
|
|
309
319
|
// #182 — non-interactive mode: install into every detected IDE, not just
|
|
310
320
|
// the default claude. The interactive flow already preselects detected
|
|
@@ -352,6 +362,7 @@ async function resolveIde(opts) {
|
|
|
352
362
|
*/
|
|
353
363
|
async function resolveCommitPlanning(opts) {
|
|
354
364
|
if (opts.commitPlanning !== null) return opts.commitPlanning;
|
|
365
|
+
if (opts.noPrompt || opts.global) return false; // global install: no planning artifacts
|
|
355
366
|
if (opts.yes || !process.stdin.isTTY) return true; // non-interactive default
|
|
356
367
|
|
|
357
368
|
const choice = await clack.select({
|
|
@@ -408,7 +419,7 @@ function getPathsForIde(ide, target) {
|
|
|
408
419
|
case 'claude':
|
|
409
420
|
return {
|
|
410
421
|
agentsDir: path.join(target, '.claude', 'agents'),
|
|
411
|
-
commandsDir: path.join(target, '.claude', 'commands'
|
|
422
|
+
commandsDir: path.join(target, '.claude', 'commands'),
|
|
412
423
|
workflowsDir: path.join(target, '.rihal', 'workflows'),
|
|
413
424
|
referencesDir: path.join(target, '.rihal', 'references'),
|
|
414
425
|
binDir: path.join(target, '.rihal', 'bin'),
|
|
@@ -971,10 +982,15 @@ function buildInstallPlan(ide = 'claude', target = process.cwd()) {
|
|
|
971
982
|
}
|
|
972
983
|
|
|
973
984
|
// Commands — IDE-specific
|
|
985
|
+
// Claude: output as .claude/commands/rihal-{name}.md (hyphen namespace → /rihal-name)
|
|
986
|
+
// Cursor/Gemini: keep original flat name inside their rihal/ subdirectory
|
|
974
987
|
for (const f of walkFiles(path.join(SOURCE_ROOT, 'commands'))) {
|
|
975
988
|
const rel = path.relative(path.join(SOURCE_ROOT, 'commands'), f);
|
|
976
989
|
const ext = ide === 'cursor' ? '.mdc' : '.md';
|
|
977
|
-
const
|
|
990
|
+
const baseName = path.basename(f, '.md');
|
|
991
|
+
const outName = ide === 'claude'
|
|
992
|
+
? `rihal-${baseName}${ext}`
|
|
993
|
+
: baseName + ext;
|
|
978
994
|
plan.push({ src: f, rel: path.join(relCommands, path.dirname(rel), outName), ide, cursor: ide === 'cursor' });
|
|
979
995
|
}
|
|
980
996
|
|
|
@@ -1050,7 +1066,7 @@ function filterPlanByModules(plan, moduleNames) {
|
|
|
1050
1066
|
if (!mod) { console.warn(` ⚠ Unknown module: ${modName}`); continue; }
|
|
1051
1067
|
for (const a of mod.agents) allowed.add(path.join('.claude', 'agents', a));
|
|
1052
1068
|
for (const w of mod.workflows) allowed.add(path.join('.rihal', 'workflows', w));
|
|
1053
|
-
for (const c of mod.commands) allowed.add(path.join('.claude', 'commands',
|
|
1069
|
+
for (const c of mod.commands) allowed.add(path.join('.claude', 'commands', `rihal-${c}`));
|
|
1054
1070
|
for (const r of mod.references) allowed.add(path.join('.rihal', 'references', r));
|
|
1055
1071
|
}
|
|
1056
1072
|
// Always include bin/ (shared infrastructure, not module-specific)
|
|
@@ -1649,6 +1665,27 @@ async function install(opts) {
|
|
|
1649
1665
|
console.log('');
|
|
1650
1666
|
}
|
|
1651
1667
|
|
|
1668
|
+
// In global install mode (~/.claude/), skip per-project artifacts — those are
|
|
1669
|
+
// created by `rcode install` inside each project directory at project-init time.
|
|
1670
|
+
// Global install only ships the read-only tooling: commands, skills, workflows, bin.
|
|
1671
|
+
if (opts.global) {
|
|
1672
|
+
// Still write the manifest so the global install is traceable/upgradeable
|
|
1673
|
+
const configDir = path.join(opts.target, '.rihal', '_config');
|
|
1674
|
+
ensureDir(configDir);
|
|
1675
|
+
fs.writeFileSync(path.join(configDir, 'manifest.yaml'), generateInstallManifest(opts));
|
|
1676
|
+
// Install skills + sidebar stubs globally
|
|
1677
|
+
let skillsInstalled = installSkills(PACKAGE_ROOT, opts.target);
|
|
1678
|
+
try {
|
|
1679
|
+
const { main: generateCommandSkills } = require(path.join(PACKAGE_ROOT, 'cli', 'generate-command-skills.cjs'));
|
|
1680
|
+
const stubsDir = path.join(opts.target, '.claude', 'skills');
|
|
1681
|
+
const result = generateCommandSkills(PACKAGE_ROOT, stubsDir, readPackageVersion());
|
|
1682
|
+
skillsInstalled += result.generated;
|
|
1683
|
+
} catch { /* non-fatal */ }
|
|
1684
|
+
console.log('');
|
|
1685
|
+
console.log(` ${dim(`${skillsInstalled} skills installed globally`)}`);
|
|
1686
|
+
return 0;
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1652
1689
|
// Write .rihal/_config/manifest.yaml + agent-manifest.csv + files-manifest.csv
|
|
1653
1690
|
const configDir = path.join(opts.target, '.rihal', '_config');
|
|
1654
1691
|
ensureDir(configDir);
|
|
@@ -1858,7 +1895,12 @@ async function install(opts) {
|
|
|
1858
1895
|
agentCount = fs.readdirSync(agentsDir).filter(f => (f.startsWith('rihal-') || f.startsWith('rcode-')) && (f.endsWith('.md') || f.endsWith('.mdc'))).length;
|
|
1859
1896
|
}
|
|
1860
1897
|
if (fs.existsSync(commandsDir)) {
|
|
1861
|
-
commandCount = fs.readdirSync(commandsDir).filter(f => f.endsWith('.md') || f.endsWith('.mdc')).length;
|
|
1898
|
+
commandCount = fs.readdirSync(commandsDir).filter(f => f.startsWith('rihal-') && (f.endsWith('.md') || f.endsWith('.mdc'))).length;
|
|
1899
|
+
}
|
|
1900
|
+
// Clean up legacy .claude/commands/rihal/ colon-namespace directory if it exists
|
|
1901
|
+
const legacyColonDir = path.join(opts.target, '.claude', 'commands', 'rihal');
|
|
1902
|
+
if (primaryIde === 'claude' && fs.existsSync(legacyColonDir)) {
|
|
1903
|
+
fs.rmSync(legacyColonDir, { recursive: true, force: true });
|
|
1862
1904
|
}
|
|
1863
1905
|
} catch {}
|
|
1864
1906
|
|
package/cli/postinstall.js
CHANGED
|
@@ -1,18 +1,78 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* rihal-code postinstall hook — runs automatically after `npm install`
|
|
2
|
+
* rihal-code postinstall hook — runs automatically after `npm install -g`
|
|
3
|
+
*
|
|
4
|
+
* Auto-installs commands, skills, workflows, and bin tools into the global
|
|
5
|
+
* Claude Code directory (~/.claude/) so every project can use rihal immediately
|
|
6
|
+
* without needing a per-project `rcode install` run.
|
|
7
|
+
*
|
|
8
|
+
* Artifacts (.planning/, STATE.md, ROADMAP.md) are always created in the
|
|
9
|
+
* project CWD at runtime — the global install only ships read-only tooling.
|
|
3
10
|
*/
|
|
4
11
|
|
|
5
|
-
|
|
12
|
+
'use strict';
|
|
13
|
+
const os = require('os');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
|
|
16
|
+
// Skip in CI or test environments
|
|
6
17
|
if (process.env.CI || process.env.NODE_ENV === 'test') {
|
|
7
18
|
process.exit(0);
|
|
8
19
|
}
|
|
9
20
|
|
|
10
|
-
|
|
21
|
+
// Only auto-install when invoked as a global package (npm install -g).
|
|
22
|
+
// A local devDependency install should not touch the user's ~/.claude/.
|
|
23
|
+
const isGlobalInstall = (() => {
|
|
24
|
+
try {
|
|
25
|
+
// npm sets npm_config_global=true for global installs
|
|
26
|
+
if (process.env.npm_config_global === 'true') return true;
|
|
27
|
+
// Fallback: check if the install prefix is a global npm prefix
|
|
28
|
+
const prefix = process.env.npm_config_prefix || '';
|
|
29
|
+
const home = os.homedir();
|
|
30
|
+
if (prefix && !prefix.startsWith(home) && !prefix.includes('node_modules')) return true;
|
|
31
|
+
return false;
|
|
32
|
+
} catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
})();
|
|
36
|
+
|
|
37
|
+
const globalTarget = path.join(os.homedir(), '.claude');
|
|
38
|
+
|
|
39
|
+
if (isGlobalInstall) {
|
|
40
|
+
// Run the global install in the background so npm output isn't blocked
|
|
41
|
+
const { install } = require('./install.js');
|
|
42
|
+
install({
|
|
43
|
+
target: globalTarget,
|
|
44
|
+
ides: ['claude'],
|
|
45
|
+
ide: 'claude',
|
|
46
|
+
yes: true,
|
|
47
|
+
noPrompt: true,
|
|
48
|
+
commitPlanning: false,
|
|
49
|
+
global: true, // signal: skip per-project artifacts (STATE.md, ROADMAP.md, .planning/)
|
|
50
|
+
silent: false,
|
|
51
|
+
}).then((code) => {
|
|
52
|
+
if (code === 0) {
|
|
53
|
+
console.log(`\n✓ Rihal commands + skills installed globally → ${globalTarget}`);
|
|
54
|
+
console.log(' All /rihal-* commands are now available in every project.\n');
|
|
55
|
+
} else {
|
|
56
|
+
console.warn(`\n⚠ Global auto-install exited with code ${code}. Run 'rcode install' manually if needed.\n`);
|
|
57
|
+
}
|
|
58
|
+
printWelcome();
|
|
59
|
+
}).catch((err) => {
|
|
60
|
+
console.warn(`\n⚠ Global auto-install failed: ${err.message}`);
|
|
61
|
+
console.warn(' Run "rcode install" manually to set up rihal commands.\n');
|
|
62
|
+
printWelcome();
|
|
63
|
+
});
|
|
64
|
+
} else {
|
|
65
|
+
printWelcome();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function printWelcome() {
|
|
69
|
+
console.log(`
|
|
11
70
|
🕌 Rihal Code installed.
|
|
12
71
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
72
|
+
Commands are available globally in every Claude Code project.
|
|
73
|
+
To set up per-project state + planning structure, run inside your project:
|
|
74
|
+
|
|
75
|
+
rcode install # creates .rihal/config.yaml, .planning/, STATE.md
|
|
16
76
|
|
|
17
77
|
🌱 The Golden Path (say these phrases in your AI IDE):
|
|
18
78
|
1. "scaffold a new project" → rihal-scaffold-project
|
|
@@ -28,5 +88,5 @@ More:
|
|
|
28
88
|
rcode dashboard # view-only Diwan on :7717
|
|
29
89
|
|
|
30
90
|
Docs: https://github.com/hanzlahabib/rihal-code
|
|
31
|
-
Tiers: docs/TIERS.md · Standards: docs/STANDARDS.md
|
|
32
91
|
`);
|
|
92
|
+
}
|