@hanzlaa/rcode 4.8.0 → 4.9.0

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/README.md CHANGED
@@ -23,7 +23,7 @@ pnpm dlx @hanzlaa/rcode install
23
23
  [![CI](https://github.com/hanzlahabib/rcode/actions/workflows/test.yml/badge.svg)](https://github.com/hanzlahabib/rcode/actions/workflows/test.yml)
24
24
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
25
25
 
26
- Status: `@hanzlaa/rcode` v4.7.0 on npm. 45 agents · 117 commands · 129 workflows · **1 runtime dependency**. Test status tracked by CI badge above. Actively dogfooded on real projects every week.
26
+ Status: `@hanzlaa/rcode` v4.8.0 on npm. 45 agents · 117 commands · 130 workflows · **1 runtime dependency**. Test status tracked by CI badge above. Actively dogfooded on real projects every week.
27
27
 
28
28
  ---
29
29
 
@@ -154,10 +154,10 @@ The point isn't "I beat LangChain." The point is **you don't need LangChain for
154
154
  | Metric | Value | Why it's not a vanity number |
155
155
  |---|---|---|
156
156
  | **Portable methodology corpus** | **~105,000 lines** of markdown | A 10-person eng org's playbooks (agents + commands + workflows + skills + references) — as files you own and grep, not a SaaS you rent. |
157
- | **Automated tests** | **495** across 62 files | The methodology is *guarded*, not vibes. Live pass/fail status is on the CI badge above; `node --test` (or `node benchmarks/facts.cjs`) reproduces locally in seconds. |
157
+ | **Automated tests** | **598** across 74 files | The methodology is *guarded*, not vibes. Live pass/fail status is on the CI badge above; `node --test` (or `node benchmarks/facts.cjs`) reproduces locally in seconds. |
158
158
  | **Tested CLI engine** | **~9,700 lines** (`rcode-tools.cjs` + `lib/`) | The deterministic brain — routing, state, planning math — is real code under test, not prompt soup. |
159
159
  | **Runtime dependencies** | **1** (`ws`, for the dashboard socket) | The dashboard is otherwise pure Node stdlib. Almost nothing to audit, nothing to CVE-scan, nothing to break on `npm install`. |
160
- | **Specialist agents / commands / workflows / skills** | **45 / 117 / 129 / 96** | An entire engineering org, phrase-activated, that travels with you across Claude Code, Cursor, Codex, VS Code, Antigravity, Windsurf. |
160
+ | **Specialist agents / commands / workflows / skills** | **45 / 117 / 130 / 96** | An entire engineering org, phrase-activated, that travels with you across Claude Code, Cursor, Codex, VS Code, Antigravity, Windsurf. |
161
161
  | **Core-op latency** | **~60 ms**, **0 LLM tokens** (best-of-7) | Intent routing, state reads, and milestone-health are deterministic *local* compute — a few ms over Node's own cold-start floor. The orchestration layer doesn't burn API tokens on bookkeeping the way pure-LLM agent frameworks do. |
162
162
 
163
163
  > Counts above are produced by `node benchmarks/facts.cjs` and may drift slightly between releases — run it for the exact current figures.
@@ -181,6 +181,8 @@ pnpm dlx @hanzlaa/rcode install
181
181
 
182
182
  `/rcode-init` detects your project state (fresh / existing / returning) and routes to the right first action. For a greenfield project it auto-routes to `/rcode-new-project`.
183
183
 
184
+ > **Want a status primer at the start of every session?** Run `/rcode-enable-hooks` to turn on a one-line project status readout (phase, plan progress, blockers) each time Claude Code starts in this project, plus 9 other opt-in guardrails (read-before-edit checks, dangerous-command blocking, auto-formatting). All off by default — a fresh install never surprises you.
185
+
184
186
  ### The full loop
185
187
 
186
188
  Four commands cover most of a real week of work — decide, plan, build, check in:
@@ -227,9 +229,9 @@ The non-goal: building yet another agent framework. There are enough. rcode stay
227
229
 
228
230
  ## Honest state of things
229
231
 
230
- - **v4.3.2** is the current release — Memory Bank now ships populated by default, brain-pull is live, and 50+ bug fixes landed from the most recent 3-project dogfeed run.
232
+ - **v4.8.0** is the current release — Memory Bank now ships populated by default, brain-pull is live, and 50+ bug fixes landed from the most recent 3-project dogfeed run.
231
233
  - **Open issues**: ~50 — half are feature requests, the rest are backlog bugs ranked by severity.
232
- - **Test suite**: 497 automated tests across 61 files, 100% pass on every release (run `node --test`). Coverage is structural (compliance + artifact schema + workflow behavioral), not line-coverage.
234
+ - **Test suite**: 598 automated tests across 74 files (run `node --test`). Live pass/fail status is on the CI badge above. Coverage is structural (compliance + artifact schema + workflow behavioral), not line-coverage.
233
235
  - **Real users**: I run it on 4 projects daily. A handful of others run it on theirs. If you find a bug, file it — most P1s ship within 48 hours.
234
236
  - **Funding**: none. This is solo work. If your company wants commercial support, [email me](mailto:hanzla.dev@gmail.com).
235
237
 
package/cli/install.js CHANGED
@@ -2502,21 +2502,32 @@ async function installInner(opts) {
2502
2502
  fs.existsSync(path.join(projectClaudeCommands, 'rcode'))
2503
2503
  );
2504
2504
  if (globalHasrcode && !projectHasrcode) {
2505
- // Global commands exist, project has none yet — filter them out of the plan
2506
- // so we don't create duplicates. Project gets .rcode/ state only.
2505
+ // Global commands exist, project has none yet — filter commands out of the
2506
+ // plan so we don't create duplicates. Project gets .rcode/ state only.
2507
+ //
2508
+ // Issue #1022: agents are NOT deferrable to global the way commands/skills
2509
+ // are — they are first-class, project-local files by design (see the
2510
+ // createInstallBackup comment above: "closes #381 — without this,
2511
+ // customized .claude/agents/rcode-*.md ... were silently lost"). Lumping
2512
+ // `.claude/agents/` into this commands-dedup filter meant a project with
2513
+ // global rcode commands installed but no project-level commands yet would
2514
+ // never get its .claude/agents/*.md files written at all, leaving only
2515
+ // whatever pre-existing subdirectories (e.g. rules/) survived untouched.
2507
2516
  const before = plan.length;
2508
2517
  const filtered = plan.filter(e => {
2509
2518
  const rel = e.rel.split(path.sep).join('/');
2510
- return !rel.startsWith('.claude/commands/') && !rel.startsWith('.claude/agents/');
2519
+ return !rel.startsWith('.claude/commands/');
2511
2520
  });
2512
2521
  if (filtered.length < before) {
2513
2522
  plan.length = 0;
2514
2523
  filtered.forEach(e => plan.push(e));
2515
- console.log(' ' + dim('Global rcode commands detected in ~/.claude/ — skipping project-level agent/command install to avoid duplicates.'));
2524
+ console.log(' ' + dim('Global rcode commands detected in ~/.claude/ — skipping project-level command install to avoid duplicates.'));
2516
2525
  console.log(' ' + dim('Use --force-overwrite to install locally anyway.'));
2517
2526
  }
2518
2527
  } else if (globalHasrcode && projectHasrcode) {
2519
2528
  // Both exist — project commands are duplicates. Remove project-level ones.
2529
+ // Agents are left untouched (#1022) — they are project-local by design,
2530
+ // never deduped against the global commands install.
2520
2531
  try {
2521
2532
  // Remove root-level rcode-*.md files
2522
2533
  const projectCommandFiles = fs.readdirSync(projectClaudeCommands)
@@ -2530,19 +2541,11 @@ async function installInner(opts) {
2530
2541
  if (fs.existsSync(rcodeSubdir)) {
2531
2542
  safeRmSync(rcodeSubdir, opts.target);
2532
2543
  }
2533
- const projectAgentsDir = path.join(opts.target, '.claude', 'agents');
2534
- if (fs.existsSync(projectAgentsDir)) {
2535
- const agentFiles = fs.readdirSync(projectAgentsDir)
2536
- .filter(f => f.startsWith('rcode-') && f.endsWith('.md'));
2537
- for (const f of agentFiles) {
2538
- fs.unlinkSync(path.join(projectAgentsDir, f));
2539
- }
2540
- }
2541
2544
  console.log(' ' + dim('Removed duplicate project-level rcode commands (global ones in ~/.claude/ take precedence).'));
2542
2545
  } catch { /* non-fatal */ }
2543
2546
  const filtered = plan.filter(e => {
2544
2547
  const rel = e.rel.split(path.sep).join('/');
2545
- return !rel.startsWith('.claude/commands/') && !rel.startsWith('.claude/agents/');
2548
+ return !rel.startsWith('.claude/commands/');
2546
2549
  });
2547
2550
  plan.length = 0;
2548
2551
  filtered.forEach(e => plan.push(e));