contextos-mcp 0.4.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/LICENSE +21 -0
- package/README.md +260 -0
- package/bin/mcp.mjs +61 -0
- package/bin/swarm.mjs +45 -0
- package/dist/agents/aider.d.ts +12 -0
- package/dist/agents/aider.js +192 -0
- package/dist/agents/aider.js.map +1 -0
- package/dist/agents/claude-code.d.ts +9 -0
- package/dist/agents/claude-code.js +236 -0
- package/dist/agents/claude-code.js.map +1 -0
- package/dist/agents/codex.d.ts +14 -0
- package/dist/agents/codex.js +203 -0
- package/dist/agents/codex.js.map +1 -0
- package/dist/agents/direct-llm.d.ts +22 -0
- package/dist/agents/direct-llm.js +254 -0
- package/dist/agents/direct-llm.js.map +1 -0
- package/dist/agents/mock.d.ts +10 -0
- package/dist/agents/mock.js +170 -0
- package/dist/agents/mock.js.map +1 -0
- package/dist/agents/opencode.d.ts +23 -0
- package/dist/agents/opencode.js +631 -0
- package/dist/agents/opencode.js.map +1 -0
- package/dist/agents/provider.d.ts +11 -0
- package/dist/agents/provider.js +31 -0
- package/dist/agents/provider.js.map +1 -0
- package/dist/compression/compressor.d.ts +28 -0
- package/dist/compression/compressor.js +268 -0
- package/dist/compression/compressor.js.map +1 -0
- package/dist/config.d.ts +43 -0
- package/dist/config.js +172 -0
- package/dist/config.js.map +1 -0
- package/dist/contextos/loader.d.ts +46 -0
- package/dist/contextos/loader.js +120 -0
- package/dist/contextos/loader.js.map +1 -0
- package/dist/contextos/selector.d.ts +46 -0
- package/dist/contextos/selector.js +80 -0
- package/dist/contextos/selector.js.map +1 -0
- package/dist/core/action-dispatcher.d.ts +15 -0
- package/dist/core/action-dispatcher.js +28 -0
- package/dist/core/action-dispatcher.js.map +1 -0
- package/dist/core/action-schema.d.ts +72 -0
- package/dist/core/action-schema.js +86 -0
- package/dist/core/action-schema.js.map +1 -0
- package/dist/core/repl-interface.d.ts +48 -0
- package/dist/core/repl-interface.js +5 -0
- package/dist/core/repl-interface.js.map +1 -0
- package/dist/core/repl.d.ts +59 -0
- package/dist/core/repl.js +353 -0
- package/dist/core/repl.js.map +1 -0
- package/dist/core/rlm.d.ts +65 -0
- package/dist/core/rlm.js +564 -0
- package/dist/core/rlm.js.map +1 -0
- package/dist/core/runtime.py +470 -0
- package/dist/core/types.d.ts +265 -0
- package/dist/core/types.js +19 -0
- package/dist/core/types.js.map +1 -0
- package/dist/env.d.ts +10 -0
- package/dist/env.js +75 -0
- package/dist/env.js.map +1 -0
- package/dist/hooks/runner.d.ts +43 -0
- package/dist/hooks/runner.js +173 -0
- package/dist/hooks/runner.js.map +1 -0
- package/dist/labs/cli.d.ts +15 -0
- package/dist/labs/cli.js +295 -0
- package/dist/labs/cli.js.map +1 -0
- package/dist/labs/episodic-memory.d.ts +132 -0
- package/dist/labs/episodic-memory.js +391 -0
- package/dist/labs/episodic-memory.js.map +1 -0
- package/dist/labs/interactive-swarm.d.ts +20 -0
- package/dist/labs/interactive-swarm.js +1173 -0
- package/dist/labs/interactive-swarm.js.map +1 -0
- package/dist/labs/interactive.d.ts +10 -0
- package/dist/labs/interactive.js +2099 -0
- package/dist/labs/interactive.js.map +1 -0
- package/dist/labs/ts-analyzer.d.ts +74 -0
- package/dist/labs/ts-analyzer.js +379 -0
- package/dist/labs/ts-analyzer.js.map +1 -0
- package/dist/labs/viewer.d.ts +12 -0
- package/dist/labs/viewer.js +1284 -0
- package/dist/labs/viewer.js.map +1 -0
- package/dist/main.d.ts +15 -0
- package/dist/main.js +247 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp/server.d.ts +16 -0
- package/dist/mcp/server.js +192775 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/session.d.ts +117 -0
- package/dist/mcp/session.js +450 -0
- package/dist/mcp/session.js.map +1 -0
- package/dist/mcp/state.d.ts +42 -0
- package/dist/mcp/state.js +537 -0
- package/dist/mcp/state.js.map +1 -0
- package/dist/mcp/tools/contextos.d.ts +17 -0
- package/dist/mcp/tools/contextos.js +583 -0
- package/dist/mcp/tools/contextos.js.map +1 -0
- package/dist/mcp/tools.d.ts +15 -0
- package/dist/mcp/tools.js +393 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/orchestration/reviewer-gate.d.ts +43 -0
- package/dist/orchestration/reviewer-gate.js +280 -0
- package/dist/orchestration/reviewer-gate.js.map +1 -0
- package/dist/orchestration/reviewer-prompt.d.ts +18 -0
- package/dist/orchestration/reviewer-prompt.js +67 -0
- package/dist/orchestration/reviewer-prompt.js.map +1 -0
- package/dist/orchestration/verification-runner.d.ts +53 -0
- package/dist/orchestration/verification-runner.js +352 -0
- package/dist/orchestration/verification-runner.js.map +1 -0
- package/dist/plugins/adapter.d.ts +11 -0
- package/dist/plugins/adapter.js +11 -0
- package/dist/plugins/adapter.js.map +1 -0
- package/dist/plugins/core/archive.d.ts +9 -0
- package/dist/plugins/core/archive.js +128 -0
- package/dist/plugins/core/archive.js.map +1 -0
- package/dist/plugins/core/digest.d.ts +11 -0
- package/dist/plugins/core/digest.js +70 -0
- package/dist/plugins/core/digest.js.map +1 -0
- package/dist/plugins/core/grants.d.ts +22 -0
- package/dist/plugins/core/grants.js +90 -0
- package/dist/plugins/core/grants.js.map +1 -0
- package/dist/plugins/core/index.d.ts +10 -0
- package/dist/plugins/core/index.js +11 -0
- package/dist/plugins/core/index.js.map +1 -0
- package/dist/plugins/core/pinning.d.ts +15 -0
- package/dist/plugins/core/pinning.js +86 -0
- package/dist/plugins/core/pinning.js.map +1 -0
- package/dist/plugins/core/types.d.ts +105 -0
- package/dist/plugins/core/types.js +22 -0
- package/dist/plugins/core/types.js.map +1 -0
- package/dist/plugins/core/updater.d.ts +16 -0
- package/dist/plugins/core/updater.js +64 -0
- package/dist/plugins/core/updater.js.map +1 -0
- package/dist/plugins/loader.d.ts +65 -0
- package/dist/plugins/loader.js +110 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/prompts/orchestrator.d.ts +6 -0
- package/dist/prompts/orchestrator.js +114 -0
- package/dist/prompts/orchestrator.js.map +1 -0
- package/dist/routing/model-resolver.d.ts +27 -0
- package/dist/routing/model-resolver.js +265 -0
- package/dist/routing/model-resolver.js.map +1 -0
- package/dist/routing/model-router.d.ts +130 -0
- package/dist/routing/model-router.js +515 -0
- package/dist/routing/model-router.js.map +1 -0
- package/dist/runtime/attestations.cjs +260 -0
- package/dist/runtime/reviewer-pipeline.cjs +319 -0
- package/dist/runtime/sandbox.cjs +468 -0
- package/dist/runtime/state-machine.cjs +885 -0
- package/dist/runtime/thread-store.cjs +175 -0
- package/dist/runtime/transactional-git.cjs +315 -0
- package/dist/runtime/verification-pipeline.cjs +435 -0
- package/dist/sandbox/execution.d.ts +165 -0
- package/dist/sandbox/execution.js +497 -0
- package/dist/sandbox/execution.js.map +1 -0
- package/dist/security/file-policy.d.ts +22 -0
- package/dist/security/file-policy.js +53 -0
- package/dist/security/file-policy.js.map +1 -0
- package/dist/security/repository-boundary.d.ts +21 -0
- package/dist/security/repository-boundary.js +119 -0
- package/dist/security/repository-boundary.js.map +1 -0
- package/dist/security/secret-filter.d.ts +36 -0
- package/dist/security/secret-filter.js +149 -0
- package/dist/security/secret-filter.js.map +1 -0
- package/dist/swarm.d.ts +14 -0
- package/dist/swarm.js +624 -0
- package/dist/swarm.js.map +1 -0
- package/dist/threads/cache.d.ts +64 -0
- package/dist/threads/cache.js +241 -0
- package/dist/threads/cache.js.map +1 -0
- package/dist/threads/manager.d.ts +94 -0
- package/dist/threads/manager.js +914 -0
- package/dist/threads/manager.js.map +1 -0
- package/dist/ui/banner.d.ts +14 -0
- package/dist/ui/banner.js +42 -0
- package/dist/ui/banner.js.map +1 -0
- package/dist/ui/dashboard.d.ts +33 -0
- package/dist/ui/dashboard.js +135 -0
- package/dist/ui/dashboard.js.map +1 -0
- package/dist/ui/index.d.ts +11 -0
- package/dist/ui/index.js +12 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/log.d.ts +39 -0
- package/dist/ui/log.js +126 -0
- package/dist/ui/log.js.map +1 -0
- package/dist/ui/onboarding.d.ts +14 -0
- package/dist/ui/onboarding.js +755 -0
- package/dist/ui/onboarding.js.map +1 -0
- package/dist/ui/run-log.d.ts +50 -0
- package/dist/ui/run-log.js +60 -0
- package/dist/ui/run-log.js.map +1 -0
- package/dist/ui/spinner.d.ts +41 -0
- package/dist/ui/spinner.js +172 -0
- package/dist/ui/spinner.js.map +1 -0
- package/dist/ui/streaming-feed.d.ts +72 -0
- package/dist/ui/streaming-feed.js +386 -0
- package/dist/ui/streaming-feed.js.map +1 -0
- package/dist/ui/summary.d.ts +18 -0
- package/dist/ui/summary.js +113 -0
- package/dist/ui/summary.js.map +1 -0
- package/dist/ui/text-input.d.ts +19 -0
- package/dist/ui/text-input.js +266 -0
- package/dist/ui/text-input.js.map +1 -0
- package/dist/ui/theme.d.ts +63 -0
- package/dist/ui/theme.js +97 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/utils/command-exists.d.ts +11 -0
- package/dist/utils/command-exists.js +41 -0
- package/dist/utils/command-exists.js.map +1 -0
- package/dist/utils/process-security.d.ts +19 -0
- package/dist/utils/process-security.js +90 -0
- package/dist/utils/process-security.js.map +1 -0
- package/dist/utils/rolling-buffer.d.ts +16 -0
- package/dist/utils/rolling-buffer.js +30 -0
- package/dist/utils/rolling-buffer.js.map +1 -0
- package/dist/utils/safe-spawn.d.ts +13 -0
- package/dist/utils/safe-spawn.js +49 -0
- package/dist/utils/safe-spawn.js.map +1 -0
- package/dist/worktree/manager.d.ts +69 -0
- package/dist/worktree/manager.js +593 -0
- package/dist/worktree/manager.js.map +1 -0
- package/dist/worktree/merge.d.ts +58 -0
- package/dist/worktree/merge.js +389 -0
- package/dist/worktree/merge.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool definitions and handlers for swarm-code.
|
|
3
|
+
*
|
|
4
|
+
* Tools:
|
|
5
|
+
* - swarm_run: Full orchestrated swarm execution (subprocess)
|
|
6
|
+
* - swarm_thread: Spawn a single coding agent thread in a worktree
|
|
7
|
+
* - swarm_status: Get current session status (threads, budget)
|
|
8
|
+
* - swarm_merge: Merge completed thread branches
|
|
9
|
+
* - swarm_cancel: Cancel running thread(s)
|
|
10
|
+
* - swarm_cleanup: Destroy session and worktrees
|
|
11
|
+
*/
|
|
12
|
+
import { execFile } from "node:child_process";
|
|
13
|
+
import { existsSync } from "node:fs";
|
|
14
|
+
import { dirname, join, resolve } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
import { z } from "zod";
|
|
17
|
+
import { assertWithinRepository } from "../security/repository-boundary.js";
|
|
18
|
+
import { redactSecrets } from "../security/secret-filter.js";
|
|
19
|
+
import { cancelThreads, cleanupSession, getBudgetState, getSession, getThreads, mergeThreads, spawnThread, } from "./session.js";
|
|
20
|
+
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
21
|
+
function _textResult(text) {
|
|
22
|
+
return { content: [{ type: "text", text: redactSecrets(text) }] };
|
|
23
|
+
}
|
|
24
|
+
function errorResult(text) {
|
|
25
|
+
return { content: [{ type: "text", text: redactSecrets(text) }], isError: true };
|
|
26
|
+
}
|
|
27
|
+
function jsonResult(data) {
|
|
28
|
+
return { content: [{ type: "text", text: redactSecrets(JSON.stringify(data, null, 2)) }] };
|
|
29
|
+
}
|
|
30
|
+
/** Track active subprocesses so they can be killed on shutdown. */
|
|
31
|
+
const activeSubprocesses = new Set();
|
|
32
|
+
/** Kill all tracked subprocesses. Called during server shutdown. */
|
|
33
|
+
export function killActiveSubprocesses() {
|
|
34
|
+
for (const child of activeSubprocesses) {
|
|
35
|
+
try {
|
|
36
|
+
child.kill("SIGTERM");
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
/* already dead */
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
activeSubprocesses.clear();
|
|
43
|
+
}
|
|
44
|
+
// ── Tool Registration ──────────────────────────────────────────────────────
|
|
45
|
+
export function registerTools(server, defaultDir) {
|
|
46
|
+
// Helper: resolve dir from tool args or default, validate existence
|
|
47
|
+
function resolveDir(dir) {
|
|
48
|
+
const resolved = dir || defaultDir;
|
|
49
|
+
if (!resolved)
|
|
50
|
+
return null;
|
|
51
|
+
const abs = resolve(resolved);
|
|
52
|
+
if (!existsSync(abs))
|
|
53
|
+
return null;
|
|
54
|
+
try {
|
|
55
|
+
if (defaultDir) {
|
|
56
|
+
const realDefault = assertWithinRepository(defaultDir, defaultDir);
|
|
57
|
+
return assertWithinRepository(abs, realDefault);
|
|
58
|
+
}
|
|
59
|
+
return assertWithinRepository(abs, abs);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// ── swarm_run ──────────────────────────────────────────────────────────
|
|
66
|
+
// Full swarm orchestration — runs the entire RLM loop as a subprocess.
|
|
67
|
+
// This is the high-level "do everything" tool.
|
|
68
|
+
server.registerTool("swarm_run", {
|
|
69
|
+
title: "Run Swarm",
|
|
70
|
+
description: "Run the full swarm orchestrator on a repository. Decomposes a task into " +
|
|
71
|
+
"parallel coding agent threads, executes them in isolated git worktrees, " +
|
|
72
|
+
"and merges results. Returns a JSON summary with success status, answer, " +
|
|
73
|
+
"thread stats, and cost breakdown.",
|
|
74
|
+
inputSchema: z.object({
|
|
75
|
+
dir: z.string().optional().describe("Path to the git repository (uses server default if not specified)"),
|
|
76
|
+
task: z.string().describe("The coding task to accomplish (e.g., 'add error handling to all API routes')"),
|
|
77
|
+
agent: z
|
|
78
|
+
.string()
|
|
79
|
+
.optional()
|
|
80
|
+
.describe("Agent backend: opencode (default), claude-code, codex, aider, direct-llm"),
|
|
81
|
+
model: z.string().optional().describe("Orchestrator model override (e.g., claude-sonnet-4-6, gpt-4o)"),
|
|
82
|
+
max_budget: z
|
|
83
|
+
.number()
|
|
84
|
+
.min(0)
|
|
85
|
+
.max(50)
|
|
86
|
+
.optional()
|
|
87
|
+
.describe("Maximum budget in USD (default: 5.00, hard cap: 50.00)"),
|
|
88
|
+
auto_route: z.boolean().optional().describe("Enable auto model/agent routing per thread (default: false)"),
|
|
89
|
+
}),
|
|
90
|
+
}, async (args) => {
|
|
91
|
+
const resolvedDir = resolveDir(args.dir);
|
|
92
|
+
if (!resolvedDir) {
|
|
93
|
+
if (!args.dir && !defaultDir)
|
|
94
|
+
return errorResult("'dir' is required — specify the repo path");
|
|
95
|
+
return errorResult(`Directory does not exist: ${resolve(args.dir || defaultDir || "")}`);
|
|
96
|
+
}
|
|
97
|
+
// Build CLI args
|
|
98
|
+
const cliArgs = ["--dir", resolvedDir, "--json", "--quiet"];
|
|
99
|
+
if (args.agent)
|
|
100
|
+
cliArgs.push("--agent", args.agent);
|
|
101
|
+
if (args.model)
|
|
102
|
+
cliArgs.push("--orchestrator", args.model);
|
|
103
|
+
if (args.max_budget != null)
|
|
104
|
+
cliArgs.push("--max-budget", String(args.max_budget));
|
|
105
|
+
if (args.auto_route)
|
|
106
|
+
cliArgs.push("--auto-route");
|
|
107
|
+
cliArgs.push(args.task);
|
|
108
|
+
// Run swarm as subprocess
|
|
109
|
+
try {
|
|
110
|
+
const result = await runSwarmSubprocess(cliArgs);
|
|
111
|
+
return jsonResult(result);
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
115
|
+
return errorResult(`Swarm execution failed: ${msg}`);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
// ── swarm_thread ──────────────────────────────────────────────────────
|
|
119
|
+
// Spawn a single coding agent thread — the low-level building block.
|
|
120
|
+
// The calling agent (Claude Code, Cursor) can orchestrate multiple threads.
|
|
121
|
+
server.registerTool("swarm_thread", {
|
|
122
|
+
title: "Spawn Thread",
|
|
123
|
+
description: "Spawn a single coding agent in an isolated git worktree. The agent " +
|
|
124
|
+
"executes the task, and the result (files changed, diff, summary) is " +
|
|
125
|
+
"returned. Use this for fine-grained control — call multiple times for " +
|
|
126
|
+
"parallel work, then use swarm_merge to integrate.",
|
|
127
|
+
inputSchema: z.object({
|
|
128
|
+
dir: z.string().optional().describe("Path to the git repository (uses server default if not specified)"),
|
|
129
|
+
task: z.string().describe("Task for the coding agent (e.g., 'fix the auth bug in src/auth.ts')"),
|
|
130
|
+
files: z.array(z.string()).optional().describe("File paths to focus on (hints for the agent)"),
|
|
131
|
+
agent: z
|
|
132
|
+
.string()
|
|
133
|
+
.optional()
|
|
134
|
+
.describe("Agent backend: opencode (default), claude-code, codex, aider, direct-llm"),
|
|
135
|
+
model: z.string().optional().describe("Model override (e.g., anthropic/claude-sonnet-4-6)"),
|
|
136
|
+
context: z.string().optional().describe("Additional context to pass to the agent"),
|
|
137
|
+
}),
|
|
138
|
+
}, async (args) => {
|
|
139
|
+
const dir = args.dir || defaultDir;
|
|
140
|
+
if (!dir)
|
|
141
|
+
return errorResult("'dir' is required — specify the repo path");
|
|
142
|
+
try {
|
|
143
|
+
const session = await getSession(dir);
|
|
144
|
+
if (args.files) {
|
|
145
|
+
for (const file of args.files) {
|
|
146
|
+
assertWithinRepository(resolve(session.dir, file), session.dir);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const result = await spawnThread(session, {
|
|
150
|
+
task: args.task,
|
|
151
|
+
files: args.files,
|
|
152
|
+
agent: args.agent,
|
|
153
|
+
model: args.model,
|
|
154
|
+
context: args.context,
|
|
155
|
+
});
|
|
156
|
+
return jsonResult({
|
|
157
|
+
success: result.success,
|
|
158
|
+
summary: result.summary,
|
|
159
|
+
files_changed: result.filesChanged,
|
|
160
|
+
diff_stats: result.diffStats,
|
|
161
|
+
duration_ms: result.durationMs,
|
|
162
|
+
cost_usd: result.estimatedCostUsd,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
167
|
+
return errorResult(`Thread failed: ${msg}`);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
// ── swarm_status ──────────────────────────────────────────────────────
|
|
171
|
+
// Get status of all threads and budget for a session.
|
|
172
|
+
server.registerTool("swarm_status", {
|
|
173
|
+
title: "Session Status",
|
|
174
|
+
description: "Get the current status of a swarm session — all threads with their " +
|
|
175
|
+
"status (pending/running/completed/failed), budget spent, and cost breakdown.",
|
|
176
|
+
inputSchema: z.object({
|
|
177
|
+
dir: z.string().optional().describe("Path to the git repository (uses server default if not specified)"),
|
|
178
|
+
}),
|
|
179
|
+
}, async (args) => {
|
|
180
|
+
const dir = args.dir || defaultDir;
|
|
181
|
+
if (!dir)
|
|
182
|
+
return errorResult("'dir' is required — specify the repo path");
|
|
183
|
+
try {
|
|
184
|
+
const session = await getSession(dir);
|
|
185
|
+
const threads = getThreads(session);
|
|
186
|
+
const budget = getBudgetState(session);
|
|
187
|
+
const threadSummaries = threads.map((t) => ({
|
|
188
|
+
id: t.id,
|
|
189
|
+
task: t.config.task,
|
|
190
|
+
status: t.status,
|
|
191
|
+
phase: t.phase,
|
|
192
|
+
agent: t.config.agent.backend,
|
|
193
|
+
model: t.config.agent.model,
|
|
194
|
+
files_changed: t.result?.filesChanged || [],
|
|
195
|
+
duration_ms: t.completedAt && t.startedAt ? t.completedAt - t.startedAt : t.startedAt ? Date.now() - t.startedAt : 0,
|
|
196
|
+
cost_usd: t.result?.estimatedCostUsd ?? t.estimatedCostUsd,
|
|
197
|
+
error: t.error,
|
|
198
|
+
}));
|
|
199
|
+
return jsonResult({
|
|
200
|
+
dir: session.dir,
|
|
201
|
+
threads: threadSummaries,
|
|
202
|
+
counts: {
|
|
203
|
+
total: threads.length,
|
|
204
|
+
running: threads.filter((t) => t.status === "running").length,
|
|
205
|
+
completed: threads.filter((t) => t.status === "completed").length,
|
|
206
|
+
failed: threads.filter((t) => t.status === "failed").length,
|
|
207
|
+
pending: threads.filter((t) => t.status === "pending").length,
|
|
208
|
+
},
|
|
209
|
+
budget: {
|
|
210
|
+
spent_usd: budget.totalSpentUsd,
|
|
211
|
+
limit_usd: budget.sessionLimitUsd,
|
|
212
|
+
per_thread_limit_usd: budget.perThreadLimitUsd,
|
|
213
|
+
tokens: budget.totalTokens,
|
|
214
|
+
},
|
|
215
|
+
session_age_ms: Date.now() - session.createdAt,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
220
|
+
return errorResult(`Status check failed: ${msg}`);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
// ── swarm_merge ───────────────────────────────────────────────────────
|
|
224
|
+
// Merge completed thread branches back to main.
|
|
225
|
+
server.registerTool("swarm_merge", {
|
|
226
|
+
title: "Merge Threads",
|
|
227
|
+
description: "Merge all completed thread branches back into the main branch. " +
|
|
228
|
+
"Threads that are still running or failed are skipped. Returns " +
|
|
229
|
+
"per-branch merge results including any conflicts.",
|
|
230
|
+
inputSchema: z.object({
|
|
231
|
+
dir: z.string().optional().describe("Path to the git repository (uses server default if not specified)"),
|
|
232
|
+
}),
|
|
233
|
+
}, async (args) => {
|
|
234
|
+
const dir = args.dir || defaultDir;
|
|
235
|
+
if (!dir)
|
|
236
|
+
return errorResult("'dir' is required — specify the repo path");
|
|
237
|
+
try {
|
|
238
|
+
const session = await getSession(dir);
|
|
239
|
+
const results = await mergeThreads(session);
|
|
240
|
+
return jsonResult({
|
|
241
|
+
merged: results.length,
|
|
242
|
+
results: results.map((r) => ({
|
|
243
|
+
branch: r.branch,
|
|
244
|
+
success: r.success,
|
|
245
|
+
message: r.message,
|
|
246
|
+
conflicts: r.conflicts,
|
|
247
|
+
})),
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
252
|
+
return errorResult(`Merge failed: ${msg}`);
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
// ── swarm_cancel ──────────────────────────────────────────────────────
|
|
256
|
+
// Cancel a specific thread or all threads.
|
|
257
|
+
server.registerTool("swarm_cancel", {
|
|
258
|
+
title: "Cancel Threads",
|
|
259
|
+
description: "Cancel running threads. Specify a thread_id to cancel a specific " +
|
|
260
|
+
"thread, or omit to cancel all running threads in the session.",
|
|
261
|
+
inputSchema: z.object({
|
|
262
|
+
dir: z.string().optional().describe("Path to the git repository (uses server default if not specified)"),
|
|
263
|
+
thread_id: z.string().optional().describe("Specific thread ID to cancel (omit to cancel all)"),
|
|
264
|
+
}),
|
|
265
|
+
}, async (args) => {
|
|
266
|
+
const dir = args.dir || defaultDir;
|
|
267
|
+
if (!dir)
|
|
268
|
+
return errorResult("'dir' is required — specify the repo path");
|
|
269
|
+
try {
|
|
270
|
+
const session = await getSession(dir);
|
|
271
|
+
const result = cancelThreads(session, args.thread_id);
|
|
272
|
+
return jsonResult(result);
|
|
273
|
+
}
|
|
274
|
+
catch (err) {
|
|
275
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
276
|
+
return errorResult(`Cancel failed: ${msg}`);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
// ── swarm_cleanup ─────────────────────────────────────────────────────
|
|
280
|
+
// Destroy a session — cancels threads, removes worktrees.
|
|
281
|
+
server.registerTool("swarm_cleanup", {
|
|
282
|
+
title: "Cleanup Session",
|
|
283
|
+
description: "Clean up a swarm session — cancels all running threads, removes " +
|
|
284
|
+
"worktrees, and frees resources. Call this when you're done with a " +
|
|
285
|
+
"directory to avoid leftover worktrees.",
|
|
286
|
+
inputSchema: z.object({
|
|
287
|
+
dir: z.string().optional().describe("Path to the git repository (uses server default if not specified)"),
|
|
288
|
+
}),
|
|
289
|
+
}, async (args) => {
|
|
290
|
+
const dir = args.dir || defaultDir;
|
|
291
|
+
if (!dir)
|
|
292
|
+
return errorResult("'dir' is required — specify the repo path");
|
|
293
|
+
try {
|
|
294
|
+
const message = await cleanupSession(dir);
|
|
295
|
+
return jsonResult({ cleaned_up: true, message });
|
|
296
|
+
}
|
|
297
|
+
catch (err) {
|
|
298
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
299
|
+
return errorResult(`Cleanup failed: ${msg}`);
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
// ── Subprocess runner ──────────────────────────────────────────────────────
|
|
304
|
+
/**
|
|
305
|
+
* Run swarm as a subprocess with --json --quiet flags.
|
|
306
|
+
* Tracks the child process so it can be killed on server shutdown.
|
|
307
|
+
*/
|
|
308
|
+
function runSwarmSubprocess(args) {
|
|
309
|
+
return new Promise((resolve, reject) => {
|
|
310
|
+
const { bin, binArgs } = findSwarmEntrypoint();
|
|
311
|
+
const child = execFile(bin, [...binArgs, ...args], {
|
|
312
|
+
encoding: "utf-8",
|
|
313
|
+
maxBuffer: 50 * 1024 * 1024,
|
|
314
|
+
timeout: 30 * 60 * 1000,
|
|
315
|
+
env: { ...process.env },
|
|
316
|
+
}, (err, stdout, stderr) => {
|
|
317
|
+
activeSubprocesses.delete(child);
|
|
318
|
+
if (err) {
|
|
319
|
+
// Try to parse JSON from stdout even on error
|
|
320
|
+
const parsed = tryParseSwarmJson(stdout);
|
|
321
|
+
if (parsed) {
|
|
322
|
+
resolve(parsed);
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
reject(new Error(stderr || err.message));
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
const parsed = tryParseSwarmJson(stdout);
|
|
329
|
+
if (parsed) {
|
|
330
|
+
resolve(parsed);
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
reject(new Error(`Could not parse swarm output: ${stdout.slice(0, 500)}`));
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
activeSubprocesses.add(child);
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Find the swarm entrypoint — prefers compiled dist/ over source.
|
|
341
|
+
* Returns the binary and args needed to run it.
|
|
342
|
+
*/
|
|
343
|
+
function findSwarmEntrypoint() {
|
|
344
|
+
const __dir = dirname(fileURLToPath(import.meta.url));
|
|
345
|
+
const root = join(__dir, "..", "..");
|
|
346
|
+
const distEntry = join(root, "dist", "main.js");
|
|
347
|
+
if (existsSync(distEntry)) {
|
|
348
|
+
return { bin: "node", binArgs: [distEntry] };
|
|
349
|
+
}
|
|
350
|
+
// Fallback: use npx tsx to run TypeScript source
|
|
351
|
+
const srcEntry = join(root, "src", "main.ts");
|
|
352
|
+
if (existsSync(srcEntry)) {
|
|
353
|
+
return { bin: "npx", binArgs: ["tsx", srcEntry] };
|
|
354
|
+
}
|
|
355
|
+
throw new Error("swarm-code entrypoint not found. Run 'npm run build' or install swarm-code globally.");
|
|
356
|
+
}
|
|
357
|
+
function tryParseSwarmJson(stdout) {
|
|
358
|
+
if (!stdout)
|
|
359
|
+
return null;
|
|
360
|
+
const trimmed = stdout.trim();
|
|
361
|
+
// Try single-line JSON (last line that starts with {)
|
|
362
|
+
const lines = trimmed.split("\n");
|
|
363
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
364
|
+
const line = lines[i].trim();
|
|
365
|
+
if (line.startsWith("{")) {
|
|
366
|
+
try {
|
|
367
|
+
const parsed = JSON.parse(line);
|
|
368
|
+
if (typeof parsed === "object" && parsed !== null && "success" in parsed) {
|
|
369
|
+
return parsed;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
/* not JSON */
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
// Fallback: first { to last }
|
|
378
|
+
const firstBrace = trimmed.indexOf("{");
|
|
379
|
+
const lastBrace = trimmed.lastIndexOf("}");
|
|
380
|
+
if (firstBrace !== -1 && lastBrace > firstBrace) {
|
|
381
|
+
try {
|
|
382
|
+
const parsed = JSON.parse(trimmed.slice(firstBrace, lastBrace + 1));
|
|
383
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
384
|
+
return parsed;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
catch {
|
|
388
|
+
/* give up */
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Independent Reviewer Gate (Dual Verdict) & Final Combined Review.
|
|
3
|
+
*
|
|
4
|
+
* Implements Superpowers-inspired single-reviewer dual-verdict gate:
|
|
5
|
+
* - specCompliance: "PASS" | "FAIL"
|
|
6
|
+
* - codeQuality: "PASS" | "FAIL"
|
|
7
|
+
*
|
|
8
|
+
* Enforces Reviewer != Implementer policy and prevents self-approval.
|
|
9
|
+
*/
|
|
10
|
+
import type { ReviewVerdict, TaskBrief, VerificationVerdict } from "../core/types.js";
|
|
11
|
+
export interface ReviewerGateOptions {
|
|
12
|
+
taskBrief: TaskBrief;
|
|
13
|
+
diff: string;
|
|
14
|
+
filesChanged: string[];
|
|
15
|
+
verificationVerdict: VerificationVerdict;
|
|
16
|
+
testOutput?: string;
|
|
17
|
+
implementerAgent?: string;
|
|
18
|
+
implementerModel?: string;
|
|
19
|
+
reviewerAgent?: string;
|
|
20
|
+
reviewerModel?: string;
|
|
21
|
+
workDir?: string;
|
|
22
|
+
repoRoot?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface CombinedReviewOptions {
|
|
25
|
+
repoRoot: string;
|
|
26
|
+
baseSha: string;
|
|
27
|
+
stagingBranch: string;
|
|
28
|
+
taskSummaries?: string[];
|
|
29
|
+
reviewerAgent?: string;
|
|
30
|
+
reviewerModel?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Determine a distinct reviewer backend to enforce Reviewer != Implementer.
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveReviewerAgent(implementerAgent?: string, requestedReviewer?: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* Evaluates an implementer's changes against the assigned TaskBrief.
|
|
38
|
+
*/
|
|
39
|
+
export declare function evaluateReviewerGate(options: ReviewerGateOptions): Promise<ReviewVerdict>;
|
|
40
|
+
/**
|
|
41
|
+
* Task 2.5f: Final holistic review of combined staging changes before merge to main.
|
|
42
|
+
*/
|
|
43
|
+
export declare function reviewCombinedStaging(options: CombinedReviewOptions): Promise<ReviewVerdict>;
|