@hanzlaa/rcode 2.1.0 → 2.3.1

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 (76) hide show
  1. package/CONTRIBUTING.md +138 -0
  2. package/README.md +83 -19
  3. package/cli/install.js +687 -80
  4. package/cli/uninstall.js +8 -0
  5. package/dist/rcode.js +19777 -0
  6. package/package.json +17 -4
  7. package/rihal/DOCS-AUDIT.md +14 -0
  8. package/rihal/agents/rihal-code-reviewer.md +1 -1
  9. package/rihal/agents/rihal-codebase-mapper.md +1 -1
  10. package/rihal/agents/rihal-docs-auditor.md +1 -1
  11. package/rihal/agents/rihal-edge-case-hunter.md +1 -1
  12. package/rihal/agents/rihal-executor.md +1 -1
  13. package/rihal/agents/rihal-hussain-pm.md +1 -0
  14. package/rihal/agents/rihal-nyquist-auditor.md +1 -1
  15. package/rihal/agents/rihal-phase-researcher.md +1 -2
  16. package/rihal/agents/rihal-planner.md +1 -1
  17. package/rihal/agents/rihal-roadmapper.md +1 -0
  18. package/rihal/agents/rihal-security-adversary.md +1 -1
  19. package/rihal/agents/rihal-security-auditor.md +1 -1
  20. package/rihal/agents/rihal-sprint-checker.md +1 -1
  21. package/rihal/agents/rihal-verifier.md +1 -1
  22. package/rihal/bin/lib/roadmap.cjs +2 -3
  23. package/rihal/bin/rihal-tools.cjs +153 -36
  24. package/rihal/brain/sources.yaml +7 -4
  25. package/rihal/commands/audit.md +8 -0
  26. package/rihal/commands/checkpoint-preview.md +13 -0
  27. package/rihal/commands/config.md +4 -4
  28. package/rihal/commands/prfaq.md +15 -0
  29. package/rihal/commands/settings.md +2 -2
  30. package/rihal/references/agent-contracts.md +12 -0
  31. package/rihal/references/karpathy-guidelines-full.md +79 -0
  32. package/rihal/references/karpathy-guidelines.md +8 -76
  33. package/rihal/references/model-profile-resolution.md +8 -0
  34. package/rihal/references/phase-argument-parsing.md +11 -0
  35. package/rihal/references/revision-loop.md +11 -0
  36. package/rihal/references/universal-anti-patterns.md +15 -0
  37. package/rihal/skills/actions/1-analysis/rihal-prfaq/SKILL.md +10 -0
  38. package/rihal/skills/actions/2-plan/rihal-create-epics-and-stories/SKILL.md +3 -1
  39. package/rihal/skills/actions/2-plan/rihal-create-milestone/SKILL.md +3 -1
  40. package/rihal/skills/actions/2-plan/rihal-create-milestone/steps/step-10-complete.md +1 -1
  41. package/rihal/skills/actions/2-plan/rihal-create-prd/SKILL.md +13 -0
  42. package/rihal/skills/actions/2-plan/rihal-create-story/SKILL.md +4 -2
  43. package/rihal/skills/actions/4-implementation/rihal-checkpoint-preview/SKILL.md +10 -0
  44. package/rihal/skills/actions/4-implementation/rihal-sprint-planning/SKILL.md +3 -1
  45. package/rihal/skills/agents/hussain-pm/SKILL.md +8 -0
  46. package/rihal/skills/agents/hussain-sm/SKILL.md +8 -0
  47. package/rihal/templates/UAT.md +29 -0
  48. package/rihal/templates/milestone.md +2 -0
  49. package/rihal/templates/sprint.md +11 -28
  50. package/rihal/templates/summary.md +30 -0
  51. package/rihal/templates/verification-report.md +28 -0
  52. package/rihal/workflows/audit-milestone.md +34 -2
  53. package/rihal/workflows/audit.md +172 -0
  54. package/rihal/workflows/autonomous.md +67 -0
  55. package/rihal/workflows/checkpoint-preview.md +7 -0
  56. package/rihal/workflows/council.md +3 -1
  57. package/rihal/workflows/dashboard.md +2 -2
  58. package/rihal/workflows/debug.md +8 -1
  59. package/rihal/workflows/diagnose-issues.md +34 -0
  60. package/rihal/workflows/do.md +47 -3
  61. package/rihal/workflows/execute-sprint.md +11 -4
  62. package/rihal/workflows/execute.md +9 -3
  63. package/rihal/workflows/install.md +2 -2
  64. package/rihal/workflows/karpathy-audit.md +7 -14
  65. package/rihal/workflows/pause-work.md +7 -1
  66. package/rihal/workflows/prfaq.md +7 -0
  67. package/rihal/workflows/profile-user.md +2 -2
  68. package/rihal/workflows/progress.md +1 -1
  69. package/rihal/workflows/settings.md +116 -118
  70. package/rihal/workflows/sprint-planning.md +39 -8
  71. package/rihal/workflows/status.md +6 -1
  72. package/rihal/workflows/ui-phase.md +3 -3
  73. package/rihal/workflows/update.md +80 -22
  74. package/rihal/workflows/validate-phase.md +7 -1
  75. package/rihal/agents/rihal-ui-designer.md +0 -6
  76. package/rihal/workflows/config.md +0 -105
