total-recall-brain 3.3.0 → 3.5.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 +1 -1
- package/bin/antigravity.mjs +19 -8
- package/extension/background.js +13 -1
- package/extension/content-script.js +18 -1
- package/extension/lib/brain-client.js +18 -5
- package/extension/options/options.js +9 -4
- package/frontend/index.html +8 -0
- package/frontend/src/api.ts +20 -1
- package/frontend/src/pages/ChatPage.tsx +9 -6
- package/frontend/src/pages/HealthPage.tsx +179 -7
- package/frontend/src/pages/IntegrationsPage.tsx +4 -2
- package/frontend/src/pages/SettingsPage.tsx +197 -2
- package/frontend/src/types.ts +16 -0
- package/package.json +2 -2
- package/scaffold/.agent/skills/total-recall/SKILL.md +55 -6
- package/scaffold/.agent/skills/total-recall/memory-vault/invariants/operating-instructions.md +2 -2
- package/scaffold/.agent/skills/total-recall/research-queue.jsonl +1 -0
- package/scaffold/.agent/skills/total-recall/skills/cli-agents/agents.yml +1 -6
- package/scaffold/.agent/skills/total-recall/skills/ssss/SKILL.md +19 -0
- package/scaffold/.agent/skills/total-recall/skills/ssss/references/ssss-spec.md +33 -5
- package/src/cli/forget.mjs +18 -12
- package/src/cli/ingest/index.mjs +3 -2
- package/src/cli/map.mjs +2 -2
- package/src/cli/rebuild.mjs +1 -1
- package/src/cli/remember.mjs +21 -11
- package/src/cli/share.mjs +7 -2
- package/src/core/append-log.mjs +131 -0
- package/src/core/clarity-rewriter.mjs +10 -6
- package/src/core/conclusion-writer.mjs +3 -2
- package/src/core/config.mjs +6 -0
- package/src/core/conflict-detector.mjs +4 -2
- package/src/core/context-compiler.mjs +412 -0
- package/src/core/daemon-loop.mjs +15 -0
- package/src/core/dream.mjs +4 -4
- package/src/core/drift-detector.mjs +3 -3
- package/src/core/embeddings.mjs +60 -10
- package/src/core/fact-seeker.mjs +70 -44
- package/src/core/import-rules.mjs +3 -2
- package/src/core/inference-engine.mjs +5 -4
- package/src/core/migrate.mjs +4 -3
- package/src/core/optimizer.mjs +6 -5
- package/src/core/parallel-context.mjs +288 -0
- package/src/core/post-mortem.mjs +4 -3
- package/src/core/research-queue.mjs +4 -3
- package/src/core/runtime.mjs +30 -7
- package/src/core/sandbox.mjs +56 -26
- package/src/core/scheduler.mjs +6 -5
- package/src/core/schema.mjs +483 -2
- package/src/core/search.mjs +167 -101
- package/src/core/surface.mjs +203 -53
- package/src/core/validated-write.mjs +100 -0
- package/src/core/vault-cache.mjs +46 -18
- package/src/core/vault.mjs +17 -29
- package/src/core/vector-field.mjs +659 -0
- package/src/core/vector-store.mjs +85 -0
- package/src/server/api.mjs +4 -3
- package/src/server/index.mjs +13 -61
- package/src/server/rest.mjs +341 -63
- package/src/server/route-manifest.json +352 -77
- package/src/server/routes/memory.mjs +85 -39
- package/src/server/routes/sessions.mjs +6 -2
- package/src/server/routes/share.mjs +9 -2
|
@@ -35,6 +35,7 @@ export default function SettingsPage() {
|
|
|
35
35
|
if (!data.budget.budget) data.budget.budget = { daily_cap_usd: 5.0, weekly_cap_usd: 25.0, enabled: true };
|
|
36
36
|
if (!data.brain) data.brain = {};
|
|
37
37
|
if (!data.brain.preferred_agent) data.brain.preferred_agent = 'auto';
|
|
38
|
+
if (!data.secrets) data.secrets = {};
|
|
38
39
|
|
|
39
40
|
setConfigData(data);
|
|
40
41
|
} catch (err: unknown) {
|
|
@@ -152,6 +153,17 @@ export default function SettingsPage() {
|
|
|
152
153
|
});
|
|
153
154
|
};
|
|
154
155
|
|
|
156
|
+
const updateSecretsProp = (prop: string, value: string) => {
|
|
157
|
+
if (!configData) return;
|
|
158
|
+
setConfigData({
|
|
159
|
+
...configData,
|
|
160
|
+
secrets: {
|
|
161
|
+
...configData.secrets,
|
|
162
|
+
[prop]: value
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
};
|
|
166
|
+
|
|
155
167
|
return (
|
|
156
168
|
<div className="page" style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
|
|
157
169
|
<div className="page-header" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 16 }}>
|
|
@@ -209,7 +221,7 @@ export default function SettingsPage() {
|
|
|
209
221
|
</div>
|
|
210
222
|
) : viewMode === 'visual' && configData ? (
|
|
211
223
|
/* ==================== VISUAL CONTROL PANEL UI ==================== */
|
|
212
|
-
<
|
|
224
|
+
<form onSubmit={(e) => { e.preventDefault(); handleSaveVisual(); }} style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(360px, 1fr))', gap: 24, flex: 1, minHeight: 0, overflowY: 'auto', paddingBottom: 24 }}>
|
|
213
225
|
|
|
214
226
|
{/* Card 1: AI Reasoning & Autonomy */}
|
|
215
227
|
<div className="card" style={{ padding: 24, display: 'flex', flexDirection: 'column', gap: 20, background: 'rgba(18, 18, 26, 0.6)', backdropFilter: 'blur(8px)', border: '1px solid var(--border)' }}>
|
|
@@ -537,7 +549,190 @@ export default function SettingsPage() {
|
|
|
537
549
|
</div>
|
|
538
550
|
</div>
|
|
539
551
|
|
|
540
|
-
|
|
552
|
+
{/* Card 5: API Keys & Integrations */}
|
|
553
|
+
<div className="card" style={{ padding: 24, display: 'flex', flexDirection: 'column', gap: 20, background: 'rgba(18, 18, 26, 0.6)', backdropFilter: 'blur(8px)', border: '1px solid var(--border)' }}>
|
|
554
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: 10, borderBottom: '1px solid var(--border)', paddingBottom: 12 }}>
|
|
555
|
+
<span style={{ fontSize: 20 }}>🔑</span>
|
|
556
|
+
<div>
|
|
557
|
+
<h3 style={{ fontSize: 15, fontWeight: 600 }}>API Keys & Integrations</h3>
|
|
558
|
+
<p style={{ fontSize: 11, color: 'var(--text-tertiary)' }}>Manage access keys and tokens for AI models and search providers</p>
|
|
559
|
+
</div>
|
|
560
|
+
</div>
|
|
561
|
+
|
|
562
|
+
{/* Google Gemini API Key */}
|
|
563
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
|
564
|
+
<label htmlFor="google_api_key" style={{ fontSize: 13, fontWeight: 500 }}>Google Gemini API Key</label>
|
|
565
|
+
<input
|
|
566
|
+
id="google_api_key"
|
|
567
|
+
type="password"
|
|
568
|
+
placeholder="AIzaSy..."
|
|
569
|
+
value={configData.secrets?.google_api_key || ''}
|
|
570
|
+
onChange={(e) => updateSecretsProp('google_api_key', e.target.value)}
|
|
571
|
+
style={{
|
|
572
|
+
background: 'var(--bg-tertiary)',
|
|
573
|
+
color: 'var(--text-primary)',
|
|
574
|
+
border: '1px solid var(--border)',
|
|
575
|
+
padding: '8px 12px',
|
|
576
|
+
borderRadius: 6,
|
|
577
|
+
outline: 'none',
|
|
578
|
+
fontSize: 13
|
|
579
|
+
}}
|
|
580
|
+
/>
|
|
581
|
+
</div>
|
|
582
|
+
|
|
583
|
+
{/* Anthropic API Key */}
|
|
584
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
|
585
|
+
<label htmlFor="anthropic_api_key" style={{ fontSize: 13, fontWeight: 500 }}>Anthropic API Key (Claude Code)</label>
|
|
586
|
+
<input
|
|
587
|
+
id="anthropic_api_key"
|
|
588
|
+
type="password"
|
|
589
|
+
placeholder="sk-ant-..."
|
|
590
|
+
value={configData.secrets?.anthropic_api_key || ''}
|
|
591
|
+
onChange={(e) => updateSecretsProp('anthropic_api_key', e.target.value)}
|
|
592
|
+
style={{
|
|
593
|
+
background: 'var(--bg-tertiary)',
|
|
594
|
+
color: 'var(--text-primary)',
|
|
595
|
+
border: '1px solid var(--border)',
|
|
596
|
+
padding: '8px 12px',
|
|
597
|
+
borderRadius: 6,
|
|
598
|
+
outline: 'none',
|
|
599
|
+
fontSize: 13
|
|
600
|
+
}}
|
|
601
|
+
/>
|
|
602
|
+
<span style={{ fontSize: 10, color: 'var(--text-tertiary)' }}>Configuring this allows Claude Code CLI to run without prompting for OAuth login.</span>
|
|
603
|
+
</div>
|
|
604
|
+
|
|
605
|
+
{/* OpenAI API Key */}
|
|
606
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
|
607
|
+
<label htmlFor="openai_api_key" style={{ fontSize: 13, fontWeight: 500 }}>OpenAI API Key (Codex)</label>
|
|
608
|
+
<input
|
|
609
|
+
id="openai_api_key"
|
|
610
|
+
type="password"
|
|
611
|
+
placeholder="sk-proj-..."
|
|
612
|
+
value={configData.secrets?.openai_api_key || ''}
|
|
613
|
+
onChange={(e) => updateSecretsProp('openai_api_key', e.target.value)}
|
|
614
|
+
style={{
|
|
615
|
+
background: 'var(--bg-tertiary)',
|
|
616
|
+
color: 'var(--text-primary)',
|
|
617
|
+
border: '1px solid var(--border)',
|
|
618
|
+
padding: '8px 12px',
|
|
619
|
+
borderRadius: 6,
|
|
620
|
+
outline: 'none',
|
|
621
|
+
fontSize: 13
|
|
622
|
+
}}
|
|
623
|
+
/>
|
|
624
|
+
</div>
|
|
625
|
+
|
|
626
|
+
{/* Tavily API Key */}
|
|
627
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
|
628
|
+
<label htmlFor="tavily_api_key" style={{ fontSize: 13, fontWeight: 500 }}>Tavily Search API Key</label>
|
|
629
|
+
<input
|
|
630
|
+
id="tavily_api_key"
|
|
631
|
+
type="password"
|
|
632
|
+
placeholder="tvly-..."
|
|
633
|
+
value={configData.secrets?.tavily_api_key || ''}
|
|
634
|
+
onChange={(e) => updateSecretsProp('tavily_api_key', e.target.value)}
|
|
635
|
+
style={{
|
|
636
|
+
background: 'var(--bg-tertiary)',
|
|
637
|
+
color: 'var(--text-primary)',
|
|
638
|
+
border: '1px solid var(--border)',
|
|
639
|
+
padding: '8px 12px',
|
|
640
|
+
borderRadius: 6,
|
|
641
|
+
outline: 'none',
|
|
642
|
+
fontSize: 13
|
|
643
|
+
}}
|
|
644
|
+
/>
|
|
645
|
+
</div>
|
|
646
|
+
|
|
647
|
+
{/* Other Search Keys (Brave, Exa, Serper) */}
|
|
648
|
+
<details style={{ fontSize: 13, color: 'var(--text-secondary)' }}>
|
|
649
|
+
<summary style={{ cursor: 'pointer', fontWeight: 500, outline: 'none', padding: '4px 0' }}>More Provider Keys (Brave, Exa, Serper, GitHub)</summary>
|
|
650
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 16, marginTop: 12, paddingLeft: 8, borderLeft: '2px solid var(--border)' }}>
|
|
651
|
+
{/* Brave Search Key */}
|
|
652
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
|
653
|
+
<label htmlFor="brave_api_key" style={{ fontSize: 12, fontWeight: 500 }}>Brave Search API Key</label>
|
|
654
|
+
<input
|
|
655
|
+
id="brave_api_key"
|
|
656
|
+
type="password"
|
|
657
|
+
value={configData.secrets?.brave_api_key || ''}
|
|
658
|
+
onChange={(e) => updateSecretsProp('brave_api_key', e.target.value)}
|
|
659
|
+
style={{
|
|
660
|
+
background: 'var(--bg-tertiary)',
|
|
661
|
+
color: 'var(--text-primary)',
|
|
662
|
+
border: '1px solid var(--border)',
|
|
663
|
+
padding: '8px 12px',
|
|
664
|
+
borderRadius: 6,
|
|
665
|
+
outline: 'none',
|
|
666
|
+
fontSize: 13
|
|
667
|
+
}}
|
|
668
|
+
/>
|
|
669
|
+
</div>
|
|
670
|
+
|
|
671
|
+
{/* Exa Search Key */}
|
|
672
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
|
673
|
+
<label htmlFor="exa_api_key" style={{ fontSize: 12, fontWeight: 500 }}>Exa API Key</label>
|
|
674
|
+
<input
|
|
675
|
+
id="exa_api_key"
|
|
676
|
+
type="password"
|
|
677
|
+
value={configData.secrets?.exa_api_key || ''}
|
|
678
|
+
onChange={(e) => updateSecretsProp('exa_api_key', e.target.value)}
|
|
679
|
+
style={{
|
|
680
|
+
background: 'var(--bg-tertiary)',
|
|
681
|
+
color: 'var(--text-primary)',
|
|
682
|
+
border: '1px solid var(--border)',
|
|
683
|
+
padding: '8px 12px',
|
|
684
|
+
borderRadius: 6,
|
|
685
|
+
outline: 'none',
|
|
686
|
+
fontSize: 13
|
|
687
|
+
}}
|
|
688
|
+
/>
|
|
689
|
+
</div>
|
|
690
|
+
|
|
691
|
+
{/* Serper API Key */}
|
|
692
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
|
693
|
+
<label htmlFor="serper_api_key" style={{ fontSize: 12, fontWeight: 500 }}>Serper (Google Search API) Key</label>
|
|
694
|
+
<input
|
|
695
|
+
id="serper_api_key"
|
|
696
|
+
type="password"
|
|
697
|
+
value={configData.secrets?.serper_api_key || ''}
|
|
698
|
+
onChange={(e) => updateSecretsProp('serper_api_key', e.target.value)}
|
|
699
|
+
style={{
|
|
700
|
+
background: 'var(--bg-tertiary)',
|
|
701
|
+
color: 'var(--text-primary)',
|
|
702
|
+
border: '1px solid var(--border)',
|
|
703
|
+
padding: '8px 12px',
|
|
704
|
+
borderRadius: 6,
|
|
705
|
+
outline: 'none',
|
|
706
|
+
fontSize: 13
|
|
707
|
+
}}
|
|
708
|
+
/>
|
|
709
|
+
</div>
|
|
710
|
+
|
|
711
|
+
{/* GitHub Token */}
|
|
712
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
|
713
|
+
<label htmlFor="github_token" style={{ fontSize: 12, fontWeight: 500 }}>GitHub Personal Access Token</label>
|
|
714
|
+
<input
|
|
715
|
+
id="github_token"
|
|
716
|
+
type="password"
|
|
717
|
+
placeholder="ghp_..."
|
|
718
|
+
value={configData.secrets?.github_token || ''}
|
|
719
|
+
onChange={(e) => updateSecretsProp('github_token', e.target.value)}
|
|
720
|
+
style={{
|
|
721
|
+
background: 'var(--bg-tertiary)',
|
|
722
|
+
color: 'var(--text-primary)',
|
|
723
|
+
border: '1px solid var(--border)',
|
|
724
|
+
padding: '8px 12px',
|
|
725
|
+
borderRadius: 6,
|
|
726
|
+
outline: 'none',
|
|
727
|
+
fontSize: 13
|
|
728
|
+
}}
|
|
729
|
+
/>
|
|
730
|
+
</div>
|
|
731
|
+
</div>
|
|
732
|
+
</details>
|
|
733
|
+
</div>
|
|
734
|
+
|
|
735
|
+
</form>
|
|
541
736
|
) : (
|
|
542
737
|
/* ==================== RAW YAML EDITOR UI ==================== */
|
|
543
738
|
<div style={{ display: 'flex', flexDirection: 'column', flex: 1, minHeight: 0 }}>
|
package/frontend/src/types.ts
CHANGED
|
@@ -159,5 +159,21 @@ export interface ConfigJson {
|
|
|
159
159
|
brain?: {
|
|
160
160
|
preferred_agent?: string
|
|
161
161
|
}
|
|
162
|
+
secrets?: {
|
|
163
|
+
google_api_key?: string
|
|
164
|
+
anthropic_api_key?: string
|
|
165
|
+
openai_api_key?: string
|
|
166
|
+
tavily_api_key?: string
|
|
167
|
+
brave_api_key?: string
|
|
168
|
+
exa_api_key?: string
|
|
169
|
+
serper_api_key?: string
|
|
170
|
+
github_token?: string
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export interface UpdateCheckResult {
|
|
175
|
+
currentVersion: string
|
|
176
|
+
latestVersion: string
|
|
177
|
+
updateAvailable: boolean
|
|
162
178
|
}
|
|
163
179
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "total-recall-brain",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"description": "Sovereign AI system — database-free, SSSS-powered personal intelligence engine deployable to any POSIX host.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"local-llm"
|
|
51
51
|
],
|
|
52
52
|
"author": "gregiteen",
|
|
53
|
-
"license": "
|
|
53
|
+
"license": "MIT",
|
|
54
54
|
"bugs": {
|
|
55
55
|
"url": "https://github.com/gregiteen/total-recall/issues"
|
|
56
56
|
},
|
|
@@ -26,9 +26,10 @@ You MUST actively reference and apply this skill under the following specific ru
|
|
|
26
26
|
|
|
27
27
|
### 3. When searching for complex domain knowledge or general facts
|
|
28
28
|
* **Trigger**: When you need to retrieve deep factual information (e.g. from the `facts/` category) or conceptual domain structures (e.g. from `concepts/`) that are not present in your active instruction files.
|
|
29
|
-
* **Action**: Use the
|
|
30
|
-
* **
|
|
31
|
-
* **
|
|
29
|
+
* **Action**: Use the semantic/lexical hybrid search engine (via the local `recall` command, or `/api/memory/search/semantic` endpoint) along with regular text search (e.g., grep):
|
|
30
|
+
* **Hybrid Search**: Blends cosine-similarity vector search and lexical density TF-IDF keyword matching using Reciprocal Rank Fusion (RRF). This blends intent-based semantic matching with exact keyword accuracy.
|
|
31
|
+
* **Hierarchical Parent-Child Search**: Memory node bodies are chunked and indexed as children. The vector store searches both the parent node and child chunks, returning matches based on maximum similarity.
|
|
32
|
+
* **Regular Text Search**: Use grep to locate exact configurations, literal keys, or symbols.
|
|
32
33
|
|
|
33
34
|
### 4. When a topic requires deep, structured domain learning and mastery
|
|
34
35
|
* **Trigger**: When you encounter a complex architectural topic, a deep conceptual system, or a technical domain where you need to acquire deep mastery to proceed effectively.
|
|
@@ -37,7 +38,7 @@ You MUST actively reference and apply this skill under the following specific ru
|
|
|
37
38
|
|
|
38
39
|
### 5. When you modify, add, or delete files in the memory vault
|
|
39
40
|
* **Trigger**: Immediately after performing any memory node writes.
|
|
40
|
-
* **Action**: Rebuild the instruction shims by sending a POST request to `/api/vault/compile`.
|
|
41
|
+
* **Action**: Rebuild the instruction shims. If using CLI commands (`npx total-recall remember` / `forget`), recompilation runs automatically in the background (asynchronously via detached subprocesses) to minimize latency. If editing vault files directly, trigger manual compilation by sending a POST request to `/api/vault/compile` or running `npx total-recall compile`.
|
|
41
42
|
|
|
42
43
|
### 6. When troubleshooting connections, port blocks, or sync errors
|
|
43
44
|
* **Trigger**: If the REST server is unreachable, ports are blocked, or the upstream sync tool encounters errors.
|
|
@@ -48,12 +49,12 @@ You MUST actively reference and apply this skill under the following specific ru
|
|
|
48
49
|
## ⚡ Core Directives for IDE Agents
|
|
49
50
|
|
|
50
51
|
### 1. Zero-Database Sovereign Integrity
|
|
51
|
-
Total Recall operates **entirely database-free**. The local filesystem is the source of truth. Every rule, pattern, decision, concept, preference, and fact exists as a plain Markdown file with semantic YAML frontmatter. Derived indexes are disposable caches. Do not look for PostgreSQL or
|
|
52
|
+
Total Recall operates **entirely database-free**. The local filesystem is the source of truth. Every rule, pattern, decision, concept, preference, and fact exists as a plain Markdown file with semantic YAML frontmatter. Derived indexes are disposable caches. While the internal Vector Store engine is pluggable and ready for native drop-in indexing engines (such as SQLite-VSS or HNSWLib), the canonical source of truth remains filesystem flat files. Do not look for PostgreSQL or traditional SQL databases.
|
|
52
53
|
|
|
53
54
|
### 2. Precise Tool & API Selection Heuristics
|
|
54
55
|
When interacting with the system, choose your interfaces based on the following:
|
|
55
56
|
* **Local Skills**: Use local skill packages (located in `.agent/skills/`) for complex workspace tasks, testing, and formatting. If a local skill has custom helper scripts, ALWAYS invoke them via your shell command tool instead of running raw standard commands.
|
|
56
|
-
* **Total Recall Brain (MANDATORY)**: For all semantic searches, memory retrieval, memory writes, and derived index recompilation, **
|
|
57
|
+
* **Total Recall Brain (MANDATORY)**: For all semantic searches, memory retrieval, memory writes, and derived index recompilation, **use either the local CLI suite (`npx total-recall`) or shell `curl` commands** targeting the REST API endpoints documented below.
|
|
57
58
|
|
|
58
59
|
### 3. Non-Destructive Code Modifications
|
|
59
60
|
When modifying existing rule surfaces or IDE shims (such as `.cursorrules`, `CLAUDE.md`, `GEMINI.md`, etc.), **NEVER** overwrite the developer's custom pre-existing rules. Instead, write compiled absolute invariants inside the managed comment block:
|
|
@@ -81,6 +82,54 @@ This spins up a secure local Express server (port 3000, increments dynamically i
|
|
|
81
82
|
|
|
82
83
|
---
|
|
83
84
|
|
|
85
|
+
## 🛠️ LOCAL CLI SUITE REFERENCE
|
|
86
|
+
|
|
87
|
+
For local workstation and terminal-based agent workflows, Total Recall provides a CLI command suite:
|
|
88
|
+
|
|
89
|
+
### 1. Save Memory Node
|
|
90
|
+
```bash
|
|
91
|
+
npx total-recall remember <category> "<content>" [options]
|
|
92
|
+
```
|
|
93
|
+
Save rules, preferences, corrections, and facts.
|
|
94
|
+
* **Categories**: `invariant`, `preference`, `correction`, `fact`, `concept`, `pattern`, `anti-pattern`, `decision`, `lore`.
|
|
95
|
+
* **Options**:
|
|
96
|
+
* `--global` / `--project`: Target scope. Global writes propagate to all registered projects.
|
|
97
|
+
* `--importance <1-5>`: Define relative importance.
|
|
98
|
+
* `--priority <level>`: Set priority level (`absolute`, `high`, `normal`, `low`).
|
|
99
|
+
* `--modality <type>`: Modality constraints (`must`, `must_not`, `should`, `should_not`, `descriptive`).
|
|
100
|
+
* `--slug <custom-slug>` / `--title "<custom-title>"`: Override automatic identifiers.
|
|
101
|
+
* `--expires <duration>`: Set expiration lifespan (e.g. `7d`, `2w`, `6h`, `3m`).
|
|
102
|
+
* *Note*: Spawns an asynchronous background surface compile process immediately on execution to avoid synchronous blockages.
|
|
103
|
+
|
|
104
|
+
### 2. Delete Memory Node
|
|
105
|
+
```bash
|
|
106
|
+
npx total-recall forget <slug> [options]
|
|
107
|
+
```
|
|
108
|
+
Delete a memory node by slug.
|
|
109
|
+
* **Options**:
|
|
110
|
+
* `--global` / `--project`: Scope layers. If omitted, checks project first, then global.
|
|
111
|
+
* `--no-compile`: Skip automatic background recompilation.
|
|
112
|
+
* *Note*: Spawns an asynchronous background surface compile process immediately on execution.
|
|
113
|
+
|
|
114
|
+
### 3. Recall / Hybrid Search
|
|
115
|
+
```bash
|
|
116
|
+
npx total-recall recall "<query>" [options]
|
|
117
|
+
```
|
|
118
|
+
Perform semantic/lexical hybrid search across rules, facts, and session history using Reciprocal Rank Fusion (RRF).
|
|
119
|
+
* **Options**:
|
|
120
|
+
* `--top-k, -k <number>`: Number of results (default: 5).
|
|
121
|
+
* `--category, -cat <name>`: Filter by SSSS category.
|
|
122
|
+
* `--tags, -t <list>`: Filter by tags.
|
|
123
|
+
* `--global` / `--project`: Search specific layer.
|
|
124
|
+
|
|
125
|
+
### 4. Build Memory Vault (Recompile)
|
|
126
|
+
```bash
|
|
127
|
+
npx total-recall compile
|
|
128
|
+
```
|
|
129
|
+
Synchronously rebuild the entire memory index (derived embeddings) and regenerate prompt instruction shims (such as `INSTRUCTIONS.md`, `GEMINI.md`, `AGENTS.md`, etc.).
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
84
133
|
## 🌐 DIRECT REST API REFERENCE
|
|
85
134
|
|
|
86
135
|
All requests to the Total Recall REST API must include the Bearer token in the `Authorization` header.
|
package/scaffold/.agent/skills/total-recall/memory-vault/invariants/operating-instructions.md
CHANGED
|
@@ -15,7 +15,7 @@ predicate: operate
|
|
|
15
15
|
object: memory_system
|
|
16
16
|
created: 2026-05-01T00:00:00.000Z
|
|
17
17
|
updated: 2026-05-15T00:00:00.000Z
|
|
18
|
-
last_accessed: 2026-
|
|
18
|
+
last_accessed: 2026-06-01T06:07:11.601Z
|
|
19
19
|
source:
|
|
20
20
|
type: scaffold
|
|
21
21
|
session_id: scaffold-seed
|
|
@@ -36,7 +36,7 @@ sentiment_polarity: directive_must
|
|
|
36
36
|
sentiment_target: memory_system
|
|
37
37
|
decay:
|
|
38
38
|
half_life_days: 365
|
|
39
|
-
access_count:
|
|
39
|
+
access_count: 3
|
|
40
40
|
x_temporal_context: 2026-05-26T23:05:06.525Z
|
|
41
41
|
---
|
|
42
42
|
# Total Recall Operating Protocol
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"id":"0efa65c2-0231-4267-a304-e0285e50011e","topic":"Total Recall repository improvement research: SSSS validated write pipeline, filesystem-native memory engines, local-first semantic indexing, Express 5 API hardening, 2026 agent memory architecture patterns","status":"pending","priority":"high","notes":"Queued from repo-wide analysis request on 2026-06-01. Focus on current best practices and meta-patterns for filesystem-native memory OS, validated operation envelopes, append-only logs, cache invalidation, research queue architecture, and secure local-first AI tools.","node_slug":null,"research_phase":"acquisition","created_at":"2026-06-01T06:07:40.102Z","updated_at":"2026-06-01T06:07:40.126Z","completed_at":null,"summary":{"id":"0efa65c2-0231-4267-a304-e0285e50011e","topic":"Total Recall repository improvement research: SSSS validated write pipeline, filesystem-native memory engines, local-first semantic indexing, Express 5 API hardening, 2026 agent memory architecture patterns","status":"pending","phase":"acquisition","last_updated":"2026-06-01T06:07:40.126Z","conclusions":[],"ongoing_directions":["Research project is enqueued / in progress in phase: acquisition"],"sources_count":0}}
|
|
@@ -5,12 +5,7 @@ agents:
|
|
|
5
5
|
priority: 1
|
|
6
6
|
enabled: true
|
|
7
7
|
exec: flag
|
|
8
|
-
|
|
9
|
-
binary: gemini
|
|
10
|
-
flags: --sandbox=false --yolo -o json
|
|
11
|
-
priority: 2
|
|
12
|
-
enabled: true
|
|
13
|
-
exec: flag
|
|
8
|
+
|
|
14
9
|
- name: claude
|
|
15
10
|
binary: claude
|
|
16
11
|
flags: --output-format json --permission-mode bypassPermissions
|
|
@@ -9,11 +9,23 @@ schema_version: 2
|
|
|
9
9
|
|
|
10
10
|
Structured Semantic Syntax System (ssss) is the core operational substrate of the Total Recall Virtual File System (VFS). This skill guides agents in inspecting, reading, and constructing SSSS-compliant memory nodes, conflict models, and derived indices.
|
|
11
11
|
|
|
12
|
+
## Spec Version
|
|
13
|
+
|
|
14
|
+
Current specification: **v0.2 — Draft** (see `references/ssss-spec.md`)
|
|
15
|
+
|
|
16
|
+
### v0.2 Changes (2026-05-30)
|
|
17
|
+
- Expanded `modality` enum: `must|must_not|should|should_not|descriptive|preference`
|
|
18
|
+
- Expanded `priority` enum: `absolute|high|normal|low` (OPTIONAL, defaults to `normal`)
|
|
19
|
+
- Added §10.1: Projection Manifest requirement with vault-hash staleness detection
|
|
20
|
+
- Added §11.3: Single canonical embedding implementation (no dual systems)
|
|
21
|
+
|
|
12
22
|
## Core Directives
|
|
13
23
|
|
|
14
24
|
1. **Schema Integrity:** Every SSSS node must strictly adhere to the frontmatter schema definitions (Modality, Category, Sentiment).
|
|
15
25
|
2. **Zero-Database Persistence:** Do not look for Postgres or SQLite. Everything lives as a git-versioned Markdown file.
|
|
16
26
|
3. **Decay and Drift Monitoring:** Use decay indicators to manage node half-lives dynamically in background ticks.
|
|
27
|
+
4. **Cached Reads:** All vault reads MUST go through `vault-cache.mjs` (`getNodes()`) — never call `loadNodes()` directly. The cache supports multi-directory (global + project) with per-directory `fs.watch` invalidation.
|
|
28
|
+
5. **Operation Contract:** All agent-generated mutations MUST flow through `processOperation()` (§6). Direct `writeNode()` calls bypass validation, idempotency, authorization, lease protection, and audit logging.
|
|
17
29
|
|
|
18
30
|
## Progressive Memory Disclosure
|
|
19
31
|
|
|
@@ -22,6 +34,13 @@ Memory flows through a 3-tier progressive hierarchy:
|
|
|
22
34
|
* **Tier 2 (Warm):** SKILL.md injects (Category-routed warm capsules).
|
|
23
35
|
* **Tier 3 (Cold):** Full memory vault (Search index files on demand).
|
|
24
36
|
|
|
37
|
+
## Performance Invariants
|
|
38
|
+
|
|
39
|
+
* `vault-cache.mjs` is the **single import point** for all node reads. The cache uses `fs.watch` auto-invalidation and supports multiple vault directories simultaneously.
|
|
40
|
+
* `walkMd()` uses `{ withFileTypes: true }` to eliminate per-file `stat()` syscalls.
|
|
41
|
+
* `deleteNode()` scans category directories directly — O(categories) not O(nodes).
|
|
42
|
+
* Surface recompilation (`triggerMutation()`) is debounced with a 2-second quiet period for batch writes.
|
|
43
|
+
|
|
25
44
|
## References
|
|
26
45
|
|
|
27
46
|
* Core SSSS specification: `references/ssss-spec.md`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SSSS — Structured Semantic Syntax System
|
|
2
2
|
|
|
3
|
-
**Specification v0.
|
|
3
|
+
**Specification v0.2 — Draft**
|
|
4
4
|
|
|
5
5
|
> This is the canonical, vendor-neutral specification for SSSS. It is the ground
|
|
6
6
|
> truth on which all SSSS implementations are built. It is intended to be vendored
|
|
@@ -198,8 +198,8 @@ The knowledge primitive. Categories: `invariants`, `patterns`, `anti-patterns`,
|
|
|
198
198
|
REQUIRED: `type`, `slug`, `category`, `title`, `status`, `schema_version`.
|
|
199
199
|
|
|
200
200
|
Knowledge-graph fields, REQUIRED when `schema_version: 2`: `confidence` (0..1),
|
|
201
|
-
`importance` (1..5), `modality` (`must|must_not|should|should_not`),
|
|
202
|
-
`predicate`, `object`, `sentiment_polarity`
|
|
201
|
+
`importance` (1..5), `modality` (`must|must_not|should|should_not|descriptive|preference`),
|
|
202
|
+
`subject`, `predicate`, `object`, `sentiment_polarity`
|
|
203
203
|
(`directive_must|directive_must_not|descriptive|preference`).
|
|
204
204
|
|
|
205
205
|
The `subject`/`predicate`/`object` triple SHOULD use stable, language-neutral
|
|
@@ -228,7 +228,8 @@ POSIX filesystems; direct writes risk partial-file corruption on crash.
|
|
|
228
228
|
```
|
|
229
229
|
|
|
230
230
|
Memory nodes in the `invariants` category additionally carry `priority: absolute`
|
|
231
|
-
and `immutable: true`.
|
|
231
|
+
and `immutable: true`. The full `priority` enum is `absolute|high|normal|low`;
|
|
232
|
+
`priority` is OPTIONAL on non-invariant categories (defaults to `normal`).
|
|
232
233
|
|
|
233
234
|
#### `skill`
|
|
234
235
|
|
|
@@ -673,6 +674,30 @@ A host that maintains projections MUST provide a means to (a) rebuild a projecti
|
|
|
673
674
|
from a vault scan, and (b) detect and repair drift between a projection and the
|
|
674
675
|
vault.
|
|
675
676
|
|
|
677
|
+
### 10.1 Projection Manifest
|
|
678
|
+
|
|
679
|
+
A host SHOULD maintain a `MANIFEST.json` (or equivalent) in the derived-artifacts
|
|
680
|
+
directory declaring each projection as disposable and recording provenance:
|
|
681
|
+
|
|
682
|
+
```jsonc
|
|
683
|
+
{
|
|
684
|
+
"type": "projection-manifest",
|
|
685
|
+
"generated_at": "2026-05-30T06:35:00Z",
|
|
686
|
+
"vault_hash": "sha256:abc123...", // content hash of the vault at build time
|
|
687
|
+
"projections": [
|
|
688
|
+
{ "file": "graph-index.jsonl", "disposable": true },
|
|
689
|
+
{ "file": "memory-layers.jsonl", "disposable": true },
|
|
690
|
+
{ "file": "embeddings.json", "disposable": true }
|
|
691
|
+
],
|
|
692
|
+
"rebuild_command": "npx total-recall compile"
|
|
693
|
+
}
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
The `vault_hash` field enables **staleness detection**: if the current vault hash
|
|
697
|
+
differs from the manifest's hash, the projections are stale and SHOULD be rebuilt.
|
|
698
|
+
This supports **incremental compilation** — a host MAY skip recompilation when the
|
|
699
|
+
hash matches, avoiding redundant I/O on unchanged vaults.
|
|
700
|
+
|
|
676
701
|
---
|
|
677
702
|
|
|
678
703
|
## 11. The Semantic Layer
|
|
@@ -713,6 +738,9 @@ disposable, never source-of-truth, fully rebuildable from the vault.
|
|
|
713
738
|
|
|
714
739
|
- It MUST record the `embedding_model` and vector `dim` that produced it. Embeddings
|
|
715
740
|
are not comparable across models; a model change REQUIRES a full reindex.
|
|
741
|
+
- A host MUST maintain exactly **one canonical embedding implementation**. Parallel
|
|
742
|
+
or duplicate embedding systems (e.g. one in JSON format and another in JSONL)
|
|
743
|
+
create consistency risks where a node is indexed in one but not the other.
|
|
716
744
|
- Retrieval SHOULD be **hybrid**: an exact/lexical pass (strong for slugs,
|
|
717
745
|
identifiers, and code) fused with a dense semantic pass (strong for meaning and
|
|
718
746
|
cross-lingual matches).
|
|
@@ -802,7 +830,7 @@ opaque ID as the slug and keep the human-readable label in `title` / `name`.
|
|
|
802
830
|
This document is versioned independently of any host and of the conformance
|
|
803
831
|
fixture set.
|
|
804
832
|
|
|
805
|
-
- The spec version is stated in the document header (currently **v0.
|
|
833
|
+
- The spec version is stated in the document header (currently **v0.2 — Draft**).
|
|
806
834
|
- Breaking changes to the file format, the type registry, or the Operation
|
|
807
835
|
Contract increment the spec version.
|
|
808
836
|
- Until **v1.0**, any version MAY introduce breaking changes.
|
package/src/cli/forget.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { resolveAgentDir, resolveBrainDir, parseLayerFlag, getBothBrains } from './agent-dir.mjs';
|
|
4
4
|
import { compileSurface } from '../core/surface.mjs';
|
|
5
|
-
import { deleteNode
|
|
5
|
+
import { deleteNode } from '../core/vault.mjs';
|
|
6
6
|
|
|
7
7
|
function printHelp() {
|
|
8
8
|
console.log(`
|
|
@@ -46,9 +46,15 @@ export default async function forget(args) {
|
|
|
46
46
|
// Check project first, then global
|
|
47
47
|
if (brains.project) {
|
|
48
48
|
const projVaultDir = path.join(brains.project.brainDir, 'memory-vault');
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
|
|
49
|
+
// Direct category scan instead of full vault load
|
|
50
|
+
if (fs.existsSync(projVaultDir)) {
|
|
51
|
+
const cats = fs.readdirSync(projVaultDir, { withFileTypes: true });
|
|
52
|
+
for (const cat of cats) {
|
|
53
|
+
if (cat.isDirectory() && fs.existsSync(path.join(projVaultDir, cat.name, `${slug}.md`))) {
|
|
54
|
+
layer = 'project';
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
52
58
|
}
|
|
53
59
|
}
|
|
54
60
|
if (layer === 'auto') {
|
|
@@ -76,17 +82,17 @@ export default async function forget(args) {
|
|
|
76
82
|
|
|
77
83
|
// Recompile unless --no-compile
|
|
78
84
|
if (!noCompile) {
|
|
79
|
-
console.log(' ⏳ Recompiling active memory surfaces and indexes...');
|
|
85
|
+
console.log(' ⏳ Recompiling active memory surfaces and indexes in the background...');
|
|
80
86
|
try {
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
instructionsFile
|
|
87
|
+
const { spawn } = await import('node:child_process');
|
|
88
|
+
const child = spawn(process.argv[0], [process.argv[1], 'compile'], {
|
|
89
|
+
detached: true,
|
|
90
|
+
stdio: 'ignore'
|
|
86
91
|
});
|
|
87
|
-
|
|
92
|
+
child.unref();
|
|
93
|
+
console.log(' ✅ Background compilation started.');
|
|
88
94
|
} catch (err) {
|
|
89
|
-
console.warn(` ⚠️ Node deleted, but
|
|
95
|
+
console.warn(` ⚠️ Node deleted, but background recompilation spawn failed: ${err.message}`);
|
|
90
96
|
}
|
|
91
97
|
}
|
|
92
98
|
}
|
package/src/cli/ingest/index.mjs
CHANGED
|
@@ -24,7 +24,8 @@ import { parseSearchHistory } from './parsers/search-history.mjs';
|
|
|
24
24
|
import { parseChromeBookmarks } from './parsers/chrome-bookmarks.mjs';
|
|
25
25
|
import { parseGoogleKeep } from './parsers/google-keep.mjs';
|
|
26
26
|
import { parseYoutubeHistory } from './parsers/youtube-history.mjs';
|
|
27
|
-
import { writeNode
|
|
27
|
+
import { writeNode } from '../../core/vault.mjs';
|
|
28
|
+
import { getNodes } from '../../core/vault-cache.mjs';
|
|
28
29
|
import { resolveBrainDir, parseLayerFlag, getBothBrains, defaultLayerForCategory } from '../../cli/agent-dir.mjs';
|
|
29
30
|
|
|
30
31
|
/**
|
|
@@ -204,7 +205,7 @@ export async function ingestGoogleTakeout(takeoutPath, options = {}) {
|
|
|
204
205
|
// Load existing vault nodes for dedup
|
|
205
206
|
let existingNodes = [];
|
|
206
207
|
if (fs.existsSync(vaultDir)) {
|
|
207
|
-
existingNodes =
|
|
208
|
+
existingNodes = getNodes(vaultDir);
|
|
208
209
|
}
|
|
209
210
|
|
|
210
211
|
// Run parsers for each detected type
|
package/src/cli/map.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { resolveBrainDir, parseLayerFlag, getBothBrains } from './agent-dir.mjs';
|
|
4
|
-
import {
|
|
4
|
+
import { getNodes } from '../core/vault-cache.mjs';
|
|
5
5
|
|
|
6
6
|
function printHelp() {
|
|
7
7
|
console.log(`
|
|
@@ -68,7 +68,7 @@ export default async function map(args) {
|
|
|
68
68
|
const vaultDir = path.join(l.path, 'memory-vault');
|
|
69
69
|
if (!fs.existsSync(vaultDir)) continue;
|
|
70
70
|
|
|
71
|
-
const nodes =
|
|
71
|
+
const nodes = getNodes(vaultDir).map(n => ({ ...n, _layer: l.name }));
|
|
72
72
|
loadedLayers.push({ name: l.name, nodes });
|
|
73
73
|
totalNodesCount += nodes.length;
|
|
74
74
|
}
|
package/src/cli/rebuild.mjs
CHANGED
|
@@ -59,7 +59,7 @@ export async function runRebuild(options = {}) {
|
|
|
59
59
|
|
|
60
60
|
console.log('🏗️ Recompiling surface from canonical vault...');
|
|
61
61
|
try {
|
|
62
|
-
const stats = await compileSurface({ vaultDir, skillsDir, derivedDir, instructionsFile });
|
|
62
|
+
const stats = await compileSurface({ vaultDir, skillsDir, derivedDir, instructionsFile, force: true });
|
|
63
63
|
console.log(`✅ Processed ${stats.nodesProcessed} canonical memory nodes.`);
|
|
64
64
|
console.log(`✅ Injected memory into ${stats.skillsInjected} skill files.`);
|
|
65
65
|
console.log(`✅ Rebuilt graph-index.jsonl, memory-layers.jsonl, and skill-routes.jsonl.`);
|