crbro-memory 2.3.1 → 2.4.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.
Files changed (3) hide show
  1. package/README.md +27 -3
  2. package/bin/crbro.mjs +126 -0
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -119,11 +119,34 @@ claude mcp add --scope user crbro -- npx -y crbro-memory
119
119
  docker build -t crbro-memory . && docker run -i -v crbro-brain:/root/.crbro crbro-memory
120
120
  ```
121
121
 
122
- ### 3. Start using it
122
+ ### 3. Make it load itself — do not skip this
123
123
 
124
- Your AI will now have access to 15 memory tools. Start any session with `crbro_boot`.
124
+ ```bash
125
+ npx crbro-memory install-boot
126
+ ```
127
+
128
+ **Installing the server does not call it.** The tools are there, the brain is on disk, and nothing reads it: the assistant answers from nothing and the memory looks broken when it is merely asleep. Every "CRBRO doesn't remember" report so far has been this, not a bug in recall.
129
+
130
+ `install-boot` wires the start into whichever clients it finds, merging into your config and never rewriting it. It is idempotent, and it leaves alone any hook you already wrote yourself:
131
+
132
+ | Client | What it writes |
133
+ |---|---|
134
+ | **Claude Code** | `SessionStart` in `~/.claude/settings.json` — a command whose stdout enters the session telling the model to call `crbro_boot` first. Claude Code cannot invoke an MCP tool from a hook, so the instruction *is* the mechanism. |
135
+ | **Codex** | `SessionStart` in `~/.codex/hooks.json` — an `mcp_tool` step that calls `crbro_boot` directly, **plus** the same printed instruction as a second layer. |
136
+
137
+ That second layer in Codex is not belt-and-braces: the hook can fire before the MCP server has finished starting, and then the direct call is simply lost. The instruction covers that window.
138
+
139
+ **Tools without session hooks** (Cursor, Windsurf, Antigravity…) do the same job from their always-on rules file — `.cursorrules`, `.windsurfrules`, User Rules. `install-boot` prints the exact line to paste:
140
+
141
+ > CRBRO: call `mcp__crbro__crbro_boot` as your FIRST tool action, before answering, unless this session already contains its result. Apply the `protocol_enforcement` block it returns for the rest of the session.
142
+
143
+ Then restart, open a new conversation, and check that `crbro_boot` **actually ran** and returned a neuron count. If you still have to call it by hand, this step did not take.
144
+
145
+ ### 4. Start using it
146
+
147
+ Your AI now has 15 memory tools and boots the brain on its own. `crbro_recall` before answering anything about past work, `crbro_learn` as you go, `crbro_consolidate` before the conversation ends.
125
148
 
126
- ### 4. (Claude Code, optional) The subagent hook
149
+ ### 5. (Claude Code, optional) The subagent hook
127
150
 
128
151
  ```bash
129
152
  npx crbro-memory install-hooks --inject
