@agent-link/agent 0.1.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.
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Claude Code SDK integration.
3
+ *
4
+ * Spawns `claude` as a child process with --output-format stream-json
5
+ * and --input-format stream-json for persistent bidirectional communication.
6
+ *
7
+ * Lifecycle:
8
+ * 1. Web user sends first message → startQuery() spawns Claude process
9
+ * 2. Each user message is enqueued into the inputStream
10
+ * 3. processOutput() iterates Claude stdout, forwarding messages via sendFn
11
+ * 4. On 'result' message → turn is complete, process stays alive for next turn
12
+ * 5. On abort / process exit → cleanup
13
+ */
14
+ import { type ChildProcess } from 'child_process';
15
+ import { Stream } from './stream.js';
16
+ export interface ClaudeMessage {
17
+ type: string;
18
+ subtype?: string;
19
+ [key: string]: unknown;
20
+ }
21
+ export interface ChatFile {
22
+ name: string;
23
+ mimeType: string;
24
+ data: string;
25
+ }
26
+ export interface ConversationState {
27
+ child: ChildProcess | null;
28
+ inputStream: Stream<ClaudeMessage> | null;
29
+ abortController: AbortController | null;
30
+ claudeSessionId: string | null;
31
+ workDir: string;
32
+ turnActive: boolean;
33
+ turnResultReceived: boolean;
34
+ }
35
+ type SendFn = (msg: Record<string, unknown>) => void;
36
+ export declare function setSendFn(fn: SendFn): void;
37
+ export declare function getConversation(): ConversationState | null;
38
+ /**
39
+ * Handle a chat message from the web client.
40
+ * Lazily starts the Claude process on the first message.
41
+ * If resumeSessionId is provided, resumes that Claude session.
42
+ */
43
+ export declare function handleChat(prompt: string, workDir: string, resumeSessionId?: string, files?: ChatFile[]): void;
44
+ /**
45
+ * Abort the current Claude process (e.g. on agent disconnect).
46
+ */
47
+ export declare function abort(): void;
48
+ /**
49
+ * Cancel the current execution (user pressed stop button).
50
+ * Kills the process and notifies the web client.
51
+ */
52
+ export declare function cancelExecution(): void;
53
+ /**
54
+ * Handle the user's answer to an AskUserQuestion control request.
55
+ * Writes a control_response back to Claude's stdin.
56
+ */
57
+ export declare function handleUserAnswer(requestId: string, answers: Record<string, unknown>): void;
58
+ export {};
package/dist/claude.js ADDED
@@ -0,0 +1,441 @@
1
+ /**
2
+ * Claude Code SDK integration.
3
+ *
4
+ * Spawns `claude` as a child process with --output-format stream-json
5
+ * and --input-format stream-json for persistent bidirectional communication.
6
+ *
7
+ * Lifecycle:
8
+ * 1. Web user sends first message → startQuery() spawns Claude process
9
+ * 2. Each user message is enqueued into the inputStream
10
+ * 3. processOutput() iterates Claude stdout, forwarding messages via sendFn
11
+ * 4. On 'result' message → turn is complete, process stays alive for next turn
12
+ * 5. On abort / process exit → cleanup
13
+ */
14
+ import { spawn } from 'child_process';
15
+ import { createInterface } from 'readline';
16
+ import { writeFileSync, mkdirSync, existsSync } from 'fs';
17
+ import { join } from 'path';
18
+ import { Stream } from './stream.js';
19
+ import { resolveClaudeCommand, getCleanEnv, streamToStdin, } from './sdk.js';
20
+ import { CONFIG_DIR } from './config.js';
21
+ // ── Module state ───────────────────────────────────────────────────────────
22
+ let conversation = null;
23
+ let sendFn = () => { };
24
+ const pendingControlRequests = new Map();
25
+ export function setSendFn(fn) {
26
+ sendFn = fn;
27
+ }
28
+ export function getConversation() {
29
+ return conversation;
30
+ }
31
+ // ── Public API ─────────────────────────────────────────────────────────────
32
+ /**
33
+ * Handle a chat message from the web client.
34
+ * Lazily starts the Claude process on the first message.
35
+ * If resumeSessionId is provided, resumes that Claude session.
36
+ */
37
+ export function handleChat(prompt, workDir, resumeSessionId, files) {
38
+ if (!conversation || !conversation.inputStream) {
39
+ startQuery(workDir, resumeSessionId);
40
+ }
41
+ const state = conversation;
42
+ state.turnActive = true;
43
+ state.turnResultReceived = false;
44
+ console.log(`[Claude] Sending: ${prompt.substring(0, 100)}${prompt.length > 100 ? '...' : ''}`);
45
+ if (files && files.length > 0) {
46
+ const content = processFilesForClaude(files, workDir, prompt);
47
+ state.inputStream.enqueue({
48
+ type: 'user',
49
+ message: { role: 'user', content },
50
+ });
51
+ }
52
+ else {
53
+ state.inputStream.enqueue({
54
+ type: 'user',
55
+ message: { role: 'user', content: prompt },
56
+ });
57
+ }
58
+ }
59
+ /**
60
+ * Abort the current Claude process (e.g. on agent disconnect).
61
+ */
62
+ export function abort() {
63
+ if (conversation?.abortController) {
64
+ conversation.abortController.abort();
65
+ }
66
+ cleanup();
67
+ }
68
+ /**
69
+ * Cancel the current execution (user pressed stop button).
70
+ * Kills the process and notifies the web client.
71
+ */
72
+ export function cancelExecution() {
73
+ if (!conversation)
74
+ return;
75
+ console.log('[Claude] Cancelling execution');
76
+ conversation.turnActive = false;
77
+ if (conversation.abortController) {
78
+ conversation.abortController.abort();
79
+ }
80
+ cleanup();
81
+ sendFn({ type: 'execution_cancelled' });
82
+ }
83
+ /**
84
+ * Handle the user's answer to an AskUserQuestion control request.
85
+ * Writes a control_response back to Claude's stdin.
86
+ */
87
+ export function handleUserAnswer(requestId, answers) {
88
+ const pending = pendingControlRequests.get(requestId);
89
+ if (!pending) {
90
+ console.warn(`[Claude] No pending control request for requestId: ${requestId}`);
91
+ return;
92
+ }
93
+ pendingControlRequests.delete(requestId);
94
+ console.log(`[Claude] Answering AskUserQuestion ${requestId}`);
95
+ const controlResponse = {
96
+ type: 'control_response',
97
+ response: {
98
+ subtype: 'success',
99
+ request_id: pending.request.request_id,
100
+ response: {
101
+ behavior: 'allow',
102
+ updatedInput: {
103
+ questions: pending.request.request.input?.questions || [],
104
+ answers,
105
+ },
106
+ },
107
+ },
108
+ };
109
+ if (pending.child.stdin && !pending.child.stdin.destroyed) {
110
+ pending.child.stdin.write(JSON.stringify(controlResponse) + '\n');
111
+ }
112
+ }
113
+ // ── Internal ───────────────────────────────────────────────────────────────
114
+ function processFilesForClaude(files, workDir, prompt) {
115
+ const attachDir = join(CONFIG_DIR, 'tmp-attachments');
116
+ if (!existsSync(attachDir)) {
117
+ mkdirSync(attachDir, { recursive: true });
118
+ }
119
+ const content = [];
120
+ const nonImagePaths = [];
121
+ for (const file of files) {
122
+ const timestamp = Date.now();
123
+ const safeName = file.name.replace(/[^a-zA-Z0-9._-]/g, '_');
124
+ const diskName = `${timestamp}-${safeName}`;
125
+ const diskPath = join(attachDir, diskName);
126
+ // Write file to disk
127
+ writeFileSync(diskPath, Buffer.from(file.data, 'base64'));
128
+ console.log(`[Claude] Saved attachment: ${diskPath}`);
129
+ if (file.mimeType.startsWith('image/')) {
130
+ // Images: send as inline base64 content blocks
131
+ content.push({
132
+ type: 'image',
133
+ source: {
134
+ type: 'base64',
135
+ media_type: file.mimeType,
136
+ data: file.data,
137
+ },
138
+ });
139
+ }
140
+ else {
141
+ // Non-images: reference by file path
142
+ nonImagePaths.push(diskPath);
143
+ }
144
+ }
145
+ // Build text block with prompt + file references
146
+ let textContent = prompt;
147
+ if (nonImagePaths.length > 0) {
148
+ textContent += '\n\nAttached files:\n' + nonImagePaths.map(p => `- ${p}`).join('\n');
149
+ }
150
+ content.push({ type: 'text', text: textContent });
151
+ return content;
152
+ }
153
+ function startQuery(workDir, resumeSessionId) {
154
+ // Tear down previous process if any
155
+ if (conversation) {
156
+ abort();
157
+ }
158
+ const inputStream = new Stream();
159
+ const abortController = new AbortController();
160
+ const state = {
161
+ child: null,
162
+ inputStream,
163
+ abortController,
164
+ claudeSessionId: resumeSessionId || null,
165
+ workDir,
166
+ turnActive: false,
167
+ turnResultReceived: false,
168
+ };
169
+ conversation = state;
170
+ // Build args
171
+ // bypassPermissions auto-approves all regular tool calls.
172
+ // --permission-prompt-tool stdio tells Claude CLI to send control_request
173
+ // via stdout for interactive tools (like AskUserQuestion) instead of
174
+ // auto-denying them. Our handleControlRequest() intercepts these and
175
+ // either auto-approves or forwards to the web UI.
176
+ const args = [
177
+ '--output-format', 'stream-json',
178
+ '--input-format', 'stream-json',
179
+ '--verbose',
180
+ '--permission-mode', 'bypassPermissions',
181
+ '--permission-prompt-tool', 'stdio',
182
+ ];
183
+ if (resumeSessionId) {
184
+ args.push('--resume', resumeSessionId);
185
+ console.log(`[Claude] Resuming session: ${resumeSessionId}`);
186
+ }
187
+ const { command, prefixArgs, spawnOpts } = resolveClaudeCommand();
188
+ const env = getCleanEnv();
189
+ console.log(`[Claude] Spawning: ${command} ${[...prefixArgs, ...args].join(' ')}`);
190
+ console.log(`[Claude] cwd: ${workDir}`);
191
+ const child = spawn(command, [...prefixArgs, ...args], {
192
+ cwd: workDir,
193
+ stdio: ['pipe', 'pipe', 'pipe'],
194
+ signal: abortController.signal,
195
+ env,
196
+ windowsHide: true,
197
+ ...spawnOpts,
198
+ });
199
+ state.child = child;
200
+ // Pipe user messages → stdin
201
+ streamToStdin(inputStream, child.stdin, abortController.signal);
202
+ // Capture stderr for debugging
203
+ let stderrBuf = '';
204
+ child.stderr.on('data', (data) => {
205
+ const text = data.toString();
206
+ stderrBuf += text;
207
+ if (process.env.DEBUG)
208
+ console.error('[Claude stderr]', text);
209
+ });
210
+ // Process stdout (JSON lines)
211
+ processOutput(child, state, stderrBuf);
212
+ // Handle process exit
213
+ child.on('close', (code) => {
214
+ if (code !== 0 && code !== null && !abortController.signal.aborted) {
215
+ const msg = stderrBuf
216
+ ? `Claude process exited with code ${code}: ${stderrBuf.trim()}`
217
+ : `Claude process exited with code ${code}`;
218
+ console.error(`[Claude] ${msg}`);
219
+ }
220
+ });
221
+ child.on('error', (err) => {
222
+ if (!abortController.signal.aborted) {
223
+ console.error(`[Claude] Process error: ${err.message}`);
224
+ }
225
+ });
226
+ }
227
+ async function processOutput(child, state, _stderrBuf) {
228
+ const rl = createInterface({ input: child.stdout });
229
+ const messageStream = new Stream();
230
+ // Reader: parse JSON lines from stdout → messageStream
231
+ (async () => {
232
+ try {
233
+ for await (const line of rl) {
234
+ if (!line.trim())
235
+ continue;
236
+ try {
237
+ const msg = JSON.parse(line);
238
+ // Capture session ID from system init
239
+ if (msg.type === 'system' && msg.session_id) {
240
+ state.claudeSessionId = msg.session_id;
241
+ console.log(`[Claude] Session ID: ${state.claudeSessionId}`);
242
+ }
243
+ // Handle control_request (tool permission checks)
244
+ if (msg.type === 'control_request') {
245
+ handleControlRequest(msg, child);
246
+ continue;
247
+ }
248
+ // Handle control_cancel_request (abort pending questions)
249
+ if (msg.type === 'control_cancel_request') {
250
+ const reqId = msg.request_id;
251
+ if (pendingControlRequests.has(reqId)) {
252
+ console.log(`[Claude] Control request cancelled: ${reqId}`);
253
+ pendingControlRequests.delete(reqId);
254
+ }
255
+ continue;
256
+ }
257
+ // Ignore control_response (responses to our own requests, if any)
258
+ if (msg.type === 'control_response') {
259
+ continue;
260
+ }
261
+ messageStream.enqueue(msg);
262
+ }
263
+ catch {
264
+ // Non-JSON line, ignore
265
+ }
266
+ }
267
+ }
268
+ catch (err) {
269
+ messageStream.error(err);
270
+ }
271
+ finally {
272
+ messageStream.done();
273
+ rl.close();
274
+ }
275
+ })();
276
+ // Consumer: iterate messages and forward to web client
277
+ let resultHandled = false;
278
+ // Track accumulated text for streaming delta computation
279
+ let lastSentText = '';
280
+ try {
281
+ for await (const msg of messageStream) {
282
+ // ── result → turn complete ──
283
+ if (msg.type === 'result') {
284
+ if (state.turnResultReceived) {
285
+ // Suppress duplicate result (SDK can emit more than one)
286
+ continue;
287
+ }
288
+ state.turnResultReceived = true;
289
+ resultHandled = true;
290
+ state.turnActive = false;
291
+ // Reset streaming text tracker
292
+ lastSentText = '';
293
+ // Forward the result, then signal turn_completed
294
+ sendOutput(msg);
295
+ sendFn({ type: 'turn_completed' });
296
+ continue;
297
+ }
298
+ // ── assistant message → extract delta and forward incrementally ──
299
+ if (msg.type === 'assistant' && msg.message) {
300
+ const message = msg.message;
301
+ const content = message.content;
302
+ if (Array.isArray(content)) {
303
+ // Extract full text from all text blocks
304
+ const fullText = content
305
+ .filter((b) => b.type === 'text')
306
+ .map((b) => b.text || '')
307
+ .join('');
308
+ // Compute delta (new text since last emit)
309
+ if (fullText.length > lastSentText.length) {
310
+ const delta = fullText.slice(lastSentText.length);
311
+ lastSentText = fullText;
312
+ sendFn({
313
+ type: 'claude_output',
314
+ data: { type: 'content_block_delta', delta },
315
+ });
316
+ }
317
+ // Forward tool_use blocks as-is (they appear once)
318
+ // Filter out AskUserQuestion — handled via control_request path
319
+ const toolBlocks = content.filter((b) => b.type === 'tool_use' && b.name !== 'AskUserQuestion');
320
+ if (toolBlocks.length > 0) {
321
+ sendFn({
322
+ type: 'claude_output',
323
+ data: { type: 'tool_use', tools: toolBlocks },
324
+ });
325
+ }
326
+ }
327
+ continue;
328
+ }
329
+ // ── user (tool_result) → forward, reset text tracker ──
330
+ if (msg.type === 'user') {
331
+ // New turn segment — reset delta tracker for next assistant message
332
+ lastSentText = '';
333
+ sendOutput(msg);
334
+ continue;
335
+ }
336
+ // ── system messages (init, compact, etc.) ──
337
+ if (msg.type === 'system') {
338
+ const sub = (msg.subtype || '');
339
+ console.log(`[Claude] system/${sub}`);
340
+ // Forward context compaction events to web client
341
+ // New format: subtype='status', status='compacting'
342
+ if (sub === 'status' && msg.status === 'compacting') {
343
+ sendFn({ type: 'context_compaction', status: 'started' });
344
+ }
345
+ // Compact boundary = compaction completed
346
+ else if (sub === 'compact_boundary') {
347
+ sendFn({ type: 'context_compaction', status: 'completed' });
348
+ }
349
+ // Legacy subtypes
350
+ else if (sub === 'compact_start') {
351
+ sendFn({ type: 'context_compaction', status: 'started' });
352
+ }
353
+ else if (sub === 'compact_complete' || sub === 'compact_end') {
354
+ sendFn({ type: 'context_compaction', status: 'completed' });
355
+ }
356
+ continue;
357
+ }
358
+ }
359
+ }
360
+ catch (err) {
361
+ const error = err;
362
+ if (error.name === 'AbortError') {
363
+ console.log('[Claude] Query aborted');
364
+ }
365
+ else if (resultHandled) {
366
+ // Ignore post-turn errors
367
+ console.warn(`[Claude] Ignoring post-result error: ${error.message}`);
368
+ }
369
+ else {
370
+ console.error(`[Claude] Error: ${error.message}`);
371
+ sendFn({
372
+ type: 'error',
373
+ message: `Claude error: ${error.message}`,
374
+ });
375
+ }
376
+ }
377
+ finally {
378
+ // If the process exited mid-turn without a result, notify web client
379
+ if (!resultHandled && state.turnActive) {
380
+ sendFn({ type: 'turn_completed' });
381
+ }
382
+ state.turnActive = false;
383
+ // Only clean up if this is still the active conversation
384
+ if (conversation === state) {
385
+ state.child = null;
386
+ state.inputStream = null;
387
+ }
388
+ }
389
+ }
390
+ function sendOutput(data) {
391
+ sendFn({ type: 'claude_output', data });
392
+ }
393
+ /**
394
+ * Handle an incoming control_request from Claude's stdout.
395
+ * For AskUserQuestion: forward to web UI and wait for user answer.
396
+ * For other tools: auto-approve immediately.
397
+ */
398
+ function handleControlRequest(request, child) {
399
+ const requestId = request.request_id;
400
+ const subtype = request.request?.subtype;
401
+ if (subtype === 'can_use_tool' && request.request.tool_name === 'AskUserQuestion') {
402
+ console.log(`[Claude] AskUserQuestion control_request: ${requestId}`);
403
+ pendingControlRequests.set(requestId, { request, child });
404
+ // Forward to web UI
405
+ sendFn({
406
+ type: 'ask_user_question',
407
+ requestId,
408
+ questions: request.request.input?.questions || [],
409
+ });
410
+ return;
411
+ }
412
+ // Auto-approve all other tool calls
413
+ const autoApproveResponse = {
414
+ type: 'control_response',
415
+ response: {
416
+ subtype: 'success',
417
+ request_id: requestId,
418
+ response: {
419
+ behavior: 'allow',
420
+ updatedInput: request.request.input || {},
421
+ },
422
+ },
423
+ };
424
+ if (child.stdin && !child.stdin.destroyed) {
425
+ child.stdin.write(JSON.stringify(autoApproveResponse) + '\n');
426
+ }
427
+ }
428
+ function cleanup() {
429
+ // Clear any pending control requests
430
+ pendingControlRequests.clear();
431
+ if (conversation) {
432
+ if (conversation.child && !conversation.child.killed) {
433
+ conversation.child.kill();
434
+ }
435
+ if (conversation.inputStream) {
436
+ conversation.inputStream.done();
437
+ }
438
+ conversation = null;
439
+ }
440
+ }
441
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};