package/package.json CHANGED
@@ -1,22 +1,25 @@
1
1
  {
2
2
  "name": "@hanzlaa/rcode",
3
- "version": "2.1.0",
3
+ "version": "2.3.1",
4
4
  "description": "Rihal Code (rcode) — installable context-brain for Rihalians. 44 agents, 93 slash commands, 58 skills, pullable Rihal standards. Unified install for Claude Code, Cursor, and Gemini.",
5
5
  "main": "cli/index.js",
6
6
  "bin": {
7
- "rcode": "cli/index.js",
8
- "rihal-code": "cli/index.js"
7
+ "rcode": "dist/rcode.js",
8
+ "rihal-code": "dist/rcode.js"
9
9
  },
10
10
  "scripts": {
11
11
  "dashboard": "node server/dashboard.js",
12
12
  "test": "node --test",
13
13
  "test:ci": "node --test --test-reporter=spec",
14
- "postinstall": "node cli/postinstall.js"
14
+ "postinstall": "node cli/postinstall.js",
15
+ "build:cli": "node scripts/build.cjs",
16
+ "build": "node scripts/build.cjs"
15
17
  },
16
18
  "files": [
17
19
  "cli/",
18
20
  "rihal/",
19
21
  "server/",
22
+ "dist/",
20
23
  ".rihal-template/",
21
24
  "README.md",
22
25
  "AGENTS.md",
@@ -54,6 +57,16 @@
54
57
  "node": ">=18.0.0"
55
58
  },
56
59
  "dependencies": {},
60
+ "devDependencies": {
61
+ "esbuild": "^0.25.0",
62
+ "picocolors": "^1.1.1",
63
+ "nanospinner": "^1.2.2",
64
+ "fast-glob": "^3.3.3",
65
+ "zod": "^3.24.0",
66
+ "semver": "^7.7.1",
67
+ "diff": "^7.0.0",
68
+ "@clack/prompts": "^0.9.1"
69
+ },
57
70
  "publishConfig": {
58
71
  "access": "public"
59
72
  }
@@ -0,0 +1,14 @@
1
+ # DOCS-AUDIT.md (per-project artefact)
2
+
3
+ This file is generated by `/rihal:document-project` into the project root
4
+ as `DOCS-AUDIT.md`. The shipped reference here just defines the schema:
5
+
6
+ - **Inventory:** every doc file (path, last-touched, owner, freshness).
7
+ - **Gaps:** docs that should exist per the project's domain (e.g. README,
8
+ CONTRIBUTING, ADRs for major decisions) but don't.
9
+ - **Stale:** docs that diverge from current code/state (links to dead
10
+ files, version mismatches, removed features still documented).
11
+ - **Recommendations:** ordered remediation list.
12
+
13
+ Workflows that @-include this file expect the live audit output, which
14
+ the workflow itself writes to disk before reading.
@@ -6,7 +6,7 @@ color: purple
6
6
  ---
7
7
 
