@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.
- package/CONTRIBUTING.md +138 -0
- package/README.md +83 -19
- package/cli/install.js +687 -80
- package/cli/uninstall.js +8 -0
- package/dist/rcode.js +19777 -0
- package/package.json +17 -4
- package/rihal/DOCS-AUDIT.md +14 -0
- package/rihal/agents/rihal-code-reviewer.md +1 -1
- package/rihal/agents/rihal-codebase-mapper.md +1 -1
- package/rihal/agents/rihal-docs-auditor.md +1 -1
- package/rihal/agents/rihal-edge-case-hunter.md +1 -1
- package/rihal/agents/rihal-executor.md +1 -1
- package/rihal/agents/rihal-hussain-pm.md +1 -0
- package/rihal/agents/rihal-nyquist-auditor.md +1 -1
- package/rihal/agents/rihal-phase-researcher.md +1 -2
- package/rihal/agents/rihal-planner.md +1 -1
- package/rihal/agents/rihal-roadmapper.md +1 -0
- package/rihal/agents/rihal-security-adversary.md +1 -1
- package/rihal/agents/rihal-security-auditor.md +1 -1
- package/rihal/agents/rihal-sprint-checker.md +1 -1
- package/rihal/agents/rihal-verifier.md +1 -1
- package/rihal/bin/lib/roadmap.cjs +2 -3
- package/rihal/bin/rihal-tools.cjs +153 -36
- package/rihal/brain/sources.yaml +7 -4
- package/rihal/commands/audit.md +8 -0
- package/rihal/commands/checkpoint-preview.md +13 -0
- package/rihal/commands/config.md +4 -4
- package/rihal/commands/prfaq.md +15 -0
- package/rihal/commands/settings.md +2 -2
- package/rihal/references/agent-contracts.md +12 -0
- package/rihal/references/karpathy-guidelines-full.md +79 -0
- package/rihal/references/karpathy-guidelines.md +8 -76
- package/rihal/references/model-profile-resolution.md +8 -0
- package/rihal/references/phase-argument-parsing.md +11 -0
- package/rihal/references/revision-loop.md +11 -0
- package/rihal/references/universal-anti-patterns.md +15 -0
- package/rihal/skills/actions/1-analysis/rihal-prfaq/SKILL.md +10 -0
- package/rihal/skills/actions/2-plan/rihal-create-epics-and-stories/SKILL.md +3 -1
- package/rihal/skills/actions/2-plan/rihal-create-milestone/SKILL.md +3 -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 +13 -0
- package/rihal/skills/actions/2-plan/rihal-create-story/SKILL.md +4 -2
- package/rihal/skills/actions/4-implementation/rihal-checkpoint-preview/SKILL.md +10 -0
- package/rihal/skills/actions/4-implementation/rihal-sprint-planning/SKILL.md +3 -1
- package/rihal/skills/agents/hussain-pm/SKILL.md +8 -0
- package/rihal/skills/agents/hussain-sm/SKILL.md +8 -0
- package/rihal/templates/UAT.md +29 -0
- package/rihal/templates/milestone.md +2 -0
- package/rihal/templates/sprint.md +11 -28
- package/rihal/templates/summary.md +30 -0
- package/rihal/templates/verification-report.md +28 -0
- package/rihal/workflows/audit-milestone.md +34 -2
- package/rihal/workflows/audit.md +172 -0
- package/rihal/workflows/autonomous.md +67 -0
- package/rihal/workflows/checkpoint-preview.md +7 -0
- package/rihal/workflows/council.md +3 -1
- package/rihal/workflows/dashboard.md +2 -2
- package/rihal/workflows/debug.md +8 -1
- package/rihal/workflows/diagnose-issues.md +34 -0
- package/rihal/workflows/do.md +47 -3
- package/rihal/workflows/execute-sprint.md +11 -4
- package/rihal/workflows/execute.md +9 -3
- package/rihal/workflows/install.md +2 -2
- package/rihal/workflows/karpathy-audit.md +7 -14
- package/rihal/workflows/pause-work.md +7 -1
- package/rihal/workflows/prfaq.md +7 -0
- package/rihal/workflows/profile-user.md +2 -2
- package/rihal/workflows/progress.md +1 -1
- package/rihal/workflows/settings.md +116 -118
- package/rihal/workflows/sprint-planning.md +39 -8
- package/rihal/workflows/status.md +6 -1
- package/rihal/workflows/ui-phase.md +3 -3
- package/rihal/workflows/update.md +80 -22
- package/rihal/workflows/validate-phase.md +7 -1
- package/rihal/agents/rihal-ui-designer.md +0 -6
- 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
|
|
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": "
|
|
8
|
-
"rihal-code": "
|
|
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.
|
|
@@ -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/`.
|
|
@@ -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.
|
|
@@ -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.
|
|
@@ -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.
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Roadmap — Rihal ROADMAP.md parsing and mutation helpers.
|
|
3
3
|
*
|
|
4
|
-
* Self-contained (stdlib only).
|
|
5
|
-
*
|
|
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 —
|
|
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> —
|
|
2572
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2809
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 (
|
|
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;
|
package/rihal/brain/sources.yaml
CHANGED
|
@@ -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
|
|
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
|
|
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:
|
|
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
|
package/rihal/commands/config.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rihal:config
|
|
3
|
-
description:
|
|
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/
|
|
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:
|
|
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.
|