total-recall-brain 3.28.2 → 3.30.1
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/bin/total-recall.mjs +24 -1
- package/docs/ARCHITECTURE.md +26 -18
- package/extension/background.js +259 -84
- package/extension/content-script.css +7 -13
- package/extension/content-script.js +252 -477
- package/extension/icons/icon-128.png +0 -0
- package/extension/icons/icon-16.png +0 -0
- package/extension/icons/icon-32.png +0 -0
- package/extension/icons/icon-48.png +0 -0
- package/extension/icons/mark.svg +6 -0
- package/extension/lib/brain-client.js +160 -73
- package/extension/lib/tokens.css +187 -0
- package/extension/lib/ui-helpers.js +229 -0
- package/extension/lib/ui-helpers.spec.mjs +94 -0
- package/extension/manifest.json +20 -5
- package/extension/options/options.css +64 -218
- package/extension/options/options.html +91 -43
- package/extension/options/options.js +208 -85
- package/extension/sidepanel/sidepanel.css +268 -970
- package/extension/sidepanel/sidepanel.html +200 -166
- package/extension/sidepanel/sidepanel.js +788 -942
- package/frontend/dist/assets/index-DGMNZi_1.js +5742 -0
- package/frontend/dist/index.html +1 -1
- package/frontend/src/api/plugins.ts +124 -92
- package/frontend/src/components/ResearchAgendaTab.spec.tsx +11 -0
- package/frontend/src/components/ResearchAgendaTab.tsx +19 -14
- package/frontend/src/pages/PluginsPage.spec.tsx +87 -16
- package/frontend/src/pages/PluginsPage.tsx +454 -1218
- package/package.json +2 -1
- package/plugins/code-quality/README.md +25 -0
- package/plugins/code-quality/cli.mjs +25 -0
- package/plugins/code-quality/plugin.json +17 -0
- package/plugins/git-sentinel/README.md +27 -0
- package/{scaffold/.agent/plugins → plugins}/git-sentinel/cli.mjs +8 -5
- package/plugins/git-sentinel/plugin.json +18 -0
- package/plugins/system-monitor/README.md +26 -0
- package/{scaffold/.agent/plugins → plugins}/system-monitor/cli.mjs +5 -4
- package/{scaffold/.agent/plugins → plugins}/system-monitor/generator.mjs +4 -5
- package/plugins/system-monitor/plugin.json +29 -0
- package/scaffold/.agent/skills/meta-harness/SKILL.md +4 -4
- package/scaffold/.agent/skills/plugins/SKILL.md +53 -0
- package/scaffold/.agent/skills/total-recall/SKILL.md +22 -6
- package/scaffold/.agent/skills/total-recall/scripts/brain-state.json +1 -0
- package/src/cli/agent.mjs +1 -1
- package/src/cli/app/index.mjs +493 -0
- package/src/cli/brain.mjs +33 -3
- package/src/cli/command.mjs +80 -41
- package/src/cli/connect.mjs +10 -1
- package/src/cli/harness.mjs +1 -1
- package/src/cli/init.mjs +3 -1
- package/src/cli/mesh.mjs +118 -12
- package/src/cli/plugin/create.mjs +144 -25
- package/src/cli/plugin/index.mjs +83 -53
- package/src/cli/plugin/install.mjs +10 -127
- package/src/cli/plugin/list.mjs +44 -44
- package/src/cli/plugin/remove.mjs +23 -30
- package/src/cli/plugin/scaffold-cmd.mjs +30 -0
- package/src/cli/plugin/search.mjs +108 -23
- package/src/cli/rebuild.mjs +37 -1
- package/src/cli/recall.mjs +17 -2
- package/src/cli/research.mjs +4 -6
- package/src/cli/share.mjs +2 -0
- package/src/core/app-deploy/apply.mjs +386 -0
- package/src/core/app-deploy/design-tokens.mjs +217 -0
- package/src/core/app-deploy/plan.mjs +249 -0
- package/src/core/app-deploy/resolve.mjs +295 -0
- package/src/core/app-deploy/source.mjs +337 -0
- package/src/core/app-deploy/standalone.mjs +248 -0
- package/src/core/app-deploy/upgrade.mjs +256 -0
- package/src/core/app-deploy/verify.mjs +213 -0
- package/src/core/bound-hosts.mjs +1 -1
- package/src/core/brain-registry.mjs +146 -0
- package/src/core/brain-state.json +1 -0
- package/src/core/daemon-loop.mjs +30 -26
- package/src/core/dream.mjs +5 -17
- package/src/core/fact-seeker.mjs +53 -368
- package/src/core/lan-discovery.mjs +3 -3
- package/src/core/mesh-access-sync.mjs +134 -0
- package/src/core/mesh-access.mjs +18 -3
- package/src/core/mesh-discover.mjs +173 -0
- package/src/core/mesh.mjs +131 -32
- package/src/core/optimizer.mjs +4 -41
- package/src/core/plugin-bundle.mjs +167 -0
- package/src/core/plugin-context.mjs +8 -13
- package/src/core/plugin-loader.mjs +272 -68
- package/src/core/plugin-peers.mjs +163 -0
- package/src/core/plugin-public.mjs +85 -0
- package/src/core/plugin-runner-child.mjs +24 -0
- package/src/core/plugin-runner.mjs +102 -0
- package/src/core/plugin-store.mjs +384 -0
- package/src/core/plugin-tasks.mjs +212 -0
- package/src/core/post-mortem.mjs +40 -9
- package/src/core/research-gate.mjs +182 -0
- package/src/core/research-queue.mjs +47 -7
- package/src/core/research-surface.mjs +211 -0
- package/src/core/research.mjs +25 -32
- package/src/core/scheduler.mjs +67 -153
- package/src/core/schema.mjs +129 -0
- package/src/core/search.mjs +12 -1
- package/src/core/secret-integration-research.mjs +12 -8
- package/src/core/secrets-store.mjs +76 -2
- package/src/core/session-watcher.mjs +6 -0
- package/src/core/surface.mjs +64 -3
- package/src/core/task-executors.mjs +8 -45
- package/src/core/vault-cache.mjs +70 -4
- package/src/server/api.mjs +21 -0
- package/src/server/rest.mjs +2 -0
- package/src/server/route-manifest.json +21 -5
- package/src/server/routes/collab.mjs +38 -11
- package/src/server/routes/extension.mjs +3 -2
- package/src/server/routes/memory.mjs +24 -2
- package/src/server/routes/mesh.mjs +7 -7
- package/src/server/routes/plugins-mesh.mjs +49 -0
- package/src/server/routes/plugins.mjs +91 -426
- package/src/server/routes/research.mjs +5 -2
- package/src/server/routes/share.mjs +2 -0
- package/src/server/tools.mjs +29 -2
- package/extension/icons/README.md +0 -27
- package/extension/lib/preconfigured.js +0 -5
- package/extension/popup/popup.css +0 -227
- package/extension/popup/popup.html +0 -50
- package/extension/popup/popup.js +0 -175
- package/frontend/dist/assets/index-U7o-qU99.js +0 -5742
- package/scaffold/.agent/plugins/.gitkeep +0 -0
- package/scaffold/.agent/plugins/code-quality/README.md +0 -16
- package/scaffold/.agent/plugins/code-quality/cli.mjs +0 -15
- package/scaffold/.agent/plugins/code-quality/plugin.json +0 -34
- package/scaffold/.agent/plugins/git-sentinel/README.md +0 -16
- package/scaffold/.agent/plugins/git-sentinel/plugin.json +0 -34
- package/scaffold/.agent/plugins/meta-harness/README.md +0 -16
- package/scaffold/.agent/plugins/meta-harness/cli.mjs +0 -34
- package/scaffold/.agent/plugins/meta-harness/plugin.json +0 -34
- package/scaffold/.agent/plugins/system-monitor/README.md +0 -16
- package/scaffold/.agent/plugins/system-monitor/plugin.json +0 -38
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "total-recall-brain",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.30.1",
|
|
4
4
|
"description": "Personal AI system — database-free, SSSS-powered intelligence engine deployable to any POSIX host.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"workspaces": [
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"frontend/index.html",
|
|
23
23
|
"frontend/src/",
|
|
24
24
|
"extension/",
|
|
25
|
+
"plugins/",
|
|
25
26
|
"templates/",
|
|
26
27
|
"scaffold/",
|
|
27
28
|
"docs/ARCHITECTURE.md",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Code Quality Report
|
|
2
|
+
|
|
3
|
+
Prints the latest report from the `code-quality` skill's background gates in the current repository. It only reads results; it never starts a typecheck or lint run. Requires `.agent/skills/code-quality/` in the repository.
|
|
4
|
+
|
|
5
|
+
**Use cases:** software-development
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx total-recall plugin install code-quality
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Use
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx total-recall code-quality report
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Share with your other nodes
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx total-recall plugin share code-quality
|
|
23
|
+
# on another node on the mesh:
|
|
24
|
+
npx total-recall plugin install peer:<this-node>/code-quality
|
|
25
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execFileSync } from 'node:child_process';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
|
|
6
|
+
// Prints the latest report written by the code-quality skill's background
|
|
7
|
+
// gates. The report script only reads results; it never starts a check.
|
|
8
|
+
export async function run() {
|
|
9
|
+
const scriptPath = path.resolve(process.cwd(), '.agent/skills/code-quality/scripts/report.mjs');
|
|
10
|
+
if (!fs.existsSync(scriptPath)) {
|
|
11
|
+
console.error(`No code-quality skill in ${process.cwd()} (expected ${scriptPath}).`);
|
|
12
|
+
process.exitCode = 1;
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const out = execFileSync(process.execPath, [scriptPath], { encoding: 'utf8', cwd: process.cwd() });
|
|
17
|
+
console.log(out);
|
|
18
|
+
} catch (err) {
|
|
19
|
+
if (err.stdout) console.log(err.stdout);
|
|
20
|
+
console.error(err.stderr || err.message);
|
|
21
|
+
process.exitCode = err.status || 1;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export default run;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://github.com/gregiteen/total-recall/blob/main/metadata.plugin.schema.json",
|
|
3
|
+
"id": "code-quality",
|
|
4
|
+
"name": "Code Quality Report",
|
|
5
|
+
"version": "1.1.0",
|
|
6
|
+
"description": "Shows the latest code-quality gate report for a repository that has the code-quality skill installed.",
|
|
7
|
+
"author": "Total Recall",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"use_cases": ["software-development"],
|
|
10
|
+
"cli": {
|
|
11
|
+
"command": "code-quality",
|
|
12
|
+
"handler": "./cli.mjs",
|
|
13
|
+
"subcommands": [
|
|
14
|
+
{ "name": "report", "description": "Print the latest gate report from .agent/skills/code-quality" }
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Git Sentinel
|
|
2
|
+
|
|
3
|
+
Reports the state of the git repository you run it in: current branch, staged / unstaged / untracked files, commits not yet pushed to upstream, and stashes.
|
|
4
|
+
|
|
5
|
+
**Use cases:** software-development
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx total-recall plugin install git-sentinel
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Use
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx total-recall git-sentinel audit # human summary
|
|
17
|
+
npx total-recall git-sentinel audit --json # machine output for agents
|
|
18
|
+
npx total-recall git-sentinel diff # diffstat of unstaged changes
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Share with your other nodes
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx total-recall plugin share git-sentinel
|
|
25
|
+
# on another node on the mesh:
|
|
26
|
+
npx total-recall plugin install peer:<this-node>/git-sentinel
|
|
27
|
+
```
|
|
@@ -15,8 +15,8 @@ function git(args, cwd = process.cwd()) {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export async function run(argv = []) {
|
|
18
|
-
|
|
19
|
-
const clean =
|
|
18
|
+
// argv: ["node", "total-recall", "git-sentinel", "<subcommand>", ...flags]
|
|
19
|
+
const clean = Array.isArray(argv) ? argv.slice(3) : [];
|
|
20
20
|
const isJson = clean.includes('--json');
|
|
21
21
|
const action = clean.find(a => !a.startsWith('--')) || 'audit';
|
|
22
22
|
|
|
@@ -24,8 +24,11 @@ export async function run(argv = []) {
|
|
|
24
24
|
const isInsideWorkTree = git(['rev-parse', '--is-inside-work-tree'], cwd) === 'true';
|
|
25
25
|
|
|
26
26
|
if (!isInsideWorkTree) {
|
|
27
|
-
|
|
28
|
-
process.
|
|
27
|
+
// Report and set the exit code; never process.exit() — a host that runs
|
|
28
|
+
// this in-process would be stopped with it.
|
|
29
|
+
console.error(`${cwd} is not inside a git repository.`);
|
|
30
|
+
process.exitCode = 1;
|
|
31
|
+
return;
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
const branch = git(['rev-parse', '--abbrev-ref', 'HEAD'], cwd) || 'unknown';
|
|
@@ -70,7 +73,7 @@ export async function run(argv = []) {
|
|
|
70
73
|
return;
|
|
71
74
|
}
|
|
72
75
|
|
|
73
|
-
console.log('\n🛡️
|
|
76
|
+
console.log('\n🛡️ Git Sentinel — Repository State\n');
|
|
74
77
|
console.log(` Active Branch: \x1b[36m${branch}\x1b[0m`);
|
|
75
78
|
console.log(` Worktree State: ${isClean ? '\x1b[32mClean ✅\x1b[0m' : `\x1b[33mDirty (${lines.length} modified/untracked files) ⚠️\x1b[0m`}`);
|
|
76
79
|
if (!isClean) {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://github.com/gregiteen/total-recall/blob/main/metadata.plugin.schema.json",
|
|
3
|
+
"id": "git-sentinel",
|
|
4
|
+
"name": "Git Sentinel",
|
|
5
|
+
"version": "1.1.0",
|
|
6
|
+
"description": "Reports the state of the current git repository: branch, dirty files, unpushed commits and stashes.",
|
|
7
|
+
"author": "Total Recall",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"use_cases": ["software-development"],
|
|
10
|
+
"cli": {
|
|
11
|
+
"command": "git-sentinel",
|
|
12
|
+
"handler": "./cli.mjs",
|
|
13
|
+
"subcommands": [
|
|
14
|
+
{ "name": "audit", "description": "Summarise branch, worktree, upstream and stash state (--json for machine output)" },
|
|
15
|
+
{ "name": "diff", "description": "Show a diffstat of unstaged changes" }
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# System Monitor
|
|
2
|
+
|
|
3
|
+
Adds a host-resources block (load average, free memory) to the compiled agent context, and records one JSON telemetry sample every 15 minutes. Samples are kept in the brain's `plugin.task_run` event log.
|
|
4
|
+
|
|
5
|
+
**Use cases:** operations, self-hosting
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx total-recall plugin install system-monitor
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Use
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx total-recall system-monitor status # human summary
|
|
17
|
+
npx total-recall system-monitor sample # one JSON sample
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Share with your other nodes
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx total-recall plugin share system-monitor
|
|
24
|
+
# on another node on the mesh:
|
|
25
|
+
npx total-recall plugin install peer:<this-node>/system-monitor
|
|
26
|
+
```
|
|
@@ -24,8 +24,8 @@ function formatUptime(seconds) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export async function run(argv = []) {
|
|
27
|
-
|
|
28
|
-
const sub = (
|
|
27
|
+
// argv: ["node", "total-recall", "system-monitor", "<subcommand>"]
|
|
28
|
+
const sub = (Array.isArray(argv) ? argv[3] : null) || 'status';
|
|
29
29
|
|
|
30
30
|
if (sub === 'status' || sub === 'stats' || sub === 'info') {
|
|
31
31
|
const totalMem = os.totalmem();
|
|
@@ -36,7 +36,7 @@ export async function run(argv = []) {
|
|
|
36
36
|
const cpus = os.cpus();
|
|
37
37
|
const memUsage = process.memoryUsage();
|
|
38
38
|
|
|
39
|
-
console.log('\n📊
|
|
39
|
+
console.log('\n📊 System Monitor\n');
|
|
40
40
|
console.log(` Host OS: ${os.type()} ${os.release()} (${os.arch()})`);
|
|
41
41
|
console.log(` Hostname: ${os.hostname()}`);
|
|
42
42
|
console.log(` CPU Cores: ${cpus.length} cores (${cpus[0]?.model || 'Unknown CPU'})`);
|
|
@@ -73,7 +73,8 @@ export async function run(argv = []) {
|
|
|
73
73
|
return;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
console.
|
|
76
|
+
console.error(`Unknown subcommand '${sub}'. Usage: npx total-recall system-monitor [status|sample]`);
|
|
77
|
+
process.exitCode = 1;
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
export default run;
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Context generator for System Monitor
|
|
5
|
-
* Invoked during
|
|
4
|
+
* Context generator for System Monitor.
|
|
5
|
+
* Invoked during surface compilation, so values are as of the last compile.
|
|
6
6
|
*/
|
|
7
|
-
export async function generateContext(
|
|
7
|
+
export async function generateContext() {
|
|
8
8
|
const load = os.loadavg().map(l => l.toFixed(2)).join(', ');
|
|
9
9
|
const freeMb = Math.round(os.freemem() / (1024 * 1024));
|
|
10
10
|
const totalMb = Math.round(os.totalmem() / (1024 * 1024));
|
|
11
11
|
const usedPercent = Math.round(((totalMb - freeMb) / totalMb) * 100);
|
|
12
12
|
|
|
13
|
-
return `####
|
|
13
|
+
return `#### Host Resources (as of ${new Date().toISOString()})
|
|
14
14
|
- Host Platform: ${os.type()} ${os.arch()} (${os.cpus().length} vCPUs)
|
|
15
15
|
- CPU Load Avg: ${load} (1m, 5m, 15m)
|
|
16
16
|
- Host Memory: ${freeMb} MB free / ${totalMb} MB total (${usedPercent}% utilized)
|
|
17
|
-
- Monitored SSSS Metrics Nodes: ${nodes.length}
|
|
18
17
|
`;
|
|
19
18
|
}
|
|
20
19
|
export default generateContext;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://github.com/gregiteen/total-recall/blob/main/metadata.plugin.schema.json",
|
|
3
|
+
"id": "system-monitor",
|
|
4
|
+
"name": "System Monitor",
|
|
5
|
+
"version": "1.1.0",
|
|
6
|
+
"description": "Host load and memory in the compiled agent context, plus a telemetry sample recorded every 15 minutes.",
|
|
7
|
+
"author": "Total Recall",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"use_cases": ["operations", "self-hosting"],
|
|
10
|
+
"cli": {
|
|
11
|
+
"command": "system-monitor",
|
|
12
|
+
"handler": "./cli.mjs",
|
|
13
|
+
"subcommands": [
|
|
14
|
+
{ "name": "status", "description": "Human-readable host resource summary" },
|
|
15
|
+
{ "name": "sample", "description": "One JSON telemetry sample" }
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
"compile": {
|
|
19
|
+
"generator": "./generator.mjs",
|
|
20
|
+
"auto": true
|
|
21
|
+
},
|
|
22
|
+
"tasks": [
|
|
23
|
+
{
|
|
24
|
+
"intent": "Record a host telemetry sample (kept in the plugin.task_run event log)",
|
|
25
|
+
"schedule": "*/15 * * * *",
|
|
26
|
+
"command": "sample"
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
@@ -43,8 +43,8 @@ npx total-recall harness dispatch codex "Generate unit tests for src/core/contex
|
|
|
43
43
|
npx total-recall harness dispatch ollama "Summarize the core invariants of SSSS"
|
|
44
44
|
|
|
45
45
|
# Cross-mesh remote dispatches
|
|
46
|
-
npx total-recall harness dispatch ollama --node
|
|
47
|
-
npx total-recall harness dispatch claude --node
|
|
46
|
+
npx total-recall harness dispatch ollama --node build-box "What is test-time compute scaling?"
|
|
47
|
+
npx total-recall harness dispatch claude --node build-box "Run git status and lint tests"
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
### 3. Multi-Harness Council
|
|
@@ -65,7 +65,7 @@ Manage background subagent tasks across the local machine and remote mesh nodes:
|
|
|
65
65
|
npx total-recall agent spawn claude "Refactor error handling in src/cli/harness.mjs" --name "Refactor Worker"
|
|
66
66
|
|
|
67
67
|
# Remote background agent on a mesh node
|
|
68
|
-
npx total-recall agent spawn agy --node
|
|
68
|
+
npx total-recall agent spawn agy --node build-box "Crawl recent preprints on quantum shuttling" --name "Quantum Scout"
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
### 2. Inspect Running Agents
|
|
@@ -100,7 +100,7 @@ npx total-recall mesh doctor --json
|
|
|
100
100
|
### 2. Non-Interactive Remote Command Execution (`mesh exec`)
|
|
101
101
|
Execute commands on remote nodes with automatic `$PATH` sanitization and structured outputs:
|
|
102
102
|
```bash
|
|
103
|
-
npx total-recall mesh exec
|
|
103
|
+
npx total-recall mesh exec build-box uname -m
|
|
104
104
|
npx total-recall mesh exec cloud docker ps
|
|
105
105
|
```
|
|
106
106
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plugins
|
|
3
|
+
description: Create, validate, install, run, and share Total Recall plugins. Use when a user wants a plugin that adds a useful command, scheduled task, agent context, or SSSS memory category.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Total Recall plugins
|
|
7
|
+
|
|
8
|
+
Build a plugin for a concrete user job. Start by stating the command, context, task, or memory category it adds and how a user will tell that it works. Do not add a plugin solely to populate a gallery.
|
|
9
|
+
|
|
10
|
+
## Where to work
|
|
11
|
+
|
|
12
|
+
Run `total-recall plugin create <id> --name "..." --description "..." --use-case <tag> --with-cli` to scaffold an installed plugin. The CLI creates a directory under the current project's `.agent/skills/total-recall/plugins/`; `--global` creates a machine-wide plugin. A plugin is a folder containing `plugin.json` and the files its manifest names. For a plugin intended to ship with Total Recall itself, use the package's `plugins/<id>/` folder and add a real install and use test.
|
|
13
|
+
|
|
14
|
+
Inspect the installed package's `metadata.plugin.schema.json` and `src/core/plugin-loader.mjs` for the current executable contract before changing a manifest. The schema supports:
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"id": "example-plugin",
|
|
19
|
+
"name": "Example Plugin",
|
|
20
|
+
"version": "1.0.0",
|
|
21
|
+
"description": "The specific job this plugin does.",
|
|
22
|
+
"author": "Author name",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"use_cases": ["research"],
|
|
25
|
+
"cli": {
|
|
26
|
+
"command": "example-plugin",
|
|
27
|
+
"handler": "./cli.mjs",
|
|
28
|
+
"subcommands": [{ "name": "status", "description": "Show current status" }]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
An ID is lowercase kebab case, starts with a letter, and is 2–64 characters. `use_cases` are descriptive kebab-case tags. Keep the manifest honest: declare only features the plugin implements. `README.md` should explain the user job, prerequisites, commands, outputs, and any data or network access.
|
|
34
|
+
|
|
35
|
+
## Implement a capability
|
|
36
|
+
|
|
37
|
+
- **Command:** export `async function run(argv)` from the `cli.handler` module. It receives `['node', 'total-recall', '<command>', '<subcommand>', ...]`. A default-exported function is also supported and receives arguments after the command. Return a result or set `process.exitCode` on failure. The runner isolates the handler in a child process, with a timeout and output cap.
|
|
38
|
+
- **Scheduled task:** add `tasks: [{ "intent": "...", "schedule": "*/15 * * * *", "command": "sample" }]`. `command` is a subcommand implemented by the plugin's CLI handler. The daemon runs it once per due minute slot and records the outcome as a `plugin.task_run` event. Keep tasks bounded and idempotent.
|
|
39
|
+
- **Agent context:** add `compile: { "generator": "./generator.mjs", "auto": true }` and export `generateContext()` from that file. Only include information useful to the agent; avoid secrets and noisy telemetry.
|
|
40
|
+
- **Memory category:** declare it under `ssss_schemas.categories` using the current manifest schema. Preserve SSSS Markdown and operation-contract writes; do not write vault documents directly.
|
|
41
|
+
|
|
42
|
+
## Validate the actual job
|
|
43
|
+
|
|
44
|
+
1. Validate `plugin.json` against the installed schema and `total-recall plugin info <id>`.
|
|
45
|
+
2. Install in a clean temporary project, then run the declared command through `total-recall <command> <subcommand>`. For tasks, verify one due run and its event. For context generators, compile and inspect the resulting block.
|
|
46
|
+
3. Exercise failure paths: missing prerequisite, invalid input, timeout, and any network failure. A plugin that installs but cannot do its advertised job is unfinished.
|
|
47
|
+
4. Review the plugin's file set before sharing. Plugin code has the recipient's process permissions when run. Never bundle secrets, browser profiles, vault data, or machine-specific paths.
|
|
48
|
+
|
|
49
|
+
## Share with another user
|
|
50
|
+
|
|
51
|
+
`total-recall plugin share <id>` marks an installed plugin shareable. Configure `TR_PUBLIC_BASE_URL` as the node's externally reachable HTTPS origin; the command and dashboard then show a direct link ending in `#sha256=<content hash>`. Send that link to the recipient. They install with `total-recall plugin install '<link>'`. The installer requires HTTPS, rejects private destination addresses and redirects, caps the bundle size, and verifies the pinned SHA-256 before writing files. There is no central catalog. The hosting node must actually be reachable at its configured HTTPS origin.
|
|
52
|
+
|
|
53
|
+
`total-recall plugin unshare <id>` stops serving the bundle. Existing installations remain on recipients' machines. Users on one private mesh may also use `peer:<host>/<id>`; mesh membership is not required for public sharing.
|
|
@@ -181,6 +181,10 @@ npx total-recall compile
|
|
|
181
181
|
```
|
|
182
182
|
Synchronously rebuild the entire memory index (derived embeddings) and regenerate prompt instruction shims (such as `INSTRUCTIONS.md`, `GEMINI.md`, `AGENTS.md`, etc.).
|
|
183
183
|
|
|
184
|
+
* **Rules are global + local.** Every project's shims carry the global brain's invariants, preferences and corrections plus the project's own; a project node with the same slug overrides the global one.
|
|
185
|
+
* `compile --global` (what `remember --global` runs) and `compile --all` also recompile every registered project, so a global rule reaches every repo at once.
|
|
186
|
+
* A client gets a shim only once it is connected (`total-recall connect claude-code|codex|antigravity|…` in that repo). No `CLAUDE.md` in a repo means Claude Code was never connected there.
|
|
187
|
+
|
|
184
188
|
### 5. Ingest OKF Bundle
|
|
185
189
|
```bash
|
|
186
190
|
npx total-recall ingest okf <path> [options]
|
|
@@ -394,11 +398,23 @@ transcript. `set`, `rotate` and `rekey` all accept it.
|
|
|
394
398
|
### Master password and `rekey`
|
|
395
399
|
|
|
396
400
|
The store is AES-256-GCM; the key is scrypt-derived (N=2^16, ~64 MB) from
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
`
|
|
400
|
-
|
|
401
|
-
|
|
401
|
+
the master password, resolved in this order:
|
|
402
|
+
|
|
403
|
+
1. `TR_SECRETS_PASSWORD` / `TR_MASTER_PASSWORD` in the environment (a
|
|
404
|
+
LaunchAgent plist injects it for launchd jobs);
|
|
405
|
+
2. macOS: the **Keychain** entry `total-recall-secrets`
|
|
406
|
+
(`security add-generic-password -s total-recall-secrets`). An ssh or mesh
|
|
407
|
+
session cannot read a locked login Keychain;
|
|
408
|
+
3. Linux and headless hosts: the env file `~/.agent/tr.env` (or `TR_ENV_FILE`)
|
|
409
|
+
containing `export TR_SECRETS_PASSWORD='…'`. It is used only when it is a
|
|
410
|
+
regular file, mode 0600, owned by you, in a directory (keep `~/.agent` 0700)
|
|
411
|
+
nobody else can write. Do not also export it from `.bashrc` — every process
|
|
412
|
+
started from the shell would inherit it.
|
|
413
|
+
|
|
414
|
+
`rekey` rotates every carrier (LaunchAgent plist, `--env-file`, Keychain) in one
|
|
415
|
+
transaction, verifying the retired password no longer decrypts before it
|
|
416
|
+
commits. No carrier on a machine means every command fails with "Secrets file
|
|
417
|
+
is not valid JSON" and `mesh` falls back to local discovery.
|
|
402
418
|
|
|
403
419
|
> **Processes hold the old password until restarted.** After a rekey, anything
|
|
404
420
|
> still running with the retired value fails with `Failed to decrypt secrets
|
|
@@ -584,7 +600,7 @@ npm test # vitest run — whole suite
|
|
|
584
600
|
npx vitest run <path> # one spec file
|
|
585
601
|
```
|
|
586
602
|
|
|
587
|
-
Current baseline: **
|
|
603
|
+
Current baseline (3.30.1): **349 spec files / 2024 tests, ~160 s** on the Mac Mini.
|
|
588
604
|
|
|
589
605
|
> **Never run the full suite, a full typecheck, or a production build on the
|
|
590
606
|
> laptop.** These go to the Mac Mini or the droplet — local runs cause slowdowns
|
package/src/cli/agent.mjs
CHANGED
|
@@ -18,7 +18,7 @@ Commands:
|
|
|
18
18
|
kill <id|pid> Terminate an active agent process
|
|
19
19
|
|
|
20
20
|
Options:
|
|
21
|
-
--node <name> Target a remote mesh node (
|
|
21
|
+
--node <name> Target a remote mesh node (build-box, cloud, etc.)
|
|
22
22
|
--json Output machine-readable JSON for Unix pipelines
|
|
23
23
|
--detach Spawn process detached in background (default: true)
|
|
24
24
|
--name <label> Assign a human-readable name to the agent session
|