@hanzlaa/rcode 2.3.4 → 2.3.6

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/config.js CHANGED
@@ -90,7 +90,7 @@ module.exports = function config(args) {
90
90
  const rihalDir = path.join(cwd, '.rihal');
91
91
  if (!fs.existsSync(rihalDir) && !opts.global) {
92
92
  console.error(`❌ No .rihal/ directory found in ${cwd}`);
93
- console.error(` Run 'rihal-code install' first, or use --global to manage user defaults.`);
93
+ console.error(` Run 'rcode install' first, or use --global to manage user defaults.`);
94
94
  process.exit(1);
95
95
  }
96
96
  printListing(cwd);
@@ -118,7 +118,7 @@ module.exports = function config(args) {
118
118
  // For global writes, we don't need .rihal/ to exist
119
119
  if (scope === 'project' && !fs.existsSync(path.join(cwd, '.rihal'))) {
120
120
  console.error(`❌ No .rihal/ directory found in ${cwd}`);
121
- console.error(` Run 'rihal-code install' first, or use --global.`);
121
+ console.error(` Run 'rcode install' first, or use --global.`);
122
122
  process.exit(1);
123
123
  }
124
124
 
@@ -137,6 +137,6 @@ module.exports = function config(args) {
137
137
  }
138
138
 
139
139
  console.error(`❌ Too many arguments.`);
140
- console.error(` Usage: rihal-code config [--global] [key] [value]`);
140
+ console.error(` Usage: rcode config [--global] [key] [value]`);
141
141
  process.exit(1);
142
142
  };
package/cli/context.js CHANGED
@@ -35,7 +35,7 @@ function parseArgs(args) {
35
35
  else if (arg === '--install-hook') opts.installHook = true;
36
36
  else {
37
37
  console.error(`Unknown flag: ${arg}`);
38
- console.error(`Usage: rihal-code context [--check|--refresh|--install-hook]`);
38
+ console.error(`Usage: rcode context [--check|--refresh|--install-hook]`);
39
39
  process.exit(1);
40
40
  }
41
41
  }
@@ -45,7 +45,7 @@ function parseArgs(args) {
45
45
  function ensureRihalDir(cwd) {
46
46
  if (!fs.existsSync(path.join(cwd, '.rihal'))) {
47
47
  console.error(`❌ No .rihal/ directory found in ${cwd}`);
48
- console.error(` Run 'rihal-code install' first.`);
48
+ console.error(` Run 'rcode install' first.`);
49
49
  process.exit(1);
50
50
  }
51
51
  }
@@ -155,10 +155,10 @@ function installHook(cwd) {
155
155
 
156
156
  const hookContent = `#!/bin/sh
157
157
  # Rihal Code — memory bank freshness check
158
- # Installed by: rihal-code context --install-hook
158
+ # Installed by: rcode context --install-hook
159
159
  # Non-blocking: prints a one-line warning if the memory bank is stale.
160
- if command -v rihal-code >/dev/null 2>&1; then
161
- output=$(rihal-code context --check 2>&1)
160
+ if command -v rcode >/dev/null 2>&1; then
161
+ output=$(rcode context --check 2>&1)
162
162
  if [ $? -ne 0 ]; then
163
163
  echo ""
164
164
  echo "⚠ Rihal memory bank is stale — run /rihal:init in your editor to refresh."
package/cli/doctor.js CHANGED
@@ -92,7 +92,7 @@ function runPreflight(cwd, packageRoot) {
92
92
  checks.push({
93
93
  label: '.rihal/ state',
94
94
  status: 'warn',
95
- message: 'not initialized in this directory (run `rihal-code install`)',
95
+ message: 'not initialized in this directory (run `rcode install`)',
96
96
  });
97
97
  }
98
98
 
@@ -196,7 +196,7 @@ function runPreflight(cwd, packageRoot) {
196
196
  checks.push({
197
197
  label: 'Memory bank',
198
198
  status: 'warn',
199
- message: `STALE — ${staleness.reasons[0]}${staleness.reasons.length > 1 ? ` (+${staleness.reasons.length - 1} more)` : ''} — run /rihal:init`,
199
+ message: `STALE — ${staleness.reasons[0]}${staleness.reasons.length > 1 ? ` (+${staleness.reasons.length - 1} more)` : ''}`,
200
200
  });
201
201
  }
202
202
  }
@@ -446,7 +446,7 @@ async function main(args) {
446
446
  // ------ Precondition: .rihal/ exists ------
447
447
  const state = loadState(cwd);
448
448
  if (!state) {
449
- console.error(`❌ No .rihal/state.json found. Run 'rihal-code init' first.`);
449
+ console.error(`❌ No .rihal/state.json found. Run 'rcode install' first.`);
450
450
  process.exit(1);
451
451
  }
452
452
  console.log(` ✓ Project: ${state.project_name || '(unnamed)'}`);
package/cli/index.js CHANGED
@@ -47,7 +47,7 @@ function printHelp() {
47
47
  Context-aware AI team methodology. See tiers: \`rihal-code tiers\`
48
48
 
49
49
  Usage:
50
- npx @hanzlahabib/rihal-code <command>
50
+ rcode <command>
51
51
 
52
52
  📦 PROJECT
53
53
  install Install Rihal Code into the current project
@@ -78,8 +78,9 @@ Usage:
78
78
 
79
79
  Getting started:
80
80
  cd my-project
81
- npx @hanzlahabib/rihal-code install # set up agents + slash commands
82
- npx @hanzlahabib/rihal-code tiers # see the Golden Path
81
+ rcode install # set up agents + slash commands
82
+ rcode tiers # see the Golden Path
83
+ rcode set-profile # choose model profile (quality | balanced | budget)
83
84
 
84
85
  Documentation: https://github.com/hanzlahabib/rihal-code
85
86
  `.trim());
package/cli/install.js CHANGED
@@ -62,6 +62,7 @@ const fg = require('fast-glob');
62
62
  const { z } = require('zod');
63
63
  const semver = require('semver');
64
64
  const { createTwoFilesPatch } = require('diff');
65
+ const clack = require('@clack/prompts');
65
66
 
66
67
  // Output helpers: always respect NO_COLOR / non-TTY (picocolors handles this).
67
68
  const ok = (s) => pc.green('✓') + ' ' + s;
@@ -1486,7 +1487,7 @@ function runInstallHealthCheck(target, counts) {
1486
1487
  console.log('');
1487
1488
  console.log(' ' + fail(`${fails} health check${fails === 1 ? '' : 's'} failed — install may be broken.`));
1488
1489
  console.log(dim(' Debug: node .rihal/bin/rihal-tools.cjs state read && ls -la .rihal/'));
1489
- console.log(dim(' Reinstall: npx @hanzlaa/rcode install . --force'));
1490
+ console.log(dim(' Reinstall: rcode install . --force'));
1490
1491
  console.log('');
1491
1492
  return false;
1492
1493
  }
@@ -1498,40 +1499,19 @@ async function main() {
1498
1499
  const argv = process.argv.slice(2);
1499
1500
  const opts = parseArgs(argv);
1500
1501
 
1501
- // Prompt for target directory when not explicitly provided and not --yes
1502
- if (!opts.targetProvided && !opts.yes && !opts.help) {
1503
- const { askText, askChoice, PromptAbortError } = require('./lib/prompts.cjs');
1504
- try {
1505
- console.log('');
1506
- const answer = await askText(
1507
- `Install Rihal Code into which directory?\n (press Enter for current directory: ${opts.target})`,
1508
- { default: opts.target }
1509
- );
1510
- const resolved = path.resolve(answer.trim() || opts.target);
1511
- opts.target = resolved;
1512
- opts.projectName = path.basename(resolved);
1513
-
1514
- const ideAnswer = await askChoice(
1515
- 'Which editor are you installing for?',
1516
- {
1517
- choices: [
1518
- { id: 'claude', label: 'Claude Code' },
1519
- { id: 'cursor', label: 'Cursor' },
1520
- { id: 'gemini', label: 'Gemini CLI' },
1521
- { id: 'all', label: 'All (Claude + Cursor + Gemini)' },
1522
- ],
1523
- default: 'claude',
1524
- }
1525
- );
1526
- opts.ide = ideAnswer[0];
1527
- console.log('');
1528
- } catch (err) {
1529
- if (err.name === 'PromptAbortError') process.exit(0);
1530
- throw err;
1531
- }
1502
+ if (opts.help) { printHelp(); return; }
1503
+
1504
+ // ── Non-interactive fast path (--yes / CI / piped stdin) ─────────────────
1505
+ const interactive = !opts.yes && process.stdin.isTTY && !process.env.CI;
1506
+
1507
+ if (interactive) {
1508
+ await runInstallWizard(opts);
1532
1509
  }
1533
1510
 
1534
- install(opts).then(code => process.exit(code)).catch(err => {
1511
+ try {
1512
+ const code = await install(opts);
1513
+ process.exit(code);
1514
+ } catch (err) {
1535
1515
  if (err.code === 'EACCES' || err.code === 'EPERM') {
1536
1516
  console.error(`✖ Permission denied: ${err.path || err.message}`);
1537
1517
  process.exit(1);
@@ -1543,7 +1523,110 @@ async function main() {
1543
1523
  console.error(`✖ Install failed: ${err.message}`);
1544
1524
  if (process.env.DEBUG) console.error(err.stack);
1545
1525
  process.exit(1);
1526
+ }
1527
+ }
1528
+
1529
+ /**
1530
+ * Interactive install wizard powered by @clack/prompts.
1531
+ * Mutates opts in-place. Exits 0 on cancel.
1532
+ */
1533
+ async function runInstallWizard(opts) {
1534
+ const { intro, outro, text, select, confirm, isCancel, cancel, note } = clack;
1535
+ const pkgVersion = readPackageVersion();
1536
+
1537
+ console.log('');
1538
+ intro(pc.bold('🕌 Rihal Code') + pc.dim(` v${pkgVersion}`));
1539
+
1540
+ // ── 1. Install directory ──────────────────────────────────────────────
1541
+ if (!opts.targetProvided) {
1542
+ const dir = await text({
1543
+ message: 'Install directory?',
1544
+ placeholder: opts.target,
1545
+ defaultValue: opts.target,
1546
+ initialValue: opts.target,
1547
+ });
1548
+ if (isCancel(dir)) { cancel('Installation cancelled.'); process.exit(0); }
1549
+ const resolved = path.resolve((dir || opts.target).trim());
1550
+ opts.target = resolved;
1551
+ opts.projectName = path.basename(resolved);
1552
+ }
1553
+
1554
+ // ── 2. Editor / LLM ──────────────────────────────────────────────────
1555
+ const editorChoice = await select({
1556
+ message: 'Which editor are you installing for?',
1557
+ options: [
1558
+ { value: 'claude', label: 'Claude Code', hint: 'recommended' },
1559
+ { value: 'cursor', label: 'Cursor' },
1560
+ { value: 'gemini', label: 'Gemini CLI', hint: 'coming soon' },
1561
+ ],
1562
+ initialValue: opts.ide || 'claude',
1546
1563
  });
1564
+ if (isCancel(editorChoice)) { cancel('Installation cancelled.'); process.exit(0); }
1565
+ opts.ide = editorChoice;
1566
+
1567
+ // ── 3. Communication language ─────────────────────────────────────────
1568
+ const langChoice = await select({
1569
+ message: 'Communication language?',
1570
+ options: [
1571
+ { value: 'English', label: 'English' },
1572
+ { value: 'Arabic', label: 'Arabic (العربية)' },
1573
+ { value: 'French', label: 'French (Français)' },
1574
+ { value: 'Spanish', label: 'Spanish (Español)' },
1575
+ { value: 'Urdu', label: 'Urdu (اردو)' },
1576
+ ],
1577
+ initialValue: opts.language || 'English',
1578
+ });
1579
+ if (isCancel(langChoice)) { cancel('Installation cancelled.'); process.exit(0); }
1580
+ opts.language = langChoice;
1581
+
1582
+ // ── 4. Agent mode ─────────────────────────────────────────────────────
1583
+ const modeChoice = await select({
1584
+ message: 'Agent mode?',
1585
+ options: [
1586
+ { value: 'guided', label: 'Guided', hint: 'confirm at key decision gates' },
1587
+ { value: 'yolo', label: 'Yolo', hint: 'fully autonomous — no confirmation' },
1588
+ ],
1589
+ initialValue: opts.mode || 'guided',
1590
+ });
1591
+ if (isCancel(modeChoice)) { cancel('Installation cancelled.'); process.exit(0); }
1592
+ opts.mode = modeChoice;
1593
+
1594
+ // ── 5. Planning artifacts ─────────────────────────────────────────────
1595
+ const planningChoice = await select({
1596
+ message: 'Where should planning artifacts (.planning/) be saved?',
1597
+ options: [
1598
+ { value: true, label: 'Commit to git', hint: 'recommended — team sees the same plans' },
1599
+ { value: false, label: 'Keep local', hint: 'gitignore — good for sensitive PRDs' },
1600
+ ],
1601
+ initialValue: true,
1602
+ });
1603
+ if (isCancel(planningChoice)) { cancel('Installation cancelled.'); process.exit(0); }
1604
+ opts.commitPlanning = planningChoice;
1605
+
1606
+ // ── 6. User name ──────────────────────────────────────────────────────
1607
+ const nameInput = await text({
1608
+ message: 'Your name? (used in agent responses)',
1609
+ placeholder: opts.userName,
1610
+ defaultValue: opts.userName,
1611
+ initialValue: opts.userName,
1612
+ });
1613
+ if (isCancel(nameInput)) { cancel('Installation cancelled.'); process.exit(0); }
1614
+ opts.userName = (nameInput || opts.userName).trim();
1615
+
1616
+ // ── Summary before install ────────────────────────────────────────────
1617
+ note(
1618
+ [
1619
+ `${pc.dim('Directory:')} ${opts.target}`,
1620
+ `${pc.dim('Editor:')} ${opts.ide}`,
1621
+ `${pc.dim('Language:')} ${opts.language}`,
1622
+ `${pc.dim('Mode:')} ${opts.mode}`,
1623
+ `${pc.dim('Planning:')} ${opts.commitPlanning ? 'committed to git' : 'kept local (gitignored)'}`,
1624
+ `${pc.dim('User:')} ${opts.userName}`,
1625
+ ].join('\n'),
1626
+ 'Installing with these settings'
1627
+ );
1628
+
1629
+ console.log('');
1547
1630
  }
1548
1631
 
1549
1632
  if (require.main === module) main();
@@ -20,7 +20,14 @@
20
20
  const fs = require('fs');
21
21
  const path = require('path');
22
22
 
23
- const PACKAGE_ROOT = path.resolve(__dirname, '..', '..');
23
+ function findPackageRoot(dir) {
24
+ while (dir !== require('path').parse(dir).root) {
25
+ if (fs.existsSync(path.join(dir, 'package.json'))) return dir;
26
+ dir = path.dirname(dir);
27
+ }
28
+ throw new Error('Could not find package root');
29
+ }
30
+ const PACKAGE_ROOT = findPackageRoot(__dirname);
24
31
  const PROFILES_PATH = path.join(PACKAGE_ROOT, 'rihal/config/model-profiles.json');
25
32
 
26
33
  let _cached = null;
@@ -11,8 +11,8 @@ console.log(`
11
11
  🕌 Rihal Code installed.
12
12
 
13
13
  First-time setup:
14
- npx @hanzlaa/rcode install # set up agents + slash commands
15
- npx @hanzlaa/rcode tiers # see the tier map
14
+ rcode install # set up agents + slash commands
15
+ rcode tiers # see the tier map
16
16
 
17
17
  🌱 The Golden Path (say these phrases in your AI IDE):
18
18
  1. "scaffold a new project" → rihal-scaffold-project
@@ -24,8 +24,8 @@ First-time setup:
24
24
  7. "sprint status" → rihal-sprint-status
25
25
 
26
26
  More:
27
- npx @hanzlaa/rcode help # all commands (grouped)
28
- npx @hanzlaa/rcode dashboard # view-only Diwan on :7717
27
+ rcode help # all commands (grouped)
28
+ rcode dashboard # view-only Diwan on :7717
29
29
 
30
30
  Docs: https://github.com/hanzlahabib/rihal-code
31
31
  Tiers: docs/TIERS.md · Standards: docs/STANDARDS.md
package/cli/set-mode.js CHANGED
@@ -45,7 +45,7 @@ module.exports = function setMode(args) {
45
45
 
46
46
  if (!fs.existsSync(rihalDir)) {
47
47
  console.error(`❌ No .rihal/ directory found in ${cwd}`);
48
- console.error(` Run 'rihal-code install' first.`);
48
+ console.error(` Run 'rcode install' first.`);
49
49
  process.exit(1);
50
50
  }
51
51
 
@@ -62,7 +62,7 @@ module.exports = function setMode(args) {
62
62
  console.log(` ${MODE_DESCRIPTIONS[mode]}`);
63
63
  console.log();
64
64
  }
65
- console.log(`Usage: rihal-code set-mode <${[...VALID_COMMUNICATION_MODES].join('|')}>`);
65
+ console.log(`Usage: rcode set-mode <${[...VALID_COMMUNICATION_MODES].join('|')}>`);
66
66
  console.log();
67
67
  return;
68
68
  }
@@ -30,7 +30,7 @@ module.exports = function setProfile(args) {
30
30
 
31
31
  if (!fs.existsSync(rihalDir)) {
32
32
  console.error(`❌ No .rihal/ directory found in ${cwd}`);
33
- console.error(` Run 'npx @hanzlahabib/rihal-code install' first.`);
33
+ console.error(` Run 'rcode install' first.`);
34
34
  process.exit(1);
35
35
  }
36
36
 
@@ -55,7 +55,7 @@ module.exports = function setProfile(args) {
55
55
  console.log(` • ${name}${marker}`);
56
56
  console.log(` ${p.description}`);
57
57
  }
58
- console.log(`\nUsage: npx @hanzlahabib/rihal-code set-profile <name>`);
58
+ console.log(`\nUsage: rcode set-profile <name>`);
59
59
  return;
60
60
  }
61
61
 
package/cli/uninstall.js CHANGED
@@ -377,7 +377,7 @@ async function runUninstall(args) {
377
377
  console.log(`\n❌ Rihal Code is not installed in this directory.`);
378
378
  console.log(` Nothing to uninstall.`);
379
379
  console.log();
380
- console.log(` To install: npx --yes github:hanzlahabib/rihal-code install`);
380
+ console.log(` To install: rcode install`);
381
381
  console.log();
382
382
  return;
383
383
  }
@@ -589,7 +589,7 @@ async function runUninstall(args) {
589
589
 
590
590
  // Hint about reinstalling
591
591
  console.log(`\nTo reinstall later:`);
592
- console.log(` npx --yes github:hanzlahabib/rihal-code install`);
592
+ console.log(` rcode install`);
593
593
  }
594
594
 
595
595
  // Direct invocation — allow `node cli/uninstall.js [flags]` to run end-to-end.
package/cli/update.js CHANGED
@@ -233,7 +233,7 @@ async function runUpdate(args, { packageRoot, packageJson }) {
233
233
  const configPath = path.join(cwd, '.rihal/config.json');
234
234
  if (!fs.existsSync(configPath)) {
235
235
  console.error(`\n❌ Rihal Code is not installed in this directory.`);
236
- console.error(` To install: rihal-code install\n`);
236
+ console.error(` To install: rcode install\n`);
237
237
  process.exit(1);
238
238
  }
239
239
 
@@ -251,7 +251,7 @@ async function runUpdate(args, { packageRoot, packageJson }) {
251
251
  const editors = detectInstalledEditors(cwd);
252
252
  if (editors.length === 0) {
253
253
  console.error(`\n❌ No editor install detected.`);
254
- console.error(` Run 'rihal-code install' to set up at least one editor first.\n`);
254
+ console.error(` Run 'rcode install' to set up at least one editor first.\n`);
255
255
  process.exit(1);
256
256
  }
257
257
 
@@ -355,7 +355,7 @@ async function runUpdate(args, { packageRoot, packageJson }) {
355
355
  if (hasDrift) {
356
356
  console.log(`⚠ Post-update verification found drift:`);
357
357
  console.log(formatReport(reports));
358
- console.log(`\n Run 'rihal-code doctor' for details, or re-run update to retry.`);
358
+ console.log(`\n Run 'rcode doctor' for details, or re-run update to retry.`);
359
359
  } else {
360
360
  console.log(` ✓ Post-update verification passed.`);
361
361
  }