8
8
  @.rihal/references/response-style.md
9
- @.rihal/references/karpathy-guidelines.md
9
+ @.rihal/references/karpathy-guidelines-full.md
10
10
  @.rihal/references/no-unauthorized-git-ops.md
11
11
 
12
12
  # Rihal Code Reviewer
@@ -7,7 +7,7 @@ color: cyan
7
7
 
8
8
 
9
9
  @.rihal/references/response-style.md
10
- @.rihal/references/karpathy-guidelines.md
10
+ @.rihal/references/karpathy-guidelines-full.md
11
11
 
12
12
  <role>
13
13
  You are a rihal codebase mapper. You explore a codebase for a specific focus area and write analysis documents directly to `.rihal/codebase/`.
@@ -6,7 +6,7 @@ color: gold
6
6
  ---
7
7
 
8
8
  @.rihal/references/response-style.md
9
- @.rihal/references/karpathy-guidelines.md
9
+ @.rihal/references/karpathy-guidelines-full.md
10
10
  @.rihal/references/no-unauthorized-git-ops.md
11
11
 
12
12
  # Rihal Documentation Auditor
@@ -6,7 +6,7 @@ color: maroon
6
6
  ---
7
7
 
8
8
  @.rihal/references/response-style.md
9
- @.rihal/references/karpathy-guidelines.md
9
+ @.rihal/references/karpathy-guidelines-full.md
10
10
  @.rihal/references/no-unauthorized-git-ops.md
11
11
 
12
12
  # Rihal Edge Case Hunter
@@ -6,7 +6,7 @@ color: yellow
6
6
  ---
7
7
 
8
8
  @.rihal/references/response-style.md
9
- @.rihal/references/karpathy-guidelines.md
9
+ @.rihal/references/karpathy-guidelines-full.md
10
10
  @.rihal/references/output-realism.md
11
11
  @.rihal/references/no-unauthorized-git-ops.md
12
12
 
@@ -7,6 +7,7 @@ color: orange
7
7
 
8
8
  @.rihal/references/response-style.md
9
9
  @.rihal/references/codebase-grounding.md
10
+ @.rihal/references/karpathy-guidelines.md
10
11
 
11
12
  # Hussain-PM — Product Manager
12
13
 
@@ -6,7 +6,7 @@ color: #8B5CF6
6
6
  ---
7
7
 
8
8
  @.rihal/references/response-style.md
9
- @.rihal/references/karpathy-guidelines.md
9
+ @.rihal/references/karpathy-guidelines-full.md
10
10
  @.rihal/references/no-unauthorized-git-ops.md
11
11
 
12
12
  <role>
@@ -7,8 +7,7 @@ color: cyan
7
7
 
8
8
 
9
9
  @.rihal/references/response-style.md
10
-
11
-
10
+ @.rihal/references/karpathy-guidelines.md
12
11
 
13
12
  <role>
14
13
  You are a Rihal phase researcher. You answer "What do I need to know to PLAN this phase well?" and produce a single RESEARCH.md that the planner consumes.
@@ -6,7 +6,7 @@ color: green
6
6
  ---
7
7
 
8
8
  @.rihal/references/response-style.md
9
- @.rihal/references/karpathy-guidelines.md
9
+ @.rihal/references/karpathy-guidelines-full.md
10
10
  @.rihal/references/output-realism.md
11
11
 
12
12
  <role>
@@ -8,6 +8,7 @@ color: purple
8
8
 
9
9
  @.rihal/references/response-style.md
10
10
  @.rihal/references/output-realism.md
11
+ @.rihal/references/karpathy-guidelines.md
11
12
 
12
13
  <role>
13
14
  You are a rihal roadmapper. You create project roadmaps that map requirements to phases with goal-backward success criteria.
@@ -6,7 +6,7 @@ color: darkred
6
6
  ---
7
7
 
8
8
  @.rihal/references/response-style.md
9
- @.rihal/references/karpathy-guidelines.md
9
+ @.rihal/references/karpathy-guidelines-full.md
10
10
  @.rihal/references/no-unauthorized-git-ops.md
11
11
 
12
12
  # Rihal Security Adversary
