total-recall-brain 3.44.0 → 3.45.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/bin/total-recall.mjs +6 -4
- package/docs/ARCHITECTURE.md +10 -7
- package/docs/reference/cli-reference.md +13 -8
- package/frontend/dist/assets/index-DACh1dhx.js +5613 -0
- package/frontend/dist/index.html +1 -1
- package/frontend/src/App.tsx +2 -2
- package/frontend/src/pages/PluginsPage.tsx +1 -1
- package/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +7 -7
- 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 +20 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-store.mjs +12 -1
- package/scaffold/.agent/skills/total-recall/plugins/automations/BRICK.md +7 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/LICENSE +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/README.md +66 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/adapters.mjs +231 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/capability/index.mjs +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/cli.mjs +121 -0
- package/{src/core/plugin-cron.mjs → scaffold/.agent/skills/total-recall/plugins/automations/cron.mjs} +1 -3
- package/scaffold/.agent/skills/total-recall/plugins/automations/inventory.mjs +88 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/package-lock.json +7661 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/package.json +35 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/plugin.json +167 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/scheduler.mjs +246 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/DESIGN.md +42 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/automations.js +2 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/card.js +273 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/commands/run-core.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/check.mjs +57 -5
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/report-data.mjs +40 -14
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/report.mjs +15 -40
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/git/README.md +112 -0
- package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/cli.mjs +135 -23
- package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/git/plugin.json +161 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/context.mjs +94 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/phase3-spec-support.mjs +50 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/runtime.mjs +40 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/spec-support.mjs +51 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/_support.mjs +195 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/auth.mjs +201 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/bisect.mjs +40 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/cli-meta.mjs +159 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit-memory.mjs +30 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit.mjs +46 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/fleet.mjs +156 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/force-push.mjs +58 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/group.mjs +119 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/handoff.mjs +59 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/message.mjs +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/resolve.mjs +60 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/rules.mjs +81 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/secret-firewall.mjs +66 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/undo.mjs +132 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/why.mjs +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/ui/card.js +2 -2
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +25 -9
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/BRICK.md +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/index.mjs +18 -6
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +124 -24
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +2 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +147 -14
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/skills/meta-harness/SKILL.md +17 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/adoption.mjs +2 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/alerts.mjs +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/cascade.mjs +92 -18
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/control.mjs +145 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +42 -21
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch-request.mjs +4 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch.mjs +33 -9
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/documentation.mjs +55 -11
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/executor.mjs +26 -4
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/hermes.mjs +29 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/index.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/included-usage.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/jobs.mjs +84 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +3 -12
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/maintenance.mjs +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/mcp-server.mjs +228 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/process-manager.mjs +25 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/reasoning.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/remote-operation.mjs +5 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/review.mjs +34 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/reviews.mjs +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/claude.mjs +319 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/codex.mjs +387 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/result.mjs +67 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/resume.mjs +373 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/run.mjs +223 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session-jobs.mjs +72 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/setup.mjs +6 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/termination.mjs +16 -12
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/threads.mjs +32 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/usage-queue.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/verify-ssss.mjs +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +285 -40
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worktree.mjs +76 -9
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +5 -5
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +47 -18
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh-diagnostics.mjs +44 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +120 -113
- package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/security/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/references/operations.md +1 -1
- package/src/cli/agent.mjs +1 -1
- package/src/cli/command.mjs +41 -2
- package/src/cli/dream.mjs +93 -69
- package/src/cli/harness.mjs +4 -4
- package/src/cli/help.mjs +1 -1
- package/src/cli/init.mjs +0 -25
- package/src/cli/lessons.mjs +51 -0
- package/src/cli/memory-plugin.mjs +1 -1
- package/src/cli/plugin/copies.mjs +64 -14
- package/src/cli/plugin/create.mjs +6 -7
- package/src/cli/plugin/index.mjs +11 -7
- package/src/cli/plugin/install.mjs +10 -15
- package/src/cli/plugin/remove.mjs +1 -1
- package/src/cli/plugin/search.mjs +2 -2
- package/src/cli/preflight.mjs +19 -6
- package/src/cli/proposals.mjs +1 -1
- package/src/cli/recall.mjs +66 -23
- package/src/cli/remember.mjs +3 -14
- package/src/cli/server.mjs +18 -0
- package/src/cli/startup.mjs +1 -0
- package/src/cli/task.mjs +9 -2
- package/src/cli/update.mjs +6 -2
- package/src/core/access-ledger.mjs +78 -0
- package/src/core/agent-manager.mjs +2 -2
- package/src/core/brain-locate.mjs +15 -0
- package/src/core/brain-updates.mjs +31 -11
- package/src/core/claude-hooks.mjs +3 -1
- package/src/core/cleanup-task.mjs +15 -0
- package/src/core/cli-commands.mjs +2 -0
- package/src/core/cli-maintenance.mjs +4 -1
- package/src/core/cli-semantic-index.mjs +23 -3
- package/src/core/context-compiler.mjs +20 -0
- package/src/core/daemon-loop.mjs +39 -62
- package/src/core/default-plugins.mjs +1 -1
- package/src/core/dream.mjs +33 -105
- package/src/core/ensure-dependencies.mjs +148 -0
- package/src/core/fast-recall.mjs +2 -2
- package/src/core/field-evaluation.mjs +23 -0
- package/src/core/gate-mode.mjs +1 -1
- package/src/core/harness-hooks.mjs +14 -2
- package/src/core/lesson-hooks.mjs +74 -0
- package/src/core/lesson-memory.mjs +24 -0
- package/src/core/lesson-sessions.mjs +52 -0
- package/src/core/lessons.mjs +96 -0
- package/src/core/meta-harness.mjs +2 -2
- package/src/core/optimizer.mjs +66 -165
- package/src/core/plugin-contracts/card.mjs +3 -0
- package/src/core/plugin-loader.mjs +12 -3
- package/src/core/plugin-runtime.mjs +40 -1
- package/src/core/plugin-store.mjs +35 -23
- package/src/core/post-mortem.mjs +52 -36
- package/src/core/preflight-gate.mjs +23 -2
- package/src/core/proposal-applier.mjs +31 -2
- package/src/core/repo-sync.mjs +4 -6
- package/src/core/required-plugins.mjs +26 -4
- package/src/core/rule-length.mjs +23 -0
- package/src/core/runtime.mjs +1 -1
- package/src/core/scheduler.mjs +35 -43
- package/src/core/schema.mjs +1 -2
- package/src/core/search.mjs +4 -3
- package/src/core/server-service.mjs +148 -0
- package/src/core/session-watcher.mjs +19 -1
- package/src/core/skill-gap.mjs +16 -0
- package/src/core/ssss-kernel-bridge.mjs +32 -4
- package/src/core/startup-health.mjs +6 -1
- package/src/core/surface.mjs +65 -54
- package/src/core/task-executors.mjs +54 -106
- package/src/core/validated-write.mjs +1 -0
- package/src/core/vector-field.mjs +134 -192
- package/src/server/invoke-core-child.mjs +24 -0
- package/src/server/invoke-core-operations.mjs +102 -0
- package/src/server/route-manifest.json +0 -56
- package/src/server/routes/brains.mjs +0 -18
- package/src/server/routes/context.mjs +0 -41
- package/src/server/routes/invoke.mjs +26 -1
- package/src/server/routes/ssss.mjs +0 -169
- package/src/server/routes/system.mjs +0 -15
- package/src/server/routes/tasks.mjs +0 -26
- package/src/server/routes/vault.mjs +2 -23
- package/frontend/dist/assets/index-DD4qONvH.js +0 -5607
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/README.md +0 -53
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/plugin.json +0 -129
- package/src/core/append-log.mjs +0 -131
- package/src/core/plugin-tasks.mjs +0 -173
- package/templates/onboarding-interview.md +0 -82
- /package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/LICENSE +0 -0
- /package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/ui/DESIGN.md +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** Continue a stored job on its branch, without reusing a deleted checkout. */
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
import { execFile } from 'node:child_process';
|
|
6
|
+
import { promisify } from 'node:util';
|
|
7
|
+
import { configDir } from './paths.mjs';
|
|
8
|
+
import { resolveJob } from './jobs.mjs';
|
|
9
|
+
import { appendCommand, jobPaths } from './control.mjs';
|
|
10
|
+
import { createWorktree, removeWorktree, commitAll, isDirty, provideDependencies } from './worktree.mjs';
|
|
11
|
+
import { dispatchWithReceipt } from './dispatch.mjs';
|
|
12
|
+
|
|
13
|
+
export async function continueJob(target, text, { fork = false, atTurn, dispatchFn, execFileFn = promisify(execFile), timeoutMs = 30000 } = {}) {
|
|
14
|
+
const job = resolveJob(target);
|
|
15
|
+
if (!fork && !job.result) throw new Error('Resume requires a finished job; use reply for a running job.');
|
|
16
|
+
if (typeof text !== 'string' || !text.trim()) throw new Error('A continuation message is required.');
|
|
17
|
+
const owner = job.result?.execution?.node || job.record?.node;
|
|
18
|
+
if (owner && owner !== 'local') {
|
|
19
|
+
const quote = value => `'${String(value).replaceAll("'", "'\\''")}'`;
|
|
20
|
+
const argv = [fork ? 'fork' : 'resume', job.result?.execution?.remoteJob || job.record?.remoteJob || job.id, ...(fork ? atTurn ? ['--at', atTurn] : [] : [text]), '--json'];
|
|
21
|
+
const report = await execFileFn(process.env.TOTAL_RECALL_BIN || 'total-recall', ['mesh', 'exec', owner,
|
|
22
|
+
`total-recall meta-harness ${argv.map(quote).join(' ')}`], { encoding: 'utf8', timeout: 600000 });
|
|
23
|
+
return JSON.parse(report.stdout);
|
|
24
|
+
}
|
|
25
|
+
const attempt = job.result?.attempts?.at(-1) || job.result;
|
|
26
|
+
const file = attempt?.progressFile || job.result?.progressFile || path.join(configDir(), 'jobs', `${job.id}.events.jsonl`);
|
|
27
|
+
let saved, status;
|
|
28
|
+
try {
|
|
29
|
+
saved = JSON.parse(fs.readFileSync(file.replace('.events.jsonl', '.session.json'), 'utf8'));
|
|
30
|
+
status = JSON.parse(fs.readFileSync(file.replace('.events.jsonl', '.status.json'), 'utf8'));
|
|
31
|
+
} catch { throw new Error('This job has no stored session.'); }
|
|
32
|
+
let sessionId = attempt?.sessionId || status.session_id;
|
|
33
|
+
if (!sessionId) throw new Error('This job has no resumable session ID.');
|
|
34
|
+
if (fork && !job.result) {
|
|
35
|
+
const delivery = await appendCommand(job.id, { type: 'fork', atTurn });
|
|
36
|
+
const deadline = Date.now() + timeoutMs;
|
|
37
|
+
let event;
|
|
38
|
+
while (!event && Date.now() < deadline) {
|
|
39
|
+
const rows = fs.readFileSync(jobPaths(job.id).events, 'utf8').trim().split('\n').filter(Boolean).map(JSON.parse);
|
|
40
|
+
const ack = rows.find(row => row.commandId === delivery.command.id && row.kind === 'ack');
|
|
41
|
+
if (ack?.ok === false) throw new Error(ack.text);
|
|
42
|
+
event = rows.find(row => row.commandId === delivery.command.id && row.kind === 'fork');
|
|
43
|
+
if (!event) await new Promise(resolve => setTimeout(resolve, 20));
|
|
44
|
+
}
|
|
45
|
+
if (!event?.sessionId) throw new Error('Fork did not return a session ID before the timeout.');
|
|
46
|
+
sessionId = event.sessionId;
|
|
47
|
+
}
|
|
48
|
+
const parentBranch = attempt?.branch || job.result?.branch || saved.branch;
|
|
49
|
+
if (!fork && (!parentBranch || !parentBranch.startsWith('meta-harness/'))) {
|
|
50
|
+
// A dispatch job worked in its own folder and has no job branch: resume it there, as it ran (A-123).
|
|
51
|
+
if (!saved.workspace) throw new Error('This job has no saved job branch or workspace.');
|
|
52
|
+
const result = await dispatchWithReceipt({ ...saved.request, sessionId, cwd: saved.workspace, contextCwd: saved.workspace,
|
|
53
|
+
contextTask: text, prompt: text, permissions: saved.request?.permissions || { read: true, write: true } },
|
|
54
|
+
{ dispatchFn, role: 'Resume' });
|
|
55
|
+
return { ...result, parentJob: job.id, workspace: saved.workspace };
|
|
56
|
+
}
|
|
57
|
+
const branch = fork ? `meta-harness/fork-${randomUUID()}` : parentBranch;
|
|
58
|
+
const cwd = saved.workspace;
|
|
59
|
+
const directory = createWorktree(cwd, { branch, existingBranch: !fork, ref: parentBranch || 'HEAD' });
|
|
60
|
+
let result, keep = false;
|
|
61
|
+
try {
|
|
62
|
+
provideDependencies(cwd, directory);
|
|
63
|
+
result = await dispatchWithReceipt({ ...saved.request, sessionId, forkSession: fork && Boolean(job.result), atTurn,
|
|
64
|
+
cwd: directory, contextCwd: cwd, contextTask: text, prompt: text, isolated: true,
|
|
65
|
+
permissions: { read: true, write: true } }, { dispatchFn, role: fork ? 'Fork' : 'Resume' });
|
|
66
|
+
const commit = commitAll(directory, `meta-harness: ${fork ? 'fork' : 'resume'} ${job.id}`);
|
|
67
|
+
return { ...result, parentJob: job.id, branch, ...(commit ? result.ok ? { commit } : { wip: commit } : {}) };
|
|
68
|
+
} catch (error) {
|
|
69
|
+
keep = isDirty(directory);
|
|
70
|
+
return { ok: false, error: error.message, branch, ...(keep ? { keptWorktree: directory } : {}) };
|
|
71
|
+
} finally { if (!keep) removeWorktree(cwd, directory); }
|
|
72
|
+
}
|
|
@@ -26,10 +26,13 @@ export async function setupIntegrations({ node, cwd = process.cwd(), env = proce
|
|
|
26
26
|
const target=mesh.findMeshNode(node);
|
|
27
27
|
if(!target)throw new Error('Maintenance node is not recorded in the mesh');
|
|
28
28
|
const plugin=getPlugin('meta-harness',cwd) || getPlugin('cli-agents',cwd);
|
|
29
|
-
if(!plugin?.valid)throw new Error('
|
|
30
|
-
await ensurePluginRecord(plugin);
|
|
29
|
+
if(!plugin?.valid)throw new Error('Metaharness (cli-agents) is not installed in the selected workspace');
|
|
30
|
+
const record=await ensurePluginRecord(plugin);
|
|
31
31
|
placement=target.hostname;
|
|
32
|
-
|
|
32
|
+
const manifest=JSON.parse(fs.readFileSync(new URL('../plugin.json',import.meta.url),'utf8'));
|
|
33
|
+
const taskNodes={...(record?.task_nodes || {})};
|
|
34
|
+
for(const task of manifest.tasks.filter(task=>task.placement==='selected-node'))taskNodes[task.command]=placement;
|
|
35
|
+
await patchPluginRecord(plugin,{task_nodes:taskNodes});
|
|
33
36
|
}
|
|
34
37
|
return {ok:true,connected,universalInstructions:'AGENTS.md; every dispatch also receives a freshly generated bootstrap',maintenanceNode:placement};
|
|
35
38
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
import {
|
|
1
|
+
/** Stop agents first. Let the operation save its work and return before the process exits. */
|
|
2
|
+
import { cancelExecution, cancellationResult } from './worker.mjs';
|
|
3
3
|
import { removeActiveWorktrees } from './worktree.mjs';
|
|
4
4
|
import { failOpenThreads } from './coordinator.mjs';
|
|
5
5
|
|
|
@@ -9,16 +9,20 @@ let installed = false;
|
|
|
9
9
|
export function stopOnTermination({ graceMs = 500 } = {}) {
|
|
10
10
|
if (installed) return;
|
|
11
11
|
installed = true;
|
|
12
|
-
let stopping = false;
|
|
13
12
|
for (const [signal, code] of Object.entries(SIGNALS)) process.on(signal, () => {
|
|
14
|
-
if (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
setTimeout(() => {
|
|
18
|
-
stopActiveProcesses('SIGKILL');
|
|
19
|
-
removeActiveWorktrees();
|
|
20
|
-
failOpenThreads();
|
|
21
|
-
process.exit(code);
|
|
22
|
-
}, graceMs);
|
|
13
|
+
if (cancellationResult()) return;
|
|
14
|
+
cancelExecution(signal, graceMs);
|
|
15
|
+
process.exitCode = code;
|
|
23
16
|
});
|
|
17
|
+
// Also cover callers that use the lifecycle helper without the CLI wrapper.
|
|
18
|
+
process.once('beforeExit', () => { if (cancellationResult()) finishCancellation(); });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function finishCancellation(result) {
|
|
22
|
+
const cancelled = cancellationResult();
|
|
23
|
+
if (!cancelled) return result;
|
|
24
|
+
const saved = removeActiveWorktrees({ preserveChanges: true });
|
|
25
|
+
failOpenThreads('The run was cancelled.');
|
|
26
|
+
process.exitCode = cancelled.exitCode;
|
|
27
|
+
return { ...result, ...cancelled, ...(saved.length ? { saved } : {}) };
|
|
24
28
|
}
|
|
@@ -48,7 +48,7 @@ function mutate(work) {
|
|
|
48
48
|
for (let attempt = 0; attempt < 8; attempt += 1) {
|
|
49
49
|
const store = storeForThreads();
|
|
50
50
|
const state = readState(store);
|
|
51
|
-
const result = work(state.threads);
|
|
51
|
+
const result = work(state.threads, state);
|
|
52
52
|
validateThreads(state.threads);
|
|
53
53
|
try {
|
|
54
54
|
store.write({ ...state, version: '2.0.0', updatedAt: new Date().toISOString(), threads: state.threads });
|
|
@@ -117,3 +117,34 @@ export function deleteThread(id) {
|
|
|
117
117
|
return true;
|
|
118
118
|
});
|
|
119
119
|
}
|
|
120
|
+
|
|
121
|
+
// Exact titles from test/threads.test.mjs and test/coordinator.test.mjs.
|
|
122
|
+
// Real multiply-job threads do not match, including failed end-to-end attempts.
|
|
123
|
+
const FIXTURE_TITLES = new Set([
|
|
124
|
+
'Implement Multi-Platform Threads', 'Canonical state', 'concurrent',
|
|
125
|
+
'Implement token bucket', 'task one', 'task two', 'task three', 'task four', 'failed verification',
|
|
126
|
+
]);
|
|
127
|
+
const CLEANUP_ID = 'a118-fixture-threads-v1';
|
|
128
|
+
|
|
129
|
+
/** Delete the known fixture titles once. The same SSSS operation records every removal. */
|
|
130
|
+
export function cleanupFixtureThreads({ dryRun = false } = {}) {
|
|
131
|
+
const plan = (threads, state) => {
|
|
132
|
+
const previous = state.cleanups?.find(row => row.id === CLEANUP_ID);
|
|
133
|
+
if (previous) return { ok: true, alreadyApplied: true, record: previous };
|
|
134
|
+
const removed = threads.filter(thread => FIXTURE_TITLES.has(thread.title))
|
|
135
|
+
.map(({ id, title, status }) => ({ id, title, status }));
|
|
136
|
+
const kept = threads.filter(thread => !FIXTURE_TITLES.has(thread.title)).map(thread => thread.id);
|
|
137
|
+
return { ok: true, record: { id: CLEANUP_ID, timestamp: new Date().toISOString(), sources: ['test/threads.test.mjs', 'test/coordinator.test.mjs'], removed, kept } };
|
|
138
|
+
};
|
|
139
|
+
const state = readState(storeForThreads());
|
|
140
|
+
const preview = plan(state.threads, state);
|
|
141
|
+
if (dryRun || preview.alreadyApplied) return { ...preview, dryRun };
|
|
142
|
+
return mutate((threads, current) => {
|
|
143
|
+
const result = plan(threads, current);
|
|
144
|
+
if (result.alreadyApplied) return result;
|
|
145
|
+
const ids = new Set(result.record.removed.map(row => row.id));
|
|
146
|
+
threads.splice(0, threads.length, ...threads.filter(thread => !ids.has(thread.id)));
|
|
147
|
+
current.cleanups = [...(current.cleanups || []), result.record];
|
|
148
|
+
return result;
|
|
149
|
+
});
|
|
150
|
+
}
|
|
@@ -90,7 +90,7 @@ export async function retryIncludedJob(id, { dispatch, route, now = Date.now() }
|
|
|
90
90
|
result = await dispatch(claimed.replay.request, { role: 'Dispatch', retryId: id });
|
|
91
91
|
} else if (claimed.replay.kind === 'route') {
|
|
92
92
|
route ??= (await import('./cascade.mjs')).executeRoutedTask;
|
|
93
|
-
result = await route(claimed.task, { cwd: claimed.workspace, gate: claimed.replay.gate, gateOptions: claimed.replay.gateOptions,
|
|
93
|
+
result = await route(claimed.task, { ...claimed.replay.controls, cwd: claimed.workspace, gate: claimed.replay.gate, gateOptions: claimed.replay.gateOptions,
|
|
94
94
|
route: { selected: claimed.agent }, pool: [claimed.agent], retryId: id });
|
|
95
95
|
} else throw new Error('Unknown included usage job operation.');
|
|
96
96
|
} catch (error) {
|
|
@@ -47,8 +47,8 @@ async function verifyEvents(documentPath, primitive, expectedCount) {
|
|
|
47
47
|
async function verifyTarget(targetArgument) {
|
|
48
48
|
const target = fs.realpathSync(path.resolve(targetArgument));
|
|
49
49
|
const readJson = file => JSON.parse(fs.readFileSync(readTargetFile(target, file), 'utf8'));
|
|
50
|
-
assert.equal(readJson('package.json').name, 'tr-plugin-meta-harness', 'Select a
|
|
51
|
-
assert.equal(readJson('plugin.json').id, owner, 'The target must own
|
|
50
|
+
assert.equal(readJson('package.json').name, 'tr-plugin-meta-harness', 'Select a Metaharness checkout');
|
|
51
|
+
assert.equal(readJson('plugin.json').id, owner, 'The target must own Metaharness state');
|
|
52
52
|
|
|
53
53
|
const scratch = fs.mkdtempSync(path.join(os.tmpdir(), 'meta-harness-ssss-gate-'));
|
|
54
54
|
const previousBrain = process.env.TR_SECRETS_BRAIN;
|
|
@@ -94,7 +94,7 @@ async function verifyTarget(targetArgument) {
|
|
|
94
94
|
|
|
95
95
|
try {
|
|
96
96
|
const [flag, target, ...rest] = process.argv.slice(2);
|
|
97
|
-
if (flag !== '--target' || !target || rest.length) throw new Error('Supply an explicit
|
|
97
|
+
if (flag !== '--target' || !target || rest.length) throw new Error('Supply an explicit Metaharness checkout with --target <directory>');
|
|
98
98
|
process.stdout.write(`${JSON.stringify(await verifyTarget(target))}\n`);
|
|
99
99
|
} catch (error) {
|
|
100
100
|
process.stdout.write(`${JSON.stringify({ ok: false, error: error.message })}\n`);
|