@@ -336,6 +359,7 @@ npx crbro-memory remove-miner # Remove the scheduled task
336
359
  ```bash
337
360
  npx crbro-memory # Start MCP server (stdio)
338
361
  npx crbro-memory init # Initialize brain + detect IDEs
362
+ npx crbro-memory install-boot # Make the memory load itself in every conversation (above)
339
363
  npx crbro-memory status # Show brain status
340
364
  npx crbro-memory reindex # Rebuild the search index
341
365
  npx crbro-memory eval # Measure retrieval quality against your own query set
package/bin/crbro.mjs CHANGED
@@ -584,6 +584,131 @@ if (command === 'init') {
584
584
  }
585
585
  }).catch(console.error);
586
586
 
587
+ } else if (command === 'install-boot') {
588
+ // ─── The step that made the memory look broken ─────────────────
589
+ //
590
+ // Installing the MCP server does not call it. Without something that runs
591
+ // crbro_boot at the start of a conversation, the brain sits there and the
592
+ // assistant answers from nothing — the memory looks installed and behaves
593
+ // like it was never there. Every report of "CRBRO does not remember" so far
594
+ // has been this, not a bug in the recall.
595
+ //
596
+ // So this wires the start itself, per client:
597
+ //
598
+ // Claude Code ~/.claude/settings.json — SessionStart runs a command whose
599
+ // stdout is added to the session, telling the model to call
600
+ // crbro_boot first. Claude Code has no way to invoke an MCP
601
+ // tool from a hook, so the instruction is the mechanism.
602
+ // Codex ~/.codex/hooks.json — SessionStart can call an MCP tool
603
+ // directly (type "mcp_tool"), so it does, AND keeps the same
604
+ // printed instruction as a second layer: the hook can fire
605
+ // before the MCP server has finished starting, and then the
606
+ // direct call is simply lost.
607
+ //
608
+ // Only files that already exist are touched, and each one is merged, never
609
+ // rewritten. Idempotent: a second run reports and changes nothing.
610
+ import('fs').then(async fs => {
611
+ const AVISO =
612
+ 'CRBRO: call mcp__crbro__crbro_boot as your FIRST tool action, before answering, ' +
613
+ 'unless this session already contains its result. Discover deferred CRBRO tools first if needed. ' +
614
+ 'Apply the protocol_enforcement block it returns for the rest of the session.';
615
+
616
+ // printf on a shell, Write-Output on Windows PowerShell. One line, no
617
+ // external file: a path stored in a hook goes stale on the next update.
618
+ const cmdPosix = `printf '%s\\n' ${JSON.stringify(AVISO)}`;
619
+ const cmdWin = `powershell -NoProfile -Command ${JSON.stringify('Write-Output ' + JSON.stringify(AVISO))}`;
620
+ const MATCHER = 'startup|resume|clear|compact';
621
+
622
+ const leerJson = (p) => {
623
+ if (!fs.existsSync(p)) return null;
624
+ try {
625
+ return JSON.parse(fs.readFileSync(p, 'utf8').replace(/^/, ''));
626
+ } catch (e) {
627
+ console.error(` ❌ ${p} exists but could not be parsed — not touching it.`);
628
+ console.error(` ${e.message}`);
629
+ process.exit(1);
630
+ }
631
+ };
632
+ const escribirJson = (p, obj) => {
633
+ const tmp = p + '.' + process.pid + '.tmp';
634
+ fs.writeFileSync(tmp, JSON.stringify(obj, null, 2) + '\n', 'utf8');
635
+ fs.renameSync(tmp, p);
636
+ };
637
+
638
+ let tocados = 0, yaEstaban = 0, ausentes = [];
639
+
640
+ // — Claude Code —
641
+ const claudePath = join(homedir(), '.claude', 'settings.json');
642
+ const claude = leerJson(claudePath) ?? (fs.existsSync(join(homedir(), '.claude')) ? {} : null);
643
+ if (claude === null) {
644
+ ausentes.push('Claude Code (~/.claude not found)');
645
+ } else {
646
+ claude.hooks = claude.hooks || {};
647
+ const list = claude.hooks.SessionStart = claude.hooks.SessionStart || [];
648
+ // Any mention of crbro counts as "already wired". A hand-rolled hook
649
+ // often points at a file — `cat ~/.claude/crbro-session-start.txt` — so
650
+ // looking for crbro_boot alone misses it and installs a second entry
651
+ // that boots the brain twice.
652
+ if (/crbro/i.test(JSON.stringify(list))) {
653
+ yaEstaban++;
654
+ console.log(' ⚪ Claude Code: SessionStart already starts CRBRO. Left alone.');
655
+ } else {
656
+ list.push({
657
+ matcher: MATCHER,
658
+ hooks: [{ type: 'command', command: cmdPosix, shell: 'bash', timeout: 10, statusMessage: 'Loading CRBRO memory...' }],
659
+ });
660
+ escribirJson(claudePath, claude);
661
+ tocados++;
662
+ console.log(` ✅ Claude Code: SessionStart hook added.\n ${claudePath}`);
663
+ }
664
+ }
665
+
666
+ // — Codex —
667
+ const codexDir = join(homedir(), '.codex');
668
+ const codexPath = join(codexDir, 'hooks.json');
669
+ if (!fs.existsSync(codexDir)) {
670
+ ausentes.push('Codex (~/.codex not found)');
671
+ } else {
672
+ const codex = leerJson(codexPath) ?? {};
673
+ codex.hooks = codex.hooks || {};
674
+ const list = codex.hooks.SessionStart = codex.hooks.SessionStart || [];
675
+ // Any mention of crbro counts as "already wired". A hand-rolled hook
676
+ // often points at a file — `cat ~/.claude/crbro-session-start.txt` — so
677
+ // looking for crbro_boot alone misses it and installs a second entry
678
+ // that boots the brain twice.
679
+ if (/crbro/i.test(JSON.stringify(list))) {
680
+ yaEstaban++;
681
+ console.log(' ⚪ Codex: SessionStart already starts CRBRO. Left alone.');
682
+ } else {
683
+ list.push({
684
+ matcher: MATCHER,
685
+ hooks: [
686
+ { type: 'mcp_tool', server: 'crbro', tool: 'crbro_boot', input: {}, timeout: 30, statusMessage: 'Loading CRBRO memory...' },
687
+ { type: 'command', command: cmdPosix, commandWindows: cmdWin, timeout: 10, statusMessage: 'Checking CRBRO start...' },
688
+ ],
689
+ });
690
+ escribirJson(codexPath, codex);
691
+ tocados++;
692
+ console.log(` ✅ Codex: SessionStart hook added (MCP call + fallback).\n ${codexPath}`);
693
+ }
694
+ }
695
+
696
+ console.log('');
697
+ if (!tocados && !yaEstaban) {
698
+ console.log(' ⚠️ Neither ~/.claude nor ~/.codex was found, so nothing was wired.');
699
+ }
700
+ for (const a of ausentes) console.log(` ⚪ Skipped ${a}`);
701
+ console.log('');
702
+ console.log(' Other tools (Cursor, Windsurf, Antigravity…) have no session hooks.');
703
+ console.log(' Put this line in their always-on rules file (.cursorrules, .windsurfrules,');
704
+ console.log(' User Rules) and it does the same job:');
705
+ console.log('');
706
+ console.log(` ${AVISO}`);
707
+ console.log('');
708
+ if (tocados) console.log(' Restart the tool, then check a new conversation actually boots CRBRO.');
709
+ console.log('');
710
+ }).catch(console.error);
711
+
587
712
  } else if (command === 'secret') {
588
713
  // ─── Credentials, from the terminal ────────────────────────────
589
714
  //
@@ -735,6 +860,7 @@ if (command === 'init') {
735
860
  console.log('');
736
861
  console.log(' Setup:');
737
862
  console.log(' npx crbro-memory init Initialize brain + detect IDEs');
863
+ console.log(' npx crbro-memory install-boot Make the memory load itself in every conversation');
738
864
  console.log(' npx crbro-memory status Show brain status');
739
865
  console.log('');
740
866
  console.log(' Auto-Mining:');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crbro-memory",
3
- "version": "2.3.1",
3
+ "version": "2.4.0",
4
4
  "mcpName": "io.github.Octonove/crbro-memory",
5
5
  "description": "CRBRO — Persistent neural memory for AI. A biological file-based MCP server that gives your AI long-term memory across sessions.",
6
6
  "main": "dist/index.js",