@synergenius/flow-weaver 0.22.6 → 0.22.8

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.
@@ -0,0 +1,132 @@
1
+ /**
2
+ * MCP bridge — creates a Unix domain socket server that the MCP tool server
3
+ * connects to for executing tools. Also generates the temporary MCP config
4
+ * and tool definition files needed by the Claude CLI.
5
+ *
6
+ * Usage:
7
+ * const bridge = await createMcpBridge(tools, executor, onToolEvent);
8
+ * // pass bridge.configPath to --mcp-config
9
+ * // ...run CLI...
10
+ * bridge.cleanup();
11
+ */
12
+ import * as net from 'node:net';
13
+ import * as fs from 'node:fs';
14
+ import * as path from 'node:path';
15
+ import * as os from 'node:os';
16
+ import { fileURLToPath } from 'node:url';
17
+ /**
18
+ * Create an MCP bridge that the Claude CLI can connect to for tool execution.
19
+ *
20
+ * @param tools Tool definitions to advertise to the CLI
21
+ * @param executor Function that executes a tool call
22
+ * @param onToolEvent Optional callback for relaying tool events
23
+ * @param logger Optional logger
24
+ */
25
+ export async function createMcpBridge(tools, executor, onToolEvent, logger) {
26
+ // Create temp directory for bridge files
27
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'fw-mcp-bridge-'));
28
+ fs.chmodSync(tmpDir, 0o700);
29
+ const socketPath = path.join(tmpDir, 'bridge.sock');
30
+ const defsPath = path.join(tmpDir, 'tools.json');
31
+ const configPath = path.join(tmpDir, 'mcp-config.json');
32
+ // Write tool definitions in MCP format
33
+ const mcpToolDefs = tools.map((t) => ({
34
+ name: t.name,
35
+ description: t.description,
36
+ inputSchema: t.inputSchema,
37
+ }));
38
+ fs.writeFileSync(defsPath, JSON.stringify(mcpToolDefs), 'utf-8');
39
+ // Resolve the MCP tool server script path.
40
+ // In prod: sibling .js file. In dev (tsx): sibling .ts file.
41
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
42
+ const jsPath = path.resolve(__dirname, 'mcp-tool-server.js');
43
+ const tsPath = path.resolve(__dirname, 'mcp-tool-server.ts');
44
+ const scriptPath = fs.existsSync(jsPath) ? jsPath : tsPath;
45
+ // In dev the script is .ts — use tsx as the loader.
46
+ const mcpCommand = process.execPath; // node
47
+ let mcpArgs = [scriptPath];
48
+ if (scriptPath.endsWith('.ts')) {
49
+ // Look for tsx in the package's node_modules
50
+ const tsxCli = path.resolve(__dirname, '../../node_modules/tsx/dist/cli.mjs');
51
+ if (fs.existsSync(tsxCli)) {
52
+ mcpArgs = [tsxCli, scriptPath];
53
+ }
54
+ }
55
+ // Write MCP config
56
+ const mcpConfig = {
57
+ mcpServers: {
58
+ 'fw-agent': {
59
+ type: 'stdio',
60
+ command: mcpCommand,
61
+ args: mcpArgs,
62
+ env: {
63
+ FW_TOOL_SOCKET: socketPath,
64
+ FW_TOOL_DEFS: defsPath,
65
+ },
66
+ },
67
+ },
68
+ };
69
+ fs.writeFileSync(configPath, JSON.stringify(mcpConfig), 'utf-8');
70
+ // Mutable handlers — swapped per request via setHandlers()
71
+ let currentExecutor = executor;
72
+ let currentOnToolEvent = onToolEvent;
73
+ // Create Unix domain socket server.
74
+ // The tool server sends a newline-terminated JSON request and waits for a
75
+ // JSON response on the same connection.
76
+ const server = net.createServer((conn) => {
77
+ let buf = '';
78
+ conn.on('data', async (chunk) => {
79
+ buf += chunk.toString();
80
+ const nlIdx = buf.indexOf('\n');
81
+ if (nlIdx === -1)
82
+ return; // wait for complete line
83
+ const line = buf.slice(0, nlIdx).trim();
84
+ buf = ''; // consume — one request per connection
85
+ try {
86
+ const { name, args } = JSON.parse(line);
87
+ currentOnToolEvent?.({ type: 'tool_call_start', name, args });
88
+ const { result, isError } = await currentExecutor(name, args);
89
+ currentOnToolEvent?.({ type: 'tool_call_result', name, result, isError });
90
+ conn.end(JSON.stringify({ result, isError }));
91
+ }
92
+ catch (err) {
93
+ const msg = err instanceof Error ? err.message : String(err);
94
+ logger?.error('MCP bridge tool execution error', err);
95
+ conn.end(JSON.stringify({ result: msg, isError: true }));
96
+ }
97
+ });
98
+ });
99
+ await new Promise((resolve, reject) => {
100
+ server.on('error', reject);
101
+ server.listen(socketPath, () => resolve());
102
+ });
103
+ let cleaned = false;
104
+ const cleanup = () => {
105
+ if (cleaned)
106
+ return;
107
+ cleaned = true;
108
+ server.close();
109
+ try {
110
+ fs.unlinkSync(socketPath);
111
+ }
112
+ catch { }
113
+ try {
114
+ fs.unlinkSync(defsPath);
115
+ }
116
+ catch { }
117
+ try {
118
+ fs.unlinkSync(configPath);
119
+ }
120
+ catch { }
121
+ try {
122
+ fs.rmdirSync(tmpDir);
123
+ }
124
+ catch { }
125
+ };
126
+ const setHandlers = (exec, onEvt) => {
127
+ currentExecutor = exec;
128
+ currentOnToolEvent = onEvt;
129
+ };
130
+ return { configPath, setHandlers, cleanup };
131
+ }
132
+ //# sourceMappingURL=mcp-bridge.js.map
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Minimal MCP stdio server that bridges tool calls to a parent process.
4
+ *
5
+ * Spawned by the Claude CLI via --mcp-config. Advertises tool definitions
6
+ * and delegates execution to the parent process through a Unix domain socket.
7
+ *
8
+ * Environment:
9
+ * FW_TOOL_SOCKET - Unix socket path for tool execution RPC
10
+ * FW_TOOL_DEFS - Path to JSON file with tool definitions
11
+ *
12
+ * Protocol over Unix socket (newline-delimited JSON):
13
+ * Request: {"name":"fw_run_command","args":{"command":"ls"}}
14
+ * Response: {"result":"...","isError":false}
15
+ *
16
+ * IMPORTANT — Transport compatibility:
17
+ * Claude Code CLI v2.1.76+ uses NDJSON (newline-delimited JSON) for MCP
18
+ * stdio, NOT the Content-Length framing from the MCP SDK spec. This server
19
+ * auto-detects the transport on the first stdin chunk: if the first
20
+ * non-whitespace character is '{', it uses NDJSON; otherwise Content-Length.
21
+ * Responses match the detected format.
22
+ *
23
+ * The CLI also sends protocolVersion "2025-11-25" (not the spec's
24
+ * "2024-11-05"). We echo back whatever version the client requests.
25
+ *
26
+ * If these behaviors change in a future CLI version, the auto-detect
27
+ * and version echo should adapt automatically.
28
+ */
29
+ export {};
30
+ //# sourceMappingURL=mcp-tool-server.d.ts.map
@@ -0,0 +1,210 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Minimal MCP stdio server that bridges tool calls to a parent process.
4
+ *
5
+ * Spawned by the Claude CLI via --mcp-config. Advertises tool definitions
6
+ * and delegates execution to the parent process through a Unix domain socket.
7
+ *
8
+ * Environment:
9
+ * FW_TOOL_SOCKET - Unix socket path for tool execution RPC
10
+ * FW_TOOL_DEFS - Path to JSON file with tool definitions
11
+ *
12
+ * Protocol over Unix socket (newline-delimited JSON):
13
+ * Request: {"name":"fw_run_command","args":{"command":"ls"}}
14
+ * Response: {"result":"...","isError":false}
15
+ *
16
+ * IMPORTANT — Transport compatibility:
17
+ * Claude Code CLI v2.1.76+ uses NDJSON (newline-delimited JSON) for MCP
18
+ * stdio, NOT the Content-Length framing from the MCP SDK spec. This server
19
+ * auto-detects the transport on the first stdin chunk: if the first
20
+ * non-whitespace character is '{', it uses NDJSON; otherwise Content-Length.
21
+ * Responses match the detected format.
22
+ *
23
+ * The CLI also sends protocolVersion "2025-11-25" (not the spec's
24
+ * "2024-11-05"). We echo back whatever version the client requests.
25
+ *
26
+ * If these behaviors change in a future CLI version, the auto-detect
27
+ * and version echo should adapt automatically.
28
+ */
29
+ import * as net from 'node:net';
30
+ import * as fs from 'node:fs';
31
+ const SOCKET_PATH = process.env.FW_TOOL_SOCKET;
32
+ const DEFS_PATH = process.env.FW_TOOL_DEFS;
33
+ if (!SOCKET_PATH || !DEFS_PATH) {
34
+ process.stderr.write('mcp-tool-server: FW_TOOL_SOCKET and FW_TOOL_DEFS are required\n');
35
+ process.exit(1);
36
+ }
37
+ // Load tool definitions (written by the bridge before spawning the CLI)
38
+ const toolDefs = JSON.parse(fs.readFileSync(DEFS_PATH, 'utf-8'));
39
+ // ---------------------------------------------------------------------------
40
+ // Unix socket RPC: send tool call, receive result
41
+ // ---------------------------------------------------------------------------
42
+ function callTool(name, args) {
43
+ return new Promise((resolve, reject) => {
44
+ const client = net.createConnection(SOCKET_PATH, () => {
45
+ client.write(JSON.stringify({ name, args }) + '\n');
46
+ });
47
+ let buf = '';
48
+ client.on('data', (chunk) => {
49
+ buf += chunk.toString();
50
+ });
51
+ client.on('end', () => {
52
+ try {
53
+ resolve(JSON.parse(buf.trim()));
54
+ }
55
+ catch {
56
+ reject(new Error(`Invalid response from tool bridge: ${buf}`));
57
+ }
58
+ });
59
+ client.on('error', (err) => reject(err));
60
+ // Safety timeout
61
+ setTimeout(() => {
62
+ client.destroy();
63
+ reject(new Error('Tool execution timed out'));
64
+ }, 130_000);
65
+ });
66
+ }
67
+ // ---------------------------------------------------------------------------
68
+ // MCP stdio protocol (JSON-RPC over stdin/stdout)
69
+ // ---------------------------------------------------------------------------
70
+ // Auto-detect transport: NDJSON (newline-delimited) or Content-Length framed.
71
+ // Claude Code CLI uses NDJSON; standard MCP SDK uses Content-Length.
72
+ let useNdjson = false;
73
+ let transportDetected = false;
74
+ function send(msg) {
75
+ const json = JSON.stringify(msg);
76
+ if (useNdjson) {
77
+ process.stdout.write(json + '\n');
78
+ }
79
+ else {
80
+ const header = `Content-Length: ${Buffer.byteLength(json)}\r\n\r\n`;
81
+ process.stdout.write(header + json);
82
+ }
83
+ }
84
+ async function handleMessage(msg) {
85
+ const { method, id, params } = msg;
86
+ if (method === 'initialize') {
87
+ // Echo back the client's protocol version for compatibility
88
+ const clientVersion = params?.protocolVersion || '2024-11-05';
89
+ send({
90
+ jsonrpc: '2.0',
91
+ id,
92
+ result: {
93
+ protocolVersion: clientVersion,
94
+ capabilities: { tools: {} },
95
+ serverInfo: { name: 'fw-agent-tools', version: '1.0.0' },
96
+ },
97
+ });
98
+ return;
99
+ }
100
+ if (method === 'notifications/initialized') {
101
+ // No response needed for notifications
102
+ return;
103
+ }
104
+ if (method === 'tools/list') {
105
+ send({
106
+ jsonrpc: '2.0',
107
+ id,
108
+ result: { tools: toolDefs },
109
+ });
110
+ return;
111
+ }
112
+ if (method === 'tools/call') {
113
+ const toolName = params?.name;
114
+ const toolArgs = params?.arguments ?? {};
115
+ try {
116
+ const { result, isError } = await callTool(toolName, toolArgs);
117
+ send({
118
+ jsonrpc: '2.0',
119
+ id,
120
+ result: {
121
+ content: [{ type: 'text', text: result }],
122
+ isError,
123
+ },
124
+ });
125
+ }
126
+ catch (err) {
127
+ send({
128
+ jsonrpc: '2.0',
129
+ id,
130
+ result: {
131
+ content: [{ type: 'text', text: err instanceof Error ? err.message : String(err) }],
132
+ isError: true,
133
+ },
134
+ });
135
+ }
136
+ return;
137
+ }
138
+ // Unknown method — return empty result for requests, ignore notifications
139
+ if (id !== undefined) {
140
+ send({ jsonrpc: '2.0', id, result: {} });
141
+ }
142
+ }
143
+ // ---------------------------------------------------------------------------
144
+ // Read JSON-RPC messages from stdin (auto-detect NDJSON vs Content-Length)
145
+ // ---------------------------------------------------------------------------
146
+ let inputBuf = '';
147
+ process.stdin.on('data', (chunk) => {
148
+ inputBuf += chunk.toString();
149
+ // Auto-detect transport on first data: if it starts with '{', it's NDJSON
150
+ if (!transportDetected) {
151
+ const trimmed = inputBuf.trimStart();
152
+ if (trimmed.startsWith('{')) {
153
+ useNdjson = true;
154
+ }
155
+ transportDetected = true;
156
+ }
157
+ if (useNdjson) {
158
+ processNdjson();
159
+ }
160
+ else {
161
+ processContentLength();
162
+ }
163
+ });
164
+ function processNdjson() {
165
+ const lines = inputBuf.split('\n');
166
+ inputBuf = lines.pop() || '';
167
+ for (const line of lines) {
168
+ if (!line.trim())
169
+ continue;
170
+ try {
171
+ const msg = JSON.parse(line);
172
+ handleMessage(msg).catch((err) => {
173
+ process.stderr.write(`mcp-tool-server error: ${err}\n`);
174
+ });
175
+ }
176
+ catch {
177
+ process.stderr.write(`mcp-tool-server: failed to parse line: ${line.slice(0, 200)}\n`);
178
+ }
179
+ }
180
+ }
181
+ function processContentLength() {
182
+ while (true) {
183
+ const headerEnd = inputBuf.indexOf('\r\n\r\n');
184
+ if (headerEnd === -1)
185
+ break;
186
+ const header = inputBuf.slice(0, headerEnd);
187
+ const match = header.match(/Content-Length:\s*(\d+)/i);
188
+ if (!match) {
189
+ inputBuf = inputBuf.slice(headerEnd + 4);
190
+ continue;
191
+ }
192
+ const contentLength = parseInt(match[1], 10);
193
+ const bodyStart = headerEnd + 4;
194
+ if (inputBuf.length < bodyStart + contentLength)
195
+ break;
196
+ const body = inputBuf.slice(bodyStart, bodyStart + contentLength);
197
+ inputBuf = inputBuf.slice(bodyStart + contentLength);
198
+ try {
199
+ const msg = JSON.parse(body);
200
+ handleMessage(msg).catch((err) => {
201
+ process.stderr.write(`mcp-tool-server error: ${err}\n`);
202
+ });
203
+ }
204
+ catch {
205
+ process.stderr.write(`mcp-tool-server: failed to parse message: ${body}\n`);
206
+ }
207
+ }
208
+ }
209
+ process.stdin.on('end', () => process.exit(0));
210
+ //# sourceMappingURL=mcp-tool-server.js.map
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Anthropic API provider — streams messages via raw fetch + SSE parsing.
3
+ * No SDK dependency. Uses only Node.js native fetch (available since Node 18).
4
+ *
5
+ * Adapted from pack-weaver's streamAnthropicWithTools.
6
+ */
7
+ import type { AgentProvider, AgentMessage, ToolDefinition, StreamEvent, StreamOptions } from '../types.js';
8
+ export interface AnthropicProviderOptions {
9
+ apiKey: string;
10
+ model?: string;
11
+ maxTokens?: number;
12
+ baseUrl?: string;
13
+ }
14
+ export declare class AnthropicProvider implements AgentProvider {
15
+ private apiKey;
16
+ private model;
17
+ private maxTokens;
18
+ private baseUrl;
19
+ constructor(options: AnthropicProviderOptions);
20
+ stream(messages: AgentMessage[], tools: ToolDefinition[], options?: StreamOptions): AsyncGenerator<StreamEvent>;
21
+ }
22
+ export declare function createAnthropicProvider(options: AnthropicProviderOptions): AnthropicProvider;
23
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Anthropic API provider — streams messages via raw fetch + SSE parsing.
3
+ * No SDK dependency. Uses only Node.js native fetch (available since Node 18).
4
+ *
5
+ * Adapted from pack-weaver's streamAnthropicWithTools.
6
+ */
7
+ export class AnthropicProvider {
8
+ apiKey;
9
+ model;
10
+ maxTokens;
11
+ baseUrl;
12
+ constructor(options) {
13
+ if (!options.apiKey) {
14
+ throw new Error('AnthropicProvider requires an API key');
15
+ }
16
+ this.apiKey = options.apiKey;
17
+ this.model = options.model ?? 'claude-sonnet-4-20250514';
18
+ this.maxTokens = options.maxTokens ?? 8192;
19
+ this.baseUrl = options.baseUrl ?? 'https://api.anthropic.com';
20
+ }
21
+ async *stream(messages, tools, options) {
22
+ const model = options?.model ?? this.model;
23
+ const maxTokens = options?.maxTokens ?? this.maxTokens;
24
+ // Build Anthropic API request body
25
+ const apiMessages = messages.map((m) => {
26
+ if (m.role === 'tool') {
27
+ return {
28
+ role: 'user',
29
+ content: [{ type: 'tool_result', tool_use_id: m.toolCallId, content: m.content }],
30
+ };
31
+ }
32
+ if (m.role === 'assistant' && m.toolCalls?.length) {
33
+ const blocks = [];
34
+ if (m.content)
35
+ blocks.push({ type: 'text', text: m.content });
36
+ for (const tc of m.toolCalls) {
37
+ blocks.push({ type: 'tool_use', id: tc.id, name: tc.name, input: tc.arguments });
38
+ }
39
+ return { role: 'assistant', content: blocks };
40
+ }
41
+ return { role: m.role, content: m.content };
42
+ });
43
+ const apiTools = tools.map((t) => ({
44
+ name: t.name,
45
+ description: t.description,
46
+ input_schema: t.inputSchema,
47
+ }));
48
+ const body = JSON.stringify({
49
+ model,
50
+ max_tokens: maxTokens,
51
+ stream: true,
52
+ ...(options?.systemPrompt ? { system: options.systemPrompt } : {}),
53
+ messages: apiMessages,
54
+ ...(apiTools.length > 0 ? { tools: apiTools } : {}),
55
+ });
56
+ const response = await fetch(`${this.baseUrl}/v1/messages`, {
57
+ method: 'POST',
58
+ headers: {
59
+ 'x-api-key': this.apiKey,
60
+ 'anthropic-version': '2025-04-15',
61
+ 'content-type': 'application/json',
62
+ },
63
+ body,
64
+ signal: options?.signal ?? AbortSignal.timeout(300_000),
65
+ });
66
+ if (!response.ok) {
67
+ const err = await response.text();
68
+ throw new Error(`Anthropic API error ${response.status}: ${err.slice(0, 200)}`);
69
+ }
70
+ if (!response.body)
71
+ throw new Error('No response body');
72
+ // Parse SSE stream
73
+ const reader = response.body.getReader();
74
+ const decoder = new TextDecoder();
75
+ let buffer = '';
76
+ const activeToolUses = new Map();
77
+ try {
78
+ while (true) {
79
+ const { done, value } = await reader.read();
80
+ if (done)
81
+ break;
82
+ buffer += decoder.decode(value, { stream: true });
83
+ const lines = buffer.split('\n');
84
+ buffer = lines.pop() || '';
85
+ for (const line of lines) {
86
+ if (!line.startsWith('data: '))
87
+ continue;
88
+ const jsonStr = line.slice(6).trim();
89
+ if (jsonStr === '[DONE]')
90
+ continue;
91
+ let event;
92
+ try {
93
+ event = JSON.parse(jsonStr);
94
+ }
95
+ catch {
96
+ continue;
97
+ }
98
+ const eventType = event.type;
99
+ if (eventType === 'content_block_start') {
100
+ const block = event.content_block;
101
+ const index = event.index;
102
+ if (block.type === 'tool_use' && block.id && block.name) {
103
+ activeToolUses.set(index, { id: block.id, name: block.name, jsonChunks: [] });
104
+ yield { type: 'tool_use_start', id: block.id, name: block.name };
105
+ }
106
+ }
107
+ if (eventType === 'content_block_delta') {
108
+ const delta = event.delta;
109
+ const index = event.index;
110
+ if (delta.type === 'text_delta' && delta.text) {
111
+ yield { type: 'text_delta', text: delta.text };
112
+ }
113
+ if (delta.type === 'thinking_delta' && delta.thinking) {
114
+ yield { type: 'thinking_delta', text: delta.thinking };
115
+ }
116
+ if (delta.type === 'input_json_delta' && delta.partial_json !== undefined) {
117
+ const active = activeToolUses.get(index);
118
+ if (active) {
119
+ active.jsonChunks.push(delta.partial_json);
120
+ yield { type: 'tool_use_delta', id: active.id, partialJson: delta.partial_json };
121
+ }
122
+ }
123
+ }
124
+ if (eventType === 'content_block_stop') {
125
+ const index = event.index;
126
+ const active = activeToolUses.get(index);
127
+ if (active) {
128
+ activeToolUses.delete(index);
129
+ let args = {};
130
+ try {
131
+ args = JSON.parse(active.jsonChunks.join(''));
132
+ }
133
+ catch {
134
+ /* malformed */
135
+ }
136
+ yield { type: 'tool_use_end', id: active.id, arguments: args };
137
+ }
138
+ }
139
+ if (eventType === 'message_start' && event.message?.usage) {
140
+ const usage = event.message.usage;
141
+ yield {
142
+ type: 'usage',
143
+ promptTokens: usage.input_tokens ?? 0,
144
+ completionTokens: usage.output_tokens ?? 0,
145
+ };
146
+ }
147
+ if (eventType === 'message_delta') {
148
+ const delta = event.delta;
149
+ if (event.usage) {
150
+ const usage = event.usage;
151
+ yield {
152
+ type: 'usage',
153
+ promptTokens: 0,
154
+ completionTokens: usage.output_tokens ?? 0,
155
+ };
156
+ }
157
+ if (delta?.stop_reason === 'tool_use') {
158
+ yield { type: 'message_stop', finishReason: 'tool_calls' };
159
+ }
160
+ else if (delta?.stop_reason === 'end_turn') {
161
+ yield { type: 'message_stop', finishReason: 'stop' };
162
+ }
163
+ else if (delta?.stop_reason === 'max_tokens') {
164
+ yield { type: 'message_stop', finishReason: 'length' };
165
+ }
166
+ else if (delta?.stop_reason) {
167
+ yield { type: 'message_stop', finishReason: 'stop' };
168
+ }
169
+ }
170
+ if (eventType === 'error') {
171
+ const errObj = event.error;
172
+ throw new Error(`Anthropic stream error: ${errObj?.message ?? 'unknown'}`);
173
+ }
174
+ }
175
+ }
176
+ }
177
+ finally {
178
+ reader.releaseLock();
179
+ }
180
+ }
181
+ }
182
+ export function createAnthropicProvider(options) {
183
+ return new AnthropicProvider(options);
184
+ }
185
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Claude CLI provider — spawns the Claude Code CLI with stream-json output
3
+ * and MCP bridge for tool execution.
4
+ *
5
+ * Adapted from platform's streamClaudeCliChat. Platform-specific dependencies
6
+ * (spawnSandboxed, getBinPath, config) are replaced with injectable options.
7
+ */
8
+ import type { AgentProvider, AgentMessage, ToolDefinition, StreamEvent, StreamOptions, ClaudeCliProviderOptions } from '../types.js';
9
+ export declare class ClaudeCliProvider implements AgentProvider {
10
+ private binPath;
11
+ private cwd;
12
+ private env;
13
+ private model;
14
+ private mcpConfigPath;
15
+ private spawnFn;
16
+ private timeout;
17
+ constructor(options?: ClaudeCliProviderOptions);
18
+ stream(messages: AgentMessage[], tools: ToolDefinition[], options?: StreamOptions): AsyncGenerator<StreamEvent>;
19
+ }
20
+ export declare function createClaudeCliProvider(options?: ClaudeCliProviderOptions): ClaudeCliProvider;
21
+ //# sourceMappingURL=claude-cli.d.ts.map