@rcrsr/rill-ext-claude-code 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Andre Bremer
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.
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Extension factory for Claude Code integration.
3
+ * Creates extension instance with config validation and process lifecycle management.
4
+ */
5
+ import { type ExtensionResult } from '@rcrsr/rill';
6
+ import type { ClaudeCodeConfig } from './types.js';
7
+ /**
8
+ * Create Claude Code extension instance.
9
+ * Validates configuration and returns host functions with cleanup.
10
+ *
11
+ * @param config - Extension configuration
12
+ * @returns ExtensionResult with prompt, skill, command functions and dispose
13
+ * @throws Error for invalid configuration (EC-1, EC-2)
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const ext = createClaudeCodeExtension({
18
+ * binaryPath: '/usr/local/bin/claude',
19
+ * defaultTimeout: 60000
20
+ * });
21
+ * // Use with rill runtime...
22
+ * await ext.dispose();
23
+ * ```
24
+ */
25
+ export declare function createClaudeCodeExtension(config?: ClaudeCodeConfig): ExtensionResult;
26
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAGL,KAAK,eAAe,EAGrB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,gBAAgB,EAAiB,MAAM,YAAY,CAAC;AAwGlE;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,GAAE,gBAAqB,GAC5B,eAAe,CAmTjB"}
@@ -0,0 +1,368 @@
1
+ /**
2
+ * Extension factory for Claude Code integration.
3
+ * Creates extension instance with config validation and process lifecycle management.
4
+ */
5
+ import which from 'which';
6
+ import { RuntimeError, emitExtensionEvent, } from '@rcrsr/rill';
7
+ import { spawnClaudeCli } from './process.js';
8
+ import { createStreamParser } from './stream-parser.js';
9
+ import { extractResult } from './result.js';
10
+ // ============================================================
11
+ // CONSTANTS
12
+ // ============================================================
13
+ const DEFAULT_BINARY_PATH = 'claude';
14
+ const DEFAULT_TIMEOUT = 30000;
15
+ const MAX_TIMEOUT = 300000;
16
+ // ============================================================
17
+ // HELPER FUNCTIONS
18
+ // ============================================================
19
+ /**
20
+ * Serialize dict args to CLI flags for skill/command.
21
+ * Boolean true values become flags without value, nested dicts use dot-notation.
22
+ *
23
+ * @param args - Dict of arguments to serialize
24
+ * @returns Array of CLI flag strings
25
+ */
26
+ function serializeArgsToFlags(args) {
27
+ const flags = [];
28
+ for (const [key, value] of Object.entries(args)) {
29
+ if (value === true) {
30
+ // Boolean true: flag without value
31
+ flags.push(`--${key}`);
32
+ }
33
+ else if (typeof value === 'object' &&
34
+ value !== null &&
35
+ !Array.isArray(value)) {
36
+ // Nested dict: dot-notation
37
+ const nested = value;
38
+ for (const [nestedKey, nestedValue] of Object.entries(nested)) {
39
+ flags.push(`--${key}.${nestedKey}`, String(nestedValue));
40
+ }
41
+ }
42
+ else {
43
+ // Other values: key-value pair
44
+ flags.push(`--${key}`, String(value));
45
+ }
46
+ }
47
+ return flags;
48
+ }
49
+ /**
50
+ * Truncate text to max length for event logging.
51
+ *
52
+ * @param text - Text to truncate
53
+ * @param maxLength - Maximum length (default: 100)
54
+ * @returns Truncated text with ellipsis if needed
55
+ */
56
+ function truncateText(text, maxLength = 100) {
57
+ if (text.length <= maxLength) {
58
+ return text;
59
+ }
60
+ return text.slice(0, maxLength) + '...';
61
+ }
62
+ // ============================================================
63
+ // VALIDATION
64
+ // ============================================================
65
+ /**
66
+ * Validate timeout is positive integer within bounds.
67
+ *
68
+ * @param timeout - Timeout in milliseconds
69
+ * @throws Error if timeout invalid
70
+ */
71
+ function validateTimeout(timeout) {
72
+ if (!Number.isInteger(timeout)) {
73
+ throw new Error('Invalid timeout: must be positive integer, max 300000');
74
+ }
75
+ if (timeout <= 0) {
76
+ throw new Error('Invalid timeout: must be positive integer, max 300000');
77
+ }
78
+ if (timeout > MAX_TIMEOUT) {
79
+ throw new Error('Invalid timeout: must be positive integer, max 300000');
80
+ }
81
+ }
82
+ // ============================================================
83
+ // FACTORY
84
+ // ============================================================
85
+ /**
86
+ * Create Claude Code extension instance.
87
+ * Validates configuration and returns host functions with cleanup.
88
+ *
89
+ * @param config - Extension configuration
90
+ * @returns ExtensionResult with prompt, skill, command functions and dispose
91
+ * @throws Error for invalid configuration (EC-1, EC-2)
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * const ext = createClaudeCodeExtension({
96
+ * binaryPath: '/usr/local/bin/claude',
97
+ * defaultTimeout: 60000
98
+ * });
99
+ * // Use with rill runtime...
100
+ * await ext.dispose();
101
+ * ```
102
+ */
103
+ export function createClaudeCodeExtension(config = {}) {
104
+ // Extract config with defaults
105
+ const binaryPath = config.binaryPath ?? DEFAULT_BINARY_PATH;
106
+ const defaultTimeout = config.defaultTimeout ?? DEFAULT_TIMEOUT;
107
+ // Validate timeout immediately
108
+ validateTimeout(defaultTimeout);
109
+ // Validate binary path eagerly (sync throw if not in PATH)
110
+ try {
111
+ which.sync(binaryPath);
112
+ }
113
+ catch {
114
+ throw new Error(`Binary not found: ${binaryPath}`);
115
+ }
116
+ // Track active processes for cleanup
117
+ const tracker = {
118
+ disposers: new Set(),
119
+ };
120
+ // Dispose function for cleanup
121
+ const dispose = () => {
122
+ // EC-16: Cleanup failure logs warning, doesn't throw
123
+ for (const disposer of tracker.disposers) {
124
+ try {
125
+ disposer();
126
+ }
127
+ catch (error) {
128
+ const message = error instanceof Error ? error.message : 'Unknown error';
129
+ console.warn(`Failed to cleanup process: ${message}`);
130
+ }
131
+ }
132
+ tracker.disposers.clear();
133
+ };
134
+ // Return extension result with implementations
135
+ const result = {
136
+ // IR-2: claude-code::prompt
137
+ prompt: {
138
+ params: [
139
+ { name: 'text', type: 'string' },
140
+ { name: 'options', type: 'dict', defaultValue: {} },
141
+ ],
142
+ fn: async (args, ctx) => {
143
+ const startTime = Date.now();
144
+ try {
145
+ // Extract arguments
146
+ const text = args[0];
147
+ const options = (args[1] ?? {});
148
+ // EC-3: Validate text is non-empty
149
+ if (text.trim().length === 0) {
150
+ throw new RuntimeError('RILL-R004', 'prompt text cannot be empty');
151
+ }
152
+ // Extract timeout option
153
+ const timeout = typeof options['timeout'] === 'number'
154
+ ? options['timeout']
155
+ : defaultTimeout;
156
+ // Spawn process and collect messages
157
+ const spawn = spawnClaudeCli(text, {
158
+ binaryPath,
159
+ timeoutMs: timeout,
160
+ });
161
+ // Register cleanup
162
+ tracker.disposers.add(spawn.dispose);
163
+ // Parse stream output
164
+ const parser = createStreamParser();
165
+ const messages = [];
166
+ spawn.ptyProcess.onData((chunk) => {
167
+ parser.processChunk(chunk, (msg) => messages.push(msg));
168
+ });
169
+ // Wait for process completion
170
+ try {
171
+ await spawn.exitCode;
172
+ parser.flush((msg) => messages.push(msg));
173
+ }
174
+ finally {
175
+ tracker.disposers.delete(spawn.dispose);
176
+ spawn.dispose();
177
+ }
178
+ // Extract result
179
+ const result = extractResult(messages);
180
+ // AC-17: Emit claude-code:prompt event
181
+ const duration = Date.now() - startTime;
182
+ emitExtensionEvent(ctx, {
183
+ event: 'claude-code:prompt',
184
+ subsystem: 'extension:claude-code',
185
+ prompt: truncateText(text),
186
+ duration,
187
+ });
188
+ // Convert to plain object literal for RillValue compatibility
189
+ return {
190
+ ...result,
191
+ tokens: { ...result.tokens },
192
+ };
193
+ }
194
+ catch (error) {
195
+ // AC-20: Emit claude-code:error event
196
+ const duration = Date.now() - startTime;
197
+ emitExtensionEvent(ctx, {
198
+ event: 'claude-code:error',
199
+ subsystem: 'extension:claude-code',
200
+ error: error instanceof Error ? error.message : 'Unknown error',
201
+ duration,
202
+ });
203
+ throw error;
204
+ }
205
+ },
206
+ description: 'Execute Claude Code prompt and return result text and token usage',
207
+ returnType: 'dict',
208
+ },
209
+ // IR-3: claude-code::skill
210
+ skill: {
211
+ params: [
212
+ { name: 'name', type: 'string' },
213
+ { name: 'args', type: 'dict', defaultValue: {} },
214
+ ],
215
+ fn: async (fnArgs, ctx) => {
216
+ const startTime = Date.now();
217
+ try {
218
+ // Extract arguments
219
+ const name = fnArgs[0];
220
+ const args = (fnArgs[1] ?? {});
221
+ // EC-10: Validate name is non-empty
222
+ if (name.trim().length === 0) {
223
+ throw new RuntimeError('RILL-R004', 'skill name cannot be empty');
224
+ }
225
+ // Format input as /{name} {serialized args}
226
+ const flags = serializeArgsToFlags(args);
227
+ const flagsText = flags.length > 0 ? ' ' + flags.join(' ') : '';
228
+ const prompt = `/${name}${flagsText}`;
229
+ // Extract timeout option
230
+ const timeout = typeof args['timeout'] === 'number'
231
+ ? args['timeout']
232
+ : defaultTimeout;
233
+ // Spawn process
234
+ const spawn = spawnClaudeCli(prompt, {
235
+ binaryPath,
236
+ timeoutMs: timeout,
237
+ });
238
+ tracker.disposers.add(spawn.dispose);
239
+ // Parse stream output
240
+ const parser = createStreamParser();
241
+ const messages = [];
242
+ spawn.ptyProcess.onData((chunk) => {
243
+ parser.processChunk(chunk, (msg) => messages.push(msg));
244
+ });
245
+ // Wait for process completion
246
+ try {
247
+ await spawn.exitCode;
248
+ parser.flush((msg) => messages.push(msg));
249
+ }
250
+ finally {
251
+ tracker.disposers.delete(spawn.dispose);
252
+ spawn.dispose();
253
+ }
254
+ // Extract result
255
+ const result = extractResult(messages);
256
+ // AC-18: Emit claude-code:skill event
257
+ const duration = Date.now() - startTime;
258
+ emitExtensionEvent(ctx, {
259
+ event: 'claude-code:skill',
260
+ subsystem: 'extension:claude-code',
261
+ name,
262
+ args,
263
+ duration,
264
+ });
265
+ // Convert to plain object literal for RillValue compatibility
266
+ return {
267
+ ...result,
268
+ tokens: { ...result.tokens },
269
+ };
270
+ }
271
+ catch (error) {
272
+ // AC-20: Emit claude-code:error event
273
+ const duration = Date.now() - startTime;
274
+ emitExtensionEvent(ctx, {
275
+ event: 'claude-code:error',
276
+ subsystem: 'extension:claude-code',
277
+ error: error instanceof Error ? error.message : 'Unknown error',
278
+ duration,
279
+ });
280
+ throw error;
281
+ }
282
+ },
283
+ description: 'Execute Claude Code skill with instruction and return structured result',
284
+ returnType: 'dict',
285
+ },
286
+ // IR-4: claude-code::command
287
+ command: {
288
+ params: [
289
+ { name: 'name', type: 'string' },
290
+ { name: 'args', type: 'dict', defaultValue: {} },
291
+ ],
292
+ fn: async (fnArgs, ctx) => {
293
+ const startTime = Date.now();
294
+ try {
295
+ // Extract arguments
296
+ const name = fnArgs[0];
297
+ const args = (fnArgs[1] ?? {});
298
+ // EC-13: Validate name is non-empty
299
+ if (name.trim().length === 0) {
300
+ throw new RuntimeError('RILL-R004', 'command name cannot be empty');
301
+ }
302
+ // Format input similar to skill
303
+ const flags = serializeArgsToFlags(args);
304
+ const flagsText = flags.length > 0 ? ' ' + flags.join(' ') : '';
305
+ const prompt = `/${name}${flagsText}`;
306
+ // Extract timeout option
307
+ const timeout = typeof args['timeout'] === 'number'
308
+ ? args['timeout']
309
+ : defaultTimeout;
310
+ // Spawn process
311
+ const spawn = spawnClaudeCli(prompt, {
312
+ binaryPath,
313
+ timeoutMs: timeout,
314
+ });
315
+ tracker.disposers.add(spawn.dispose);
316
+ // Parse stream output
317
+ const parser = createStreamParser();
318
+ const messages = [];
319
+ spawn.ptyProcess.onData((chunk) => {
320
+ parser.processChunk(chunk, (msg) => messages.push(msg));
321
+ });
322
+ // Wait for process completion
323
+ try {
324
+ await spawn.exitCode;
325
+ parser.flush((msg) => messages.push(msg));
326
+ }
327
+ finally {
328
+ tracker.disposers.delete(spawn.dispose);
329
+ spawn.dispose();
330
+ }
331
+ // Extract result
332
+ const result = extractResult(messages);
333
+ // AC-19: Emit claude-code:command event
334
+ const duration = Date.now() - startTime;
335
+ emitExtensionEvent(ctx, {
336
+ event: 'claude-code:command',
337
+ subsystem: 'extension:claude-code',
338
+ name,
339
+ args,
340
+ duration,
341
+ });
342
+ // Convert to plain object literal for RillValue compatibility
343
+ return {
344
+ ...result,
345
+ tokens: { ...result.tokens },
346
+ };
347
+ }
348
+ catch (error) {
349
+ // AC-20: Emit claude-code:error event
350
+ const duration = Date.now() - startTime;
351
+ emitExtensionEvent(ctx, {
352
+ event: 'claude-code:error',
353
+ subsystem: 'extension:claude-code',
354
+ error: error instanceof Error ? error.message : 'Unknown error',
355
+ duration,
356
+ });
357
+ throw error;
358
+ }
359
+ },
360
+ description: 'Execute Claude Code command with task description and return execution summary',
361
+ returnType: 'dict',
362
+ },
363
+ };
364
+ // IR-5: Dispose function for process cleanup
365
+ result.dispose = dispose;
366
+ return result;
367
+ }
368
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @rcrsr/rill-ext-claude-code
3
+ *
4
+ * Extension for executing Claude Code toolkit operations from rill scripts.
5
+ */
6
+ export declare const VERSION = "0.1.0";
7
+ export type { TokenCounts, TokenUsage, TextBlock, ToolUseBlock, ToolResultBlock, ContentBlock, SystemMessage, AssistantMessage, UserMessage, ResultMessage, ClaudeMessage, ClaudeCodeConfig, PromptOptions, ClaudeCodeResult, } from './types.js';
8
+ export type { StreamParser } from './stream-parser.js';
9
+ export { createStreamParser } from './stream-parser.js';
10
+ export { extractResult } from './result.js';
11
+ export type { SpawnResult, SpawnOptions } from './process.js';
12
+ export { spawnClaudeCli } from './process.js';
13
+ export { createClaudeCodeExtension } from './factory.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,eAAO,MAAM,OAAO,UAAU,CAAC;AAM/B,YAAY,EACV,WAAW,EACX,UAAU,EACV,SAAS,EACT,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAMpB,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAMxD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAM5C,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAM9C,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @rcrsr/rill-ext-claude-code
3
+ *
4
+ * Extension for executing Claude Code toolkit operations from rill scripts.
5
+ */
6
+ // ============================================================
7
+ // VERSION
8
+ // ============================================================
9
+ export const VERSION = '0.1.0';
10
+ export { createStreamParser } from './stream-parser.js';
11
+ // ============================================================
12
+ // RESULT EXTRACTION
13
+ // ============================================================
14
+ export { extractResult } from './result.js';
15
+ export { spawnClaudeCli } from './process.js';
16
+ // ============================================================
17
+ // EXTENSION FACTORY
18
+ // ============================================================
19
+ export { createClaudeCodeExtension } from './factory.js';
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,+DAA+D;AAC/D,UAAU;AACV,+DAA+D;AAE/D,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AA4B/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,+DAA+D;AAC/D,oBAAoB;AACpB,+DAA+D;AAE/D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAO5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,+DAA+D;AAC/D,oBAAoB;AACpB,+DAA+D;AAE/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Process manager for Claude CLI spawning and lifecycle.
3
+ * Handles PTY spawn, timeout enforcement, and cleanup.
4
+ */
5
+ import * as pty from 'node-pty';
6
+ /**
7
+ * Process spawn result.
8
+ * Includes PTY instance and cleanup function.
9
+ */
10
+ export interface SpawnResult {
11
+ /** PTY process instance */
12
+ readonly ptyProcess: pty.IPty;
13
+ /** Exit code promise (resolves when process exits) */
14
+ readonly exitCode: Promise<number>;
15
+ /** Cleanup function (kills process if running) */
16
+ readonly dispose: () => void;
17
+ }
18
+ /**
19
+ * Options for spawning Claude CLI process.
20
+ */
21
+ export interface SpawnOptions {
22
+ /** Path to Claude CLI binary (default: 'claude') */
23
+ readonly binaryPath?: string | undefined;
24
+ /** Timeout in milliseconds (kills process after duration) */
25
+ readonly timeoutMs?: number | undefined;
26
+ /** Working directory for process (default: inherit) */
27
+ readonly cwd?: string | undefined;
28
+ /** Environment variables (default: inherit) */
29
+ readonly env?: Record<string, string | undefined> | undefined;
30
+ }
31
+ /**
32
+ * Spawn Claude CLI process with timeout enforcement.
33
+ *
34
+ * @param prompt - User prompt to send to Claude
35
+ * @param options - Spawn options
36
+ * @returns Process handle with exit code and cleanup
37
+ * @throws RuntimeError RILL-R004 for spawn failures
38
+ */
39
+ export declare function spawnClaudeCli(prompt: string, options?: SpawnOptions): SpawnResult;
40
+ //# sourceMappingURL=process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../src/process.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAOhC;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,2BAA2B;IAC3B,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC;IAC9B,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,kDAAkD;IAClD,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,oDAAoD;IACpD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,6DAA6D;IAC7D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,uDAAuD;IACvD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,+CAA+C;IAC/C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;CAC/D;AAMD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,YAAiB,GACzB,WAAW,CA8Kb"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Process manager for Claude CLI spawning and lifecycle.
3
+ * Handles PTY spawn, timeout enforcement, and cleanup.
4
+ */
5
+ import * as pty from 'node-pty';
6
+ import { RuntimeError } from '@rcrsr/rill';
7
+ // ============================================================
8
+ // SPAWN FUNCTION
9
+ // ============================================================
10
+ /**
11
+ * Spawn Claude CLI process with timeout enforcement.
12
+ *
13
+ * @param prompt - User prompt to send to Claude
14
+ * @param options - Spawn options
15
+ * @returns Process handle with exit code and cleanup
16
+ * @throws RuntimeError RILL-R004 for spawn failures
17
+ */
18
+ export function spawnClaudeCli(prompt, options = {}) {
19
+ const { binaryPath = 'claude', timeoutMs, cwd = process.cwd(), env = process.env, } = options;
20
+ // Track timeout and process state
21
+ let timeoutId;
22
+ let disposed = false;
23
+ // Create promise for exit code
24
+ let resolveExit;
25
+ let rejectExit;
26
+ const exitCode = new Promise((resolve, reject) => {
27
+ resolveExit = resolve;
28
+ rejectExit = reject;
29
+ });
30
+ // Spawn process
31
+ let ptyProcess;
32
+ try {
33
+ ptyProcess = pty.spawn(binaryPath, [
34
+ '--output-format',
35
+ 'stream-json',
36
+ '--dangerously-skip-permissions',
37
+ '--verbose',
38
+ ], {
39
+ name: 'xterm-256color',
40
+ cols: 80,
41
+ rows: 30,
42
+ cwd,
43
+ env,
44
+ });
45
+ }
46
+ catch (error) {
47
+ // Handle spawn errors
48
+ if (error instanceof Error) {
49
+ const code = error.code;
50
+ // EC-4: Binary not found
51
+ if (code === 'ENOENT') {
52
+ throw new RuntimeError('RILL-R004', 'claude binary not found', undefined, { binaryPath });
53
+ }
54
+ // EC-5: Permission denied
55
+ if (code === 'EACCES') {
56
+ throw new RuntimeError('RILL-R004', 'Permission denied: claude', undefined, { binaryPath });
57
+ }
58
+ // EC-6: Generic spawn failure
59
+ throw new RuntimeError('RILL-R004', `Failed to spawn claude binary: ${error.message}`, undefined, { binaryPath, originalError: error.message });
60
+ }
61
+ // Unknown error type
62
+ throw new RuntimeError('RILL-R004', `Failed to spawn claude binary: Unknown error`, undefined, { binaryPath });
63
+ }
64
+ // Set up timeout enforcement
65
+ if (timeoutMs !== undefined && timeoutMs > 0) {
66
+ timeoutId = setTimeout(() => {
67
+ if (!disposed) {
68
+ disposed = true;
69
+ ptyProcess.kill();
70
+ rejectExit(new RuntimeError('RILL-R004', `Claude CLI timeout after ${timeoutMs}ms`, undefined, { timeoutMs }));
71
+ }
72
+ }, timeoutMs);
73
+ }
74
+ // Handle process exit
75
+ ptyProcess.onExit((event) => {
76
+ if (timeoutId) {
77
+ clearTimeout(timeoutId);
78
+ }
79
+ if (!disposed) {
80
+ disposed = true;
81
+ const { exitCode: code } = event;
82
+ // EC-9: Non-zero exit code
83
+ if (code !== 0) {
84
+ rejectExit(new RuntimeError('RILL-R004', `Claude CLI exited with code ${code}`, undefined, { exitCode: code }));
85
+ }
86
+ else {
87
+ resolveExit(code);
88
+ }
89
+ }
90
+ });
91
+ // Write prompt to stdin and close
92
+ try {
93
+ ptyProcess.write(prompt);
94
+ // Signal EOF by not writing more (PTY handles stdin closure differently)
95
+ }
96
+ catch (error) {
97
+ // If write fails, clean up and throw
98
+ if (timeoutId) {
99
+ clearTimeout(timeoutId);
100
+ }
101
+ ptyProcess.kill();
102
+ const message = error instanceof Error ? error.message : 'Unknown error';
103
+ throw new RuntimeError('RILL-R004', `Failed to write prompt to claude process: ${message}`, undefined, { originalError: message });
104
+ }
105
+ // Cleanup function
106
+ const dispose = () => {
107
+ if (disposed) {
108
+ return;
109
+ }
110
+ disposed = true;
111
+ if (timeoutId) {
112
+ clearTimeout(timeoutId);
113
+ }
114
+ // EC-16: Cleanup failure warning
115
+ try {
116
+ ptyProcess.kill();
117
+ }
118
+ catch (error) {
119
+ // Log warning but don't throw
120
+ const message = error instanceof Error ? error.message : 'Unknown error';
121
+ console.warn(`Failed to kill claude process during cleanup: ${message}`);
122
+ }
123
+ };
124
+ return {
125
+ ptyProcess,
126
+ exitCode,
127
+ dispose,
128
+ };
129
+ }
130
+ //# sourceMappingURL=process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../src/process.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAiC3C,+DAA+D;AAC/D,iBAAiB;AACjB,+DAA+D;AAE/D;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAc,EACd,UAAwB,EAAE;IAE1B,MAAM,EACJ,UAAU,GAAG,QAAQ,EACrB,SAAS,EACT,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,EACnB,GAAG,GAAG,OAAO,CAAC,GAAG,GAClB,GAAG,OAAO,CAAC;IAEZ,kCAAkC;IAClC,IAAI,SAAoD,CAAC;IACzD,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,+BAA+B;IAC/B,IAAI,WAAmC,CAAC;IACxC,IAAI,UAAkC,CAAC;IAEvC,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACvD,WAAW,GAAG,OAAO,CAAC;QACtB,UAAU,GAAG,MAAM,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,gBAAgB;IAChB,IAAI,UAAoB,CAAC;IACzB,IAAI,CAAC;QACH,UAAU,GAAG,GAAG,CAAC,KAAK,CACpB,UAAU,EACV;YACE,iBAAiB;YACjB,aAAa;YACb,gCAAgC;YAChC,WAAW;SACZ,EACD;YACE,IAAI,EAAE,gBAAgB;YACtB,IAAI,EAAE,EAAE;YACR,IAAI,EAAE,EAAE;YACR,GAAG;YACH,GAAG;SACJ,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,sBAAsB;QACtB,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAI,KAAmC,CAAC,IAAI,CAAC;YAEvD,yBAAyB;YACzB,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,MAAM,IAAI,YAAY,CACpB,WAAW,EACX,yBAAyB,EACzB,SAAS,EACT,EAAE,UAAU,EAAE,CACf,CAAC;YACJ,CAAC;YAED,0BAA0B;YAC1B,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,MAAM,IAAI,YAAY,CACpB,WAAW,EACX,2BAA2B,EAC3B,SAAS,EACT,EAAE,UAAU,EAAE,CACf,CAAC;YACJ,CAAC;YAED,8BAA8B;YAC9B,MAAM,IAAI,YAAY,CACpB,WAAW,EACX,kCAAkC,KAAK,CAAC,OAAO,EAAE,EACjD,SAAS,EACT,EAAE,UAAU,EAAE,aAAa,EAAE,KAAK,CAAC,OAAO,EAAE,CAC7C,CAAC;QACJ,CAAC;QAED,qBAAqB;QACrB,MAAM,IAAI,YAAY,CACpB,WAAW,EACX,8CAA8C,EAC9C,SAAS,EACT,EAAE,UAAU,EAAE,CACf,CAAC;IACJ,CAAC;IAED,6BAA6B;IAC7B,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAC7C,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAC1B,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,QAAQ,GAAG,IAAI,CAAC;gBAChB,UAAU,CAAC,IAAI,EAAE,CAAC;gBAClB,UAAU,CACR,IAAI,YAAY,CACd,WAAW,EACX,4BAA4B,SAAS,IAAI,EACzC,SAAS,EACT,EAAE,SAAS,EAAE,CACd,CACF,CAAC;YACJ,CAAC;QACH,CAAC,EAAE,SAAS,CAAC,CAAC;IAChB,CAAC;IAED,sBAAsB;IACtB,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QAC1B,IAAI,SAAS,EAAE,CAAC;YACd,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QAED,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG,IAAI,CAAC;YAChB,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;YAEjC,2BAA2B;YAC3B,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,UAAU,CACR,IAAI,YAAY,CACd,WAAW,EACX,+BAA+B,IAAI,EAAE,EACrC,SAAS,EACT,EAAE,QAAQ,EAAE,IAAI,EAAE,CACnB,CACF,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,WAAW,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,kCAAkC;IAClC,IAAI,CAAC;QACH,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACzB,yEAAyE;IAC3E,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,qCAAqC;QACrC,IAAI,SAAS,EAAE,CAAC;YACd,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QACD,UAAU,CAAC,IAAI,EAAE,CAAC;QAElB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACzE,MAAM,IAAI,YAAY,CACpB,WAAW,EACX,6CAA6C,OAAO,EAAE,EACtD,SAAS,EACT,EAAE,aAAa,EAAE,OAAO,EAAE,CAC3B,CAAC;IACJ,CAAC;IAED,mBAAmB;IACnB,MAAM,OAAO,GAAG,GAAS,EAAE;QACzB,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QAED,QAAQ,GAAG,IAAI,CAAC;QAEhB,IAAI,SAAS,EAAE,CAAC;YACd,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QAED,iCAAiC;QACjC,IAAI,CAAC;YACH,UAAU,CAAC,IAAI,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,8BAA8B;YAC9B,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YACzE,OAAO,CAAC,IAAI,CAAC,iDAAiD,OAAO,EAAE,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACL,UAAU;QACV,QAAQ;QACR,OAAO;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Result extraction from Claude Code message streams.
3
+ * Accumulates tokens, costs, and text from parsed messages.
4
+ */
5
+ import type { ClaudeMessage, ClaudeCodeResult } from './types.js';
6
+ /**
7
+ * Extracts complete ClaudeCodeResult from parsed message stream.
8
+ * Accumulates token counts across assistant messages and extracts cost/duration from final result message.
9
+ *
10
+ * @param messages - Parsed stream messages (ClaudeMessage[])
11
+ * @returns Complete result dict with text, tokens, cost, and exitCode
12
+ */
13
+ export declare function extractResult(messages: readonly ClaudeMessage[]): ClaudeCodeResult;
14
+ //# sourceMappingURL=result.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAIjB,MAAM,YAAY,CAAC;AAEpB;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,SAAS,aAAa,EAAE,GACjC,gBAAgB,CA8ClB"}
package/dist/result.js ADDED
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Result extraction from Claude Code message streams.
3
+ * Accumulates tokens, costs, and text from parsed messages.
4
+ */
5
+ /**
6
+ * Extracts complete ClaudeCodeResult from parsed message stream.
7
+ * Accumulates token counts across assistant messages and extracts cost/duration from final result message.
8
+ *
9
+ * @param messages - Parsed stream messages (ClaudeMessage[])
10
+ * @returns Complete result dict with text, tokens, cost, and exitCode
11
+ */
12
+ export function extractResult(messages) {
13
+ // Initialize accumulation state
14
+ const tokens = {
15
+ prompt: 0,
16
+ cacheWrite5m: 0,
17
+ cacheWrite1h: 0,
18
+ cacheRead: 0,
19
+ output: 0,
20
+ };
21
+ const textParts = [];
22
+ let cost = 0;
23
+ let duration = 0;
24
+ let exitCode = 0;
25
+ // Iterate messages and accumulate
26
+ for (const msg of messages) {
27
+ if (msg.type === 'assistant') {
28
+ // Accumulate token counts from usage field
29
+ if (msg.message.usage) {
30
+ accumulateTokens(tokens, msg.message.usage);
31
+ }
32
+ // Extract text content from content blocks
33
+ for (const block of msg.message.content) {
34
+ if (block.type === 'text') {
35
+ textParts.push(block.text);
36
+ }
37
+ }
38
+ }
39
+ else if (msg.type === 'result') {
40
+ // Extract cost and duration from final result message
41
+ cost = msg.cost_usd;
42
+ duration = msg.duration_ms;
43
+ exitCode = msg.is_error ? 1 : 0;
44
+ // Include final usage from result message
45
+ accumulateTokens(tokens, msg.usage);
46
+ }
47
+ }
48
+ return {
49
+ result: textParts.join(''),
50
+ tokens,
51
+ cost,
52
+ exitCode,
53
+ duration,
54
+ };
55
+ }
56
+ /**
57
+ * Accumulates token counts from usage field into TokenCounts structure.
58
+ * Maps usage fields to TokenCounts fields:
59
+ * - input_tokens -> prompt
60
+ * - output_tokens -> output
61
+ * - cache_creation.ephemeral_5m_input_tokens -> cacheWrite5m
62
+ * - cache_creation.ephemeral_1h_input_tokens -> cacheWrite1h
63
+ * - cache_read_input_tokens -> cacheRead
64
+ *
65
+ * @param tokens - TokenCounts accumulator (mutated)
66
+ * @param usage - TokenUsage from assistant message or result message
67
+ */
68
+ function accumulateTokens(tokens, usage) {
69
+ // Accumulate input tokens (non-cached prompt)
70
+ if (usage.input_tokens !== undefined) {
71
+ tokens.prompt += usage.input_tokens;
72
+ }
73
+ // Accumulate output tokens
74
+ if (usage.output_tokens !== undefined) {
75
+ tokens.output += usage.output_tokens;
76
+ }
77
+ // Accumulate cache write tokens (5-minute)
78
+ if (usage.cache_creation?.ephemeral_5m_input_tokens !== undefined) {
79
+ tokens.cacheWrite5m +=
80
+ usage.cache_creation.ephemeral_5m_input_tokens;
81
+ }
82
+ // Accumulate cache write tokens (1-hour)
83
+ if (usage.cache_creation?.ephemeral_1h_input_tokens !== undefined) {
84
+ tokens.cacheWrite1h +=
85
+ usage.cache_creation.ephemeral_1h_input_tokens;
86
+ }
87
+ // Accumulate cache read tokens
88
+ if (usage.cache_read_input_tokens !== undefined) {
89
+ tokens.cacheRead +=
90
+ usage.cache_read_input_tokens;
91
+ }
92
+ }
93
+ //# sourceMappingURL=result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,QAAkC;IAElC,gCAAgC;IAChC,MAAM,MAAM,GAAgB;QAC1B,MAAM,EAAE,CAAC;QACT,YAAY,EAAE,CAAC;QACf,YAAY,EAAE,CAAC;QACf,SAAS,EAAE,CAAC;QACZ,MAAM,EAAE,CAAC;KACV,CAAC;IACF,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,kCAAkC;IAClC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC7B,2CAA2C;YAC3C,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBACtB,gBAAgB,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC9C,CAAC;YAED,2CAA2C;YAC3C,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBACxC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBAC1B,SAAS,CAAC,IAAI,CAAE,KAAmB,CAAC,IAAI,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACjC,sDAAsD;YACtD,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC;YACpB,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC;YAC3B,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAEhC,0CAA0C;YAC1C,gBAAgB,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,OAAO;QACL,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM;QACN,IAAI;QACJ,QAAQ;QACR,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,gBAAgB,CAAC,MAAmB,EAAE,KAAiB;IAC9D,8CAA8C;IAC9C,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACpC,MAA6B,CAAC,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC;IAC9D,CAAC;IAED,2BAA2B;IAC3B,IAAI,KAAK,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACrC,MAA6B,CAAC,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC;IAC/D,CAAC;IAED,2CAA2C;IAC3C,IAAI,KAAK,CAAC,cAAc,EAAE,yBAAyB,KAAK,SAAS,EAAE,CAAC;QACjE,MAAmC,CAAC,YAAY;YAC/C,KAAK,CAAC,cAAc,CAAC,yBAAyB,CAAC;IACnD,CAAC;IAED,yCAAyC;IACzC,IAAI,KAAK,CAAC,cAAc,EAAE,yBAAyB,KAAK,SAAS,EAAE,CAAC;QACjE,MAAmC,CAAC,YAAY;YAC/C,KAAK,CAAC,cAAc,CAAC,yBAAyB,CAAC;IACnD,CAAC;IAED,+BAA+B;IAC/B,IAAI,KAAK,CAAC,uBAAuB,KAAK,SAAS,EAAE,CAAC;QAC/C,MAAgC,CAAC,SAAS;YACzC,KAAK,CAAC,uBAAuB,CAAC;IAClC,CAAC;AACH,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Stream parser for line-delimited JSON from Claude CLI.
3
+ * Handles chunked PTY output with ANSI escape sequences.
4
+ */
5
+ import type { ClaudeMessage } from './types.js';
6
+ /**
7
+ * Stream parser for line-delimited JSON.
8
+ * Buffers incomplete lines across chunks.
9
+ */
10
+ export interface StreamParser {
11
+ /**
12
+ * Process a chunk of raw PTY output.
13
+ * Emits parsed messages via callback.
14
+ * Throws RuntimeError RILL-R004 for invalid JSON on complete lines.
15
+ *
16
+ * @param chunk - Raw data from PTY (Buffer or string)
17
+ * @param onMessage - Callback for each parsed message
18
+ * @throws RuntimeError with code RILL-R004 for invalid JSON
19
+ */
20
+ processChunk(chunk: Buffer | string, onMessage: (message: ClaudeMessage) => void): void;
21
+ /**
22
+ * Flush remaining buffered data.
23
+ * Call when stream ends to process incomplete lines.
24
+ *
25
+ * @param onMessage - Callback for final parsed messages
26
+ * @throws RuntimeError with code RILL-R004 for invalid JSON
27
+ */
28
+ flush(onMessage: (message: ClaudeMessage) => void): void;
29
+ }
30
+ /**
31
+ * Create a new stream parser instance.
32
+ *
33
+ * @returns Stream parser with buffering state
34
+ */
35
+ export declare function createStreamParser(): StreamParser;
36
+ //# sourceMappingURL=stream-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-parser.d.ts","sourceRoot":"","sources":["../src/stream-parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMhD;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;;;OAQG;IACH,YAAY,CACV,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,SAAS,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,GAC1C,IAAI,CAAC;IAER;;;;;;OAMG;IACH,KAAK,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI,CAAC;CAC1D;AAuCD;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CAyEjD"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Stream parser for line-delimited JSON from Claude CLI.
3
+ * Handles chunked PTY output with ANSI escape sequences.
4
+ */
5
+ import { RuntimeError } from '@rcrsr/rill';
6
+ // ============================================================
7
+ // ANSI ESCAPE SEQUENCE REMOVAL
8
+ // ============================================================
9
+ /**
10
+ * Regular expression matching ANSI escape sequences.
11
+ * Matches CSI sequences (ESC[...m) and other control codes.
12
+ * Uses String.fromCharCode to avoid ESLint no-control-regex errors.
13
+ */
14
+ const ANSI_ESCAPE_PATTERN = new RegExp([
15
+ // CSI sequences: ESC [ ... letter
16
+ `${String.fromCharCode(0x1b)}\\[[0-9;]*[A-Za-z]`,
17
+ // OSC sequences: ESC ] ... BEL
18
+ `${String.fromCharCode(0x1b)}\\][^${String.fromCharCode(0x07)}]*${String.fromCharCode(0x07)}`,
19
+ // ESC = and ESC >
20
+ `${String.fromCharCode(0x1b)}[=>]`,
21
+ // Character set selection: ESC ( or ESC ) followed by code
22
+ `${String.fromCharCode(0x1b)}[()][AB012]`,
23
+ ].join('|'), 'g');
24
+ /**
25
+ * Strip ANSI escape sequences from text.
26
+ *
27
+ * @param text - Raw text with potential ANSI codes
28
+ * @returns Clean text with ANSI sequences removed
29
+ */
30
+ function stripAnsi(text) {
31
+ return text.replace(ANSI_ESCAPE_PATTERN, '');
32
+ }
33
+ // ============================================================
34
+ // PARSER FACTORY
35
+ // ============================================================
36
+ /**
37
+ * Create a new stream parser instance.
38
+ *
39
+ * @returns Stream parser with buffering state
40
+ */
41
+ export function createStreamParser() {
42
+ let buffer = '';
43
+ let lineNumber = 0;
44
+ /**
45
+ * Process a single complete line.
46
+ * Emits parsed message or throws RuntimeError on failure.
47
+ */
48
+ function processLine(line, onMessage) {
49
+ lineNumber++;
50
+ // Skip empty lines
51
+ if (line.trim().length === 0) {
52
+ return;
53
+ }
54
+ try {
55
+ const parsed = JSON.parse(line);
56
+ // Validate parsed object has 'type' discriminant
57
+ if (typeof parsed !== 'object' ||
58
+ parsed === null ||
59
+ !('type' in parsed)) {
60
+ throw new Error('Missing "type" field in message');
61
+ }
62
+ onMessage(parsed);
63
+ }
64
+ catch {
65
+ // EC-7: Complete line with invalid JSON is non-recoverable
66
+ throw new RuntimeError('RILL-R004', `Invalid stream-json output: line ${lineNumber}: ${line}`);
67
+ }
68
+ }
69
+ return {
70
+ processChunk(chunk, onMessage) {
71
+ // Convert Buffer to string if needed
72
+ const text = typeof chunk === 'string' ? chunk : chunk.toString('utf8');
73
+ // Append to buffer (ANSI codes included for now)
74
+ buffer += text;
75
+ // Process complete lines
76
+ let newlineIndex;
77
+ while ((newlineIndex = buffer.indexOf('\n')) !== -1) {
78
+ const rawLine = buffer.slice(0, newlineIndex);
79
+ buffer = buffer.slice(newlineIndex + 1);
80
+ // Strip ANSI from complete line before parsing
81
+ const cleanLine = stripAnsi(rawLine);
82
+ processLine(cleanLine, onMessage);
83
+ }
84
+ },
85
+ flush(onMessage) {
86
+ // Process remaining buffer as final line
87
+ if (buffer.trim().length > 0) {
88
+ const cleanLine = stripAnsi(buffer);
89
+ processLine(cleanLine, onMessage);
90
+ buffer = '';
91
+ }
92
+ },
93
+ };
94
+ }
95
+ //# sourceMappingURL=stream-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-parser.js","sourceRoot":"","sources":["../src/stream-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Type definitions for Claude Code extension.
3
+ * Defines message types, token tracking, and result structures.
4
+ */
5
+ /**
6
+ * Token count breakdown from Claude Code CLI.
7
+ * Tracks prompt tokens, cache operations, and output tokens.
8
+ */
9
+ export interface TokenCounts {
10
+ /** Non-cached prompt tokens */
11
+ readonly prompt: number;
12
+ /** Tokens written to 5-minute cache */
13
+ readonly cacheWrite5m: number;
14
+ /** Tokens written to 1-hour cache */
15
+ readonly cacheWrite1h: number;
16
+ /** Tokens read from cache */
17
+ readonly cacheRead: number;
18
+ /** Output tokens generated */
19
+ readonly output: number;
20
+ }
21
+ /**
22
+ * Token usage data from Claude API response.
23
+ * Maps to TokenCounts fields via extraction logic.
24
+ */
25
+ export interface TokenUsage {
26
+ /** Non-cached input tokens */
27
+ readonly input_tokens?: number | undefined;
28
+ /** Generated output tokens */
29
+ readonly output_tokens?: number | undefined;
30
+ /** Cache read tokens */
31
+ readonly cache_read_input_tokens?: number | undefined;
32
+ /** Structured cache creation tracking */
33
+ readonly cache_creation?: {
34
+ /** 5-minute cache write tokens */
35
+ readonly ephemeral_5m_input_tokens?: number | undefined;
36
+ /** 1-hour cache write tokens */
37
+ readonly ephemeral_1h_input_tokens?: number | undefined;
38
+ } | undefined;
39
+ }
40
+ /**
41
+ * Text content block.
42
+ */
43
+ export interface TextBlock {
44
+ readonly type: 'text';
45
+ readonly text: string;
46
+ }
47
+ /**
48
+ * Tool use request block.
49
+ */
50
+ export interface ToolUseBlock {
51
+ readonly type: 'tool_use';
52
+ readonly id: string;
53
+ readonly name: string;
54
+ readonly input: Record<string, unknown>;
55
+ }
56
+ /**
57
+ * Tool result response block.
58
+ */
59
+ export interface ToolResultBlock {
60
+ readonly type: 'tool_result';
61
+ readonly tool_use_id: string;
62
+ readonly content: string | unknown;
63
+ readonly is_error?: boolean | undefined;
64
+ }
65
+ /**
66
+ * Content block variants for message content arrays.
67
+ */
68
+ export type ContentBlock = TextBlock | ToolUseBlock | ToolResultBlock;
69
+ /**
70
+ * System initialization message.
71
+ * First message in stream, establishes session config.
72
+ */
73
+ export interface SystemMessage {
74
+ readonly type: 'system';
75
+ readonly subtype: 'init';
76
+ readonly model: string;
77
+ readonly tools?: readonly unknown[] | undefined;
78
+ readonly mcp_servers?: readonly unknown[] | undefined;
79
+ }
80
+ /**
81
+ * Assistant response message.
82
+ * Contains text and tool use blocks.
83
+ */
84
+ export interface AssistantMessage {
85
+ readonly type: 'assistant';
86
+ readonly message: {
87
+ readonly content: readonly ContentBlock[];
88
+ readonly usage?: TokenUsage | undefined;
89
+ };
90
+ }
91
+ /**
92
+ * User message with tool results.
93
+ * Contains tool result blocks.
94
+ */
95
+ export interface UserMessage {
96
+ readonly type: 'user';
97
+ readonly message: {
98
+ readonly content: readonly ContentBlock[];
99
+ };
100
+ }
101
+ /**
102
+ * Result message with cost and duration.
103
+ * Final message in stream with aggregated metrics.
104
+ */
105
+ export interface ResultMessage {
106
+ readonly type: 'result';
107
+ readonly cost_usd: number;
108
+ readonly duration_ms: number;
109
+ readonly is_error: boolean;
110
+ readonly usage: TokenUsage;
111
+ }
112
+ /**
113
+ * Discriminated union of all Claude Code message types.
114
+ * Discriminant field: `type`
115
+ */
116
+ export type ClaudeMessage = SystemMessage | AssistantMessage | UserMessage | ResultMessage;
117
+ /**
118
+ * Configuration options for Claude Code integration.
119
+ */
120
+ export interface ClaudeCodeConfig {
121
+ /** Path to Claude Code CLI binary (default: 'claude') */
122
+ readonly binaryPath?: string | undefined;
123
+ /** Default timeout in milliseconds (default: 120000) */
124
+ readonly defaultTimeout?: number | undefined;
125
+ }
126
+ /**
127
+ * Options for prompt execution.
128
+ */
129
+ export interface PromptOptions {
130
+ /** Execution timeout in milliseconds (overrides defaultTimeout) */
131
+ readonly timeout?: number | undefined;
132
+ }
133
+ /**
134
+ * Complete result from Claude Code prompt execution.
135
+ * Aggregates all stream messages into single structure.
136
+ */
137
+ export interface ClaudeCodeResult {
138
+ /** Combined text result from all assistant messages */
139
+ readonly result: string;
140
+ /** Token count breakdown */
141
+ readonly tokens: TokenCounts;
142
+ /** Total cost in USD */
143
+ readonly cost: number;
144
+ /** Exit code from CLI process (0 = success) */
145
+ readonly exitCode: number;
146
+ /** Total execution duration in milliseconds */
147
+ readonly duration: number;
148
+ }
149
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Type definitions for Claude Code extension.
3
+ * Defines message types, token tracking, and result structures.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@rcrsr/rill-ext-claude-code",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "peerDependencies": {
8
+ "node-pty": "^1.0.0",
9
+ "@rcrsr/rill": "^0.6.0"
10
+ },
11
+ "devDependencies": {
12
+ "@types/which": "^3.0.4",
13
+ "@rcrsr/rill": "^0.6.0"
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "dependencies": {
22
+ "which": "^6.0.0"
23
+ },
24
+ "scripts": {
25
+ "build": "tsc --build",
26
+ "test": "vitest run",
27
+ "typecheck": "tsc --noEmit",
28
+ "lint": "eslint --config ../../../eslint.config.js src/",
29
+ "check": "pnpm run build && pnpm run test && pnpm run lint"
30
+ }
31
+ }