total-recall-brain 3.41.3 → 3.41.4

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.
Files changed (80) hide show
  1. package/bin/total-recall.mjs +10 -1
  2. package/frontend/dist/assets/{index-DFenQQEQ.js → index-CRzjQLu7.js} +77 -72
  3. package/frontend/dist/index.html +1 -1
  4. package/package.json +7 -5
  5. package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +2 -2
  6. package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +1 -1
  7. package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +1 -1
  8. package/scaffold/.agent/skills/total-recall/plugins/auth/src/cli-secret.mjs +48 -0
  9. package/scaffold/.agent/skills/total-recall/plugins/auth/src/login-projections.mjs +42 -0
  10. package/scaffold/.agent/skills/total-recall/plugins/auth/src/mesh-secrets.mjs +18 -0
  11. package/scaffold/.agent/skills/total-recall/plugins/auth/src/routes/secrets.mjs +5 -2
  12. package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-carriers.mjs +76 -0
  13. package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-prune.mjs +37 -0
  14. package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-sync.mjs +53 -17
  15. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +12 -12
  16. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +1 -1
  17. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +12 -12
  18. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +1 -1
  19. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +23 -8
  20. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +6 -2
  21. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package-lock.json +23 -8
  22. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package.json +5 -1
  23. package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +23 -10
  24. package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +5 -3
  25. package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +1 -1
  26. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/grants.mjs +7 -3
  27. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/mesh.mjs +61 -38
  28. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/core/leader-election.mjs +57 -2
  29. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/core/mesh.mjs +220 -36
  30. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/server/routes/mesh.mjs +7 -2
  31. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +65 -0
  32. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/BRICK.md +59 -0
  33. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/index.mjs +534 -0
  34. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +139 -0
  35. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +2849 -0
  36. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +26 -0
  37. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +376 -0
  38. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/skills/meta-harness/SKILL.md +37 -0
  39. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/adapters/dsh.mjs +446 -0
  40. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/alerts.mjs +23 -0
  41. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +398 -0
  42. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/documentation.mjs +152 -0
  43. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/executor.mjs +82 -0
  44. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +90 -0
  45. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +415 -0
  46. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/runtime.mjs +36 -0
  47. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/setup.mjs +35 -0
  48. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/tracker.mjs +133 -0
  49. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +233 -0
  50. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +32 -0
  51. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +845 -0
  52. package/scaffold/.agent/skills/total-recall/plugins/openwiki/capability/BRICK.md +64 -0
  53. package/scaffold/.agent/skills/total-recall/plugins/openwiki/capability/index.mjs +250 -0
  54. package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +344 -14
  55. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +2917 -140
  56. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +9 -3
  57. package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +223 -5
  58. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/config.mjs +129 -0
  59. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +355 -0
  60. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/upstream-watcher.mjs +375 -0
  61. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/DESIGN.md +35 -22
  62. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +947 -323
  63. package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +23 -8
  64. package/scaffold/.agent/skills/total-recall/plugins/security/package.json +5 -1
  65. package/src/cli/config.mjs +3 -0
  66. package/src/cli/connect.mjs +12 -116
  67. package/src/cli/harness.mjs +0 -1
  68. package/src/cli/plugin/create.mjs +56 -3
  69. package/src/cli/plugin/index.mjs +15 -3
  70. package/src/cli/plugin/monetization.mjs +232 -12
  71. package/src/cli/preflight.mjs +161 -0
  72. package/src/core/cli-commands.mjs +2 -0
  73. package/src/core/context-compiler.mjs +8 -1
  74. package/src/core/default-plugins.mjs +1 -1
  75. package/src/core/meta-harness.mjs +16 -38
  76. package/src/core/plugin-dependencies.mjs +6 -1
  77. package/src/core/preflight-gate.mjs +77 -0
  78. package/src/core/preflight-receipt.mjs +123 -0
  79. package/src/core/runtime.mjs +0 -3
  80. package/src/core/surface.mjs +38 -1
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Upstream agent harness tracking: live versions, changelogs, and contracts.
3
+ */
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import os from 'node:os';
7
+ import { spawnSync } from 'node:child_process';
8
+ import { findBinary } from './worker.mjs';
9
+
10
+ const CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
11
+ const versionCache = new Map();
12
+
13
+ /**
14
+ * Dynamically resolves the currently installed version for an agent binary.
15
+ */
16
+ export function getInstalledVersion(agentId, binaryPath = null) {
17
+ const binary = binaryPath || findBinary(agentId === 'cursor' ? 'cursor-agent' : agentId);
18
+ if (!binary) return null;
19
+
20
+ try {
21
+ if (agentId === 'claude') {
22
+ const updateResult = path.join(os.homedir(), '.claude', '.last-update-result.json');
23
+ if (fs.existsSync(updateResult)) {
24
+ try {
25
+ const data = JSON.parse(fs.readFileSync(updateResult, 'utf8'));
26
+ if (data.version_to) return data.version_to;
27
+ } catch {}
28
+ }
29
+ }
30
+ const res = spawnSync(binary, ['--version'], { timeout: 2500, encoding: 'utf8' });
31
+ const output = (res.stdout || res.stderr || '').trim();
32
+ const match = output.match(/\b\d+\.\d+(?:\.\d+)?\b/);
33
+ return match ? match[0] : null;
34
+ } catch {
35
+ return null;
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Retrieves the latest upstream version for a harness without hardcoded downgrade traps.
41
+ */
42
+ export async function getLatestVersion(agentId, installedVersion = null) {
43
+ const cached = versionCache.get(agentId);
44
+ if (cached && (Date.now() - cached.ts) < CACHE_TTL_MS) {
45
+ return cached.version;
46
+ }
47
+
48
+ let latest = installedVersion || 'unknown';
49
+
50
+ try {
51
+ if (agentId === 'claude') {
52
+ const res = await fetch('https://registry.npmjs.org/@anthropic-ai/claude-code/latest', {
53
+ signal: AbortSignal.timeout(3000),
54
+ });
55
+ if (res.ok) {
56
+ const data = await res.json();
57
+ if (data.version) latest = data.version;
58
+ }
59
+ } else if (agentId === 'codex') {
60
+ const res = await fetch('https://registry.npmjs.org/@openai/codex/latest', {
61
+ signal: AbortSignal.timeout(3000),
62
+ });
63
+ if (res.ok) {
64
+ const data = await res.json();
65
+ if (data.version) latest = data.version;
66
+ }
67
+ } else if (agentId === 'agy') {
68
+ const bin = findBinary('agy');
69
+ if (bin) {
70
+ const res = spawnSync(bin, ['changelog'], { timeout: 3000, encoding: 'utf8' });
71
+ const output = res.stdout || '';
72
+ const match = output.match(/^(\d+\.\d+\.\d+):/m);
73
+ if (match) latest = match[1];
74
+ else if (installedVersion) latest = installedVersion;
75
+ }
76
+ } else if (installedVersion) {
77
+ latest = installedVersion;
78
+ }
79
+ } catch {
80
+ if (installedVersion) latest = installedVersion;
81
+ }
82
+
83
+ versionCache.set(agentId, { version: latest, ts: Date.now() });
84
+ return latest;
85
+ }
86
+
87
+ /**
88
+ * Returns recent changelog highlights for a harness.
89
+ */
90
+ export function getAgentChangelog(agentId, maxVersions = 3) {
91
+ if (agentId === 'agy') {
92
+ const bin = findBinary('agy');
93
+ if (!bin) return { ok: false, error: 'Antigravity binary not found' };
94
+
95
+ try {
96
+ const res = spawnSync(bin, ['changelog'], { timeout: 4000, encoding: 'utf8' });
97
+ const raw = (res.stdout || '').trim();
98
+ if (!raw) return { ok: false, error: 'Changelog empty' };
99
+
100
+ const sections = raw.split(/\n\n(?=\d+\.\d+\.\d+:)/);
101
+ const recent = sections.slice(0, maxVersions).join('\n\n');
102
+ return { ok: true, agent: 'agy', changelog: recent };
103
+ } catch (err) {
104
+ return { ok: false, error: err.message };
105
+ }
106
+ }
107
+
108
+ return { ok: false, error: `Direct changelog not implemented for ${agentId}` };
109
+ }
110
+
111
+ /**
112
+ * Comprehensive upstream status report across all supported adapters.
113
+ */
114
+ export async function inspectUpstreamFleet(adapters) {
115
+ const reports = [];
116
+
117
+ for (const adapter of adapters) {
118
+ const installed = getInstalledVersion(adapter.id);
119
+ const latest = await getLatestVersion(adapter.id, installed);
120
+ const updateAvailable = installed && latest && latest !== 'unknown' && installed !== latest;
121
+
122
+ reports.push({
123
+ id: adapter.id,
124
+ name: adapter.name,
125
+ installed: installed || null,
126
+ latest: latest || null,
127
+ updateAvailable: Boolean(updateAvailable),
128
+ docs: adapter.docs || null,
129
+ });
130
+ }
131
+
132
+ return reports;
133
+ }
@@ -0,0 +1,233 @@
1
+ /** Portable read-only discovery / bounded dispatch worker; streamed to SSH stdin. */
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { spawn } from 'node:child_process';
6
+
7
+ export const ADAPTERS = [
8
+ { id: 'claude', name: 'Claude Code', binary: 'claude', args: ['--output-format', 'json', '--permission-mode', 'acceptEdits', '-p'], input: 'stdin', auth: ['auth', 'status'], docs: 'https://code.claude.com/docs/en/headless' },
9
+ { id: 'codex', name: 'Codex', binary: 'codex', args: ['exec', '--sandbox', 'workspace-write', '--json', '-'], input: 'stdin', auth: ['login', 'status'], docs: 'https://developers.openai.com/codex/noninteractive' },
10
+ { id: 'agy', name: 'Antigravity', binary: 'agy', args: ['--mode', 'accept-edits', '--sandbox', '--output-format', 'json', '-p'], input: 'argument', docs: 'https://antigravity.google/docs/cli/reference' },
11
+ { id: 'cursor', name: 'Cursor', binary: 'cursor-agent', args: ['--print', '--output-format', 'json'], input: 'argument', auth: ['status'], docs: 'https://docs.cursor.com/en/cli/reference/parameters' },
12
+ { id: 'dsh', name: 'DSH', binary: 'dsh', args: ['--profile', 'headless', '--json', '-'], input: 'stdin', docs: 'https://github.com/deepseek-ai/deepseek-harness/blob/master/apps/cli/README.md' },
13
+ { id: 'grok', name: 'Grok', binary: 'grok', args: ['--output-format', 'json', '-p'], input: 'argument', docs: 'https://docs.x.ai/build/cli/headless-scripting' },
14
+ { id: 'muse', name: 'Muse', binary: 'muse', args: ['exec', '--json'], input: 'file', docs: 'https://dev.meta.ai/docs/muse-code/' },
15
+ { id: 'pi', name: 'Pi', binary: 'pi', args: ['--print', '--mode', 'json', '--tools', 'read,bash', '--no-mcp', '--no-extensions'], input: 'stdin', docs: 'https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/docs/cli.md' },
16
+ { id: 'hermes', name: 'Hermes', binary: 'hermes', args: ['chat', '--oneshot', '--format', 'stream-json', '--query-file', '-'], input: 'stdin', docs: 'https://github.com/NousResearch/hermes-agent/blob/main/website/docs/reference/cli-commands.md' }
17
+ ];
18
+
19
+ export const EXTENDED_ADAPTERS = [
20
+ { id: 'ollama', name: 'Ollama', binary: 'ollama', args: ['run', process.env.TR_OLLAMA_MODEL || 'gemma4:latest'], input: 'stdin', docs: 'https://ollama.com/library' },
21
+ { id: 'openclaw', name: 'OpenClaw', binary: 'openclaw', args: ['agent', '--message'], input: 'argument', docs: 'https://openclaw.ai/docs' },
22
+ { id: 'aider', name: 'Aider', binary: 'aider', args: ['--yes', '--message'], input: 'argument', docs: 'https://aider.chat/docs' },
23
+ { id: 'goose', name: 'Goose', binary: 'goose', args: ['run', '--text'], input: 'argument', docs: 'https://block.github.io/goose/' },
24
+ { id: 'openhands', name: 'OpenHands', binary: 'openhands', args: ['run'], input: 'argument', docs: 'https://docs.all-hands.dev/' },
25
+ { id: 'cline', name: 'Cline', binary: 'cline', args: ['task', '--json'], input: 'argument', docs: 'https://cline.bot/docs' }
26
+ ];
27
+
28
+ export function getCustomAdaptersDirs() {
29
+ const brain = process.env.TR_SECRETS_BRAIN || path.join(process.env.AGENT_DIR || path.join(os.homedir(), '.agent'), 'skills/total-recall');
30
+ return [
31
+ path.join(brain, 'config/harnesses'),
32
+ path.join(process.cwd(), '.meta-harness/adapters')
33
+ ];
34
+ }
35
+
36
+ export function loadCustomAdapters() {
37
+ const custom = [];
38
+ for (const dir of getCustomAdaptersDirs()) {
39
+ if (!fs.existsSync(dir)) continue;
40
+ try {
41
+ for (const file of fs.readdirSync(dir)) {
42
+ if (!file.endsWith('.json')) continue;
43
+ const fullPath = path.join(dir, file);
44
+ try {
45
+ const spec = JSON.parse(fs.readFileSync(fullPath, 'utf8'));
46
+ if (spec && typeof spec.id === 'string' && typeof spec.binary === 'string') {
47
+ custom.push({
48
+ id: spec.id,
49
+ name: spec.name || spec.id,
50
+ binary: spec.binary,
51
+ args: Array.isArray(spec.args) ? spec.args : ['-p'],
52
+ input: spec.input || 'argument',
53
+ docs: spec.docs || null,
54
+ custom: true,
55
+ sourcePath: fullPath
56
+ });
57
+ }
58
+ } catch {}
59
+ }
60
+ } catch {}
61
+ }
62
+ return custom;
63
+ }
64
+
65
+ export function getActiveAdapters() {
66
+ const custom = loadCustomAdapters();
67
+ const map = new Map();
68
+ for (const a of ADAPTERS) map.set(a.id, a);
69
+ for (const e of EXTENDED_ADAPTERS) map.set(e.id, e);
70
+ for (const c of custom) map.set(c.id, { ...map.get(c.id), ...c });
71
+ return Array.from(map.values());
72
+ }
73
+
74
+ export function agentEnvironment(source = process.env) {
75
+ const allowed = ['PATH', 'HOME', 'USER', 'LOGNAME', 'SHELL', 'TMPDIR', 'TMP', 'TEMP', 'LANG', 'LC_ALL', 'TERM', 'SYSTEMROOT', 'SystemRoot', 'APPDATA', 'LOCALAPPDATA', 'USERPROFILE', 'CODEX_HOME', 'CLAUDE_CONFIG_DIR', 'XDG_CONFIG_HOME', 'XDG_DATA_HOME', 'DSH_HOME', 'HERMES_HOME', 'PI_CODING_AGENT_DIR'];
76
+ return Object.fromEntries(allowed.filter(key => typeof source[key] === 'string').map(key => [key, source[key]]));
77
+ }
78
+
79
+ export function findBinary(name, env = process.env) {
80
+ const home = env.HOME || env.USERPROFILE || os.homedir();
81
+ const installed = [path.dirname(process.execPath), path.join(home, '.local/bin'), path.join(home, '.npm-global/bin'), path.join(home, 'bin')];
82
+ const versions = path.join(home, '.nvm/versions/node');
83
+ try { for (const version of fs.readdirSync(versions).sort().reverse()) installed.push(path.join(versions, version, 'bin')); } catch {}
84
+ for (const dir of [...new Set([...(env.PATH || '').split(path.delimiter), ...installed].filter(Boolean))]) {
85
+ const file = path.join(dir, name);
86
+ try { if (fs.statSync(file).isFile()) { fs.accessSync(file, fs.constants.X_OK); return file; } } catch {}
87
+ }
88
+ return null;
89
+ }
90
+
91
+ export function runProcess(binary, args, { cwd, input = '', timeoutMs = 300000, env = agentEnvironment(), maxBytes = 2 * 1024 * 1024 } = {}) {
92
+ return new Promise(resolve => {
93
+ let stdout = '', stderr = '', bytes = 0, reason = null, child, timer, escalation, settled = false;
94
+ const kill = signal => { try { if (process.platform !== 'win32') process.kill(-child.pid, signal); else child.kill(signal); } catch {} };
95
+ const finish = (exitCode, signal) => {
96
+ if (settled) return;
97
+ settled = true; clearTimeout(timer);
98
+ // A parent can exit on TERM while a descendant still holds the process group.
99
+ // Finish the owned group cleanup before releasing an aborted operation.
100
+ if (reason && escalation) {
101
+ clearTimeout(escalation);
102
+ escalation = setTimeout(() => { kill('SIGKILL'); resolve({ exitCode, signal, stdout, stderr, reason }); }, 500);
103
+ } else resolve({ exitCode, signal, stdout, stderr, reason });
104
+ };
105
+ const stop = cause => { if (reason) return; reason = cause; kill('SIGTERM'); escalation = setTimeout(() => kill('SIGKILL'), 500); };
106
+ try { child = spawn(binary, args, { cwd, env, shell: false, detached: process.platform !== 'win32', stdio: ['pipe', 'pipe', 'pipe'] }); }
107
+ catch { finish(null); return; }
108
+ timer = setTimeout(() => stop('timeout'), timeoutMs);
109
+ child.on('error', () => { reason = 'spawn-error'; finish(null); });
110
+ child.stdin.on('error', () => {});
111
+ for (const [stream, output] of [[child.stdout, true], [child.stderr, false]]) stream.on('data', chunk => {
112
+ const part = chunk.subarray(0, Math.max(0, maxBytes - bytes)).toString(); bytes += chunk.length;
113
+ if (output) stdout += part; else stderr += part;
114
+ if (bytes > maxBytes) stop('output-limit');
115
+ });
116
+ child.on('close', finish); child.stdin.end(input);
117
+ });
118
+ }
119
+
120
+ export function parseAgentResult(id, result) {
121
+ if (result.reason || result.exitCode !== 0) return { ok: false, error: result.reason || 'Agent process failed' };
122
+ let frames;
123
+ try { const value = JSON.parse(result.stdout); frames = Array.isArray(value) ? value : [value]; }
124
+ catch { try { frames = result.stdout.trim().split('\n').filter(Boolean).map(line => JSON.parse(line)); } catch { return { ok: false, error: 'Agent output is not valid structured data' }; } }
125
+ if (!frames.length || frames.some(frame => !frame || typeof frame !== 'object')) return { ok: false, error: 'Agent returned no result' };
126
+ if (frames.some(frame => frame.error || frame.is_error || ['error', 'turn.failed'].includes(frame.type) || ['FAILED', 'ERROR', 'CANCELED', 'WAITING'].includes(frame.status))) return { ok: false, error: 'Agent reported failure' };
127
+ const last = frames.at(-1);
128
+ let text;
129
+ if (id === 'codex' && last.type === 'turn.completed') text = frames.filter(frame => frame.type === 'item.completed' && frame.item?.type === 'agent_message').map(frame => frame.item.text).join('\n');
130
+ if (['claude', 'cursor', 'grok'].includes(id) && last.type === 'result' && last.subtype === 'success') text = last.result;
131
+ if (id === 'agy' && last.status === 'SUCCESS') text = last.response;
132
+ if (id === 'dsh' && last.type === 'final') text = last.text;
133
+ if (id === 'hermes' && last.type === 'result' && last.exit_code === 0) text = last.text;
134
+ if (id === 'pi' && last.type === 'agent_end') {
135
+ const messages = last.messages || [];
136
+ if (messages.some(message => ['error', 'aborted'].includes(message.stopReason))) return { ok: false, error: 'Pi turn failed' };
137
+ text = messages.filter(message => message.role === 'assistant').flatMap(message => message.content || []).filter(part => part.type === 'text').map(part => part.text).join('\n');
138
+ }
139
+ if (['ollama', 'openclaw', 'aider', 'goose', 'openhands', 'cline'].includes(id) || loadCustomAdapters().some(c => c.id === id)) {
140
+ text = result.stdout.trim();
141
+ }
142
+ // The official headless contract documents JSONL plus exit status, not MSP
143
+ // notifications. Preserve the actual log rather than invent a headless schema.
144
+ // Exit zero certifies a finished turn only; it never certifies the requested work.
145
+ if (id === 'muse') return { ok: true, response: result.stdout.trim(), events: frames, completionEvidence: 'headless-process-exit', commandExecutionVerified: false };
146
+ return typeof text === 'string' && text.trim() ? { ok: true, response: text, commandExecutionVerified: false } : { ok: false, error: 'Agent did not produce a recognized completed result' };
147
+ }
148
+
149
+ /** Rebuild the instruction payload from the selected node/workspace, never a cached prompt. */
150
+ export async function totalRecallBootstrap(request, { probe = runProcess, env = process.env } = {}) {
151
+ const binary = findBinary('total-recall', env);
152
+ if (!binary) throw new Error('Total Recall is not installed on the selected node');
153
+ const invoke = async args => {
154
+ const result = await probe(binary, args, { cwd: request.cwd, timeoutMs: 120000, maxBytes: 4 * 1024 * 1024, env: agentEnvironment(env) });
155
+ if (result.reason || result.exitCode !== 0) throw new Error(`Total Recall ${args[0]} failed; dispatch refused`);
156
+ return result.stdout;
157
+ };
158
+ const actions = request.permissions?.write ? 'read,edit,test' : 'read';
159
+ await invoke(['cli-agents','setup','--json']);
160
+ const capsule = JSON.parse(await invoke(['context', request.prompt.slice(0,2000), '--action', actions, '--budget', '24000', '--format', 'json']));
161
+ if (capsule.ready !== true || typeof capsule.context !== 'string') throw new Error('Required Total Recall context is not ready');
162
+ const help = await invoke(['--help']);
163
+ const plugins = JSON.parse(await invoke(['plugin', 'library', '--json']));
164
+ const commands = JSON.parse(await invoke(['composable-cli', 'library', '--json']));
165
+ const docs = JSON.parse(await invoke(['cli-agents', 'docs-ensure', '--agent', request.agent, '--json']));
166
+ if (docs.ok !== true) throw new Error('Official agent documentation is unavailable or stale');
167
+ return `Requester: the operator of this Total Recall workspace.\nUse Total Recall and its owning plugin CLI for this task. The following context and command inventories were obtained automatically on this node before dispatch. Official documentation is cached at ${docs.directory}. Read the applicable cached references before changing an integration.\n\nTask context:\n${capsule.context}\n\nComplete CLI help:\n${help}\n\nInstalled plugin command library:\n${JSON.stringify(plugins)}\n\nComposed command library:\n${JSON.stringify(commands)}\n\nRequested task:\n${request.prompt}`;
168
+ }
169
+
170
+ export async function inspectAgents({ probe = runProcess, env = process.env, ids } = {}) {
171
+ const agents = [];
172
+ for (const adapter of getActiveAdapters()) {
173
+ if (ids && !ids.includes(adapter.id)) continue;
174
+ const binary = findBinary(adapter.binary, env);
175
+ const item = { id: adapter.id, name: adapter.name, installed: Boolean(binary), authenticated: 'unknown', executionVerified: false, docs: adapter.docs };
176
+ if (binary) {
177
+ const version = await probe(binary, ['--version'], { timeoutMs: 8000 });
178
+ item.version = version.exitCode === 0 ? (version.stdout || version.stderr).match(/\b\d+\.\d+(?:\.\d+)?\b/)?.[0] || null : null;
179
+ item.versionVerified = Boolean(item.version);
180
+ if (adapter.auth) {
181
+ const auth = await probe(binary, adapter.auth, { timeoutMs: 15000 });
182
+ if (adapter.id === 'codex') item.authenticated = auth.exitCode === 0 && /Logged in using ChatGPT/i.test(auth.stdout + auth.stderr);
183
+ if (adapter.id === 'claude') {
184
+ try { const value = JSON.parse(auth.stdout); item.authenticated = auth.exitCode === 0 && value.loggedIn === true && value.authMethod === 'claude.ai' && value.apiProvider === 'firstParty' && !value.apiKeySource && Boolean(value.subscriptionType); } catch { item.authenticated = false; }
185
+ }
186
+ if (adapter.id === 'cursor') item.authenticated = auth.exitCode === 0 && /logged in|authenticated/i.test(auth.stdout) && !/not authenticated|not logged in/i.test(auth.stdout);
187
+ }
188
+ }
189
+ agents.push(item);
190
+ }
191
+ return { agents, evidence: 'Installed version/auth metadata; actual command execution requires a separate completed run' };
192
+ }
193
+
194
+ export async function dispatchAgent(request, { probe = runProcess, env = process.env, bootstrap = totalRecallBootstrap } = {}) {
195
+ const adapter = getActiveAdapters().find(item => item.id === request.agent);
196
+ if (!adapter || !path.isAbsolute(request.cwd || '') || typeof request.prompt !== 'string' || !request.prompt.trim() || Buffer.byteLength(request.prompt) > 65536) throw new Error('Explicit supported agent, absolute workspace and bounded prompt required');
197
+ if (!fs.statSync(request.cwd).isDirectory()) throw new Error('Selected workspace is not a directory');
198
+ const binary = findBinary(adapter.binary, env);
199
+ if (!binary) throw new Error(`${adapter.name} is not installed on the selected node`);
200
+ const inspected = await inspectAgents({ probe, env, ids: [adapter.id] });
201
+ const state = inspected.agents.find(item => item.id === adapter.id);
202
+ if (!state.versionVerified || state.authenticated === false) throw new Error('Selected agent version or account is not ready');
203
+ if (state.authenticated === 'unknown' && request.allowUnknownAuth !== true) throw new Error('Selected account authentication is unknown; explicitly select this agent to verify it through execution');
204
+ const prompt = await bootstrap(request, { probe, env });
205
+ const args = [...adapter.args];
206
+ const allowWrites = request.permissions?.write === true;
207
+ if (adapter.id === 'codex') args[args.indexOf('--sandbox') + 1] = allowWrites ? 'workspace-write' : 'read-only';
208
+ if (adapter.id === 'claude') args[args.indexOf('--permission-mode') + 1] = allowWrites ? 'acceptEdits' : 'plan';
209
+ if (adapter.id === 'agy') args[args.indexOf('--mode') + 1] = allowWrites ? 'accept-edits' : 'plan';
210
+ if (adapter.id === 'muse' && !allowWrites) args.push('--disable-write');
211
+ let input = adapter.input === 'stdin' ? prompt : '', temporary;
212
+ if (adapter.input === 'argument' || adapter.input === 'file') {
213
+ temporary = fs.mkdtempSync(path.join(os.tmpdir(), 'cli-agent-prompt-'));
214
+ const file = path.join(temporary, 'prompt.txt'); fs.writeFileSync(file, prompt, { mode: 0o600 });
215
+ if (adapter.input === 'file') args.push('--prompt-file', file);
216
+ else args.push(`Read ${file} completely before taking action. It contains the required Total Recall task context, full CLI/plugin/composed-command inventories, official documentation location and the requested task. Carry out that task using the supplied context.`);
217
+ }
218
+ try { return { agent: adapter.id, ...parseAgentResult(adapter.id, await probe(binary, args, { cwd: request.cwd, input, timeoutMs: 300000 })) }; }
219
+ finally { if (temporary) fs.rmSync(temporary, { recursive: true, force: true }); }
220
+ }
221
+
222
+ export async function runWorker(request) {
223
+ if (request.operation === 'inspect') return { ...await inspectAgents(), defaultCwd: os.homedir() };
224
+ if (request.operation === 'dispatch') return dispatchAgent(request);
225
+ if (request.operation === 'direct') {
226
+ if (!path.isAbsolute(request.cwd || '') || !Array.isArray(request.argv) || request.argv.some(arg => typeof arg !== 'string')) throw new Error('Explicit workspace and argv required');
227
+ const binary = findBinary('total-recall');
228
+ if (!binary) throw new Error('Total Recall CLI is not installed on the selected node');
229
+ const result = await runProcess(binary, request.argv.slice(1), { cwd: request.cwd });
230
+ return { ok: result.exitCode === 0 && !result.reason, output: result.stdout, error: result.reason || (result.exitCode ? 'CLI command failed' : undefined), exitCode: result.exitCode, commandExecutionVerified: result.exitCode === 0 && !result.reason };
231
+ }
232
+ throw new Error('Unknown CLI-agent worker operation');
233
+ }
@@ -0,0 +1,32 @@
1
+ # DESIGN.md — Meta Harness
2
+
3
+ ```yaml
4
+ tokens:
5
+ brand-name: "Meta Harness"
6
+ wordmark: "META HARNESS"
7
+ color-primary: "#3b82f6"
8
+ color-background: "#0c1427"
9
+ color-surface: "#1e293b"
10
+ color-accent: "#38bdf8"
11
+ color-ok: "#10b981"
12
+ color-warn: "#f59e0b"
13
+ color-danger: "#ef4444"
14
+ color-text: "#f1f5f9"
15
+ color-muted: "#94a3b8"
16
+ color-line: "#1e293b"
17
+ badge: "Agent Runtime Matrix"
18
+ font-mono: "'JetBrains Mono', 'Fira Code', monospace"
19
+ border-radius: "8px"
20
+ ```
21
+
22
+ ## Brand & Typographic Wordmark
23
+ - **Name**: Meta Harness
24
+ - **Wordmark Logo**: `META HARNESS` (clean typographic badge, no invented cyber delimiters)
25
+ - **Palette**: Primary `#3b82f6`, Surface `#0c1427`, Secondary Surface `#1e293b`, Accent `#38bdf8`, Line `#1e293b`, Text `#f1f5f9`.
26
+ - **States**: Verified Pass `#10b981`, Warning `#f59e0b`, Danger `#ef4444`.
27
+
28
+ ## Interface Architecture
29
+ 1. **Header**: Descriptive typographic badge, mesh target chip, total verified agent counter.
30
+ 2. **Mesh Node Switcher**: Dynamic toggle buttons querying registered mesh nodes.
31
+ 3. **Multi-Agent Matrix**: Grid of supported CLI agents with binary status, auth badge, and version.
32
+ 4. **Structured Fleet Inspector**: Interactive inspector displaying permissions, primary model, and doc freshness.