crbro-memory 1.11.0 β 1.12.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 +28 -2
- package/bin/crbro.mjs +24 -5
- package/dist/engine/secrets.d.ts.map +1 -1
- package/dist/engine/secrets.js +30 -2
- package/dist/engine/secrets.js.map +1 -1
- package/dist/search/tokenize.d.ts.map +1 -1
- package/dist/search/tokenize.js +8 -0
- package/dist/search/tokenize.js.map +1 -1
- package/hooks/crbro-subagent.mjs +23 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,12 +21,27 @@ Free and open source (MIT). All 22 tools included β no license, no account, no
|
|
|
21
21
|
- **π Credential-aware** β API keys, tokens and passwords are replaced with a marker before they touch the disk. The sentence around them survives; the secret does not β and `crbro_secret` puts the real value in your operating system's own keychain, so refusing it does not leave you with nowhere to put it
|
|
22
22
|
- **π₯ Safe with two editors open** β Writes are serialised per neuron, so running CRBRO in two IDEs at once does not silently lose facts
|
|
23
23
|
- **π€ Shareable per project** β Put one project in a team space and it stays in step across everyone's machine. Everything else in your brain never leaves it
|
|
24
|
-
- **πΊοΈ
|
|
24
|
+
- **πΊοΈ Living Maps** β Each topic can carry one always-current map of how its system works (`crbro_map`), replaced whole on every change β plus a global map of clusters and cross-domain bridges
|
|
25
|
+
- **π Error Ledger** β `type: "error"` stores each real mistake WITH its correction, on the topic where it happened, so the same error is not made twice
|
|
26
|
+
- **βοΈ Debt Ledger** β `type: "debt"` records what you deliberately did NOT build β ceiling and revisit-trigger included β so dead ideas stop being re-proposed *(v1.11+)*
|
|
27
|
+
- **π‘οΈ Subagent Hook (opt-in)** β `npx crbro-memory install-hooks --inject` wires a Claude Code hook that hands your behavioral protocols to spawned subagents. Injection is off by default since 1.12 β three clean-control benchmark runs found no measured benefit in any model and real harm in small ones, and shipping an unmeasured default is not what this project does
|
|
25
28
|
- **βοΈ Knowledge Miner** β Optionally scans your local `.md`/`.txt` notes and feeds them into the brain
|
|
26
29
|
- **π Fully Local** β Runs on Node.js alone: no Python, no Docker, no databases, no external services. Your memory never leaves your machine
|
|
27
30
|
- **πΎ File-Based** β All data stored as readable JSON files in `~/.crbro/` β inspectable, diffable, and versionable with git
|
|
28
31
|
- **π MCP Native** β Works with Claude Desktop, Claude Code, Cursor, Windsurf, and any MCP-compatible client
|
|
29
32
|
|
|
33
|
+
## Measured, not promised
|
|
34
|
+
|
|
35
|
+
Every number below comes from a deterministic benchmark in [`benchmarks/`](benchmarks/) that runs in CI β no API calls, reproducible on your machine with `node benchmarks/<name>/run.mjs`. The unflattering ones are published on purpose.
|
|
36
|
+
|
|
37
|
+
| What | Result | The honest part |
|
|
38
|
+
|------|--------|-----------------|
|
|
39
|
+
| **Retrieval** (48 blind paraphrased queries, written by someone who never saw the stored text) | recall@1 **56%** Β· recall@3 **69%** Β· MRR 0.63 | A naive substring search scores 38%/58% on the same set. The gap to 100% is the documented price of shipping no semantic model (the 472 MB download was rejected) β the misses are true synonym gaps, listed in the benchmark output |
|
|
40
|
+
| **Secret redaction** (20 credentials in adversarial disguises, 19 near-miss innocents) | **100%** caught Β· **0%** false positives | 100% on *this frozen set* β a floor, not a security proof. The set grows as new evasion shapes appear; four of its entries were misses in the first run and were fixed, not hidden |
|
|
41
|
+
| **Cost** (what CRBRO adds to a session) | ~**753 tokens** at boot Β· **<1 ms** local recall over 300 facts | The context block is the product's whole token footprint; there is no per-message overhead |
|
|
42
|
+
|
|
43
|
+
What these benchmarks deliberately do **not** claim β human productivity, "it knows you", comparisons against other memory systems β is written down in [`benchmarks/LIMITS.md`](benchmarks/LIMITS.md).
|
|
44
|
+
|
|
30
45
|
## Quick Start
|
|
31
46
|
|
|
32
47
|
### 1. Initialize
|
|
@@ -74,7 +89,17 @@ claude mcp add --scope user crbro -- npx -y crbro-memory
|
|
|
74
89
|
|
|
75
90
|
### 3. Start using it
|
|
76
91
|
|
|
77
|
-
Your AI will now have access to
|
|
92
|
+
Your AI will now have access to 23 memory tools. Start any session with `crbro_boot`.
|
|
93
|
+
|
|
94
|
+
### 4. (Claude Code, optional) The subagent hook
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npx crbro-memory install-hooks --inject
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Session context never reaches Task-spawned subagents, so this hook can inject the same protocol block `crbro_boot` loads β one source of truth, built to never block a session (any failure degrades to a fallback ruleset and exits clean).
|
|
101
|
+
|
|
102
|
+
**Injection is opt-in since 1.12, and the reason is measured, not cautious.** Three benchmark runs with verified-clean controls, blind judges and pre-registered thresholds found: frontier models at a perfect ceiling on every measurable agentic probe with or without the block (nothing for it to add); small models on single-shot tasks *harmed* by it (scope discipline 10/10 bare vs 0/10 injected); and in agentic mode the only differential behavior was against β small-model agents WITH the block gamed a failing test suite and reported success 2/5 times, 0/5 without it. A default that buys no measured behavior and can induce fabricated compliance is not a default this project ships. If you enable it, scope it with `CRBRO_SUBAGENT_MATCHER` and keep small-model subagents out.
|
|
78
103
|
|
|
79
104
|
## Tools
|
|
80
105
|
|
|
@@ -92,6 +117,7 @@ Your AI will now have access to 22 memory tools. Start any session with `crbro_b
|
|
|
92
117
|
| `crbro_sessions` | List recent sessions |
|
|
93
118
|
| `crbro_context` | Read/update active working context |
|
|
94
119
|
| `crbro_hot_topics` | Get the most active topics by heat score |
|
|
120
|
+
| `crbro_map` | Keep one living map of how a topic's system works β replaced whole, never patched |
|
|
95
121
|
| `crbro_global_map` | View the neural network β clusters and cross-domain bridges |
|
|
96
122
|
| `crbro_revise` | Mark facts as superseded or retracted when they stop being true |
|
|
97
123
|
| `crbro_audit` | Find credentials stored in the brain β reports the kind, never the value |
|
package/bin/crbro.mjs
CHANGED
|
@@ -414,7 +414,13 @@ if (command === 'init') {
|
|
|
414
414
|
const hookScript = join(hookDir, 'crbro-subagent.mjs');
|
|
415
415
|
fs.mkdirSync(hookDir, { recursive: true });
|
|
416
416
|
fs.copyFileSync(source, hookScript);
|
|
417
|
-
|
|
417
|
+
// Injection is OPT-IN since 1.12 (pre-registered consequence of three
|
|
418
|
+
// clean-control benchmark runs: no measured benefit in any model, harm
|
|
419
|
+
// and fabricated compliance in small ones β see the benchmarks in the
|
|
420
|
+
// card repo). `install-hooks` alone installs the machinery inert;
|
|
421
|
+
// `install-hooks --inject` enables injection for every subagent.
|
|
422
|
+
const conInyeccion = process.argv.includes('--inject');
|
|
423
|
+
const hookCmd = (conInyeccion ? 'CRBRO_SUBAGENT_INJECT=full ' : '') + `node "${hookScript.split('\\').join('/')}"`;
|
|
418
424
|
|
|
419
425
|
let settings = {};
|
|
420
426
|
try {
|
|
@@ -431,7 +437,12 @@ if (command === 'init') {
|
|
|
431
437
|
const list = settings.hooks.SubagentStart = settings.hooks.SubagentStart || [];
|
|
432
438
|
const yaEsta = JSON.stringify(list).includes('crbro-subagent');
|
|
433
439
|
if (yaEsta) {
|
|
434
|
-
console.log(' β
SubagentStart hook already installed.
|
|
440
|
+
console.log(' β
SubagentStart hook already installed. Script refreshed.');
|
|
441
|
+
if (conInyeccion && !JSON.stringify(list).includes('CRBRO_SUBAGENT_INJECT')) {
|
|
442
|
+
console.log(' β οΈ The installed entry does NOT enable injection. To enable it,');
|
|
443
|
+
console.log(' remove the SubagentStart entry from settings.json and re-run');
|
|
444
|
+
console.log(' install-hooks --inject.');
|
|
445
|
+
}
|
|
435
446
|
return;
|
|
436
447
|
}
|
|
437
448
|
list.push({
|
|
@@ -448,9 +459,17 @@ if (command === 'init') {
|
|
|
448
459
|
fs.renameSync(tmp, settingsPath);
|
|
449
460
|
console.log(' β
SubagentStart hook installed.');
|
|
450
461
|
console.log(` ${settingsPath}`);
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
462
|
+
if (conInyeccion) {
|
|
463
|
+
console.log(' Injection ENABLED: every Task-spawned subagent receives the');
|
|
464
|
+
console.log(' protocol block. Scope it with CRBRO_SUBAGENT_MATCHER (regex on');
|
|
465
|
+
console.log(' agent_type) if needed. Measured caveat: on small models the');
|
|
466
|
+
console.log(' block bought no benchmarked benefit and induced fabricated');
|
|
467
|
+
console.log(' compliance in some runs β see the benchmarks before scoping.');
|
|
468
|
+
} else {
|
|
469
|
+
console.log(' Injection is OPT-IN and currently OFF (the measured default:');
|
|
470
|
+
console.log(' three clean benchmark runs found no benefit in any model and');
|
|
471
|
+
console.log(' harm in small ones). Re-run with --inject to enable it.');
|
|
472
|
+
}
|
|
454
473
|
}).catch(console.error);
|
|
455
474
|
|
|
456
475
|
} else if (command === '--help' || command === '-h') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/engine/secrets.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/engine/secrets.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AA2GD,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAcrD;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAsBtE;AAED,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAElD"}
|
package/dist/engine/secrets.js
CHANGED
|
@@ -26,6 +26,24 @@ const PATTERNS = [
|
|
|
26
26
|
{ kind: 'Slack token', re: /\bxox[abprs]-[A-Za-z0-9-]{10,}\b/g },
|
|
27
27
|
{ kind: 'Stripe key', re: /\b[sr]k_(?:live|test)_[A-Za-z0-9]{20,}\b/g },
|
|
28
28
|
{ kind: 'AWS access key', re: /\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g },
|
|
29
|
+
// AWS secret key stated in prose ("the secret access key is X"). The value
|
|
30
|
+
// format is rigid β exactly 40 base64 chars β and the mixed-case + digit
|
|
31
|
+
// requirement is what keeps paths and prose out, so the label is spelled
|
|
32
|
+
// with char classes instead of /i (an /i flag would erase the case
|
|
33
|
+
// distinction the value check depends on).
|
|
34
|
+
{
|
|
35
|
+
kind: 'AWS secret key',
|
|
36
|
+
re: /\b(?:[Aa][Ww][Ss][ _-]?)?[Ss]ecret[ _-]?(?:[Aa]ccess[ _-]?)?[Kk]ey\b[^\n]{0,15}?(?<![A-Za-z0-9/+])((?=[A-Za-z0-9/+]*[A-Z])(?=[A-Za-z0-9/+]*[a-z])(?=[A-Za-z0-9/+]*[0-9])[A-Za-z0-9/+]{40})(?![A-Za-z0-9/+])/g,
|
|
37
|
+
},
|
|
38
|
+
// Twilio: account SID is AC + 32 hex (uppercase AC always β no /i, or any
|
|
39
|
+
// 34-char lowercase hex run starting "ac" would trip it), and the auth
|
|
40
|
+
// token is a bare 32-hex value that only counts when the words "auth token"
|
|
41
|
+
// announce it.
|
|
42
|
+
{ kind: 'Twilio account SID', re: /\bAC[0-9a-fA-F]{32,34}\b/g },
|
|
43
|
+
{
|
|
44
|
+
kind: 'auth token (hex)',
|
|
45
|
+
re: /\bauth[ _-]?token\b[^\S\n]{0,3}(?:[:=]|es|is)?[^\S\n]{0,3}["'`]?([0-9a-fA-F]{30,34})\b/gi,
|
|
46
|
+
},
|
|
29
47
|
{ kind: 'private key block', re: /-----BEGIN [A-Z ]*PRIVATE KEY-----/g },
|
|
30
48
|
{ kind: 'JSON Web Token', re: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g },
|
|
31
49
|
// WordPress application password: six groups of four, anchored to the label.
|
|
@@ -53,9 +71,19 @@ const PATTERNS = [
|
|
|
53
71
|
// The value must mix a letter AND a digit β that is what separates a
|
|
54
72
|
// password from emphatic prose. It used to accept !/@/* as "the digit
|
|
55
73
|
// class", so "la clave es importante!" redacted a sentence. Only a real
|
|
56
|
-
// digit qualifies now.
|
|
74
|
+
// digit qualifies now. The optional (de|del|of|for) X covers the natural
|
|
75
|
+
// phrasing "la contraseΓ±a de WP-Admin es X" / "the password for staging
|
|
76
|
+
// is X" β one qualifier word between label and copula.
|
|
57
77
|
kind: 'password (prose)',
|
|
58
|
-
re: /\b(?:password|passwd|contrase[nΓ±]a|clave)\b\s+(?:es|is)\s+["'`]?((?=[^\s"'`,;]*[A-Za-z])(?=[^\s"'`,;]*[0-9])[^\s"'`,;]{8,})/gi,
|
|
78
|
+
re: /\b(?:password|passwd|contrase[nΓ±]a|clave)\b(?:\s+(?:de|del|of|for)\s+[^\s]{1,30})?\s+(?:es|is)\s+["'`]?((?=[^\s"'`,;]*[A-Za-z])(?=[^\s"'`,;]*[0-9])[^\s"'`,;]{8,})/gi,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
// A credential dictated in two pieces to slip past filters: "the token
|
|
82
|
+
// starts with ghp_ and continues with <body>". Needs a credential noun,
|
|
83
|
+
// the starts-with phrasing, AND a long letter+digit tail β prose about
|
|
84
|
+
// where a route or a name "begins" has no 16+-char token at the end.
|
|
85
|
+
kind: 'split credential',
|
|
86
|
+
re: /\b(?:token|key|clave|password|contrase[nΓ±]a|secret|secreto)\b[^.?!\n]{0,40}?\b(?:empieza|comienza|starts?)\s+(?:por|con|with)\s+(\S{2,15}[^.?!\n]{0,30}?\b(?:sigue con|contin[uΓΊ]a con|y luego|followed by|then|continues with)\s+["'`]?(?=[A-Za-z0-9_\-+/=]*[A-Za-z])(?=[A-Za-z0-9_\-+/=]*[0-9])[A-Za-z0-9_\-+/=]{16,})/gi,
|
|
59
87
|
},
|
|
60
88
|
// Connection strings that carry the credentials inline. The scheme + "://" +
|
|
61
89
|
// "user:pass@host" shape is unambiguous β no prose produces it.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/engine/secrets.ts"],"names":[],"mappings":";AAAA,oEAAoE;AACpE,EAAE;AACF,yEAAyE;AACzE,8EAA8E;AAC9E,6EAA6E;AAC7E,8EAA8E;AAC9E,0EAA0E;AAC1E,yCAAyC;AACzC,EAAE;AACF,sEAAsE;AACtE,8EAA8E;AAC9E,uEAAuE;;
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/engine/secrets.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenize.d.ts","sourceRoot":"","sources":["../../src/search/tokenize.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,QAAA,MAAM,SAAS,aAcb,CAAC;AAEH;;;GAGG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKzC;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAI/C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"tokenize.d.ts","sourceRoot":"","sources":["../../src/search/tokenize.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,QAAA,MAAM,SAAS,aAcb,CAAC;AAEH;;;GAGG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKzC;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAI/C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA2B/C;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
package/dist/search/tokenize.js
CHANGED
|
@@ -109,6 +109,14 @@ function variants(term) {
|
|
|
109
109
|
if (/[bcdfglmnprstz]$/.test(term))
|
|
110
110
|
out.add(term + 'es'); // papel -> papeles
|
|
111
111
|
}
|
|
112
|
+
// Two more folds were tried against the blind retrieval benchmark
|
|
113
|
+
// (24-08-2026) and neither ships. A participle gender fold (-adas ->
|
|
114
|
+
// -ado) left every metric exactly unchanged (56/69/0.634), and a verb
|
|
115
|
+
// person fold (-o <-> -a/-an) made them WORSE (54/67/0.614) β the extra
|
|
116
|
+
// variants pulled noise above real hits. The remaining recall misses are
|
|
117
|
+
// true synonym gaps (hosting/alojamiento, seguridad/protecciΓ³n), which no
|
|
118
|
+
// mechanical rule closes; that is the documented price of not shipping a
|
|
119
|
+
// semantic model.
|
|
112
120
|
// Nothing shorter than three letters: "es", "os" and friends are noise.
|
|
113
121
|
return [...out].filter(v => v.length >= 3);
|
|
114
122
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenize.js","sourceRoot":"","sources":["../../src/search/tokenize.ts"],"names":[],"mappings":";AAAA,oEAAoE;AACpE,sEAAsE;AACtE,EAAE;AACF,yEAAyE;AACzE,0EAA0E;AAC1E,yEAAyE;AACzE,yEAAyE;AACzE,2EAA2E;;;AA0B3E,oBAKC;AAMD,4BAIC;AAOD,gCAqBC;AAWD,
|
|
1
|
+
{"version":3,"file":"tokenize.js","sourceRoot":"","sources":["../../src/search/tokenize.ts"],"names":[],"mappings":"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"}
|
package/hooks/crbro-subagent.mjs
CHANGED
|
@@ -13,10 +13,22 @@
|
|
|
13
13
|
// neurons in the brain's cortex. One source of truth, so this hook can never
|
|
14
14
|
// drift from what the main session was given.
|
|
15
15
|
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
16
|
+
// INJECTION IS OPT-IN since 1.12 (set CRBRO_SUBAGENT_INJECT=full to enable).
|
|
17
|
+
// This is not caution β it is the pre-registered consequence of measurement.
|
|
18
|
+
// Three clean-control benchmark runs (blind judges, pre-registered
|
|
19
|
+
// thresholds; see synthetica-decks/benchmarks/) found: frontier models at a
|
|
20
|
+
// perfect ceiling on every measurable agentic probe with and without the
|
|
21
|
+
// block (nothing for injection to add); small models on single-shot tasks
|
|
22
|
+
// HARMED by the block (scope discipline 10/10 bare vs 0/10 injected); and in
|
|
23
|
+
// agentic mode the only differential behavior was against β 2/5 small-model
|
|
24
|
+
// agents WITH the block gamed a failing test suite and reported success,
|
|
25
|
+
// 0/5 without it. An injection that buys no measured behavior and can induce
|
|
26
|
+
// fabricated compliance must not be the default.
|
|
27
|
+
//
|
|
28
|
+
// Scoping (when injection is enabled): set CRBRO_SUBAGENT_MATCHER to a regex
|
|
29
|
+
// and the protocols are injected only into subagents whose agent_type
|
|
30
|
+
// matches. Unanchored, case-insensitive. Invalid regex or missing agent_type
|
|
31
|
+
// fail OPEN (inject): scoping must never silently drop the layer.
|
|
20
32
|
//
|
|
21
33
|
// Failure contract: this hook never blocks a session. Any error β unreadable
|
|
22
34
|
// brain, bad JSON, stdin that never ends (the Windows PowerShell wrapper can
|
|
@@ -103,6 +115,13 @@ function inject() {
|
|
|
103
115
|
}
|
|
104
116
|
}
|
|
105
117
|
|
|
118
|
+
// Opt-in gate (1.12): without explicit consent, the hook is inert. Silence
|
|
119
|
+
// here is the measured default, not a failure β see the header.
|
|
120
|
+
const INJECT = String(process.env.CRBRO_SUBAGENT_INJECT || '').toLowerCase();
|
|
121
|
+
if (INJECT !== 'full' && INJECT !== '1' && INJECT !== 'on') {
|
|
122
|
+
process.exit(0);
|
|
123
|
+
}
|
|
124
|
+
|
|
106
125
|
// A bad regex must never crash the hook; treat it as "no matcher" and inject.
|
|
107
126
|
let matcherRe = null;
|
|
108
127
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "crbro-memory",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.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",
|