@@ -6,7 +6,7 @@ color: purple
6
6
  ---
7
7
 
8
8
  @.rihal/references/response-style.md
9
- @.rihal/references/karpathy-guidelines.md
9
+ @.rihal/references/karpathy-guidelines-full.md
10
10
  @.rihal/references/no-unauthorized-git-ops.md
11
11
 
12
12
  # Rihal Security Auditor
@@ -7,7 +7,7 @@ color: green
7
7
 
8
8
 
9
9
  @.rihal/references/response-style.md
10
- @.rihal/references/karpathy-guidelines.md
10
+ @.rihal/references/karpathy-guidelines-full.md
11
11
 
12
12
  <role>
13
13
  You are a Rihal sprint checker. Verify that sprints WILL achieve the phase goal, not just that they look complete.
@@ -6,7 +6,7 @@ color: green
6
6
  ---
7
7
 
8
8
  @.rihal/references/response-style.md
9
- @.rihal/references/karpathy-guidelines.md
9
+ @.rihal/references/karpathy-guidelines-full.md
10
10
  @.rihal/references/no-unauthorized-git-ops.md
11
11
 
12
12
  <role>
@@ -1,9 +1,8 @@
1
1
  /**
2
2
  * Roadmap — Rihal ROADMAP.md parsing and mutation helpers.
3
3
  *
4
- * Self-contained (stdlib only). Matches GSD output shapes for the subset of
5
- * commands that Rihal workflows currently invoke: get-phase, list-phases,
6
- * update-plan-progress, and clear.
4
+ * Self-contained (stdlib only). Subcommands invoked by Rihal workflows:
5
+ * get-phase, list-phases, update-plan-progress, clear.
7
6
  */
8
7
 
9
8
  const fs = require('fs');
