acp-factory 0.0.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,33 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2024-XX-XX
11
+
12
+ ### Added
13
+
14
+ - Initial release
15
+ - `AgentFactory` for registering and spawning agents
16
+ - `AgentHandle` for managing agent processes
17
+ - `Session` for interacting with agent sessions
18
+ - Pre-registered `claude-code` agent
19
+ - Streaming responses via async iterators
20
+ - Permission handling modes: `auto-approve`, `auto-deny`, `callback`, `interactive`
21
+ - Interactive permission requests as session updates
22
+ - `session.interruptWith()` for interrupting and redirecting agents
23
+ - `session.fork()` for creating independent session copies (experimental)
24
+ - `agentHandle.forkSession()` for forking by session ID (experimental)
25
+ - `session.addContext()` stub for future mid-execution messaging
26
+ - Custom file read/write handlers
27
+ - Terminal operation handlers
28
+ - MCP server support
29
+ - Full TypeScript type exports
30
+
31
+ ### Dependencies
32
+
33
+ - `@agentclientprotocol/sdk` ^0.10.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Sudocode AI
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,341 @@
1
+ # acp-factory
2
+
3
+ A TypeScript library for spawning and managing AI agents through the [Agent Client Protocol (ACP)](https://agentclientprotocol.com/).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install acp-factory
9
+ ```
10
+
11
+ ## Prerequisites
12
+
13
+ - Node.js 18+
14
+ - [Claude Code](https://claude.ai/claude-code) installed and authenticated (run `claude` once to set up)
15
+ - Or set `ANTHROPIC_API_KEY` environment variable
16
+
17
+ ## Quick Start
18
+
19
+ ```typescript
20
+ import { AgentFactory } from "acp-factory";
21
+
22
+ // Spawn a Claude Code agent
23
+ const agent = await AgentFactory.spawn("claude-code", {
24
+ permissionMode: "auto-approve",
25
+ });
26
+
27
+ // Create a session
28
+ const session = await agent.createSession(process.cwd());
29
+
30
+ // Send a prompt and stream responses
31
+ for await (const update of session.prompt("What files are in this directory?")) {
32
+ if (update.sessionUpdate === "agent_message_chunk") {
33
+ if (update.content.type === "text") {
34
+ process.stdout.write(update.content.text);
35
+ }
36
+ }
37
+ }
38
+
39
+ // Clean up
40
+ await agent.close();
41
+ ```
42
+
43
+ ## API Reference
44
+
45
+ ### AgentFactory
46
+
47
+ Static class for managing agent types and spawning agents.
48
+
49
+ ```typescript
50
+ // List available agents
51
+ AgentFactory.listAgents(); // ["claude-code"]
52
+
53
+ // Register a custom agent
54
+ AgentFactory.register("my-agent", {
55
+ command: "npx",
56
+ args: ["my-agent-acp"],
57
+ env: { MY_VAR: "value" },
58
+ });
59
+
60
+ // Spawn an agent
61
+ const agent = await AgentFactory.spawn("claude-code", options);
62
+ ```
63
+
64
+ ### AgentHandle
65
+
66
+ Represents a running agent process.
67
+
68
+ ```typescript
69
+ // Agent capabilities
70
+ agent.capabilities; // { loadSession: true, ... }
71
+
72
+ // Create a new session
73
+ const session = await agent.createSession("/path/to/cwd", {
74
+ mode: "code", // Optional: initial mode
75
+ mcpServers: [], // Optional: MCP servers to connect
76
+ });
77
+
78
+ // Load an existing session
79
+ const session = await agent.loadSession(sessionId, "/path/to/cwd");
80
+
81
+ // Fork an existing session (experimental)
82
+ const forkedSession = await agent.forkSession(sessionId);
83
+
84
+ // Close the agent
85
+ await agent.close();
86
+
87
+ // Check if running
88
+ agent.isRunning(); // true/false
89
+ ```
90
+
91
+ ### Session
92
+
93
+ High-level interface for interacting with an agent session.
94
+
95
+ ```typescript
96
+ // Session properties
97
+ session.id; // Session ID
98
+ session.modes; // Available modes ["code", "ask", ...]
99
+ session.models; // Available models ["claude-sonnet-4-...", ...]
100
+
101
+ // Send a prompt (returns async iterable)
102
+ for await (const update of session.prompt("Hello!")) {
103
+ // Handle updates
104
+ }
105
+
106
+ // Cancel the current prompt
107
+ await session.cancel();
108
+
109
+ // Set the session mode
110
+ await session.setMode("ask");
111
+
112
+ // Interrupt and redirect with new context
113
+ for await (const update of session.interruptWith("Focus on tests only")) {
114
+ // Handle updates from new prompt
115
+ }
116
+
117
+ // Fork the session (experimental)
118
+ const forkedSession = await session.fork();
119
+ ```
120
+
121
+ ## Session Updates
122
+
123
+ The `prompt()` method yields `SessionUpdate` objects:
124
+
125
+ ```typescript
126
+ for await (const update of session.prompt("Hello")) {
127
+ switch (update.sessionUpdate) {
128
+ case "agent_message_chunk":
129
+ // Text or image content from the agent
130
+ if (update.content.type === "text") {
131
+ process.stdout.write(update.content.text);
132
+ }
133
+ break;
134
+
135
+ case "tool_call":
136
+ // Agent is calling a tool
137
+ console.log(`Tool: ${update.title}`);
138
+ break;
139
+
140
+ case "tool_call_update":
141
+ // Tool call status changed
142
+ if (update.status === "completed") {
143
+ console.log("Tool completed");
144
+ }
145
+ break;
146
+
147
+ case "agent_thought_chunk":
148
+ // Agent's thinking (if enabled)
149
+ break;
150
+ }
151
+ }
152
+ ```
153
+
154
+ ## Permission Modes
155
+
156
+ Control how permission requests are handled:
157
+
158
+ ```typescript
159
+ // Auto-approve all requests (default)
160
+ await AgentFactory.spawn("claude-code", {
161
+ permissionMode: "auto-approve",
162
+ });
163
+
164
+ // Auto-deny all requests
165
+ await AgentFactory.spawn("claude-code", {
166
+ permissionMode: "auto-deny",
167
+ });
168
+
169
+ // Use a callback handler
170
+ await AgentFactory.spawn("claude-code", {
171
+ permissionMode: "callback",
172
+ onPermissionRequest: async (request) => {
173
+ // Return permission response
174
+ return {
175
+ outcome: { outcome: "selected", optionId: "allow" },
176
+ };
177
+ },
178
+ });
179
+
180
+ // Interactive mode - permissions emitted as session updates
181
+ await AgentFactory.spawn("claude-code", {
182
+ permissionMode: "interactive",
183
+ });
184
+ ```
185
+
186
+ ### Interactive Permissions
187
+
188
+ With `permissionMode: "interactive"`, permission requests appear as session updates:
189
+
190
+ ```typescript
191
+ import { type ExtendedSessionUpdate } from "acp-factory";
192
+
193
+ for await (const update of session.prompt("Write a file")) {
194
+ if (update.sessionUpdate === "permission_request") {
195
+ // Show options to user
196
+ console.log(`Permission needed: ${update.toolCall.title}`);
197
+ update.options.forEach((opt, i) => {
198
+ console.log(`${i + 1}. ${opt.name}`);
199
+ });
200
+
201
+ // Respond to the request
202
+ session.respondToPermission(update.requestId, update.options[0].optionId);
203
+ // Or cancel it
204
+ // session.cancelPermission(update.requestId);
205
+ }
206
+ }
207
+ ```
208
+
209
+ ## Interrupting and Redirecting
210
+
211
+ Interrupt an agent mid-execution and redirect with new context:
212
+
213
+ ```typescript
214
+ const promptIterator = session.prompt("Analyze this codebase")[Symbol.asyncIterator]();
215
+
216
+ while (true) {
217
+ const { done, value } = await promptIterator.next();
218
+ if (done) break;
219
+
220
+ handleUpdate(value);
221
+
222
+ if (userWantsToRedirect) {
223
+ // Interrupt and provide new direction
224
+ for await (const update of session.interruptWith("Focus only on the tests")) {
225
+ handleUpdate(update);
226
+ }
227
+ break;
228
+ }
229
+ }
230
+ ```
231
+
232
+ ## Forking Sessions
233
+
234
+ Fork a session to create an independent copy with shared history:
235
+
236
+ ```typescript
237
+ // Original session continues normally
238
+ const session = await agent.createSession(process.cwd());
239
+ await consumePrompt(session.prompt("Analyze the codebase"));
240
+
241
+ // Fork to generate summary without affecting original
242
+ const summarySession = await session.fork();
243
+ for await (const update of summarySession.prompt("Summarize our conversation")) {
244
+ // This doesn't affect the original session
245
+ }
246
+
247
+ // Original session can continue independently
248
+ for await (const update of session.prompt("Now implement the feature")) {
249
+ // Continues from original context
250
+ }
251
+ ```
252
+
253
+ ## Custom File and Terminal Handlers
254
+
255
+ Override default file operations or provide terminal support:
256
+
257
+ ```typescript
258
+ const agent = await AgentFactory.spawn("claude-code", {
259
+ // Custom file handling
260
+ onFileRead: async (path) => {
261
+ return await myCustomRead(path);
262
+ },
263
+ onFileWrite: async (path, content) => {
264
+ await myCustomWrite(path, content);
265
+ },
266
+
267
+ // Terminal support (all handlers required)
268
+ onTerminalCreate: async (params) => {
269
+ const id = createTerminal(params.command, params.args);
270
+ return { terminalId: id };
271
+ },
272
+ onTerminalOutput: async (terminalId) => {
273
+ return getTerminalOutput(terminalId);
274
+ },
275
+ onTerminalKill: async (terminalId) => {
276
+ killTerminal(terminalId);
277
+ },
278
+ onTerminalRelease: async (terminalId) => {
279
+ releaseTerminal(terminalId);
280
+ },
281
+ onTerminalWaitForExit: async (terminalId) => {
282
+ return await waitForExit(terminalId);
283
+ },
284
+ });
285
+ ```
286
+
287
+ ## Examples
288
+
289
+ See the [examples](./examples) directory:
290
+
291
+ - [`basic-usage.ts`](./examples/basic-usage.ts) - Simple prompt and response
292
+ - [`interactive-permissions.ts`](./examples/interactive-permissions.ts) - Handle permissions in UI
293
+ - [`interrupt-context.ts`](./examples/interrupt-context.ts) - Interrupt and redirect agent
294
+
295
+ Run examples with:
296
+
297
+ ```bash
298
+ npx tsx examples/basic-usage.ts
299
+ ```
300
+
301
+ ## Type Exports
302
+
303
+ The library exports all necessary types:
304
+
305
+ ```typescript
306
+ import {
307
+ // Core classes
308
+ AgentFactory,
309
+ AgentHandle,
310
+ Session,
311
+
312
+ // Configuration types
313
+ type AgentConfig,
314
+ type SpawnOptions,
315
+ type SessionOptions,
316
+ type PermissionMode,
317
+
318
+ // Session update types
319
+ type SessionUpdate,
320
+ type ExtendedSessionUpdate,
321
+ type PermissionRequestUpdate,
322
+
323
+ // Content types
324
+ type ContentBlock,
325
+ type TextContent,
326
+ type ImageContent,
327
+
328
+ // Tool types
329
+ type ToolCall,
330
+ type ToolCallUpdate,
331
+
332
+ // Permission types
333
+ type PermissionOption,
334
+ type RequestPermissionRequest,
335
+ type RequestPermissionResponse,
336
+ } from "acp-factory";
337
+ ```
338
+
339
+ ## License
340
+
341
+ MIT
@@ -0,0 +1,55 @@
1
+ /**
2
+ * AgentHandle - Represents a running agent with an ACP connection
3
+ */
4
+ import * as acp from "@agentclientprotocol/sdk";
5
+ import type { AgentConfig, SpawnOptions, SessionOptions } from "./types.js";
6
+ import type { AgentCapabilities } from "@agentclientprotocol/sdk";
7
+ import { Session } from "./session.js";
8
+ /**
9
+ * Handle to a running agent process with ACP connection
10
+ */
11
+ export declare class AgentHandle {
12
+ private readonly process;
13
+ private readonly connection;
14
+ private readonly clientHandler;
15
+ readonly capabilities: AgentCapabilities;
16
+ private constructor();
17
+ /**
18
+ * Create and initialize an agent handle
19
+ * @internal
20
+ */
21
+ static create(config: AgentConfig, options: SpawnOptions): Promise<AgentHandle>;
22
+ /**
23
+ * Create a new session with the agent
24
+ */
25
+ createSession(cwd: string, options?: SessionOptions): Promise<Session>;
26
+ /**
27
+ * Load an existing session by ID
28
+ */
29
+ loadSession(sessionId: string, cwd: string, mcpServers?: Array<{
30
+ name: string;
31
+ uri: string;
32
+ }>): Promise<Session>;
33
+ /**
34
+ * Fork an existing session to create a new independent session
35
+ *
36
+ * The forked session inherits the conversation history from the original,
37
+ * allowing operations without affecting the original session's state.
38
+ *
39
+ * @experimental This relies on the unstable session/fork ACP capability
40
+ */
41
+ forkSession(sessionId: string): Promise<Session>;
42
+ /**
43
+ * Close the agent connection and terminate the process
44
+ */
45
+ close(): Promise<void>;
46
+ /**
47
+ * Get the underlying connection (for advanced use)
48
+ */
49
+ getConnection(): acp.ClientSideConnection;
50
+ /**
51
+ * Check if the agent process is still running
52
+ */
53
+ isRunning(): boolean;
54
+ }
55
+ //# sourceMappingURL=agent-handle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-handle.d.ts","sourceRoot":"","sources":["../src/agent-handle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,GAAG,MAAM,0BAA0B,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC;;GAEG;AACH,qBAAa,WAAW;IAIpB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,aAAa;IALhC,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAAC;IAEzC,OAAO;IASP;;;OAGG;WACU,MAAM,CACjB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,WAAW,CAAC;IA+EvB;;OAEG;IACG,aAAa,CACjB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,OAAO,CAAC;IAuBnB;;OAEG;IACG,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAM,GACpD,OAAO,CAAC,OAAO,CAAC;IAoBnB;;;;;;;OAOG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkBtD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B;;OAEG;IACH,aAAa,IAAI,GAAG,CAAC,oBAAoB;IAIzC;;OAEG;IACH,SAAS,IAAI,OAAO;CAGrB"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * AgentHandle - Represents a running agent with an ACP connection
3
+ */
4
+ import { spawn } from "node:child_process";
5
+ import { Writable, Readable } from "node:stream";
6
+ import * as acp from "@agentclientprotocol/sdk";
7
+ import { Session } from "./session.js";
8
+ import { ACPClientHandler } from "./client-handler.js";
9
+ /**
10
+ * Handle to a running agent process with ACP connection
11
+ */
12
+ export class AgentHandle {
13
+ process;
14
+ connection;
15
+ clientHandler;
16
+ capabilities;
17
+ constructor(process, connection, clientHandler, capabilities) {
18
+ this.process = process;
19
+ this.connection = connection;
20
+ this.clientHandler = clientHandler;
21
+ this.capabilities = capabilities;
22
+ }
23
+ /**
24
+ * Create and initialize an agent handle
25
+ * @internal
26
+ */
27
+ static async create(config, options) {
28
+ // 1. Spawn subprocess
29
+ const env = {
30
+ ...process.env,
31
+ ...config.env,
32
+ ...options.env,
33
+ };
34
+ const agentProcess = spawn(config.command, config.args, {
35
+ stdio: ["pipe", "pipe", "inherit"],
36
+ env,
37
+ });
38
+ // Handle process errors
39
+ agentProcess.on("error", (err) => {
40
+ console.error(`Agent process error: ${err.message}`);
41
+ });
42
+ // 2. Set up NDJSON streams
43
+ if (!agentProcess.stdin || !agentProcess.stdout) {
44
+ agentProcess.kill();
45
+ throw new Error("Failed to get agent process stdio streams");
46
+ }
47
+ const input = Writable.toWeb(agentProcess.stdin);
48
+ const output = Readable.toWeb(agentProcess.stdout);
49
+ const stream = acp.ndJsonStream(input, output);
50
+ // 3. Create client handler and connection
51
+ const clientHandler = new ACPClientHandler({
52
+ onPermissionRequest: options.onPermissionRequest,
53
+ onFileRead: options.onFileRead,
54
+ onFileWrite: options.onFileWrite,
55
+ onTerminalCreate: options.onTerminalCreate,
56
+ onTerminalOutput: options.onTerminalOutput,
57
+ onTerminalKill: options.onTerminalKill,
58
+ onTerminalRelease: options.onTerminalRelease,
59
+ onTerminalWaitForExit: options.onTerminalWaitForExit,
60
+ }, options.permissionMode ?? "auto-approve");
61
+ const connection = new acp.ClientSideConnection(() => clientHandler, stream);
62
+ // 4. Initialize connection
63
+ try {
64
+ const initResult = await connection.initialize({
65
+ protocolVersion: acp.PROTOCOL_VERSION,
66
+ clientCapabilities: {
67
+ fs: {
68
+ readTextFile: true,
69
+ writeTextFile: true,
70
+ },
71
+ terminal: !!(options.onTerminalCreate &&
72
+ options.onTerminalOutput &&
73
+ options.onTerminalKill &&
74
+ options.onTerminalRelease &&
75
+ options.onTerminalWaitForExit),
76
+ },
77
+ });
78
+ return new AgentHandle(agentProcess, connection, clientHandler, initResult.agentCapabilities ?? {});
79
+ }
80
+ catch (error) {
81
+ agentProcess.kill();
82
+ throw error;
83
+ }
84
+ }
85
+ /**
86
+ * Create a new session with the agent
87
+ */
88
+ async createSession(cwd, options = {}) {
89
+ const result = await this.connection.newSession({
90
+ cwd,
91
+ mcpServers: options.mcpServers ?? [],
92
+ });
93
+ // Set mode if specified
94
+ if (options.mode && this.connection.setSessionMode) {
95
+ await this.connection.setSessionMode({
96
+ sessionId: result.sessionId,
97
+ modeId: options.mode,
98
+ });
99
+ }
100
+ return new Session(result.sessionId, this.connection, this.clientHandler, result.modes?.availableModes?.map((m) => m.id) ?? [], result.models?.availableModels?.map((m) => m.modelId) ?? []);
101
+ }
102
+ /**
103
+ * Load an existing session by ID
104
+ */
105
+ async loadSession(sessionId, cwd, mcpServers = []) {
106
+ if (!this.capabilities.loadSession) {
107
+ throw new Error("Agent does not support loading sessions");
108
+ }
109
+ const result = await this.connection.loadSession({
110
+ sessionId,
111
+ cwd,
112
+ mcpServers,
113
+ });
114
+ return new Session(sessionId, this.connection, this.clientHandler, result.modes?.availableModes?.map((m) => m.id) ?? [], result.models?.availableModels?.map((m) => m.modelId) ?? []);
115
+ }
116
+ /**
117
+ * Fork an existing session to create a new independent session
118
+ *
119
+ * The forked session inherits the conversation history from the original,
120
+ * allowing operations without affecting the original session's state.
121
+ *
122
+ * @experimental This relies on the unstable session/fork ACP capability
123
+ */
124
+ async forkSession(sessionId) {
125
+ if (!this.capabilities.sessionCapabilities?.fork) {
126
+ throw new Error("Agent does not support forking sessions");
127
+ }
128
+ const result = await this.connection.forkSession({
129
+ sessionId,
130
+ });
131
+ return new Session(result.sessionId, this.connection, this.clientHandler, result.modes?.availableModes?.map((m) => m.id) ?? [], result.models?.availableModels?.map((m) => m.modelId) ?? []);
132
+ }
133
+ /**
134
+ * Close the agent connection and terminate the process
135
+ */
136
+ async close() {
137
+ this.process.kill();
138
+ // Wait for the connection to close
139
+ await this.connection.closed;
140
+ }
141
+ /**
142
+ * Get the underlying connection (for advanced use)
143
+ */
144
+ getConnection() {
145
+ return this.connection;
146
+ }
147
+ /**
148
+ * Check if the agent process is still running
149
+ */
150
+ isRunning() {
151
+ return !this.process.killed && this.process.exitCode === null;
152
+ }
153
+ }
154
+ //# sourceMappingURL=agent-handle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-handle.js","sourceRoot":"","sources":["../src/agent-handle.ts"],"names":[],"mappings":"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"}