Inject TORCH tools into runtime launches

This commit is contained in:
thePR0M3TH3AN committed 2026-09-27 19:00:20 -04:00
1 parent 3efdbd258f
commit bcbe2fc319
8 files changed
+91 -24

No files matched your search

+14 -3
View File
@@ -28,6 +28,16 @@ function commandRecord(command, args, cwd) {
return { command, args, cwd, mutatesRuntime: true };
}
function mcpArgs(mcp) {
if (!mcp) return [];
if (typeof mcp.name !== 'string' || typeof mcp.command !== 'string' || !Array.isArray(mcp.args)) {
throw new TorchError('Claude MCP launch configuration is invalid', { code: 'INVALID_RUNTIME_INPUT' });
}
return ['--mcp-config', JSON.stringify({
mcpServers: { [mcp.name]: { command: mcp.command, args: mcp.args } },
})];
}
function mcpName(areaId) {
return `torch-${areaId.toLowerCase().replace(/[^a-z0-9_-]+/g, '-').replace(/^-|-$/g, '')}`;
}
@@ -85,7 +95,7 @@ export class ClaudeRuntimeAdapter {
};
}
createSession({ areaId, title, worktree, promptFile, firstMessage, model = 'opus', background = true } = {}) {
createSession({ areaId, title, worktree, promptFile, firstMessage, model = 'opus', background = true, mcp } = {}) {
const runtimeSessionId = this.idFactory();
const args = [];
if (background) args.push('--bg');
@@ -94,6 +104,7 @@ export class ClaudeRuntimeAdapter {
'--session-id', runtimeSessionId,
'-n', `TORCH · ${text(title ?? areaId, 'title')}`,
'--append-system-prompt-file', text(promptFile, 'promptFile'),
...mcpArgs(mcp),
);
if (firstMessage) args.push(text(firstMessage, 'firstMessage'));
return {
@@ -102,10 +113,10 @@ export class ClaudeRuntimeAdapter {
};
}
resumeSession({ areaId, runtimeSessionId, worktree, model = 'opus', message, background = true } = {}) {
resumeSession({ areaId, runtimeSessionId, worktree, model = 'opus', message, background = true, mcp } = {}) {
const args = [];
if (background) args.push('--bg');
args.push('--model', text(model, 'model'), '--resume', text(runtimeSessionId, 'runtimeSessionId'));
args.push('--model', text(model, 'model'), ...mcpArgs(mcp), '--resume', text(runtimeSessionId, 'runtimeSessionId'));
if (message) args.push(text(message, 'message'));
return {
adapter: this.name, areaId: text(areaId, 'areaId'), runtimeSessionId,
+19 -5
View File
@@ -31,6 +31,18 @@ function commandRecord(command, args, cwd) {
return { command, args, cwd, mutatesRuntime: true };
}
function mcpArgs(mcp) {
if (!mcp) return [];
if (typeof mcp.name !== 'string' || !/^[a-z0-9_-]+$/.test(mcp.name)
|| typeof mcp.command !== 'string' || !Array.isArray(mcp.args)) {
throw new TorchError('Codex MCP launch configuration is invalid', { code: 'INVALID_RUNTIME_INPUT' });
}
return [
'-c', `mcp_servers.${mcp.name}.command=${JSON.stringify(mcp.command)}`,
'-c', `mcp_servers.${mcp.name}.args=${JSON.stringify(mcp.args)}`,
];
}
function mcpName(areaId) {
return `torch-${areaId.toLowerCase().replace(/[^a-z0-9_-]+/g, '-').replace(/^-|-$/g, '')}`;
}
@@ -89,19 +101,20 @@ export class CodexRuntimeAdapter {
mutationPerformed: false,
mcp: {
name: mcpName(id),
command: this.executable,
args: ['mcp', 'add', mcpName(id), '--', this.nodeExecutable, entry, '--root', root, '--area', id],
command: this.nodeExecutable,
args: [entry, '--root', root, '--area', id],
cwd: root,
},
note: 'Apply this identity-bound MCP registration only through an owner-approved Codex configuration change.',
note: 'Pass this identity-bound MCP server as an invocation-scoped Codex configuration.',
};
}
createSession({ areaId, worktree, promptFile, firstMessage, model } = {}) {
createSession({ areaId, worktree, promptFile, firstMessage, model, mcp } = {}) {
const id = text(areaId, 'areaId');
const cwd = text(worktree, 'worktree');
const args = [
'exec', '--json', '--cd', cwd, '--sandbox', 'workspace-write', '--approve-for-me',
...mcpArgs(mcp),
...optionalModelArgs(model),
`${text(firstMessage, 'firstMessage')}\n\nRead and follow the TORCH domain prompt at ${text(promptFile, 'promptFile')}.`,
];
@@ -115,12 +128,13 @@ export class CodexRuntimeAdapter {
};
}
resumeSession({ areaId, runtimeSessionId, worktree, message, model } = {}) {
resumeSession({ areaId, runtimeSessionId, worktree, message, model, mcp } = {}) {
const id = text(areaId, 'areaId');
const sessionId = text(runtimeSessionId, 'runtimeSessionId');
const cwd = text(worktree, 'worktree');
const args = [
'exec', '--json', '--cd', cwd, '--sandbox', 'workspace-write', '--approve-for-me',
...mcpArgs(mcp),
...optionalModelArgs(model), 'resume', sessionId, text(message, 'message'),
];
return {
+30 -6
View File
@@ -1,11 +1,14 @@
import { execFileSync } from 'node:child_process';
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { TorchError } from '../kernel/errors.mjs';
import { readInstallManifest } from '../kernel/install.mjs';
import { loadFleetDefinition } from '../kernel/worktrees.mjs';
import { validateRuntimeAdapter } from '../adapters/runtime.mjs';
const MCP_ENTRY = fileURLToPath(new URL('../mcp/server.mjs', import.meta.url));
function localStateRoot(manifest) {
const record = (manifest.external ?? []).find((entry) => entry.type === 'local-state');
if (!record?.path) throw new TorchError('Installation manifest has no local state root', { code: 'LOCAL_STATE_MISSING' });
@@ -140,6 +143,15 @@ export function planFleetUp({ repositoryRoot, controlPlane, adapter, adapters, f
}
validateRuntimeAdapter(runtimeAdapter);
const identity = controlPlane.identity(area.id);
const runtimeIntegration = runtimeAdapter.configure({
repositoryRoot, areaId: area.id, mcpEntry: MCP_ENTRY,
});
if (runtimeIntegration?.mutationPerformed !== false || !runtimeIntegration?.mcp) {
blockers.push({
areaId: area.id, code: 'RUNTIME_CONFIGURATION_INVALID', runtime,
});
continue;
}
const prompts = promptPaths(stateRoot, worktree, area.id);
const runtimeConfig = config.runtimes?.[runtime] ?? {};
const model = area.model ?? runtimeConfig.model;
@@ -148,11 +160,11 @@ export function planFleetUp({ repositoryRoot, controlPlane, adapter, adapters, f
const runtimePlan = shouldResume
? runtimeAdapter.resumeSession({
areaId: area.id, runtimeSessionId: identity.runtimeSessionId, worktree: worktree.path,
model, background, message: startupMessage(area.id, false),
model, background, message: startupMessage(area.id, false), mcp: runtimeIntegration.mcp,
})
: runtimeAdapter.createSession({
areaId: area.id, title: area.title, worktree: worktree.path, promptFile: prompts.combined,
firstMessage: startupMessage(area.id, true), model, background,
firstMessage: startupMessage(area.id, true), model, background, mcp: runtimeIntegration.mcp,
});
actions.push({
areaId: area.id, title: area.title, mode: shouldResume ? 'resume' : 'create',
@@ -160,7 +172,8 @@ export function planFleetUp({ repositoryRoot, controlPlane, adapter, adapters, f
requiresRuntimeIdCapture: runtimePlan.requiresRuntimeIdCapture ?? false,
completionState: runtimePlan.completionState ?? 'starting',
worktree: worktree.path, branch: worktree.branch, promptFile: prompts.combined,
promptSources: [prompts.common, prompts.area], launch: runtimePlan.launch,
promptSources: [prompts.common, prompts.area], mcp: runtimeIntegration.mcp,
launch: runtimePlan.launch,
});
}
@@ -200,6 +213,16 @@ export function planAreaUp({ repositoryRoot, controlPlane, areaId, adapter, adap
}
validateRuntimeAdapter(runtimeAdapter);
const identity = controlPlane.identity(area.id);
const runtimeIntegration = runtimeAdapter.configure({
repositoryRoot, areaId: area.id, mcpEntry: MCP_ENTRY,
});
if (runtimeIntegration?.mutationPerformed !== false || !runtimeIntegration?.mcp) {
return {
action: 'area-up', projectId: manifest.projectId, areaId, fresh,
actions: [], blockers: [{ areaId, code: 'RUNTIME_CONFIGURATION_INVALID', runtime }],
canProceed: false, mutationPerformed: false,
};
}
const prompts = promptPaths(localStateRoot(manifest), worktree, area.id);
const runtimeConfig = config.runtimes?.[runtime] ?? {};
const model = area.model ?? runtimeConfig.model;
@@ -208,11 +231,11 @@ export function planAreaUp({ repositoryRoot, controlPlane, areaId, adapter, adap
const runtimePlan = shouldResume
? runtimeAdapter.resumeSession({
areaId: area.id, runtimeSessionId: identity.runtimeSessionId, worktree: worktree.path,
model, background, message: startupMessage(area.id, false),
model, background, message: startupMessage(area.id, false), mcp: runtimeIntegration.mcp,
})
: runtimeAdapter.createSession({
areaId: area.id, title: area.title, worktree: worktree.path, promptFile: prompts.combined,
firstMessage: startupMessage(area.id, true), model, background,
firstMessage: startupMessage(area.id, true), model, background, mcp: runtimeIntegration.mcp,
});
const action = {
areaId: area.id, title: area.title, mode: shouldResume ? 'resume' : 'create',
@@ -220,7 +243,8 @@ export function planAreaUp({ repositoryRoot, controlPlane, areaId, adapter, adap
requiresRuntimeIdCapture: runtimePlan.requiresRuntimeIdCapture ?? false,
completionState: runtimePlan.completionState ?? 'starting',
worktree: worktree.path, branch: worktree.branch, promptFile: prompts.combined,
promptSources: [prompts.common, prompts.area], launch: runtimePlan.launch,
promptSources: [prompts.common, prompts.area], mcp: runtimeIntegration.mcp,
launch: runtimePlan.launch,
};
return {
action: 'area-up', projectId: manifest.projectId, areaId, fresh,