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.
- package/README.md +27 -3
- package/bin/crbro.mjs +126 -0
- 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.
|
|
122
|
+
### 3. Make it load itself — do not skip this
|
|
123
123
|
|
|
124
|
-
|
|
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
|
-
###
|
|
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
|
+
"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",
|