@rcrsr/rill-ext-claude-code 0.9.0 → 0.16.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/dist/index.js CHANGED
@@ -1,26 +1,712 @@
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
- export const configSchema = {
21
- binaryPath: { type: 'string' },
22
- defaultTimeout: { type: 'number' },
23
- dangerouslySkipPermissions: { type: 'boolean' },
24
- settingSources: { type: 'string' },
1
+ // src/index.ts
2
+ import { createRequire } from "module";
3
+
4
+ // src/stream-parser.ts
5
+ var ANSI_ESCAPE_PATTERN = new RegExp(
6
+ [
7
+ // CSI sequences: ESC [ ... letter
8
+ `${String.fromCharCode(27)}\\[[0-9;]*[A-Za-z]`,
9
+ // OSC sequences: ESC ] ... BEL
10
+ `${String.fromCharCode(27)}\\][^${String.fromCharCode(7)}]*${String.fromCharCode(7)}`,
11
+ // ESC = and ESC >
12
+ `${String.fromCharCode(27)}[=>]`,
13
+ // Character set selection: ESC ( or ESC ) followed by code
14
+ `${String.fromCharCode(27)}[()][AB012]`
15
+ ].join("|"),
16
+ "g"
17
+ );
18
+ function stripAnsi(text) {
19
+ return text.replace(ANSI_ESCAPE_PATTERN, "");
20
+ }
21
+ function createStreamParser() {
22
+ let buffer = "";
23
+ function processLine(line, onMessage) {
24
+ if (line.trim().length === 0) {
25
+ return;
26
+ }
27
+ const cleaned = line.trim().replace(/\[<u/g, "");
28
+ if (cleaned.length === 0) {
29
+ return;
30
+ }
31
+ try {
32
+ const parsed = JSON.parse(cleaned);
33
+ if (typeof parsed !== "object" || parsed === null || !("type" in parsed)) {
34
+ return;
35
+ }
36
+ onMessage(parsed);
37
+ } catch {
38
+ }
39
+ }
40
+ return {
41
+ processChunk(chunk, onMessage) {
42
+ const text = typeof chunk === "string" ? chunk : chunk.toString("utf8");
43
+ buffer += text;
44
+ let newlineIndex;
45
+ while ((newlineIndex = buffer.indexOf("\n")) !== -1) {
46
+ const rawLine = buffer.slice(0, newlineIndex);
47
+ buffer = buffer.slice(newlineIndex + 1);
48
+ const cleanLine = stripAnsi(rawLine);
49
+ processLine(cleanLine, onMessage);
50
+ }
51
+ },
52
+ flush(onMessage) {
53
+ if (buffer.trim().length > 0) {
54
+ const cleanLine = stripAnsi(buffer);
55
+ processLine(cleanLine, onMessage);
56
+ buffer = "";
57
+ }
58
+ }
59
+ };
60
+ }
61
+
62
+ // src/result.ts
63
+ function extractResult(messages) {
64
+ const tokens = {
65
+ prompt: 0,
66
+ cacheWrite5m: 0,
67
+ cacheWrite1h: 0,
68
+ cacheRead: 0,
69
+ output: 0
70
+ };
71
+ const textParts = [];
72
+ let cost = 0;
73
+ let duration = 0;
74
+ let exitCode = 0;
75
+ for (const msg of messages) {
76
+ if (msg.type === "assistant") {
77
+ if (msg.message.usage) {
78
+ accumulateTokens(tokens, msg.message.usage);
79
+ }
80
+ for (const block of msg.message.content) {
81
+ if (block.type === "text") {
82
+ textParts.push(block.text);
83
+ }
84
+ }
85
+ } else if (msg.type === "result") {
86
+ cost = msg.cost_usd;
87
+ duration = msg.duration_ms;
88
+ exitCode = msg.is_error ? 1 : 0;
89
+ accumulateTokens(tokens, msg.usage);
90
+ }
91
+ }
92
+ return {
93
+ result: textParts.join(""),
94
+ tokens,
95
+ cost,
96
+ exitCode,
97
+ duration
98
+ };
99
+ }
100
+ function accumulateTokens(tokens, usage) {
101
+ if (usage.input_tokens !== void 0) {
102
+ tokens.prompt += usage.input_tokens;
103
+ }
104
+ if (usage.output_tokens !== void 0) {
105
+ tokens.output += usage.output_tokens;
106
+ }
107
+ if (usage.cache_creation?.ephemeral_5m_input_tokens !== void 0) {
108
+ tokens.cacheWrite5m += usage.cache_creation.ephemeral_5m_input_tokens;
109
+ }
110
+ if (usage.cache_creation?.ephemeral_1h_input_tokens !== void 0) {
111
+ tokens.cacheWrite1h += usage.cache_creation.ephemeral_1h_input_tokens;
112
+ }
113
+ if (usage.cache_read_input_tokens !== void 0) {
114
+ tokens.cacheRead += usage.cache_read_input_tokens;
115
+ }
116
+ }
117
+
118
+ // src/process.ts
119
+ import * as pty from "node-pty";
120
+ import { RuntimeError } from "@rcrsr/rill";
121
+ function spawnClaudeCli(prompt, options = {}) {
122
+ const {
123
+ binaryPath = "claude",
124
+ timeoutMs,
125
+ cwd = process.cwd(),
126
+ env = process.env,
127
+ dangerouslySkipPermissions = true,
128
+ settingSources = ""
129
+ } = options;
130
+ const args = [
131
+ "-p",
132
+ prompt,
133
+ "--output-format",
134
+ "stream-json",
135
+ "--verbose",
136
+ "--no-session-persistence",
137
+ "--setting-sources",
138
+ settingSources
139
+ ];
140
+ if (dangerouslySkipPermissions) {
141
+ args.push("--dangerously-skip-permissions");
142
+ }
143
+ let timeoutId;
144
+ let disposed = false;
145
+ let resolveExit;
146
+ let rejectExit;
147
+ const exitCode = new Promise((resolve, reject) => {
148
+ resolveExit = resolve;
149
+ rejectExit = reject;
150
+ });
151
+ let ptyProcess;
152
+ try {
153
+ ptyProcess = pty.spawn(binaryPath, args, {
154
+ name: "xterm-256color",
155
+ cols: 80,
156
+ rows: 30,
157
+ cwd,
158
+ env
159
+ });
160
+ } catch (error) {
161
+ if (error instanceof Error) {
162
+ const code = error.code;
163
+ if (code === "ENOENT") {
164
+ throw new RuntimeError(
165
+ "RILL-R004",
166
+ "claude binary not found",
167
+ void 0,
168
+ { binaryPath }
169
+ );
170
+ }
171
+ if (code === "EACCES") {
172
+ throw new RuntimeError(
173
+ "RILL-R004",
174
+ "Permission denied: claude",
175
+ void 0,
176
+ { binaryPath }
177
+ );
178
+ }
179
+ throw new RuntimeError(
180
+ "RILL-R004",
181
+ `Failed to spawn claude binary: ${error.message}`,
182
+ void 0,
183
+ { binaryPath, originalError: error.message }
184
+ );
185
+ }
186
+ throw new RuntimeError(
187
+ "RILL-R004",
188
+ `Failed to spawn claude binary: Unknown error`,
189
+ void 0,
190
+ { binaryPath }
191
+ );
192
+ }
193
+ if (timeoutMs !== void 0 && timeoutMs > 0) {
194
+ timeoutId = setTimeout(() => {
195
+ if (!disposed) {
196
+ disposed = true;
197
+ ptyProcess.kill();
198
+ rejectExit(
199
+ new RuntimeError(
200
+ "RILL-R004",
201
+ `Claude CLI timeout after ${timeoutMs}ms`,
202
+ void 0,
203
+ { timeoutMs }
204
+ )
205
+ );
206
+ }
207
+ }, timeoutMs);
208
+ }
209
+ ptyProcess.onExit((event) => {
210
+ if (timeoutId) {
211
+ clearTimeout(timeoutId);
212
+ }
213
+ if (!disposed) {
214
+ disposed = true;
215
+ const { exitCode: code } = event;
216
+ if (code !== 0) {
217
+ rejectExit(
218
+ new RuntimeError(
219
+ "RILL-R004",
220
+ `Claude CLI exited with code ${code}`,
221
+ void 0,
222
+ { exitCode: code }
223
+ )
224
+ );
225
+ } else {
226
+ resolveExit(code);
227
+ }
228
+ }
229
+ });
230
+ const dispose = () => {
231
+ if (disposed) {
232
+ return;
233
+ }
234
+ disposed = true;
235
+ if (timeoutId) {
236
+ clearTimeout(timeoutId);
237
+ }
238
+ try {
239
+ ptyProcess.kill();
240
+ } catch (error) {
241
+ const message = error instanceof Error ? error.message : "Unknown error";
242
+ console.warn(`Failed to kill claude process during cleanup: ${message}`);
243
+ }
244
+ };
245
+ return {
246
+ ptyProcess,
247
+ exitCode,
248
+ dispose
249
+ };
250
+ }
251
+
252
+ // src/factory.ts
253
+ import which from "which";
254
+ import {
255
+ RuntimeError as RuntimeError3,
256
+ emitExtensionEvent,
257
+ rillTypeToTypeValue
258
+ } from "@rcrsr/rill";
259
+
260
+ // ../../shared/ext-param/dist/param.js
261
+ import { RuntimeError as RuntimeError2 } from "@rcrsr/rill";
262
+ function validateParamName(name) {
263
+ if (name === "") {
264
+ throw new RuntimeError2("RILL-R001", "param name must not be empty");
265
+ }
266
+ if (/\s/.test(name)) {
267
+ throw new RuntimeError2("RILL-R001", "param name must be a valid identifier");
268
+ }
269
+ }
270
+ function buildAnnotations(desc) {
271
+ if (desc !== void 0) {
272
+ return { description: desc };
273
+ }
274
+ return {};
275
+ }
276
+ var p = {
277
+ /**
278
+ * IR-1: Creates a string parameter descriptor.
279
+ *
280
+ * @param name - Parameter name (must be a valid identifier)
281
+ * @param desc - Optional description
282
+ * @returns RillParam with type 'string'
283
+ */
284
+ str(name, desc) {
285
+ validateParamName(name);
286
+ return {
287
+ name,
288
+ type: { type: "string" },
289
+ defaultValue: void 0,
290
+ annotations: buildAnnotations(desc)
291
+ };
292
+ },
293
+ /**
294
+ * IR-2: Creates a number parameter descriptor.
295
+ *
296
+ * @param name - Parameter name (must be a valid identifier)
297
+ * @param desc - Optional description
298
+ * @param def - Optional default value
299
+ * @returns RillParam with type 'number'
300
+ */
301
+ num(name, desc, def) {
302
+ validateParamName(name);
303
+ return {
304
+ name,
305
+ type: { type: "number" },
306
+ defaultValue: def,
307
+ annotations: buildAnnotations(desc)
308
+ };
309
+ },
310
+ /**
311
+ * IR-3: Creates a boolean parameter descriptor.
312
+ *
313
+ * @param name - Parameter name (must be a valid identifier)
314
+ * @param desc - Optional description
315
+ * @param def - Optional default value
316
+ * @returns RillParam with type 'bool'
317
+ */
318
+ bool(name, desc, def) {
319
+ validateParamName(name);
320
+ return {
321
+ name,
322
+ type: { type: "bool" },
323
+ defaultValue: def,
324
+ annotations: buildAnnotations(desc)
325
+ };
326
+ },
327
+ /**
328
+ * IR-4: Creates a dict parameter descriptor.
329
+ *
330
+ * @param name - Parameter name (must be a valid identifier)
331
+ * @param desc - Optional description
332
+ * @param def - Optional default value
333
+ * @param fields - Optional structural field definitions (RillFieldDef with type and optional defaultValue)
334
+ * @returns RillParam with type 'dict' (with fields if provided)
335
+ */
336
+ dict(name, desc, def, fields) {
337
+ validateParamName(name);
338
+ const type = fields !== void 0 ? { type: "dict", fields } : { type: "dict" };
339
+ return {
340
+ name,
341
+ type,
342
+ defaultValue: def,
343
+ annotations: buildAnnotations(desc)
344
+ };
345
+ },
346
+ /**
347
+ * IR-5: Creates a list parameter descriptor.
348
+ *
349
+ * @param name - Parameter name (must be a valid identifier)
350
+ * @param itemType - Optional element type; omitted when not provided
351
+ * @param desc - Optional description
352
+ * @returns RillParam with type 'list' (with element if itemType provided)
353
+ */
354
+ list(name, itemType, desc) {
355
+ validateParamName(name);
356
+ const type = itemType !== void 0 ? { type: "list", element: itemType } : { type: "list" };
357
+ return {
358
+ name,
359
+ type,
360
+ defaultValue: void 0,
361
+ annotations: buildAnnotations(desc)
362
+ };
363
+ },
364
+ /**
365
+ * IR-6: Creates a callable parameter descriptor.
366
+ *
367
+ * @param name - Parameter name (must be a valid identifier)
368
+ * @param desc - Optional description
369
+ * @returns RillParam with type 'closure'
370
+ */
371
+ callable(name, desc) {
372
+ validateParamName(name);
373
+ return {
374
+ name,
375
+ type: { type: "closure" },
376
+ defaultValue: void 0,
377
+ annotations: buildAnnotations(desc)
378
+ };
379
+ }
380
+ };
381
+
382
+ // src/factory.ts
383
+ var DEFAULT_BINARY_PATH = "claude";
384
+ var DEFAULT_TIMEOUT = 18e5;
385
+ var MAX_TIMEOUT = 36e5;
386
+ function serializeArgsToFlags(args) {
387
+ const flags = [];
388
+ for (const [key, value] of Object.entries(args)) {
389
+ if (value === true) {
390
+ flags.push(`--${key}`);
391
+ } else if (typeof value === "object" && value !== null && !Array.isArray(value)) {
392
+ const nested = value;
393
+ for (const [nestedKey, nestedValue] of Object.entries(nested)) {
394
+ flags.push(`--${key}.${nestedKey}`, String(nestedValue));
395
+ }
396
+ } else {
397
+ flags.push(`--${key}`, String(value));
398
+ }
399
+ }
400
+ return flags;
401
+ }
402
+ function truncateText(text, maxLength = 100) {
403
+ if (text.length <= maxLength) {
404
+ return text;
405
+ }
406
+ return text.slice(0, maxLength) + "...";
407
+ }
408
+ function validateTimeout(timeout) {
409
+ if (!Number.isInteger(timeout)) {
410
+ throw new Error("Invalid timeout: must be positive integer, max 3600000");
411
+ }
412
+ if (timeout <= 0) {
413
+ throw new Error("Invalid timeout: must be positive integer, max 3600000");
414
+ }
415
+ if (timeout > MAX_TIMEOUT) {
416
+ throw new Error("Invalid timeout: must be positive integer, max 3600000");
417
+ }
418
+ }
419
+ function createClaudeCodeExtension(config = {}) {
420
+ const binaryPath = config.binaryPath ?? DEFAULT_BINARY_PATH;
421
+ const defaultTimeout = config.defaultTimeout ?? DEFAULT_TIMEOUT;
422
+ const dangerouslySkipPermissions = config.dangerouslySkipPermissions ?? true;
423
+ const settingSources = config.settingSources ?? "";
424
+ validateTimeout(defaultTimeout);
425
+ try {
426
+ which.sync(binaryPath);
427
+ } catch {
428
+ throw new Error(`Binary not found: ${binaryPath}`);
429
+ }
430
+ const tracker = {
431
+ disposers: /* @__PURE__ */ new Set()
432
+ };
433
+ const dispose = () => {
434
+ for (const disposer of tracker.disposers) {
435
+ try {
436
+ disposer();
437
+ } catch (error) {
438
+ const message = error instanceof Error ? error.message : "Unknown error";
439
+ console.warn(`Failed to cleanup process: ${message}`);
440
+ }
441
+ }
442
+ tracker.disposers.clear();
443
+ };
444
+ const result = {
445
+ // IR-2: claude-code::prompt
446
+ prompt: {
447
+ params: [
448
+ p.str("text"),
449
+ p.dict("options", void 0, {}, {
450
+ timeout: { type: { type: "number" }, defaultValue: 0 }
451
+ })
452
+ ],
453
+ fn: async (args, ctx) => {
454
+ const startTime = Date.now();
455
+ try {
456
+ const text = args["text"];
457
+ const options = args["options"] ?? {};
458
+ if (text.trim().length === 0) {
459
+ throw new RuntimeError3("RILL-R004", "prompt text cannot be empty");
460
+ }
461
+ const timeout = typeof options["timeout"] === "number" ? options["timeout"] : defaultTimeout;
462
+ const spawn2 = spawnClaudeCli(text, {
463
+ binaryPath,
464
+ timeoutMs: timeout,
465
+ dangerouslySkipPermissions,
466
+ settingSources
467
+ });
468
+ tracker.disposers.add(spawn2.dispose);
469
+ const parser = createStreamParser();
470
+ const messages = [];
471
+ spawn2.ptyProcess.onData((chunk) => {
472
+ parser.processChunk(chunk, (msg) => messages.push(msg));
473
+ });
474
+ try {
475
+ await spawn2.exitCode;
476
+ parser.flush((msg) => messages.push(msg));
477
+ } finally {
478
+ tracker.disposers.delete(spawn2.dispose);
479
+ spawn2.dispose();
480
+ }
481
+ const result2 = extractResult(messages);
482
+ const duration = Date.now() - startTime;
483
+ emitExtensionEvent(ctx, {
484
+ event: "claude-code:prompt",
485
+ subsystem: "extension:claude-code",
486
+ prompt: truncateText(text),
487
+ duration
488
+ });
489
+ return {
490
+ ...result2,
491
+ tokens: { ...result2.tokens }
492
+ };
493
+ } catch (error) {
494
+ const duration = Date.now() - startTime;
495
+ emitExtensionEvent(ctx, {
496
+ event: "claude-code:error",
497
+ subsystem: "extension:claude-code",
498
+ error: error instanceof Error ? error.message : "Unknown error",
499
+ duration
500
+ });
501
+ throw error;
502
+ }
503
+ },
504
+ annotations: { description: "Execute Claude Code prompt and return result text and token usage" },
505
+ returnType: rillTypeToTypeValue({
506
+ type: "dict",
507
+ fields: {
508
+ result: { type: { type: "string" } },
509
+ tokens: { type: { type: "dict", fields: {
510
+ prompt: { type: { type: "number" } },
511
+ cacheWrite5m: { type: { type: "number" } },
512
+ cacheWrite1h: { type: { type: "number" } },
513
+ cacheRead: { type: { type: "number" } },
514
+ output: { type: { type: "number" } }
515
+ } } },
516
+ cost: { type: { type: "number" } },
517
+ exitCode: { type: { type: "number" } },
518
+ duration: { type: { type: "number" } }
519
+ }
520
+ })
521
+ },
522
+ // IR-3: claude-code::skill
523
+ skill: {
524
+ params: [
525
+ p.str("name"),
526
+ p.dict("args", void 0, {}, {
527
+ timeout: { type: { type: "number" }, defaultValue: 0 }
528
+ })
529
+ ],
530
+ fn: async (fnArgs, ctx) => {
531
+ const startTime = Date.now();
532
+ try {
533
+ const name = fnArgs["name"];
534
+ const args = fnArgs["args"] ?? {};
535
+ if (name.trim().length === 0) {
536
+ throw new RuntimeError3("RILL-R004", "skill name cannot be empty");
537
+ }
538
+ const flags = serializeArgsToFlags(args);
539
+ const flagsText = flags.length > 0 ? " " + flags.join(" ") : "";
540
+ const prompt = `/${name}${flagsText}`;
541
+ const timeout = typeof args["timeout"] === "number" ? args["timeout"] : defaultTimeout;
542
+ const spawn2 = spawnClaudeCli(prompt, {
543
+ binaryPath,
544
+ timeoutMs: timeout,
545
+ dangerouslySkipPermissions,
546
+ settingSources
547
+ });
548
+ tracker.disposers.add(spawn2.dispose);
549
+ const parser = createStreamParser();
550
+ const messages = [];
551
+ spawn2.ptyProcess.onData((chunk) => {
552
+ parser.processChunk(chunk, (msg) => messages.push(msg));
553
+ });
554
+ try {
555
+ await spawn2.exitCode;
556
+ parser.flush((msg) => messages.push(msg));
557
+ } finally {
558
+ tracker.disposers.delete(spawn2.dispose);
559
+ spawn2.dispose();
560
+ }
561
+ const result2 = extractResult(messages);
562
+ const duration = Date.now() - startTime;
563
+ emitExtensionEvent(ctx, {
564
+ event: "claude-code:skill",
565
+ subsystem: "extension:claude-code",
566
+ name,
567
+ args,
568
+ duration
569
+ });
570
+ return {
571
+ ...result2,
572
+ tokens: { ...result2.tokens }
573
+ };
574
+ } catch (error) {
575
+ const duration = Date.now() - startTime;
576
+ emitExtensionEvent(ctx, {
577
+ event: "claude-code:error",
578
+ subsystem: "extension:claude-code",
579
+ error: error instanceof Error ? error.message : "Unknown error",
580
+ duration
581
+ });
582
+ throw error;
583
+ }
584
+ },
585
+ annotations: { description: "Execute Claude Code skill with instruction and return structured result" },
586
+ returnType: rillTypeToTypeValue({
587
+ type: "dict",
588
+ fields: {
589
+ result: { type: { type: "string" } },
590
+ tokens: { type: { type: "dict", fields: {
591
+ prompt: { type: { type: "number" } },
592
+ cacheWrite5m: { type: { type: "number" } },
593
+ cacheWrite1h: { type: { type: "number" } },
594
+ cacheRead: { type: { type: "number" } },
595
+ output: { type: { type: "number" } }
596
+ } } },
597
+ cost: { type: { type: "number" } },
598
+ exitCode: { type: { type: "number" } },
599
+ duration: { type: { type: "number" } }
600
+ }
601
+ })
602
+ },
603
+ // IR-4: claude-code::command
604
+ command: {
605
+ params: [
606
+ p.str("name"),
607
+ p.dict("args", void 0, {}, {
608
+ timeout: { type: { type: "number" }, defaultValue: 0 }
609
+ })
610
+ ],
611
+ fn: async (fnArgs, ctx) => {
612
+ const startTime = Date.now();
613
+ try {
614
+ const name = fnArgs["name"];
615
+ const args = fnArgs["args"] ?? {};
616
+ if (name.trim().length === 0) {
617
+ throw new RuntimeError3("RILL-R004", "command name cannot be empty");
618
+ }
619
+ const flags = serializeArgsToFlags(args);
620
+ const flagsText = flags.length > 0 ? " " + flags.join(" ") : "";
621
+ const prompt = `/${name}${flagsText}`;
622
+ const timeout = typeof args["timeout"] === "number" ? args["timeout"] : defaultTimeout;
623
+ const spawn2 = spawnClaudeCli(prompt, {
624
+ binaryPath,
625
+ timeoutMs: timeout,
626
+ dangerouslySkipPermissions,
627
+ settingSources
628
+ });
629
+ tracker.disposers.add(spawn2.dispose);
630
+ const parser = createStreamParser();
631
+ const messages = [];
632
+ spawn2.ptyProcess.onData((chunk) => {
633
+ parser.processChunk(chunk, (msg) => messages.push(msg));
634
+ });
635
+ try {
636
+ await spawn2.exitCode;
637
+ parser.flush((msg) => messages.push(msg));
638
+ } finally {
639
+ tracker.disposers.delete(spawn2.dispose);
640
+ spawn2.dispose();
641
+ }
642
+ const result2 = extractResult(messages);
643
+ const duration = Date.now() - startTime;
644
+ emitExtensionEvent(ctx, {
645
+ event: "claude-code:command",
646
+ subsystem: "extension:claude-code",
647
+ name,
648
+ args,
649
+ duration
650
+ });
651
+ return {
652
+ ...result2,
653
+ tokens: { ...result2.tokens }
654
+ };
655
+ } catch (error) {
656
+ const duration = Date.now() - startTime;
657
+ emitExtensionEvent(ctx, {
658
+ event: "claude-code:error",
659
+ subsystem: "extension:claude-code",
660
+ error: error instanceof Error ? error.message : "Unknown error",
661
+ duration
662
+ });
663
+ throw error;
664
+ }
665
+ },
666
+ annotations: { description: "Execute Claude Code command with task description and return execution summary" },
667
+ returnType: rillTypeToTypeValue({
668
+ type: "dict",
669
+ fields: {
670
+ result: { type: { type: "string" } },
671
+ tokens: { type: { type: "dict", fields: {
672
+ prompt: { type: { type: "number" } },
673
+ cacheWrite5m: { type: { type: "number" } },
674
+ cacheWrite1h: { type: { type: "number" } },
675
+ cacheRead: { type: { type: "number" } },
676
+ output: { type: { type: "number" } }
677
+ } } },
678
+ cost: { type: { type: "number" } },
679
+ exitCode: { type: { type: "number" } },
680
+ duration: { type: { type: "number" } }
681
+ }
682
+ })
683
+ }
684
+ };
685
+ result.dispose = dispose;
686
+ return result;
687
+ }
688
+
689
+ // src/index.ts
690
+ var _require = createRequire(import.meta.url);
691
+ var _pkg = _require("../package.json");
692
+ var VERSION = _pkg.version;
693
+ var configSchema = {
694
+ binaryPath: { type: "string" },
695
+ defaultTimeout: { type: "number" },
696
+ dangerouslySkipPermissions: { type: "boolean" },
697
+ settingSources: { type: "string" }
698
+ };
699
+ var extensionManifest = {
700
+ factory: createClaudeCodeExtension,
701
+ configSchema,
702
+ version: VERSION
703
+ };
704
+ export {
705
+ VERSION,
706
+ configSchema,
707
+ createClaudeCodeExtension,
708
+ createStreamParser,
709
+ extensionManifest,
710
+ extractResult,
711
+ spawnClaudeCli
25
712
  };
26
- //# sourceMappingURL=index.js.map