@@ -1950,7 +1950,7 @@ function cmdState(subArgs) {
1950
1950
  // --- promote-backlog <from> --to <target> ---
1951
1951
  // Promote a 999.x parking-lot phase to a real phase number.
1952
1952
  // Mutates state.phases[]; renames the on-disk directory if present.
1953
- // Tracks issue #159 (M2.5 — GSD-parity 999.x convention).
1953
+ // Tracks issue #159 (M2.5 — 999.x parking-lot convention).
1954
1954
  if (sub === 'promote-backlog') {
1955
1955
  const from = subArgs[1];
1956
1956
  const flags = parseFlags(2);
@@ -2568,8 +2568,12 @@ function cmdResolveModel(agentId) {
2568
2568
  }
2569
2569
 
2570
2570
  /**
2571
- * config set --key <k> --value <v> — update a key in .rihal/config.yaml
2572
- * Writes YAML-style `key: value` (quotes strings with spaces).
2571
+ * config set --key <k> --value <v> — DEPRECATED legacy form.
2572
+ *
2573
+ * Closes #233. The original implementation used a flat YAML parser that
2574
+ * destroyed the nested `workflow:` and `git:` sections on every save.
2575
+ * This shim now delegates to the nested-safe writer in lib/config.cjs and
2576
+ * emits a one-line deprecation warning to stderr so callers migrate.
2573
2577
  */
2574
2578
  function cmdConfigSet(subArgs) {
2575
2579
  const flags = {};
@@ -2587,34 +2591,10 @@ function cmdConfigSet(subArgs) {
2587
2591
  if (!key) throw new Error('config set requires --key <key> --value <value>\n e.g. config set --key language --value Arabic');
2588
2592
  if (!value) throw new Error('config set requires --key <key> --value <value>\n e.g. config set --key language --value Arabic');
2589
2593
 
2590
- const configPath = path.join(RIHAL_DIR, 'config.yaml');
2591
- fs.mkdirSync(RIHAL_DIR, { recursive: true });
2592
-
2593
- let content = '';
2594
- if (fs.existsSync(configPath)) {
2595
- content = fs.readFileSync(configPath, 'utf8');
2596
- }
2597
-
2598
- // Parse current config
2599
- const config = parseSimpleYaml(content);
2600
-
2601
- // Update the key
2602
- config[key] = value;
2603
-
2604
- // Serialize back to YAML
2605
- const lines = [];
2606
- for (const [k, v] of Object.entries(config)) {
2607
- const needsQuotes = /\s/.test(v);
2608
- const yamlValue = needsQuotes ? `"${v.replace(/"/g, '\\"')}"` : v;
2609
- lines.push(`${k}: ${yamlValue}`);
2610
- }
2611
-
2612
- const newContent = lines.join('\n') + '\n';
2613
- const tmp = configPath + '.tmp';
2614
- fs.writeFileSync(tmp, newContent, 'utf8');
2615
- fs.renameSync(tmp, configPath);
2594
+ process.stderr.write(`[deprecated] 'config set --key X --value Y' — use 'config-set X Y' instead (preserves nested YAML).\n`);
2616
2595
 
2617
- return { ok: true, key, value, path: configPath };
2596
+ const cfg = require(path.join(__dirname, 'lib', 'config.cjs'));
2597
+ return cfg.cmdSet(PROJECT_ROOT, key, value);
2618
2598
  }
2619
2599
 
2620
2600
  /**
@@ -2805,8 +2785,26 @@ function cmdNotesCount() {
2805
2785
  */
2806
2786
  function cmdBrain(args) {
2807
2787
  const sub = args[0] || 'help';
2808
- const sourcesPath = path.join(PROJECT_ROOT, 'rihal', 'brain', 'sources.yaml');
2809
- const brainDir = path.join(PROJECT_ROOT, 'rihal', 'brain');
2788
+ // sources.yaml lives under .rihal/brain/ in user installs (v2.2+).
2789
+ // Older installs may have it at rihal/brain/ (pre-v2.2) — fall back for compat.
2790
+ let sourcesPath = path.join(RIHAL_DIR, 'brain', 'sources.yaml');
2791
+ let brainDir = path.join(RIHAL_DIR, 'brain');
2792
+ if (!fs.existsSync(sourcesPath)) {
2793
+ const legacyPath = path.join(PROJECT_ROOT, 'rihal', 'brain', 'sources.yaml');
2794
+ if (fs.existsSync(legacyPath)) {
2795
+ sourcesPath = legacyPath;
2796
+ brainDir = path.join(PROJECT_ROOT, 'rihal', 'brain');
2797
+ }
2798
+ }
2799
+
2800
+ // Resolve a source's dest directory relative to brainDir.
2801
+ // Accepts legacy absolute-looking values ("rihal/brain/rihal-github/") by
2802
+ // stripping any leading "rihal/brain/" so the resolved path sits inside the
2803
+ // chosen brainDir. New sources.yaml should use bare names ("rihal-github/").
2804
+ function resolveDest(dest) {
2805
+ const trimmed = String(dest || '').replace(/^rihal\/brain\//, '').replace(/^\/+/, '');
2806
+ return path.join(brainDir, trimmed);
2807
+ }
2810
2808
 
2811
2809
  if (!fs.existsSync(sourcesPath)) {
2812
2810
  return {
@@ -2913,7 +2911,7 @@ function cmdBrain(args) {
2913
2911
  if (sub === 'status') {
2914
2912
  const report = { ok: true, sources: [] };
2915
2913
  for (const s of sources) {
2916
- const destPath = path.join(PROJECT_ROOT, s.dest || '');
2914
+ const destPath = resolveDest(s.dest);
2917
2915
  const exists = fs.existsSync(destPath);
2918
2916
  report.sources.push({
2919
2917
  name: s.name,
@@ -2947,7 +2945,7 @@ function cmdBrain(args) {
2947
2945
 
2948
2946
  if (repo === 'self') {
2949
2947
  // In-repo copy — use rsync-ish node copy from paths under project root.
2950
- const destPath = path.join(PROJECT_ROOT, s.dest);
2948
+ const destPath = resolveDest(s.dest);
2951
2949
  fs.mkdirSync(destPath, { recursive: true });
2952
2950
  const paths = Array.isArray(s.paths) ? s.paths : [];
2953
2951
  let copied = 0;
@@ -2989,7 +2987,7 @@ function cmdBrain(args) {
2989
2987
  const paths = Array.isArray(s.paths) ? s.paths : [];
2990
2988
  execSync(`git -C "${tmp}" sparse-checkout set ${paths.map(p => `"${p}"`).join(' ')}`, { stdio: 'pipe' });
2991
2989
 
2992
- const destPath = path.join(PROJECT_ROOT, s.dest);
2990
+ const destPath = resolveDest(s.dest);
2993
2991
  fs.mkdirSync(destPath, { recursive: true });
2994
2992
  // Copy everything the sparse checkout materialized.
2995
2993
  function copyTree(src, dst) {
@@ -3015,7 +3013,7 @@ function cmdBrain(args) {
3015
3013
  }
3016
3014
 
3017
3015
  /**
3018
- * cmdProgress — single pre-computed progress blob (GSD-parity, issue #159).
3016
+ * cmdProgress — single pre-computed progress blob (issue #159).
3019
3017
  *
3020
3018
  * Subcommands:
3021
3019
  * progress init Full snapshot — everything /rihal:progress needs.
@@ -3301,6 +3299,121 @@ function cmdStateSnapshot() {
3301
3299
  };
3302
3300
  }
3303
3301
 
3302
+ /**
3303
+ * cmdGitignore — re-render the rcode-managed block in .gitignore based on
3304
+ * current config (specifically commit_planning from .rihal/config.yaml).
3305
+ *
3306
+ * Subcommands:
3307
+ * gitignore refresh rewrite the rcode block in-place
3308
+ * gitignore status report current commit_planning + block presence
3309
+ *
3310
+ * Mirrors the logic in cli/install.js ensureRcodeGitignore — kept in sync
3311
+ * by convention. Any change to the block format should update both.
3312
+ * Closes #189 — runtime toggle for commit_planning.
3313
+ */
3314
+ function cmdGitignore(args) {
3315
+ const sub = args[0] || 'refresh';
3316
+ const gitignorePath = path.join(PROJECT_ROOT, '.gitignore');
3317
+ const configPath = path.join(RIHAL_DIR, 'config.yaml');
3318
+
3319
+ // Read commit_planning from config; default true if missing.
3320
+ let commitPlanning = true;
3321
+ if (fs.existsSync(configPath)) {
3322
+ const cfg = fs.readFileSync(configPath, 'utf8');
3323
+ const m = cfg.match(/^\s*commit_planning:\s*(true|false)\s*$/m);
3324
+ if (m) commitPlanning = (m[1] === 'true');
3325
+ }
3326
+
3327
+ const BEGIN = '# ===== rcode-managed gitignore block (npx @hanzlaa/rcode install) =====';
3328
+ const END = '# ===== end rcode-managed gitignore block =====';
3329
+
3330
+ if (sub === 'status') {
3331
+ const exists = fs.existsSync(gitignorePath);
3332
+ const hasBlock = exists && fs.readFileSync(gitignorePath, 'utf8').includes(BEGIN);
3333
+ return {
3334
+ ok: true,
3335
+ gitignore_exists: exists,
3336
+ block_present: hasBlock,
3337
+ commit_planning: commitPlanning,
3338
+ };
3339
+ }
3340
+
3341
+ if (sub !== 'refresh') {
3342
+ return { ok: false, error: `Unknown gitignore subcommand: ${sub}. Try: refresh | status` };
3343
+ }
3344
+
3345
+ const lines = [
3346
+ '',
3347
+ BEGIN,
3348
+ '# Added automatically on rcode install. Idempotent — safe to re-run.',
3349
+ '# Edit `commit_planning` in .rihal/config.yaml, then: rihal-tools gitignore refresh',
3350
+ '',
3351
+ '# Installed methodology files (regenerate with: npx @hanzlaa/rcode install)',
3352
+ '.claude/',
3353
+ '.rihal/bin/',
3354
+ '.rihal/workflows/',
3355
+ '.rihal/references/',
3356
+ '.rihal/commands/',
3357
+ '.rihal/skills/',
3358
+ '',
3359
+ '# Pulled Rihal brain content (refresh with: rcode brain pull)',
3360
+ '.rihal/brain/rihal-github/',
3361
+ '.rihal/brain/rihal-docs/',
3362
+ '.rihal/brain/best-practices/',
3363
+ '',
3364
+ '# Runtime noise',
3365
+ '.rihal/state.json.lock',
3366
+ '.planning/debug/',
3367
+ '.planning/_backup/',
3368
+ ];
3369
+ if (!commitPlanning) {
3370
+ lines.push('', '# Planning artifacts — kept local (commit_planning: false)', '.planning/');
3371
+ }
3372
+ lines.push(
3373
+ '',
3374
+ '# What you DO commit:',
3375
+ '# .rihal/config.yaml - project mode/language/profile/commit_planning',
3376
+ '# .rihal/state.json - decisions, roadmap pointer, blockers',
3377
+ '# .rihal/brain/sources.yaml - brain source manifest',
3378
+ commitPlanning
3379
+ ? '# .planning/ - PRD, roadmap, sprints, SUMMARY.md files'
3380
+ : '# (planning artifacts are NOT committed — see commit_planning in config)',
3381
+ END,
3382
+ ''
3383
+ );
3384
+ const BLOCK = lines.join('\n');
3385
+
3386
+ /** Replace the rcode block in text using indexOf — safer than regex. */
3387
+ function spliceBlock(existing, newBlock) {
3388
+ const start = existing.indexOf(BEGIN);
3389
+ if (start < 0) return null;
3390
+ const endIdx = existing.indexOf(END, start);
3391
+ if (endIdx < 0) return null;
3392
+ // Include trailing newline after END if present, and leading newline before BEGIN.
3393
+ let sliceStart = start;
3394
+ if (sliceStart > 0 && existing[sliceStart - 1] === '\n') sliceStart -= 1;
3395
+ let sliceEnd = endIdx + END.length;
3396
+ if (existing[sliceEnd] === '\n') sliceEnd += 1;
3397
+ return existing.slice(0, sliceStart) + newBlock + existing.slice(sliceEnd);
3398
+ }
3399
+
3400
+ if (!fs.existsSync(gitignorePath)) {
3401
+ fs.writeFileSync(gitignorePath, BLOCK);
3402
+ return { ok: true, action: 'created', commit_planning: commitPlanning };
3403
+ }
3404
+ const existing = fs.readFileSync(gitignorePath, 'utf8');
3405
+ if (existing.includes(BEGIN)) {
3406
+ const rewritten = spliceBlock(existing, BLOCK);
3407
+ if (rewritten !== null && rewritten !== existing) {
3408
+ fs.writeFileSync(gitignorePath, rewritten);
3409
+ return { ok: true, action: 'updated', commit_planning: commitPlanning };
3410
+ }
3411
+ return { ok: true, action: 'no-change', commit_planning: commitPlanning };
3412
+ }
3413
+ fs.writeFileSync(gitignorePath, existing + BLOCK);
3414
+ return { ok: true, action: 'appended', commit_planning: commitPlanning };
3415
+ }
3416
+
3304
3417
  function cmdFindFiles(rawArgs) {
3305
3418
  const flags = {};
3306
3419
  const parts = rawArgs.split(/\s+/).filter(p => p);
@@ -3455,6 +3568,10 @@ async function main() {
3455
3568
  result = cmdStateSnapshot();
3456
3569
  break;
3457
3570
  }
3571
+ case 'gitignore': {
3572
+ result = cmdGitignore(args);
3573
+ break;
3574
+ }
3458
3575
  case 'agent-skills':
3459
3576
  result = cmdAgentInfo(args[0]);
3460
3577
  break;
@@ -34,7 +34,7 @@ sources:
34
34
  - docs/issue-standards.md
35
35
  - docs/commit-standards.md
36
36
  - docs/review-checklist.md
37
- dest: rihal/brain/rihal-github/
37
+ dest: rihal-github/
38
38
 
39
39
  - name: rihal-docs
40
40
  description: >
@@ -47,13 +47,16 @@ sources:
47
47
  - "guides/**/*.md"
48
48
  - "standards/**/*.md"
49
49
  - "playbooks/**/*.md"
50
- dest: rihal/brain/rihal-docs/
50
+ dest: rihal-docs/
51
51
 
52
52
  - name: rihal-best-practices
53
53
  description: >
54
54
  Hanzla's one-year-of-usage best practices — in-repo, version-
55
- controlled alongside the rest of Rihal Code.
55
+ controlled alongside the rest of Rihal Code. Resolved from the
56
+ installed .rihal/skills/_shared/ dir (or the package's own
57
+ rihal/skills/_shared/ when running inside the rihal-code repo).
56
58
  repo: self
57
59
  paths:
60
+ - .rihal/skills/_shared/**/*.md
58
61
  - rihal/skills/_shared/**/*.md
59
- dest: rihal/brain/best-practices/
62
+ dest: best-practices/
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: rihal:audit
3
+ description: Single audit entry point — asks what to audit (phase, milestone, UAT, code, fix, work) and dispatches to the right subroute. Honours .rihal/config.yaml mode.
4
+ argument-hint: "[phase | milestone | uat | code | fix | work] [...subroute args]"
5
+ allowed-tools: Read, Write, Bash, AskUserQuestion
6
+ ---
7
+
8
+ @.rihal/workflows/audit.md
@@ -0,0 +1,13 @@
1
+ ---
2
+ name: rihal:checkpoint-preview
3
+ description: Human-in-the-loop change review — makes sense of a diff, focuses attention where it matters, and walks through testing. Use when you say "checkpoint", "walk me through this", or "human review".
4
+ argument-hint: "[<branch-or-diff>]"
5
+ allowed-tools:
6
+ - Read
7
+ - Bash
8
+ - Grep
9
+ - Glob
10
+ - AskUserQuestion
11
+ ---
12
+
13
+ @.rihal/workflows/checkpoint-preview.md
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  name: rihal:config
3
- description: View or edit Rihal configuration (language, mode, model profile, branching strategy)
4
- argument-hint: "[show | set <key> <value>]"
5
- allowed-tools: Read, Bash, AskUserQuestion
3
+ description: Alias for /rihal:settings — view or edit Rihal config (language, mode, model profile, workflow gates, git strategy)
4
+ argument-hint: "[show | get <key> | set <key> <value>]"
5
+ allowed-tools: Read, Write, Bash, AskUserQuestion
6
6
  ---
7
7
 
8
- @.rihal/workflows/config.md
8
+ @.rihal/workflows/settings.md
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: rihal:prfaq
3
+ description: Working Backwards PRFAQ challenge — stress-test a product concept by writing the press release before building it. Produces a battle-hardened PRFAQ document + PRD distillate.
4
+ argument-hint: "[<idea>] [--headless] [--customer=<persona>] [--problem=<problem>] [--stakes=<why>] [--solution=<concept>]"
5
+ allowed-tools:
6
+ - Read
7
+ - Bash
8
+ - Write
9
+ - Agent
10
+ - AskUserQuestion
11
+ - WebSearch
12
+ - WebFetch
13
+ ---
14
+
15
+ @.rihal/workflows/prfaq.md
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: rihal:settings
3
- description: Interactive configuration wizard for Rihal project settings. Update model profile, research strategy, execution gates, and branching strategy.
4
- argument-hint: ""
3
+ description: View or edit Rihal project settings (mode, model_profile, workflow gates, git strategy). Supports show / get / set / interactive modes.
4
+ argument-hint: "[show | get <key> | set <key> <value>]"
5
5
  allowed-tools: Read, Write, Bash, AskUserQuestion
6
6
  ---
7
7
 
@@ -0,0 +1,12 @@
1
+ # Agent Contracts
2
+
3
+ Conventions Rihal sub-agents follow when invoked from a workflow.
4
+
5
+ - **Input**: a single prompt string. The orchestrator passes structured data
6
+ inline (path lists, JSON blobs) — sub-agents do not stream args.
7
+ - **Output**: one final message back to the orchestrator. No partial state
8
+ is visible mid-run.
9
+ - **Side effects**: each agent's tool list is its full surface — any tool
10
+ not granted in the agent definition is unavailable.
11
+ - **Failure**: agents that hit an obstacle return a structured "blocked"
12
+ message rather than fabricating output.