@alessai/hive-mcp 1.0.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.
Files changed (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +217 -0
  3. package/conf/cli_clients/claude.json +9 -0
  4. package/conf/cli_clients/codex.json +9 -0
  5. package/conf/cli_clients/gemini.json +9 -0
  6. package/conf/cli_clients/glm.json +12 -0
  7. package/dist/agents/base.d.ts +12 -0
  8. package/dist/agents/base.d.ts.map +1 -0
  9. package/dist/agents/base.js +138 -0
  10. package/dist/agents/base.js.map +1 -0
  11. package/dist/agents/claude.d.ts +10 -0
  12. package/dist/agents/claude.d.ts.map +1 -0
  13. package/dist/agents/claude.js +19 -0
  14. package/dist/agents/claude.js.map +1 -0
  15. package/dist/agents/codex.d.ts +10 -0
  16. package/dist/agents/codex.d.ts.map +1 -0
  17. package/dist/agents/codex.js +21 -0
  18. package/dist/agents/codex.js.map +1 -0
  19. package/dist/agents/factory.d.ts +4 -0
  20. package/dist/agents/factory.d.ts.map +1 -0
  21. package/dist/agents/factory.js +17 -0
  22. package/dist/agents/factory.js.map +1 -0
  23. package/dist/agents/gemini.d.ts +23 -0
  24. package/dist/agents/gemini.d.ts.map +1 -0
  25. package/dist/agents/gemini.js +62 -0
  26. package/dist/agents/gemini.js.map +1 -0
  27. package/dist/config/constants.d.ts +10 -0
  28. package/dist/config/constants.d.ts.map +1 -0
  29. package/dist/config/constants.js +15 -0
  30. package/dist/config/constants.js.map +1 -0
  31. package/dist/config/internal-defaults.d.ts +3 -0
  32. package/dist/config/internal-defaults.d.ts.map +1 -0
  33. package/dist/config/internal-defaults.js +23 -0
  34. package/dist/config/internal-defaults.js.map +1 -0
  35. package/dist/config/registry.d.ts +5 -0
  36. package/dist/config/registry.d.ts.map +1 -0
  37. package/dist/config/registry.js +59 -0
  38. package/dist/config/registry.js.map +1 -0
  39. package/dist/continuation/store.d.ts +6 -0
  40. package/dist/continuation/store.d.ts.map +1 -0
  41. package/dist/continuation/store.js +123 -0
  42. package/dist/continuation/store.js.map +1 -0
  43. package/dist/index.d.ts +3 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +98 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/log.d.ts +3 -0
  48. package/dist/log.d.ts.map +1 -0
  49. package/dist/log.js +5 -0
  50. package/dist/log.js.map +1 -0
  51. package/dist/parsers/base.d.ts +9 -0
  52. package/dist/parsers/base.d.ts.map +1 -0
  53. package/dist/parsers/base.js +11 -0
  54. package/dist/parsers/base.js.map +1 -0
  55. package/dist/parsers/claude.d.ts +13 -0
  56. package/dist/parsers/claude.d.ts.map +1 -0
  57. package/dist/parsers/claude.js +110 -0
  58. package/dist/parsers/claude.js.map +1 -0
  59. package/dist/parsers/codex.d.ts +16 -0
  60. package/dist/parsers/codex.d.ts.map +1 -0
  61. package/dist/parsers/codex.js +39 -0
  62. package/dist/parsers/codex.js.map +1 -0
  63. package/dist/parsers/gemini.d.ts +13 -0
  64. package/dist/parsers/gemini.d.ts.map +1 -0
  65. package/dist/parsers/gemini.js +37 -0
  66. package/dist/parsers/gemini.js.map +1 -0
  67. package/dist/parsers/index.d.ts +8 -0
  68. package/dist/parsers/index.d.ts.map +1 -0
  69. package/dist/parsers/index.js +22 -0
  70. package/dist/parsers/index.js.map +1 -0
  71. package/dist/parsers/raw.d.ts +5 -0
  72. package/dist/parsers/raw.d.ts.map +1 -0
  73. package/dist/parsers/raw.js +6 -0
  74. package/dist/parsers/raw.js.map +1 -0
  75. package/dist/progress.d.ts +4 -0
  76. package/dist/progress.d.ts.map +1 -0
  77. package/dist/progress.js +12 -0
  78. package/dist/progress.js.map +1 -0
  79. package/dist/prompts/loader.d.ts +12 -0
  80. package/dist/prompts/loader.d.ts.map +1 -0
  81. package/dist/prompts/loader.js +48 -0
  82. package/dist/prompts/loader.js.map +1 -0
  83. package/dist/tools/hive-consensus.d.ts +3 -0
  84. package/dist/tools/hive-consensus.d.ts.map +1 -0
  85. package/dist/tools/hive-consensus.js +54 -0
  86. package/dist/tools/hive-consensus.js.map +1 -0
  87. package/dist/tools/hive.d.ts +3 -0
  88. package/dist/tools/hive.d.ts.map +1 -0
  89. package/dist/tools/hive.js +114 -0
  90. package/dist/tools/hive.js.map +1 -0
  91. package/dist/types.d.ts +81 -0
  92. package/dist/types.d.ts.map +1 -0
  93. package/dist/types.js +2 -0
  94. package/dist/types.js.map +1 -0
  95. package/package.json +52 -0
  96. package/prompts/analyst.txt +6 -0
  97. package/prompts/apilookup.txt +6 -0
  98. package/prompts/challenger.txt +6 -0
  99. package/prompts/debugger.txt +6 -0
  100. package/prompts/default.txt +4 -0
  101. package/prompts/docgen.txt +6 -0
  102. package/prompts/planner.txt +6 -0
  103. package/prompts/precommit.txt +6 -0
  104. package/prompts/refactor.txt +6 -0
  105. package/prompts/reviewer.txt +6 -0
  106. package/prompts/secaudit.txt +6 -0
  107. package/prompts/testgen.txt +6 -0
  108. package/prompts/thinker.txt +6 -0
  109. package/prompts/tracer.txt +6 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 alessai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,217 @@
1
+ # Hive MCP
2
+
3
+ An MCP server that spawns external AI CLIs as subagents. Give any MCP-compatible host (Claude Code, Cursor, Windsurf, etc.) the ability to delegate tasks to Gemini, Claude, Codex, or any custom CLI tool.
4
+
5
+ ## What it does
6
+
7
+ Hive exposes two MCP tools:
8
+
9
+ - **`hivesingle`** — Spawn a single CLI agent with a role-specific system prompt
10
+ - **`hive`** — Spawn 2+ CLI agents in parallel with the same prompt, collect all responses
11
+
12
+ Each agent runs as a child process with full tool access (filesystem, shell, web search) — whatever the underlying CLI supports.
13
+
14
+ ## Install
15
+
16
+ ### Claude Code
17
+
18
+ ```bash
19
+ claude mcp add hive -- npx @alessai/hive-mcp
20
+ ```
21
+
22
+ ### Cursor / Windsurf / other MCP hosts
23
+
24
+ Add to your MCP config:
25
+
26
+ ```json
27
+ {
28
+ "hive": {
29
+ "type": "stdio",
30
+ "command": "npx",
31
+ "args": ["hive-mcp"]
32
+ }
33
+ }
34
+ ```
35
+
36
+ ### From source
37
+
38
+ ```bash
39
+ git clone https://github.com/alessai/Hive-MCP.git
40
+ cd Hive-MCP
41
+ npm install && npm run build
42
+ claude mcp add hive node ./dist/index.js
43
+ ```
44
+
45
+ ## Prerequisites
46
+
47
+ You need the CLI tools installed for whichever agents you want to use:
48
+
49
+ | Agent | CLI | Install |
50
+ |-------|-----|---------|
51
+ | Gemini | `gemini` | `npm install -g @anthropic-ai/gemini-cli` or see [Gemini CLI docs](https://github.com/google-gemini/gemini-cli) |
52
+ | Claude | `claude` | `npm install -g @anthropic-ai/claude-code` or see [Claude Code docs](https://docs.anthropic.com/en/docs/claude-code) |
53
+ | Codex | `codex` | See [Codex CLI docs](https://github.com/openai/codex) |
54
+
55
+ Only install the CLIs you plan to use. Hive will report a clear error if a CLI isn't found.
56
+
57
+ ## Tools
58
+
59
+ ### `hivesingle`
60
+
61
+ Spawn a single CLI agent.
62
+
63
+ | Parameter | Type | Required | Description |
64
+ |-----------|------|----------|-------------|
65
+ | `client` | string | yes | CLI client to use (`gemini`, `claude`, `codex`, `glm`, or custom) |
66
+ | `prompt` | string | yes | The task or question |
67
+ | `role` | string | no | Role-based system prompt (see [Roles](#roles)) |
68
+ | `continuation_id` | string | no | Thread ID for multi-turn conversations |
69
+ | `cwd` | string | no | Working directory for the CLI process |
70
+
71
+ ### `hive`
72
+
73
+ Spawn multiple CLI agents in parallel with the same prompt. Defaults to `gemini` + `glm`.
74
+
75
+ | Parameter | Type | Required | Description |
76
+ |-----------|------|----------|-------------|
77
+ | `clients` | string[] | no | CLI clients to query (default: `["gemini", "glm"]`) |
78
+ | `prompt` | string | yes | The task or question |
79
+ | `role` | string | no | Role-based system prompt (see [Roles](#roles)) |
80
+ | `cwd` | string | no | Working directory for all CLI processes |
81
+
82
+ ## Roles
83
+
84
+ Role prompts shape agent behavior. Each role injects a system prompt tailored for the task:
85
+
86
+ | Role | Purpose |
87
+ |------|---------|
88
+ | `default` | General-purpose assistant |
89
+ | `reviewer` | Code review — bugs, style, security |
90
+ | `debugger` | Systematic debugging and root cause analysis |
91
+ | `planner` | Break down tasks into implementation steps |
92
+ | `thinker` | Deep exploration before answering |
93
+ | `analyst` | Architecture and dependency analysis |
94
+ | `refactor` | Improve code structure without changing behavior |
95
+ | `testgen` | Generate comprehensive test cases |
96
+ | `secaudit` | Security audit (OWASP top 10, etc.) |
97
+ | `docgen` | Generate documentation |
98
+ | `precommit` | Pre-commit review checklist |
99
+ | `challenger` | Devil's advocate — find flaws and risks |
100
+ | `apilookup` | Find correct API usage and signatures |
101
+ | `tracer` | Trace execution flow through code |
102
+
103
+ All agents also receive a capabilities preamble reminding them they have full tool access (filesystem, shell, web).
104
+
105
+ ## CLI client configuration
106
+
107
+ ### Built-in clients
108
+
109
+ Hive ships with configs for 4 clients in `conf/cli_clients/`:
110
+
111
+ | Client | CLI | Model | Timeout |
112
+ |--------|-----|-------|---------|
113
+ | `gemini` | `gemini` | gemini-2.5-pro | 5 min |
114
+ | `claude` | `claude` | default | 30 min |
115
+ | `glm` | `claude` | opus | 30 min |
116
+ | `codex` | `codex` | default | 10 min |
117
+
118
+ ### Custom clients
119
+
120
+ Add JSON files to `~/.hive/cli_clients/` to register custom clients or override built-ins.
121
+
122
+ ```json
123
+ {
124
+ "name": "my-agent",
125
+ "command": "my-cli-tool",
126
+ "runner": "gemini",
127
+ "additional_args": ["--flag", "value"],
128
+ "env": {},
129
+ "timeout_seconds": 300,
130
+ "roles": {}
131
+ }
132
+ ```
133
+
134
+ **Fields:**
135
+
136
+ | Field | Type | Description |
137
+ |-------|------|-------------|
138
+ | `name` | string | Client name (used in tool calls) |
139
+ | `command` | string | CLI executable name or path |
140
+ | `runner` | string | Agent behavior: `"gemini"`, `"claude"`, `"codex"`, or omit for base |
141
+ | `additional_args` | string[] | Extra CLI arguments |
142
+ | `env` | object | Environment variables for the process |
143
+ | `timeout_seconds` | number | Process timeout (default: 300) |
144
+ | `roles` | object | Per-role overrides (optional) |
145
+
146
+ The `runner` field determines how Hive interacts with the CLI:
147
+
148
+ | Runner | System prompt | Output format | Parser |
149
+ |--------|--------------|---------------|--------|
150
+ | `gemini` | via `-p` flag | JSON (`-o json`) | Extracts from Gemini JSON response |
151
+ | `claude` | via `--append-system-prompt` flag | JSON (`--output-format json`) | Extracts from Claude JSONL events |
152
+ | `codex` | via stdin | JSONL (`exec --json`) | Extracts from Codex JSONL stream |
153
+ | base (default) | via stdin | raw text | Returns stdout as-is |
154
+
155
+ User configs in `~/.hive/cli_clients/` override built-in configs with the same name.
156
+
157
+ ## Multi-turn conversations
158
+
159
+ Pass a `continuation_id` to `hivesingle` to maintain context across calls. Hive stores conversation turns on disk (`~/.hive/threads/`) with a 30-minute TTL and 100-thread LRU cap.
160
+
161
+ ```
162
+ # First call
163
+ hivesingle(client: "gemini", prompt: "Explain this codebase", continuation_id: "session-1")
164
+
165
+ # Follow-up (context is preserved)
166
+ hivesingle(client: "gemini", prompt: "Now focus on the auth module", continuation_id: "session-1")
167
+ ```
168
+
169
+ ## How it works
170
+
171
+ ```
172
+ MCP Host (Claude Code, Cursor, etc.)
173
+ ↓ MCP tool call
174
+ Hive MCP Server
175
+ ↓ child_process.spawn()
176
+ CLI Agent (gemini, claude, codex)
177
+ ↓ stdout/stderr
178
+ Parse output → return to host
179
+ ```
180
+
181
+ 1. The MCP host calls `hivesingle` or `hive`
182
+ 2. Hive resolves the client config, loads the role prompt, and builds CLI arguments
183
+ 3. The CLI is spawned as a child process with the prompt piped via stdin or flags
184
+ 4. Hive streams progress notifications back to the host while waiting
185
+ 5. On completion, the output is parsed (JSON/JSONL/raw) and returned
186
+
187
+ Each agent runs in its own process with full access to whatever tools the CLI provides. Hive is just the bridge.
188
+
189
+ ## Project structure
190
+
191
+ ```
192
+ ├── conf/cli_clients/ # Built-in CLI client configs (JSON)
193
+ ├── prompts/ # 14 role-based system prompt templates
194
+ ├── src/
195
+ │ ├── index.ts # MCP server entry point, tool registration
196
+ │ ├── types.ts # TypeScript interfaces
197
+ │ ├── agents/ # CLI agent implementations (base, gemini, claude, codex)
198
+ │ ├── config/ # Config loading, internal defaults, constants
199
+ │ ├── parsers/ # Output parsers (gemini JSON, claude JSONL, codex JSONL, raw)
200
+ │ ├── prompts/ # Prompt template loader
201
+ │ ├── continuation/ # Multi-turn conversation store
202
+ │ └── tools/ # Tool handlers (hivesingle, hive consensus)
203
+ ├── dist/ # Compiled output (gitignored)
204
+ └── package.json
205
+ ```
206
+
207
+ ## Development
208
+
209
+ ```bash
210
+ npm run dev # Watch mode (recompiles on changes)
211
+ npm run build # One-time build
212
+ npm start # Run the server directly
213
+ ```
214
+
215
+ ## License
216
+
217
+ [MIT](LICENSE)
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "claude",
3
+ "command": "claude",
4
+ "runner": "claude",
5
+ "additional_args": ["--permission-mode", "bypassPermissions"],
6
+ "env": {},
7
+ "timeout_seconds": 1800,
8
+ "roles": {}
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "codex",
3
+ "command": "codex",
4
+ "runner": "codex",
5
+ "additional_args": [],
6
+ "env": {},
7
+ "timeout_seconds": 600,
8
+ "roles": {}
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "gemini",
3
+ "command": "gemini",
4
+ "runner": "gemini",
5
+ "additional_args": ["-m", "gemini-2.5-pro"],
6
+ "env": {},
7
+ "timeout_seconds": 300,
8
+ "roles": {}
9
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "glm",
3
+ "command": "claude",
4
+ "runner": "claude",
5
+ "additional_args": [
6
+ "--permission-mode", "bypassPermissions",
7
+ "--model", "opus"
8
+ ],
9
+ "env": {},
10
+ "timeout_seconds": 1800,
11
+ "roles": {}
12
+ }
@@ -0,0 +1,12 @@
1
+ import type { ResolvedClient, SpawnResult, ProgressCallback } from "../types.js";
2
+ export declare class BaseCLIAgent {
3
+ protected client: ResolvedClient;
4
+ constructor(client: ResolvedClient);
5
+ /** Build the full args array for the CLI command */
6
+ protected buildArgs(systemPrompt: string | undefined, userPrompt: string): string[];
7
+ /** Build the stdin content to pipe to the process */
8
+ protected buildStdin(systemPrompt: string | undefined, userPrompt: string): string;
9
+ /** Run the CLI process */
10
+ run(systemPrompt: string | undefined, userPrompt: string, cwd?: string, onProgress?: ProgressCallback): Promise<SpawnResult>;
11
+ }
12
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/agents/base.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAoBjF,qBAAa,YAAY;IACvB,SAAS,CAAC,MAAM,EAAE,cAAc,CAAC;gBAErB,MAAM,EAAE,cAAc;IAIlC,oDAAoD;IACpD,SAAS,CAAC,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAUnF,qDAAqD;IACrD,SAAS,CAAC,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;IAOlF,0BAA0B;IACpB,GAAG,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC;CA6GnI"}
@@ -0,0 +1,138 @@
1
+ import { spawn } from "node:child_process";
2
+ import { MAX_OUTPUT_CHARS } from "../config/constants.js";
3
+ import { log } from "../log.js";
4
+ // Track active child processes for cleanup on server exit
5
+ const activeChildren = new Set();
6
+ function cleanupChildren() {
7
+ for (const child of activeChildren) {
8
+ try {
9
+ if (child.pid)
10
+ process.kill(-child.pid, "SIGKILL");
11
+ }
12
+ catch { /* already dead */ }
13
+ }
14
+ activeChildren.clear();
15
+ }
16
+ // Clean up children on exit. Use "exit" event only — signal handlers
17
+ // that call process.exit() prevent stdout from flushing (breaks MCP stdio transport).
18
+ process.on("exit", cleanupChildren);
19
+ export class BaseCLIAgent {
20
+ client;
21
+ constructor(client) {
22
+ this.client = client;
23
+ }
24
+ /** Build the full args array for the CLI command */
25
+ buildArgs(systemPrompt, userPrompt) {
26
+ const args = [...this.client.output_args, ...this.client.additional_args];
27
+ if (systemPrompt && this.client.prompt_injection === "flag" && this.client.prompt_flag) {
28
+ args.push(this.client.prompt_flag, systemPrompt);
29
+ }
30
+ return args;
31
+ }
32
+ /** Build the stdin content to pipe to the process */
33
+ buildStdin(systemPrompt, userPrompt) {
34
+ if (systemPrompt && this.client.prompt_injection === "stdin") {
35
+ return `${systemPrompt}\n\n${userPrompt}`;
36
+ }
37
+ return userPrompt;
38
+ }
39
+ /** Run the CLI process */
40
+ async run(systemPrompt, userPrompt, cwd, onProgress) {
41
+ const args = this.buildArgs(systemPrompt, userPrompt);
42
+ const stdinContent = this.buildStdin(systemPrompt, userPrompt);
43
+ // Strip env vars that block nested sessions or corrupt JSON output
44
+ const { CLAUDECODE: _1, // Prevents Claude-in-Claude nesting check
45
+ FORCE_COLOR: _2, // Prevents ANSI escape codes in JSON output
46
+ NO_COLOR: _3, // Let CLIs decide color based on TTY detection
47
+ ...cleanEnv } = process.env;
48
+ const env = { ...cleanEnv, ...this.client.env };
49
+ const timeoutMs = this.client.timeout_seconds * 1000;
50
+ log(`[${this.client.name}] Spawning: ${this.client.command} ${args.map(a => a.length > 80 ? a.slice(0, 80) + "..." : a).join(" ")}`);
51
+ return new Promise((resolve) => {
52
+ let stdout = "";
53
+ let stderr = "";
54
+ let timedOut = false;
55
+ let settled = false;
56
+ const spawnStart = Date.now();
57
+ const child = spawn(this.client.command, args, {
58
+ cwd: cwd ?? process.cwd(),
59
+ env,
60
+ stdio: ["pipe", "pipe", "pipe"],
61
+ detached: true, // Create process group so we can kill the entire tree
62
+ });
63
+ activeChildren.add(child);
64
+ // Periodic progress updates every 10s while waiting
65
+ const progressInterval = onProgress ? setInterval(() => {
66
+ const elapsed = Math.round((Date.now() - spawnStart) / 1000);
67
+ const bytesReceived = stdout.length + stderr.length;
68
+ const progressPct = Math.min(80, Math.round((elapsed / this.client.timeout_seconds) * 80));
69
+ onProgress(`Waiting for ${this.client.name} response... (${elapsed}s elapsed, ${bytesReceived.toLocaleString()} bytes received)`, progressPct, 100).catch(() => { }); // fire-and-forget, don't crash on notification failure
70
+ }, 10_000) : undefined;
71
+ const timer = setTimeout(() => {
72
+ timedOut = true;
73
+ log(`[${this.client.name}] Timeout after ${this.client.timeout_seconds}s — sending SIGTERM`);
74
+ // Kill the entire process group (child + its subprocesses)
75
+ try {
76
+ if (child.pid)
77
+ process.kill(-child.pid, "SIGTERM");
78
+ }
79
+ catch { /* already dead */ }
80
+ // Force kill after 3s grace period
81
+ setTimeout(() => {
82
+ try {
83
+ if (child.pid)
84
+ process.kill(-child.pid, "SIGKILL");
85
+ }
86
+ catch { /* already dead */ }
87
+ }, 3000);
88
+ }, timeoutMs);
89
+ child.stdout.on("data", (chunk) => {
90
+ // Raw buffer needs to be large enough to capture verbose JSON event streams
91
+ // (Claude's --output-format json includes init events with all tool names).
92
+ // Final response is still capped at MAX_OUTPUT_CHARS in hive.ts.
93
+ if (stdout.length < MAX_OUTPUT_CHARS * 20) {
94
+ stdout += chunk.toString();
95
+ }
96
+ });
97
+ child.stderr.on("data", (chunk) => {
98
+ if (stderr.length < MAX_OUTPUT_CHARS) {
99
+ stderr += chunk.toString();
100
+ }
101
+ });
102
+ // Prevent stdin errors from crashing the server (child may die before write completes)
103
+ child.stdin.on("error", () => { });
104
+ const finish = (exitCode) => {
105
+ if (settled)
106
+ return;
107
+ settled = true;
108
+ clearTimeout(timer);
109
+ if (progressInterval)
110
+ clearInterval(progressInterval);
111
+ activeChildren.delete(child);
112
+ log(`[${this.client.name}] Exited: code=${exitCode} timedOut=${timedOut} stdout=${stdout.length}bytes stderr=${stderr.length}bytes`);
113
+ resolve({ stdout, stderr, exitCode, timedOut });
114
+ };
115
+ child.on("close", (code) => finish(code));
116
+ child.on("error", (err) => {
117
+ const msg = err.code === "ENOENT"
118
+ ? `CLI "${this.client.command}" not found. Is it installed and in PATH?`
119
+ : `Spawn error: ${err.message}`;
120
+ log(`[${this.client.name}] Error: ${msg}`);
121
+ stderr += `\n${msg}`;
122
+ finish(1);
123
+ });
124
+ // Detached processes won't keep the parent alive — unref so MCP server can exit cleanly
125
+ child.unref();
126
+ // Write to stdin and close
127
+ if (stdinContent) {
128
+ child.stdin.write(stdinContent, () => {
129
+ child.stdin.end();
130
+ });
131
+ }
132
+ else {
133
+ child.stdin.end();
134
+ }
135
+ });
136
+ }
137
+ }
138
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/agents/base.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { BaseCLIAgent } from "./base.js";
2
+ import type { ResolvedClient } from "../types.js";
3
+ export declare class ClaudeAgent extends BaseCLIAgent {
4
+ constructor(client: ResolvedClient);
5
+ /** Claude uses --append-system-prompt flag for system prompt injection, user prompt via stdin */
6
+ protected buildArgs(systemPrompt: string | undefined, userPrompt: string): string[];
7
+ /** Claude gets user prompt via stdin only (system prompt goes via flag) */
8
+ protected buildStdin(systemPrompt: string | undefined, userPrompt: string): string;
9
+ }
10
+ //# sourceMappingURL=claude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/agents/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,qBAAa,WAAY,SAAQ,YAAY;gBAC/B,MAAM,EAAE,cAAc;IAIlC,iGAAiG;cAC9E,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAU5F,2EAA2E;cACxD,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;CAG5F"}
@@ -0,0 +1,19 @@
1
+ import { BaseCLIAgent } from "./base.js";
2
+ export class ClaudeAgent extends BaseCLIAgent {
3
+ constructor(client) {
4
+ super(client);
5
+ }
6
+ /** Claude uses --append-system-prompt flag for system prompt injection, user prompt via stdin */
7
+ buildArgs(systemPrompt, userPrompt) {
8
+ const args = [...this.client.output_args, ...this.client.additional_args];
9
+ if (systemPrompt && this.client.prompt_flag) {
10
+ args.push(this.client.prompt_flag, systemPrompt);
11
+ }
12
+ return args;
13
+ }
14
+ /** Claude gets user prompt via stdin only (system prompt goes via flag) */
15
+ buildStdin(systemPrompt, userPrompt) {
16
+ return userPrompt;
17
+ }
18
+ }
19
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/agents/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzC,MAAM,OAAO,WAAY,SAAQ,YAAY;IAC3C,YAAY,MAAsB;QAChC,KAAK,CAAC,MAAM,CAAC,CAAC;IAChB,CAAC;IAED,iGAAiG;IAC9E,SAAS,CAAC,YAAgC,EAAE,UAAkB;QAC/E,MAAM,IAAI,GAAa,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QAEpF,IAAI,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC5C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QACnD,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2EAA2E;IACxD,UAAU,CAAC,YAAgC,EAAE,UAAkB;QAChF,OAAO,UAAU,CAAC;IACpB,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ import { BaseCLIAgent } from "./base.js";
2
+ import type { ResolvedClient, SpawnResult, ProgressCallback } from "../types.js";
3
+ export declare class CodexAgent extends BaseCLIAgent {
4
+ constructor(client: ResolvedClient);
5
+ /** Codex uses `exec` subcommand — inject it before other args if not already present */
6
+ protected buildArgs(systemPrompt: string | undefined, userPrompt: string): string[];
7
+ /** Codex JSONL output can have broken lines — stderr is useful for diagnostics */
8
+ run(systemPrompt: string | undefined, userPrompt: string, cwd?: string, onProgress?: ProgressCallback): Promise<SpawnResult>;
9
+ }
10
+ //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/agents/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEjF,qBAAa,UAAW,SAAQ,YAAY;gBAC9B,MAAM,EAAE,cAAc;IAIlC,wFAAwF;cACrE,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAW5F,kFAAkF;IACnE,GAAG,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC;CAI5I"}
@@ -0,0 +1,21 @@
1
+ import { BaseCLIAgent } from "./base.js";
2
+ export class CodexAgent extends BaseCLIAgent {
3
+ constructor(client) {
4
+ super(client);
5
+ }
6
+ /** Codex uses `exec` subcommand — inject it before other args if not already present */
7
+ buildArgs(systemPrompt, userPrompt) {
8
+ const args = super.buildArgs(systemPrompt, userPrompt);
9
+ // Ensure 'exec' is first if output_args doesn't already start with it
10
+ if (args[0] !== "exec") {
11
+ // output_args for codex should be ["exec", "--json"] so this is a safety check
12
+ }
13
+ return args;
14
+ }
15
+ /** Codex JSONL output can have broken lines — stderr is useful for diagnostics */
16
+ async run(systemPrompt, userPrompt, cwd, onProgress) {
17
+ const result = await super.run(systemPrompt, userPrompt, cwd, onProgress);
18
+ return result;
19
+ }
20
+ }
21
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/agents/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzC,MAAM,OAAO,UAAW,SAAQ,YAAY;IAC1C,YAAY,MAAsB;QAChC,KAAK,CAAC,MAAM,CAAC,CAAC;IAChB,CAAC;IAED,wFAAwF;IACrE,SAAS,CAAC,YAAgC,EAAE,UAAkB;QAC/E,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAEvD,sEAAsE;QACtE,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;YACvB,+EAA+E;QACjF,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kFAAkF;IACzE,KAAK,CAAC,GAAG,CAAC,YAAgC,EAAE,UAAkB,EAAE,GAAY,EAAE,UAA6B;QAClH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;QAC1E,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
@@ -0,0 +1,4 @@
1
+ import type { ResolvedClient } from "../types.js";
2
+ import { BaseCLIAgent } from "./base.js";
3
+ export declare function createAgent(client: ResolvedClient): BaseCLIAgent;
4
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/agents/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAKzC,wBAAgB,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,YAAY,CAWhE"}
@@ -0,0 +1,17 @@
1
+ import { BaseCLIAgent } from "./base.js";
2
+ import { GeminiAgent } from "./gemini.js";
3
+ import { ClaudeAgent } from "./claude.js";
4
+ import { CodexAgent } from "./codex.js";
5
+ export function createAgent(client) {
6
+ switch (client.runner) {
7
+ case "gemini":
8
+ return new GeminiAgent(client);
9
+ case "claude":
10
+ return new ClaudeAgent(client);
11
+ case "codex":
12
+ return new CodexAgent(client);
13
+ default:
14
+ return new BaseCLIAgent(client);
15
+ }
16
+ }
17
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/agents/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,UAAU,WAAW,CAAC,MAAsB;IAChD,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;QACtB,KAAK,QAAQ;YACX,OAAO,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;QACjC,KAAK,QAAQ;YACX,OAAO,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;QACjC,KAAK,OAAO;YACV,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;QAChC;YACE,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;AACH,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { BaseCLIAgent } from "./base.js";
2
+ import type { ResolvedClient, SpawnResult, ProgressCallback } from "../types.js";
3
+ export declare class GeminiAgent extends BaseCLIAgent {
4
+ constructor(client: ResolvedClient);
5
+ /**
6
+ * Gemini uses -p for headless mode. When both -p and stdin are provided,
7
+ * -p gives the instruction and stdin provides content.
8
+ *
9
+ * Strategy:
10
+ * - System prompt → -p flag (instructions)
11
+ * - User prompt → stdin (content, no arg length limit)
12
+ * - No system prompt → -p with user prompt directly
13
+ */
14
+ protected buildArgs(systemPrompt: string | undefined, userPrompt: string): string[];
15
+ /**
16
+ * Stdin carries the user prompt when system prompt is in -p,
17
+ * or empty when user prompt is short enough for -p.
18
+ */
19
+ protected buildStdin(systemPrompt: string | undefined, userPrompt: string): string;
20
+ /** Filter known Gemini stderr noise */
21
+ run(systemPrompt: string | undefined, userPrompt: string, cwd?: string, onProgress?: ProgressCallback): Promise<SpawnResult>;
22
+ }
23
+ //# sourceMappingURL=gemini.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/agents/gemini.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEjF,qBAAa,WAAY,SAAQ,YAAY;gBAC/B,MAAM,EAAE,cAAc;IAIlC;;;;;;;;OAQG;cACgB,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAoB5F;;;OAGG;cACgB,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;IAY3F,uCAAuC;IACxB,GAAG,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC;CAa5I"}
@@ -0,0 +1,62 @@
1
+ import { BaseCLIAgent } from "./base.js";
2
+ export class GeminiAgent extends BaseCLIAgent {
3
+ constructor(client) {
4
+ super(client);
5
+ }
6
+ /**
7
+ * Gemini uses -p for headless mode. When both -p and stdin are provided,
8
+ * -p gives the instruction and stdin provides content.
9
+ *
10
+ * Strategy:
11
+ * - System prompt → -p flag (instructions)
12
+ * - User prompt → stdin (content, no arg length limit)
13
+ * - No system prompt → -p with user prompt directly
14
+ */
15
+ buildArgs(systemPrompt, userPrompt) {
16
+ const args = [...this.client.output_args, ...this.client.additional_args];
17
+ if (systemPrompt) {
18
+ // System prompt as -p instruction, user prompt goes via stdin
19
+ args.push("-p", systemPrompt);
20
+ }
21
+ else {
22
+ // No system prompt — use -p for headless mode with short prompt,
23
+ // or stdin for long prompts to avoid arg length limits
24
+ if (userPrompt.length < 50_000) {
25
+ args.push("-p", userPrompt);
26
+ }
27
+ else {
28
+ // Long prompt — -p with minimal instruction, full prompt via stdin
29
+ args.push("-p", "Process the following input:");
30
+ }
31
+ }
32
+ return args;
33
+ }
34
+ /**
35
+ * Stdin carries the user prompt when system prompt is in -p,
36
+ * or empty when user prompt is short enough for -p.
37
+ */
38
+ buildStdin(systemPrompt, userPrompt) {
39
+ if (systemPrompt) {
40
+ // System prompt is in -p, user prompt goes here
41
+ return userPrompt;
42
+ }
43
+ // No system prompt — if short, it went in -p; if long, it goes here
44
+ if (userPrompt.length < 50_000) {
45
+ return "";
46
+ }
47
+ return userPrompt;
48
+ }
49
+ /** Filter known Gemini stderr noise */
50
+ async run(systemPrompt, userPrompt, cwd, onProgress) {
51
+ const result = await super.run(systemPrompt, userPrompt, cwd, onProgress);
52
+ if (result.stderr) {
53
+ result.stderr = result.stderr
54
+ .split("\n")
55
+ .filter(line => !line.includes("WARNING") && !line.includes("I/O"))
56
+ .join("\n")
57
+ .trim();
58
+ }
59
+ return result;
60
+ }
61
+ }
62
+ //# sourceMappingURL=gemini.js.map