total-recall-brain 3.1.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/LICENSE +21 -0
- package/README.md +173 -0
- package/bin/antigravity.mjs +212 -0
- package/bin/init.mjs +36 -0
- package/bin/oci-sniper.sh +69 -0
- package/bin/total-recall.mjs +229 -0
- package/docs/ARCHITECTURE.md +251 -0
- package/docs/IDE_INTEGRATION.md +112 -0
- package/package.json +71 -0
- package/scaffold/.agent/skills/total-recall/SKILL.md +195 -0
- package/scaffold/.agent/skills/total-recall/evals/evals.json +20 -0
- package/scaffold/.agent/skills/total-recall/memory-vault/concepts/cli-help-reference.md +145 -0
- package/scaffold/.agent/skills/total-recall/memory-vault/invariants/operating-instructions.md +75 -0
- package/scaffold/.agent/skills/total-recall/memory-vault/preferences/always-websearch-gap.md +16 -0
- package/scaffold/.agent/skills/total-recall/memory-vault/preferences/topic-research-sop.md +17 -0
- package/scaffold/.agent/skills/total-recall/references/api-reference.md +187 -0
- package/scaffold/.agent/skills/total-recall/references/architecture-reference.md +81 -0
- package/scaffold/.agent/skills/total-recall/references/cli-reference.md +103 -0
- package/scaffold/.agent/skills/total-recall/references/ssss-reference.md +88 -0
- package/scaffold/.agent/skills/total-recall/references/troubleshooting.md +68 -0
- package/scaffold/.agent/skills/total-recall/scripts/sync-repo.mjs +83 -0
- package/scaffold/.agent/skills/total-recall/skills/cli-agents/SKILL.md +122 -0
- package/scaffold/.agent/skills/total-recall/skills/cli-agents/agents.yml +27 -0
- package/scaffold/.agent/skills/total-recall/skills/cli-agents/references/antigravity.txt +20 -0
- package/scaffold/.agent/skills/total-recall/skills/cli-agents/references/claude.txt +58 -0
- package/scaffold/.agent/skills/total-recall/skills/cli-agents/references/codex.txt +81 -0
- package/scaffold/.agent/skills/total-recall/skills/cli-agents/references/gemini.txt +44 -0
- package/scaffold/.agent/skills/total-recall/skills/research/SKILL.md +337 -0
- package/scaffold/.agent/skills/total-recall/skills/skill/SKILL.md +281 -0
- package/scaffold/.agent/skills/total-recall/skills/skill/assets/skill-template/SKILL.md +20 -0
- package/scaffold/.agent/skills/total-recall/skills/skill/evals/evals.json +20 -0
- package/scaffold/.agent/skills/total-recall/skills/skill/hooks/on-skill-add.sh +14 -0
- package/scaffold/.agent/skills/total-recall/skills/skill/hooks/on-skill-delete.sh +14 -0
- package/scaffold/.agent/skills/total-recall/skills/skill/learnings/.gitkeep +0 -0
- package/scaffold/.agent/skills/total-recall/skills/skill/references/.gitkeep +0 -0
- package/scaffold/.agent/skills/total-recall/skills/skill/scripts/.gitkeep +0 -0
- package/scaffold/.agent/skills/total-recall/skills/skill/scripts/create-skill.sh +65 -0
- package/scaffold/.agent/skills/total-recall/skills/skill/scripts/enforce-skill-optimization.mjs +135 -0
- package/scaffold/.agent/skills/total-recall/skills/skill/scripts/find-skills.mjs +124 -0
- package/scaffold/.agent/skills/total-recall/skills/skill/scripts/scan-skill.mjs +207 -0
- package/scaffold/.agent/skills/total-recall/skills/skill/scripts/skill-watcher.mjs +64 -0
- package/scaffold/.agent/skills/total-recall/skills/skill/subagents/audit-all-skills.md +62 -0
- package/scaffold/.agent/skills/total-recall/skills/ssss/SKILL.md +27 -0
- package/scaffold/.agent/skills/total-recall/skills/ssss/evals/evals.json +17 -0
- package/scaffold/.agent/skills/total-recall/skills/ssss/references/ssss-spec.md +117 -0
- package/scaffold/.agent/skills/total-recall/skills/ssss/scripts/validate-schema.mjs +54 -0
- package/scaffold/.agent/skills/total-recall/skills/ssss/subagents/audit-ssss-node.md +9 -0
- package/scaffold/.agent/skills/total-recall/subagents/total-recall-diagnostician.md +13 -0
- package/src/cli/agent-dir.mjs +105 -0
- package/src/cli/backup.mjs +313 -0
- package/src/cli/brain.mjs +224 -0
- package/src/cli/chat.mjs +74 -0
- package/src/cli/config.mjs +247 -0
- package/src/cli/connect.mjs +872 -0
- package/src/cli/daemon.mjs +228 -0
- package/src/cli/deploy-ui.mjs +1793 -0
- package/src/cli/deploy.mjs +1726 -0
- package/src/cli/doctor.mjs +254 -0
- package/src/cli/dream.mjs +80 -0
- package/src/cli/forget.mjs +92 -0
- package/src/cli/friction.mjs +21 -0
- package/src/cli/generate-pat.mjs +65 -0
- package/src/cli/hash-password.mjs +22 -0
- package/src/cli/help.mjs +153 -0
- package/src/cli/import-rules.mjs +102 -0
- package/src/cli/ingest/index.mjs +318 -0
- package/src/cli/ingest/parsers/chrome-bookmarks.mjs +238 -0
- package/src/cli/ingest/parsers/google-keep.mjs +147 -0
- package/src/cli/ingest/parsers/search-history.mjs +142 -0
- package/src/cli/ingest/parsers/youtube-history.mjs +181 -0
- package/src/cli/ingest/utils/dedup.mjs +69 -0
- package/src/cli/ingest/utils/takeout-walker.mjs +101 -0
- package/src/cli/ingest.mjs +102 -0
- package/src/cli/init.mjs +736 -0
- package/src/cli/integration-dispatcher.mjs +128 -0
- package/src/cli/lint.mjs +166 -0
- package/src/cli/map.mjs +194 -0
- package/src/cli/migrate.mjs +87 -0
- package/src/cli/rebuild.mjs +88 -0
- package/src/cli/recall.mjs +219 -0
- package/src/cli/relay.mjs +518 -0
- package/src/cli/remember.mjs +306 -0
- package/src/cli/research.mjs +381 -0
- package/src/cli/reset-password.mjs +75 -0
- package/src/cli/restore.mjs +135 -0
- package/src/cli/setup.mjs +616 -0
- package/src/cli/share.mjs +180 -0
- package/src/cli/skill.mjs +313 -0
- package/src/cli/snapshot.mjs +108 -0
- package/src/cli/start.mjs +63 -0
- package/src/cli/status.mjs +296 -0
- package/src/cli/sync.mjs +383 -0
- package/src/cli/uninstall.mjs +613 -0
- package/src/cli/upgrade.mjs +141 -0
- package/src/cli/wizard.html +3682 -0
- package/src/core/blackboard.mjs +54 -0
- package/src/core/clarity-rewriter.mjs +770 -0
- package/src/core/conclusion-writer.mjs +259 -0
- package/src/core/config.mjs +277 -0
- package/src/core/conflict-detector.mjs +536 -0
- package/src/core/crypto.mjs +107 -0
- package/src/core/daemon-control.mjs +158 -0
- package/src/core/daemon-loop.mjs +364 -0
- package/src/core/dream.mjs +347 -0
- package/src/core/drift-detector.mjs +143 -0
- package/src/core/embeddings.mjs +632 -0
- package/src/core/emergency-alerts.mjs +137 -0
- package/src/core/evolution.mjs +107 -0
- package/src/core/fact-seeker.mjs +1602 -0
- package/src/core/friction.mjs +95 -0
- package/src/core/import-rules.mjs +308 -0
- package/src/core/inference-engine.mjs +367 -0
- package/src/core/logger.mjs +75 -0
- package/src/core/memory-layers.mjs +96 -0
- package/src/core/migrate.mjs +116 -0
- package/src/core/notifications.mjs +77 -0
- package/src/core/operation-validator.mjs +272 -0
- package/src/core/optimizer.mjs +330 -0
- package/src/core/pattern_detector.mjs +113 -0
- package/src/core/post-mortem.mjs +413 -0
- package/src/core/protect-instructions.mjs +148 -0
- package/src/core/quick-capture.mjs +145 -0
- package/src/core/research-queue.mjs +431 -0
- package/src/core/research.mjs +461 -0
- package/src/core/runtime.mjs +515 -0
- package/src/core/sandbox.mjs +163 -0
- package/src/core/scheduler.mjs +569 -0
- package/src/core/schema.mjs +333 -0
- package/src/core/search.mjs +219 -0
- package/src/core/semantic-index.mjs +276 -0
- package/src/core/session-watcher.mjs +850 -0
- package/src/core/snapshot.mjs +133 -0
- package/src/core/source-adapters.mjs +1038 -0
- package/src/core/steering.mjs +137 -0
- package/src/core/surface.mjs +444 -0
- package/src/core/task_runner.mjs +125 -0
- package/src/core/tts.mjs +142 -0
- package/src/core/usage-tracker.mjs +349 -0
- package/src/core/vault-cache.mjs +76 -0
- package/src/core/vault.mjs +273 -0
- package/src/core/watchdog.mjs +236 -0
- package/src/server/api.mjs +944 -0
- package/src/server/auth.mjs +410 -0
- package/src/server/index.mjs +868 -0
- package/src/server/keys.mjs +181 -0
- package/src/server/rest.mjs +1652 -0
- package/src/server/route-manifest.json +77 -0
- package/src/server/routes/_shared.mjs +93 -0
- package/src/server/routes/keys.mjs +55 -0
- package/src/server/routes/memory.mjs +249 -0
- package/src/server/routes/sessions.mjs +336 -0
- package/src/server/routes/share.mjs +138 -0
- package/src/server/tools.mjs +618 -0
- package/templates/Caddyfile +37 -0
- package/templates/com.totalrecall.backup.plist +42 -0
- package/templates/com.totalrecall.daemon.plist +40 -0
- package/templates/com.totalrecall.duckdns.plist +23 -0
- package/templates/com.totalrecall.server.plist +46 -0
- package/templates/default-config/budget.yml +6 -0
- package/templates/default-config/runtime.yml +11 -0
- package/templates/default-config/security.yml +53 -0
- package/templates/default-config/voice.yml +34 -0
- package/templates/obsidian-queries/conflicts.md +26 -0
- package/templates/obsidian-queries/daily.md +17 -0
- package/templates/obsidian-queries/index.md +38 -0
- package/templates/obsidian-queries/skills.md +14 -0
- package/templates/onboarding-interview.md +72 -0
- package/templates/skill_engineering.md +40 -0
- package/templates/total-recall-daemon.service +21 -0
- package/templates/total-recall-server.service +20 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 UltraChat
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Total Recall ā SSSS Sovereign AI OS
|
|
2
|
+
|
|
3
|
+
[](package.json)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](.github/workflows/test.yml)
|
|
6
|
+
|
|
7
|
+
> **A database-free, filesystem-native AI memory layer.** Works in any IDE. Self-hosts on any VM. Costs nothing to store.
|
|
8
|
+
|
|
9
|
+
Total Recall is the open-source reference implementation of the **SSSS (Structured Semantic Syntax System)** ā a specification for storing AI memory, skills, and workflows as plain Markdown files instead of opaque, hosted databases.
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
your AI brain = ~/.agent/skills/total-recall/memory-vault/*.md
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
No database overhead. No vendor lock-in. Your thoughts, on your machine.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## š Choose Your Setup
|
|
20
|
+
|
|
21
|
+
### š„ļø 1. IDE Memory Only (2 minutes)
|
|
22
|
+
|
|
23
|
+
Add persistent, highly contextual memory to **Claude Code**, **Cursor**, **Codex CLI**, or any IDE agent in your active workspace:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
cd ~/my-project
|
|
27
|
+
npx total-recall init # provision global brain and local project VFS shims
|
|
28
|
+
npx total-recall connect claude-code # symlink CLAUDE.md ā INSTRUCTIONS.md
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Supported IDEs and surfaces:
|
|
32
|
+
|
|
33
|
+
| Client Command | Connection Mode | Targeted Projection Target |
|
|
34
|
+
| :--- | :--- | :--- |
|
|
35
|
+
| `npx total-recall connect claude-code` | Symlink | Symlinks `CLAUDE.md` to the compiled instruction surface |
|
|
36
|
+
| `npx total-recall connect codex` | Symlink | Symlinks `AGENTS.md` to the compiled instruction surface |
|
|
37
|
+
| `npx total-recall connect antigravity` | Symlink | Symlinks `AGENTS.md` to the compiled instruction surface |
|
|
38
|
+
| `npx total-recall connect gemini` | Symlink | Symlinks `GEMINI.md` to the compiled instruction surface |
|
|
39
|
+
| `npx total-recall connect cursor` | File Projection | Writes/updates `.cursor/rules/total-recall.mdc` with frontmatter rules |
|
|
40
|
+
| `npx total-recall connect aider` | File Projection | Writes/updates `.aider.rules.md` file rules |
|
|
41
|
+
|
|
42
|
+
> [!NOTE]
|
|
43
|
+
> **Non-Destructive Integration:**
|
|
44
|
+
> Your existing custom rules are **never overwritten**. Total Recall operates exclusively inside the clearly-marked comment bounds:
|
|
45
|
+
> `<!-- BEGIN INJECTED MEMORY: do not edit by hand; rebuilt by total-recall surface -->`
|
|
46
|
+
> `...`
|
|
47
|
+
> `<!-- END INJECTED MEMORY -->`
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
### š§ 2. Full Sovereign Brain VM (10 minutes)
|
|
52
|
+
|
|
53
|
+
Deploy the full autonomous stack ā a secure OpenAI-compatible REST server, dynamic React dashboard, continuous Dream Cycle daemon, and local session relays ā on your own VM.
|
|
54
|
+
|
|
55
|
+
**Prerequisites:**
|
|
56
|
+
- A standard Linux or macOS server/workstation.
|
|
57
|
+
- Node.js ā„ 20.
|
|
58
|
+
- A primary API Key (e.g. `GOOGLE_API_KEY` for high-speed Google `gemini-embedding-2` vectors, featuring OpenAI fallback).
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Start the interactive configuration wizard:
|
|
62
|
+
npx total-recall init
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The interactive wizard provisions the configuration, registers authorized Personal Access Tokens (PATs), configures secure Caddy reverse-proxying, and prompts you to choose your **Selectable UI Deployment Location**:
|
|
66
|
+
|
|
67
|
+
| Mode | Target URL | Primary Target |
|
|
68
|
+
| :--- | :--- | :--- |
|
|
69
|
+
| **Local Bind** | `http://127.0.0.1:3000` | Local operations. Binds strictly to your loopback interface. |
|
|
70
|
+
| **Quick Tunnel** | `https://*.trycloudflare.com` | Spawns a background Cloudflare tunnel for zero-configuration public URL access. |
|
|
71
|
+
| **Named Tunnel** | `https://your-tunnel.domain.com` | Hooks up securely to a pre-registered Cloudflare tunnel daemon. |
|
|
72
|
+
| **Custom Domain** | `https://your-domain.com` | Hooks up to your public DNS, reverse-proxied and secured by Caddy TLS. |
|
|
73
|
+
|
|
74
|
+
To start the server daemon, run:
|
|
75
|
+
```bash
|
|
76
|
+
npm start
|
|
77
|
+
```
|
|
78
|
+
*Vite automatically installs and builds the beautiful Glassmorphic React SPA on first boot, serving the dashboard dynamically.*
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
### š 3. Obsidian Integration
|
|
83
|
+
|
|
84
|
+
Visualize your entire memory vault, rules network, and daily logs directly inside Obsidian with native backlinks and graphs:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npx total-recall connect obsidian
|
|
88
|
+
```
|
|
89
|
+
*Auto-detects your vault path on macOS (or pass `--vault ~/path/to/vault` on Linux/other), symlinking your memory vault and installing interactive Dataview dashboard trackers.*
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
### š¬ 4. UltraChat Integration
|
|
94
|
+
|
|
95
|
+
UltraChat integrates securely with your brain via our OpenAI-compatible chat API, injecting active memory instructions into system prompts on the fly:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
npx total-recall connect ultrachat --brain https://your-server.com --token YOUR_PAT
|
|
99
|
+
```
|
|
100
|
+
*Generates the OpenAI-compatible configuration parameters (baseURL, model, token auth header).*
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## š§ Dual-Layer Brain Architecture
|
|
105
|
+
|
|
106
|
+
Total Recall partitions your sovereign brain memory into two virtual layers:
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
110
|
+
ā GLOBAL LAYER ā
|
|
111
|
+
ā ~/.agent/skills/tr/ ā
|
|
112
|
+
āāāāāāāāāāāāā¬āāāāāāāāāāāāā
|
|
113
|
+
ā
|
|
114
|
+
ā¼ Overridden by
|
|
115
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
116
|
+
ā PROJECT LAYER ā
|
|
117
|
+
ā <repo>/.agent/skills/ ā
|
|
118
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
1. **Global Layer** (`~/.agent/skills/total-recall/`): Contains global user preferences, master API keys, global logs, and the baseline identity context (`SOUL.md`, `USER.md`).
|
|
122
|
+
2. **Project Layer** (`<repo>/.agent/skills/total-recall/`): Contains local repository facts, project-specific habits, and specialized research agendas.
|
|
123
|
+
|
|
124
|
+
*When compiling rules or searching, project-level nodes take precedence and override global nodes on slug collisions. CLI operations like `remember`, `recall`, `research`, `backup`, and `restore` accept `--global` and `--project` flags to steer memories to the right layer.*
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## ā” CLI Command Reference
|
|
129
|
+
|
|
130
|
+
| Command | Description |
|
|
131
|
+
| :--- | :--- |
|
|
132
|
+
| `npx total-recall init` | Initialize the global or local project VFS memory schemas. |
|
|
133
|
+
| `npx total-recall connect <client>` | Wire a local IDE, Obsidian vault, or UltraChat client to your brain. |
|
|
134
|
+
| `npx total-recall deploy` | Configure startup services, Caddy proxy servers, and platform auto-starts. |
|
|
135
|
+
| `npx total-recall compile` | Rebuild `INSTRUCTIONS.md` from merged global & project memory nodes. |
|
|
136
|
+
| `npx total-recall dream` | Trigger a manual Dream Cycle (GC, pattern extraction, decay consolidation). |
|
|
137
|
+
| `npx total-recall lint` | Validate vault nodes against the SSSS v2 frontmatter Zod schema. |
|
|
138
|
+
| `npx total-recall backup` | Create password-encrypted tarballs, push git backups, or sync Obsidian. |
|
|
139
|
+
| `npx total-recall restore <file>` | Restore your sovereign VFS from an encrypted tarball backup. |
|
|
140
|
+
| `npx total-recall status` | Show brain health summary, connected client registries, and daemon status. |
|
|
141
|
+
| `npx total-recall generate-pat` | Provision granular, label-based Personal Access Tokens (PATs) for auth. |
|
|
142
|
+
| `npx total-recall daemon` | Manage the background Dream Cycle daemon (start / stop / status). |
|
|
143
|
+
| `npx total-recall relay` | Manage background local session-sync relays watching IDE log files. |
|
|
144
|
+
| `npx total-recall config` | Read or update system settings, Allowed Origins, or USD budget caps dynamically. |
|
|
145
|
+
| `npx total-recall skill` | Search, install, security-audit, and remove packages from the skills.sh registry. |
|
|
146
|
+
| `npx total-recall uninstall` | Completely stop background services and wipe Total Recall from the system. |
|
|
147
|
+
| `npx total-recall friction` | Inspect watchdog telemetry logs to identify workflow latency bottlenecks. |
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## š Security, Sandboxing, & Safety
|
|
152
|
+
|
|
153
|
+
- **甬 Hardened VM Sandbox:** All subagent script executions run inside an isolated vm sandbox environment (`sandbox.mjs`) featuring POSIX namespace restrictions, strict memory/CPU bounds, and a command execution whitelist. The sandbox is **disabled by default** (`security.yml.sandbox.enabled: false`) for maximum security.
|
|
154
|
+
- **Cost Watchdog & Limits:** Daily and weekly maximum cost thresholds (`config/budget.yml`) are enforced dynamically via a cost supervisor in `runtime.mjs` that instantly suspends subagent dispatches if budget caps are exceeded.
|
|
155
|
+
- **OWASP-aligned scrypt Security:** Master credentials and API keys are AES-256-GCM encrypted under `secrets.enc` with OWASP-aligned scrypt key derivation.
|
|
156
|
+
- **Privacy Redactions:** Memory nodes marked with `privacy: local_only` are automatically stripped before any external API dispatches or reasoning agent calls.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## š§¹ Service Uninstallation
|
|
161
|
+
|
|
162
|
+
To cleanly stop background daemons, unload platform agents (macOS launchd plists / Linux systemd services), remove symlink shims from all workspaces, and purge global configs:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
npx total-recall uninstall
|
|
166
|
+
```
|
|
167
|
+
> [!IMPORTANT]
|
|
168
|
+
> **Safety First:**
|
|
169
|
+
> The uninstaller automatically detects version-controlled files, **preserving** local workspace `.agent/skills/` and `.agent/memory-vault/` directories inside active git project repositories to ensure you never lose custom rules and memories.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
*Sovereign. Database-free. Yours.*
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import os from 'node:os';
|
|
6
|
+
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
let prompt = '';
|
|
9
|
+
let outputJson = false;
|
|
10
|
+
let requestedModel = process.env.TR_CLI_MODEL || 'default';
|
|
11
|
+
|
|
12
|
+
if (args.includes('-h') || args.includes('--help')) {
|
|
13
|
+
console.log(`
|
|
14
|
+
Antigravity CLI Agent Wrapper ā Headless Zero-Dependency Cognitive Agent
|
|
15
|
+
|
|
16
|
+
Usage:
|
|
17
|
+
antigravity [options] [prompt]
|
|
18
|
+
antigravity -p "prompt"
|
|
19
|
+
|
|
20
|
+
Options:
|
|
21
|
+
-p, --prompt The text prompt to generate content for
|
|
22
|
+
-m, --model Gemini API model identifier or alias (default: default / gemini-3.5-flash)
|
|
23
|
+
Supported aliases:
|
|
24
|
+
- default / gemini / flash / gemini-flash -> dynamically resolves best Flash model
|
|
25
|
+
- pro / gemini-pro / 3.1-pro -> dynamically resolves best Pro model
|
|
26
|
+
-o, --json Output dynamic JSON response payload (choices: stream/json/default)
|
|
27
|
+
--json Output dynamic JSON response payload
|
|
28
|
+
-h, --help Show this help information
|
|
29
|
+
|
|
30
|
+
Examples:
|
|
31
|
+
antigravity "Say hello"
|
|
32
|
+
antigravity -p "Write an essay about AI" -m pro
|
|
33
|
+
antigravity -p "Get system stats" --json
|
|
34
|
+
`);
|
|
35
|
+
process.exit(0);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
for (let i = 0; i < args.length; i++) {
|
|
39
|
+
if (args[i] === '-p' || args[i] === '--prompt') {
|
|
40
|
+
prompt = args[i + 1] || '';
|
|
41
|
+
i++;
|
|
42
|
+
} else if (args[i] === '-o' && args[i + 1] === 'json') {
|
|
43
|
+
outputJson = true;
|
|
44
|
+
i++;
|
|
45
|
+
} else if (args[i] === '--json') {
|
|
46
|
+
outputJson = true;
|
|
47
|
+
} else if (args[i] === '-m' || args[i] === '--model') {
|
|
48
|
+
requestedModel = args[i + 1] || requestedModel;
|
|
49
|
+
i++;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!prompt && args.length > 0) {
|
|
54
|
+
prompt = args[args.length - 1];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!prompt) {
|
|
58
|
+
console.error('Error: No prompt provided. Use -p "prompt"');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Robust fallback to load GOOGLE_API_KEY from .env files when executed standalone
|
|
63
|
+
if (!process.env.GOOGLE_API_KEY) {
|
|
64
|
+
try {
|
|
65
|
+
let dir = process.cwd();
|
|
66
|
+
while (dir !== path.dirname(dir)) {
|
|
67
|
+
const envPath = path.join(dir, '.env');
|
|
68
|
+
if (fs.existsSync(envPath)) {
|
|
69
|
+
const content = fs.readFileSync(envPath, 'utf8');
|
|
70
|
+
for (const line of content.split('\n')) {
|
|
71
|
+
const match = line.match(/^\s*GOOGLE_API_KEY\s*=\s*(["']?)(.*?)\1\s*$/);
|
|
72
|
+
if (match) {
|
|
73
|
+
process.env.GOOGLE_API_KEY = match[2];
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (process.env.GOOGLE_API_KEY) break;
|
|
79
|
+
dir = path.dirname(dir);
|
|
80
|
+
}
|
|
81
|
+
} catch {
|
|
82
|
+
// Silent ignore
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const apiKey = process.env.GOOGLE_API_KEY;
|
|
87
|
+
if (!apiKey) {
|
|
88
|
+
console.error('Error: GOOGLE_API_KEY environment variable is not configured.');
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Resolve the model dynamically from the API registry based on the category/alias selected
|
|
93
|
+
async function resolveGenerativeModel(selectedModel) {
|
|
94
|
+
const aliases = {
|
|
95
|
+
gemini: 'flash',
|
|
96
|
+
default: 'flash',
|
|
97
|
+
flash: 'flash',
|
|
98
|
+
'gemini-flash': 'flash',
|
|
99
|
+
'3.5-flash': 'flash',
|
|
100
|
+
pro: 'pro',
|
|
101
|
+
'gemini-pro': 'pro',
|
|
102
|
+
'3.1-pro': 'pro'
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const category = aliases[selectedModel];
|
|
106
|
+
if (!category) {
|
|
107
|
+
// If it's a full model string, use it directly
|
|
108
|
+
return selectedModel;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey}`, {
|
|
113
|
+
signal: AbortSignal.timeout(5000)
|
|
114
|
+
});
|
|
115
|
+
if (res.ok) {
|
|
116
|
+
const data = await res.json();
|
|
117
|
+
const models = data.models || [];
|
|
118
|
+
|
|
119
|
+
if (category === 'pro') {
|
|
120
|
+
const proPreferences = [
|
|
121
|
+
'gemini-3.1-pro-preview',
|
|
122
|
+
'gemini-2.5-pro',
|
|
123
|
+
'gemini-1.5-pro',
|
|
124
|
+
'gemini-pro-latest'
|
|
125
|
+
];
|
|
126
|
+
for (const p of proPreferences) {
|
|
127
|
+
if (models.some(m => m.name === `models/${p}`)) {
|
|
128
|
+
return p;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
const flashPreferences = [
|
|
133
|
+
'gemini-3.5-flash',
|
|
134
|
+
'gemini-3.1-flash-lite',
|
|
135
|
+
'gemini-2.5-flash',
|
|
136
|
+
'gemini-2.0-flash-lite',
|
|
137
|
+
'gemini-flash-latest'
|
|
138
|
+
];
|
|
139
|
+
for (const p of flashPreferences) {
|
|
140
|
+
if (models.some(m => m.name === `models/${p}`)) {
|
|
141
|
+
return p;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
} catch {
|
|
147
|
+
// Silent failover to hardcoded default targets
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Ultimate fallback
|
|
151
|
+
return category === 'pro' ? 'gemini-3.1-pro-preview' : 'gemini-3.5-flash';
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function main() {
|
|
155
|
+
try {
|
|
156
|
+
const resolvedModel = await resolveGenerativeModel(requestedModel);
|
|
157
|
+
const url = `https://generativelanguage.googleapis.com/v1beta/models/${resolvedModel}:generateContent?key=${apiKey}`;
|
|
158
|
+
|
|
159
|
+
const res = await fetch(url, {
|
|
160
|
+
method: 'POST',
|
|
161
|
+
headers: {
|
|
162
|
+
'Content-Type': 'application/json',
|
|
163
|
+
},
|
|
164
|
+
body: JSON.stringify({
|
|
165
|
+
contents: [{
|
|
166
|
+
parts: [{ text: prompt }]
|
|
167
|
+
}]
|
|
168
|
+
})
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
if (!res.ok) {
|
|
172
|
+
const errText = await res.text();
|
|
173
|
+
throw new Error(`Gemini API returned status ${res.status}: ${errText}`);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const data = await res.json();
|
|
177
|
+
const text = data.candidates?.[0]?.content?.parts?.[0]?.text || '';
|
|
178
|
+
|
|
179
|
+
// Save usage data for token monitoring/budget safety
|
|
180
|
+
try {
|
|
181
|
+
const promptTokens = data.usageMetadata?.promptTokenCount || 0;
|
|
182
|
+
const candidatesTokens = data.usageMetadata?.candidatesTokenCount || 0;
|
|
183
|
+
if (promptTokens > 0 || candidatesTokens > 0) {
|
|
184
|
+
const tmpDir = path.join(os.homedir(), '.gemini', 'tmp', 'antigravity', 'chats');
|
|
185
|
+
if (!fs.existsSync(tmpDir)) {
|
|
186
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
187
|
+
}
|
|
188
|
+
const usageLine = JSON.stringify({
|
|
189
|
+
timestamp: new Date().toISOString(),
|
|
190
|
+
tokens: {
|
|
191
|
+
input: promptTokens,
|
|
192
|
+
output: candidatesTokens
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
fs.appendFileSync(path.join(tmpDir, 'usage.jsonl'), usageLine + '\n', 'utf8');
|
|
196
|
+
}
|
|
197
|
+
} catch {
|
|
198
|
+
// Silent ignore
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (outputJson) {
|
|
202
|
+
console.log(JSON.stringify({ response: text }));
|
|
203
|
+
} else {
|
|
204
|
+
console.log(text);
|
|
205
|
+
}
|
|
206
|
+
} catch (err) {
|
|
207
|
+
console.error('Error calling Gemini API:', err.message);
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
main();
|
package/bin/init.mjs
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
|
|
7
|
+
const HOME = os.homedir();
|
|
8
|
+
const AGENT_DIR = path.join(HOME, '.agent');
|
|
9
|
+
const BRAIN_DIR = path.join(AGENT_DIR, 'skills', 'total-recall');
|
|
10
|
+
|
|
11
|
+
const directories = [
|
|
12
|
+
path.join(AGENT_DIR, 'skills'),
|
|
13
|
+
path.join(BRAIN_DIR, 'memory-vault', 'invariants'),
|
|
14
|
+
path.join(BRAIN_DIR, 'memory-vault', 'patterns'),
|
|
15
|
+
path.join(BRAIN_DIR, 'memory-vault', 'anti-patterns'),
|
|
16
|
+
path.join(BRAIN_DIR, 'memory-vault', 'preferences'),
|
|
17
|
+
path.join(BRAIN_DIR, 'memory-vault', 'decisions'),
|
|
18
|
+
path.join(BRAIN_DIR, 'memory-vault', 'concepts'),
|
|
19
|
+
path.join(BRAIN_DIR, 'memory-derived'),
|
|
20
|
+
path.join(BRAIN_DIR, 'memory-inbox', 'pending'),
|
|
21
|
+
path.join(BRAIN_DIR, 'memory-inbox', 'conflicts'),
|
|
22
|
+
path.join(BRAIN_DIR, 'sessions'),
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
console.log('š Initializing Total Recall SSSS Memory Vault...\n');
|
|
26
|
+
|
|
27
|
+
directories.forEach(dir => {
|
|
28
|
+
if (!fs.existsSync(dir)) {
|
|
29
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
30
|
+
console.log(`ā
Created: ${dir}`);
|
|
31
|
+
} else {
|
|
32
|
+
console.log(`š Exists: ${dir}`);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
console.log('\nš SSSS Vault initialization complete. No database required.');
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Oracle Cloud Instance Auto-Provisioning Sniper
|
|
4
|
+
# This script will continuously attempt to create an Ampere A1 instance
|
|
5
|
+
# until capacity is available in your region.
|
|
6
|
+
|
|
7
|
+
# --- CONFIGURATION (Replace these with your exact OCIDs from the Oracle Console) ---
|
|
8
|
+
COMPARTMENT_ID="ocid1.tenancy.oc1..aaaaaaaabjccfnrjtwyf2shaww62vxpavualyuxr277uhgd66yyxjw2wjg2a"
|
|
9
|
+
SUBNET_ID="ocid1.subnet.oc1.phx.aaaaaaaatpvwsqwnxzbmacl4nwfqrqlky4br25iv2muyk36b4oe7vmfzfcia"
|
|
10
|
+
IMAGE_ID="ocid1.image.oc1.phx.aaaaaaaaza5inn2bm77iz5yqaobyqi6x5k2w7buo4tbekiijkuluetyr3dkq"
|
|
11
|
+
SSH_KEY_FILE="$HOME/.ssh/id_ed25519.pub"
|
|
12
|
+
AVAILABILITY_DOMAIN="JJIu:PHX-AD-1" # Switched to AD-1 since AD-2 was out of capacity
|
|
13
|
+
SHAPE="VM.Standard.A1.Flex"
|
|
14
|
+
OCPUS=4
|
|
15
|
+
MEMORY=24
|
|
16
|
+
# -----------------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
if ! command -v ~/bin/oci &> /dev/null && ! command -v oci &> /dev/null; then
|
|
19
|
+
echo "OCI CLI is not installed."
|
|
20
|
+
echo "1. Install it via Homebrew: brew install oci-cli"
|
|
21
|
+
echo "2. Authenticate: ~/bin/oci setup config"
|
|
22
|
+
exit 1
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Determine correct oci binary path
|
|
26
|
+
OCI_BIN="oci"
|
|
27
|
+
if [ -x "$HOME/bin/oci" ]; then
|
|
28
|
+
OCI_BIN="$HOME/bin/oci"
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
echo "Starting OCI Sniper... Target: $SHAPE ($OCPUS OCPUs, $MEMORY GB RAM) in $AVAILABILITY_DOMAIN"
|
|
32
|
+
|
|
33
|
+
while true; do
|
|
34
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Attempting to provision instance..."
|
|
35
|
+
|
|
36
|
+
# Capture both stdout and stderr, and the exit code
|
|
37
|
+
OUTPUT=$($OCI_BIN compute instance launch \
|
|
38
|
+
--compartment-id "$COMPARTMENT_ID" \
|
|
39
|
+
--availability-domain "$AVAILABILITY_DOMAIN" \
|
|
40
|
+
--shape "$SHAPE" \
|
|
41
|
+
--shape-config "{\"memoryInGBs\": $MEMORY, \"ocpus\": $OCPUS}" \
|
|
42
|
+
--subnet-id "$SUBNET_ID" \
|
|
43
|
+
--image-id "$IMAGE_ID" \
|
|
44
|
+
--ssh-authorized-keys-file "$SSH_KEY_FILE" \
|
|
45
|
+
--display-name "Total-Recall-Brain" \
|
|
46
|
+
--assign-public-ip true 2>&1)
|
|
47
|
+
|
|
48
|
+
EXIT_CODE=$?
|
|
49
|
+
|
|
50
|
+
if [ $EXIT_CODE -eq 0 ]; then
|
|
51
|
+
echo "ā
SUCCESS! Instance provisioned."
|
|
52
|
+
echo "$OUTPUT"
|
|
53
|
+
|
|
54
|
+
# Trigger macOS Desktop Notification
|
|
55
|
+
osascript -e 'display notification "Your 24GB Oracle instance has been successfully provisioned!" with title "Total Recall Sniper"'
|
|
56
|
+
if [ -f "node .agent/skills/notifications/scripts/notify.mjs" ]; then
|
|
57
|
+
node .agent/skills/notifications/scripts/notify.mjs "Total Recall Sniper" "Your 24GB Oracle instance has been successfully provisioned! Go to your dashboard to get the IP."
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
echo "Sniper terminating. Go check your Oracle Dashboard!"
|
|
61
|
+
exit 0
|
|
62
|
+
else
|
|
63
|
+
# It failed. Let's just print the error and wait 60 seconds to try again.
|
|
64
|
+
echo "ā Provisioning failed (Oracle API is busy or out of capacity). Retrying in 60 seconds..."
|
|
65
|
+
# If they want to see the error they can check the terminal output:
|
|
66
|
+
echo "$OUTPUT" | grep -E '"message"|"code"|Exception' | head -n 3
|
|
67
|
+
sleep 60
|
|
68
|
+
fi
|
|
69
|
+
done
|