total-recall-brain 3.41.3 → 3.41.5
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 +12 -2
- package/docs/reference/cli-reference.md +18 -0
- package/frontend/dist/assets/{index-DFenQQEQ.js → index-WT3gs-x6.js} +75 -70
- package/frontend/dist/index.html +1 -1
- package/package.json +7 -5
- package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +2 -2
- package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/cli-secret.mjs +48 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/login-projections.mjs +42 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/mesh-secrets.mjs +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/routes/secrets.mjs +5 -2
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-carriers.mjs +76 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-prune.mjs +37 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-sync.mjs +53 -17
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +3114 -36
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +3114 -36
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +3131 -28
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +6 -2
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package-lock.json +3132 -29
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package.json +5 -1
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +3164 -73
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +5 -3
- package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/grants.mjs +7 -3
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/mesh.mjs +61 -38
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/core/leader-election.mjs +57 -2
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/core/mesh.mjs +220 -36
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/server/routes/mesh.mjs +7 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +65 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/BRICK.md +59 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/index.mjs +534 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +139 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +5937 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +26 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +376 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/skills/meta-harness/SKILL.md +37 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/adapters/dsh.mjs +446 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/alerts.mjs +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +398 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/documentation.mjs +172 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/executor.mjs +82 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +90 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +415 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/runtime.mjs +36 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/setup.mjs +35 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/tracker.mjs +133 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +233 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +32 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +845 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/capability/BRICK.md +64 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/capability/index.mjs +250 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +619 -41
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +3134 -31
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +9 -3
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +413 -14
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/config.mjs +129 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/generate.mjs +159 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/graph.mjs +197 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/lint.mjs +153 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/mesh-vaults.mjs +261 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +502 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/search.mjs +114 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/token.mjs +96 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/upstream-watcher.mjs +375 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/DESIGN.md +35 -22
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +1225 -364
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/vendor/openwiki.mjs +8987 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +3114 -83
- package/scaffold/.agent/skills/total-recall/plugins/security/package.json +5 -1
- package/src/cli/compact.mjs +108 -0
- package/src/cli/config.mjs +3 -0
- package/src/cli/connect.mjs +12 -116
- package/src/cli/context.mjs +52 -23
- package/src/cli/forget.mjs +2 -0
- package/src/cli/harness.mjs +0 -1
- package/src/cli/plugin/create.mjs +56 -3
- package/src/cli/plugin/index.mjs +15 -3
- package/src/cli/plugin/monetization.mjs +232 -12
- package/src/cli/preflight.mjs +161 -0
- package/src/cli/release.mjs +386 -0
- package/src/core/cli-commands.mjs +4 -0
- package/src/core/context-compactor.mjs +143 -0
- package/src/core/context-compiler.mjs +8 -1
- package/src/core/default-plugins.mjs +1 -1
- package/src/core/meta-harness.mjs +16 -38
- package/src/core/plugin-dependencies.mjs +6 -1
- package/src/core/preflight-gate.mjs +77 -0
- package/src/core/preflight-receipt.mjs +123 -0
- package/src/core/runtime.mjs +0 -3
- package/src/core/surface.mjs +39 -2
- package/src/server/invoke-durability.mjs +39 -0
- package/src/server/invoke-write-child.mjs +25 -0
- package/src/server/routes/invoke.mjs +7 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Vault and Mesh Discovery Engine for OpenWiki.
|
|
3
|
+
*
|
|
4
|
+
* Uses the Total Recall Mesh plugin dynamically (zero hardcoded hosts/IPs/devices).
|
|
5
|
+
* Discovers local vaults, registered project vaults, and live online mesh peers.
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import os from 'node:os';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
import { execFileSync, spawnSync } from 'node:child_process';
|
|
11
|
+
import { readProjects } from './refresh.mjs';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Returns the path to the global vault directory.
|
|
15
|
+
*/
|
|
16
|
+
export function getGlobalVaultPath(home = os.homedir()) {
|
|
17
|
+
return path.join(home, '.agent', 'skills', 'total-recall', 'memory-vault');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Discovers all active vault roots on the current machine dynamically:
|
|
22
|
+
* - Global memory vault
|
|
23
|
+
* - Every registered project repository's memory vault
|
|
24
|
+
* - Every registered project repository's openwiki projection directory
|
|
25
|
+
*/
|
|
26
|
+
export function discoverLocalVaults({ home = os.homedir() } = {}) {
|
|
27
|
+
const vaults = [];
|
|
28
|
+
|
|
29
|
+
// 1. Global Vault
|
|
30
|
+
const globalVault = getGlobalVaultPath(home);
|
|
31
|
+
if (fs.existsSync(globalVault)) {
|
|
32
|
+
vaults.push({
|
|
33
|
+
type: 'global',
|
|
34
|
+
name: 'global-vault',
|
|
35
|
+
root: globalVault,
|
|
36
|
+
isVault: true,
|
|
37
|
+
hasOpenWikiDir: fs.existsSync(path.join(globalVault, 'openwiki-articles')) ||
|
|
38
|
+
fs.existsSync(path.join(globalVault, 'openwiki-hubs')),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 2. Project Vaults & Repositories from project-registry
|
|
43
|
+
let projects = [];
|
|
44
|
+
try {
|
|
45
|
+
projects = readProjects();
|
|
46
|
+
} catch {
|
|
47
|
+
projects = [];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
for (const proj of projects) {
|
|
51
|
+
const projectVault = path.join(proj.root, '.agent', 'skills', 'total-recall', 'memory-vault');
|
|
52
|
+
const projectOpenWiki = path.join(proj.root, 'openwiki');
|
|
53
|
+
vaults.push({
|
|
54
|
+
type: 'project',
|
|
55
|
+
name: proj.name,
|
|
56
|
+
root: proj.root,
|
|
57
|
+
vaultPath: fs.existsSync(projectVault) ? projectVault : null,
|
|
58
|
+
openwikiPath: fs.existsSync(projectOpenWiki) ? projectOpenWiki : null,
|
|
59
|
+
hasOpenWikiDir: fs.existsSync(projectOpenWiki),
|
|
60
|
+
isVault: fs.existsSync(projectVault),
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return vaults;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Dynamically queries the mesh plugin for live mesh peers.
|
|
69
|
+
* Zero hardcoded hostnames, IPs, or personal user configurations.
|
|
70
|
+
*/
|
|
71
|
+
export function getMeshNodes() {
|
|
72
|
+
try {
|
|
73
|
+
const stdout = execFileSync('total-recall', ['mesh', 'status'], {
|
|
74
|
+
encoding: 'utf8',
|
|
75
|
+
timeout: 6000,
|
|
76
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const lines = stdout.split('\n');
|
|
80
|
+
const jsonLine = lines.find((l) => l.trim().startsWith('{') && l.includes('"nodes"'));
|
|
81
|
+
if (!jsonLine) return [];
|
|
82
|
+
|
|
83
|
+
const parsed = JSON.parse(jsonLine);
|
|
84
|
+
if (!Array.isArray(parsed.nodes)) return [];
|
|
85
|
+
|
|
86
|
+
return parsed.nodes
|
|
87
|
+
.filter((n) => n && n.ip && typeof n.ip === 'string')
|
|
88
|
+
.map((n) => ({
|
|
89
|
+
hostname: n.os_hostname || n.hostname || n.title || n.ip,
|
|
90
|
+
ip: n.ip,
|
|
91
|
+
ips: Array.isArray(n.ips) ? n.ips : [n.ip],
|
|
92
|
+
self: Boolean(n.self),
|
|
93
|
+
online: Boolean(n.online),
|
|
94
|
+
os: n.os || 'unknown',
|
|
95
|
+
}));
|
|
96
|
+
} catch {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Execute a command on a remote mesh node via Total Recall mesh plugin.
|
|
103
|
+
* Guarded against self-execution (never ssh a machine into itself).
|
|
104
|
+
*/
|
|
105
|
+
export function execOnMeshNode(nodeTarget, commandStr, { timeoutMs = 25000 } = {}) {
|
|
106
|
+
if (!nodeTarget || typeof nodeTarget !== 'string') {
|
|
107
|
+
throw new Error('A valid mesh node identifier or IP is required');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Verify against dynamic mesh self status
|
|
111
|
+
const nodes = getMeshNodes();
|
|
112
|
+
const matched = nodes.find(
|
|
113
|
+
(n) => n.ip === nodeTarget || n.hostname.toLowerCase() === nodeTarget.toLowerCase()
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
if (matched?.self) {
|
|
117
|
+
throw new Error(`Target node '${nodeTarget}' is the local host. Do not mesh exec into self.`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const result = spawnSync('total-recall', ['mesh', 'exec', nodeTarget, commandStr], {
|
|
121
|
+
encoding: 'utf8',
|
|
122
|
+
timeout: timeoutMs,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
ok: result.status === 0,
|
|
127
|
+
status: result.status,
|
|
128
|
+
stdout: result.stdout || '',
|
|
129
|
+
stderr: result.stderr || '',
|
|
130
|
+
error: result.error ? result.error.message : null,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Scans a directory for OpenWiki markdown hub files.
|
|
136
|
+
*/
|
|
137
|
+
export function scanDirectoryHubs(targetDir, { label = '', repoName = '' } = {}) {
|
|
138
|
+
const hubs = [];
|
|
139
|
+
if (!fs.existsSync(targetDir)) return hubs;
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
const entries = fs.readdirSync(targetDir, { withFileTypes: true });
|
|
143
|
+
for (const ent of entries) {
|
|
144
|
+
if (ent.isFile() && ent.name.endsWith('.md')) {
|
|
145
|
+
const fullPath = path.join(targetDir, ent.name);
|
|
146
|
+
try {
|
|
147
|
+
const content = fs.readFileSync(fullPath, 'utf8');
|
|
148
|
+
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
149
|
+
const title = titleMatch ? titleMatch[1].trim() : ent.name.replace(/\.md$/, '');
|
|
150
|
+
const lines = content.split('\n').length;
|
|
151
|
+
hubs.push({
|
|
152
|
+
title,
|
|
153
|
+
fileName: ent.name,
|
|
154
|
+
path: fullPath,
|
|
155
|
+
repoName: repoName || path.basename(path.dirname(targetDir)),
|
|
156
|
+
sourceType: label || 'openwiki',
|
|
157
|
+
lines,
|
|
158
|
+
size_bytes: Buffer.byteLength(content, 'utf8'),
|
|
159
|
+
});
|
|
160
|
+
} catch {
|
|
161
|
+
// ignore unreadable files
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
} catch {
|
|
166
|
+
// directory read error
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return hubs;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Universal Hubs Discovery across:
|
|
174
|
+
* - Current cwd `./openwiki`
|
|
175
|
+
* - All registered project vaults (`--all-vaults`)
|
|
176
|
+
* - Global memory vault (`openwiki-*` categories)
|
|
177
|
+
* - Remote mesh node (`--node <target>`)
|
|
178
|
+
*/
|
|
179
|
+
export async function discoverAllHubs({
|
|
180
|
+
allVaults = false,
|
|
181
|
+
node = null,
|
|
182
|
+
cwd = process.cwd(),
|
|
183
|
+
} = {}) {
|
|
184
|
+
// If target is a remote mesh node, delegate through mesh
|
|
185
|
+
if (node && node !== 'local' && node !== 'self') {
|
|
186
|
+
const nodes = getMeshNodes();
|
|
187
|
+
const selfNode = nodes.find((n) => n.self);
|
|
188
|
+
const isSelf = selfNode && (selfNode.ip === node || selfNode.hostname.toLowerCase() === node.toLowerCase());
|
|
189
|
+
|
|
190
|
+
if (!isSelf) {
|
|
191
|
+
const meshRes = execOnMeshNode(node, `total-recall openwiki hubs ${allVaults ? '--all-vaults' : ''} --json`);
|
|
192
|
+
if (meshRes.ok) {
|
|
193
|
+
try {
|
|
194
|
+
const parsed = JSON.parse(meshRes.stdout);
|
|
195
|
+
return {
|
|
196
|
+
node,
|
|
197
|
+
isRemote: true,
|
|
198
|
+
hubs: parsed.hubs || [],
|
|
199
|
+
count: parsed.count || (parsed.hubs ? parsed.hubs.length : 0),
|
|
200
|
+
};
|
|
201
|
+
} catch {
|
|
202
|
+
throw new Error(`Invalid JSON response from mesh node ${node}: ${meshRes.stdout}`);
|
|
203
|
+
}
|
|
204
|
+
} else {
|
|
205
|
+
throw new Error(`Mesh exec failed on node ${node}: ${meshRes.stderr || meshRes.error}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const allHubs = [];
|
|
211
|
+
|
|
212
|
+
// 1. Current working directory openwiki
|
|
213
|
+
const localOpenWiki = path.resolve(cwd, 'openwiki');
|
|
214
|
+
const localHubs = scanDirectoryHubs(localOpenWiki, {
|
|
215
|
+
label: 'current-workspace',
|
|
216
|
+
repoName: path.basename(cwd),
|
|
217
|
+
});
|
|
218
|
+
allHubs.push(...localHubs);
|
|
219
|
+
|
|
220
|
+
// If not all vaults requested, return local hubs
|
|
221
|
+
if (!allVaults) {
|
|
222
|
+
return {
|
|
223
|
+
node: 'local',
|
|
224
|
+
isRemote: false,
|
|
225
|
+
hubs: allHubs,
|
|
226
|
+
count: allHubs.length,
|
|
227
|
+
scope: 'workspace',
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// 2. Scan all project vaults across the machine
|
|
232
|
+
const localVaults = discoverLocalVaults();
|
|
233
|
+
for (const vault of localVaults) {
|
|
234
|
+
if (vault.type === 'project' && vault.openwikiPath) {
|
|
235
|
+
if (path.resolve(vault.openwikiPath) === path.resolve(localOpenWiki)) continue;
|
|
236
|
+
const projHubs = scanDirectoryHubs(vault.openwikiPath, {
|
|
237
|
+
label: 'project-openwiki',
|
|
238
|
+
repoName: vault.name,
|
|
239
|
+
});
|
|
240
|
+
allHubs.push(...projHubs);
|
|
241
|
+
} else if (vault.type === 'global') {
|
|
242
|
+
const gHubsDir = path.join(vault.root, 'openwiki-hubs');
|
|
243
|
+
const gArticlesDir = path.join(vault.root, 'openwiki-articles');
|
|
244
|
+
if (fs.existsSync(gHubsDir)) {
|
|
245
|
+
allHubs.push(...scanDirectoryHubs(gHubsDir, { label: 'global-vault-hubs', repoName: 'global-vault' }));
|
|
246
|
+
}
|
|
247
|
+
if (fs.existsSync(gArticlesDir)) {
|
|
248
|
+
allHubs.push(...scanDirectoryHubs(gArticlesDir, { label: 'global-vault-articles', repoName: 'global-vault' }));
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return {
|
|
254
|
+
node: 'local',
|
|
255
|
+
isRemote: false,
|
|
256
|
+
hubs: allHubs,
|
|
257
|
+
count: allHubs.length,
|
|
258
|
+
scope: 'all-vaults',
|
|
259
|
+
vaultsScanned: localVaults.length,
|
|
260
|
+
};
|
|
261
|
+
}
|