@openbuilder/cli 0.50.43 → 0.50.44

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.
Files changed (82) hide show
  1. package/dist/chunks/{Banner-C-FTiOIR.js → Banner-BlktOjfl.js} +2 -2
  2. package/dist/chunks/Banner-BlktOjfl.js.map +1 -0
  3. package/dist/chunks/_commonjsHelpers-h-Bqc03Z.js +34 -0
  4. package/dist/chunks/_commonjsHelpers-h-Bqc03Z.js.map +1 -0
  5. package/dist/chunks/auto-update-Dq2PFvjt.js +1 -0
  6. package/dist/chunks/auto-update-Dq2PFvjt.js.map +1 -0
  7. package/dist/chunks/build-D0qYqIq0.js +1 -0
  8. package/dist/chunks/build-D0qYqIq0.js.map +1 -0
  9. package/dist/chunks/cleanup-qVTsA3tk.js +1 -0
  10. package/dist/chunks/cleanup-qVTsA3tk.js.map +1 -0
  11. package/dist/chunks/cli-auth-ChCnxlFl.js +1 -0
  12. package/dist/chunks/cli-auth-ChCnxlFl.js.map +1 -0
  13. package/dist/chunks/cli-error-BjQwvWtK.js +1 -0
  14. package/dist/chunks/cli-error-BjQwvWtK.js.map +1 -0
  15. package/dist/chunks/config-BGP1jZJ4.js +1 -0
  16. package/dist/chunks/config-BGP1jZJ4.js.map +1 -0
  17. package/dist/chunks/config-manager-BkbjtN-H.js +1 -0
  18. package/dist/chunks/config-manager-BkbjtN-H.js.map +1 -0
  19. package/dist/chunks/database-BvAbD4sP.js +1 -0
  20. package/dist/chunks/database-BvAbD4sP.js.map +1 -0
  21. package/dist/chunks/database-setup-BYjIRAmT.js +1 -0
  22. package/dist/chunks/database-setup-BYjIRAmT.js.map +1 -0
  23. package/dist/chunks/devtools-7A3EXJhY.js +75 -0
  24. package/dist/chunks/devtools-7A3EXJhY.js.map +1 -0
  25. package/dist/chunks/exports-ij9sv4UM.js +7793 -0
  26. package/dist/chunks/exports-ij9sv4UM.js.map +1 -0
  27. package/dist/chunks/index-oFqGtEeF.js +119 -0
  28. package/dist/chunks/index-oFqGtEeF.js.map +1 -0
  29. package/dist/chunks/{init-DNyPS_SR.js → init-BsQ3dhwf.js} +9 -9
  30. package/dist/chunks/init-BsQ3dhwf.js.map +1 -0
  31. package/dist/chunks/{init-tui-EFMXj-MG.js → init-tui-Dvk6Ndvl.js} +8 -8
  32. package/dist/chunks/init-tui-Dvk6Ndvl.js.map +1 -0
  33. package/dist/chunks/logger-ZpJi7chw.js +1 -0
  34. package/dist/chunks/logger-ZpJi7chw.js.map +1 -0
  35. package/dist/chunks/login-BhtodVsj.js +1 -0
  36. package/dist/chunks/login-BhtodVsj.js.map +1 -0
  37. package/dist/chunks/logout-CDDASeuQ.js +1 -0
  38. package/dist/chunks/logout-CDDASeuQ.js.map +1 -0
  39. package/dist/chunks/{main-tui-D-SG-Ba5.js → main-tui-Cklcr3FX.js} +10 -10
  40. package/dist/chunks/main-tui-Cklcr3FX.js.map +1 -0
  41. package/dist/chunks/manager-CvGX9qqe.js +1 -0
  42. package/dist/chunks/manager-CvGX9qqe.js.map +1 -0
  43. package/dist/chunks/{port-allocator-B0q7xkLs.js → port-allocator-Ct3ioni4.js} +2 -34
  44. package/dist/chunks/port-allocator-Ct3ioni4.js.map +1 -0
  45. package/dist/chunks/process-killer-CaUL7Kpl.js +1 -0
  46. package/dist/chunks/process-killer-CaUL7Kpl.js.map +1 -0
  47. package/dist/chunks/prompts-1QbE_bRr.js +1 -0
  48. package/dist/chunks/prompts-1QbE_bRr.js.map +1 -0
  49. package/dist/chunks/repo-cloner-CpOQjFSo.js +1 -0
  50. package/dist/chunks/repo-cloner-CpOQjFSo.js.map +1 -0
  51. package/dist/chunks/repo-detector-B_oj696o.js +1 -0
  52. package/dist/chunks/repo-detector-B_oj696o.js.map +1 -0
  53. package/dist/chunks/{run-Cor14S0I.js → run-wycadErJ.js} +15 -28
  54. package/dist/chunks/run-wycadErJ.js.map +1 -0
  55. package/dist/chunks/runner-logger-instance-nDWv2h2T.js +1 -0
  56. package/dist/chunks/runner-logger-instance-nDWv2h2T.js.map +1 -0
  57. package/dist/chunks/spinner-BJL9zWAJ.js +1 -0
  58. package/dist/chunks/spinner-BJL9zWAJ.js.map +1 -0
  59. package/dist/chunks/{start-k9iGDVWo.js → start-CQKEEma-.js} +8 -7
  60. package/dist/chunks/start-CQKEEma-.js.map +1 -0
  61. package/dist/chunks/start-traditional-uoLZXdxm.js +1 -0
  62. package/dist/chunks/start-traditional-uoLZXdxm.js.map +1 -0
  63. package/dist/chunks/status-cS8YwtUx.js +1 -0
  64. package/dist/chunks/status-cS8YwtUx.js.map +1 -0
  65. package/dist/chunks/{vendor-react-CXgiD1Dl.js → theme-CktnrDZj.js} +47 -227
  66. package/dist/chunks/theme-CktnrDZj.js.map +1 -0
  67. package/dist/chunks/upgrade-CKjl4HlB.js +1 -0
  68. package/dist/chunks/upgrade-CKjl4HlB.js.map +1 -0
  69. package/dist/chunks/use-app-Cj2bzWaw.js +10 -0
  70. package/dist/chunks/use-app-Cj2bzWaw.js.map +1 -0
  71. package/dist/chunks/{useBuildState-DscLOZLl.js → useBuildState-pcDGDakI.js} +2 -2
  72. package/dist/chunks/useBuildState-pcDGDakI.js.map +1 -0
  73. package/dist/cli/index.js +6 -5
  74. package/dist/cli/index.js.map +1 -0
  75. package/dist/index.js +2044 -106
  76. package/dist/index.js.map +1 -0
  77. package/dist/instrument.js +64119 -37
  78. package/dist/instrument.js.map +1 -0
  79. package/package.json +1 -1
  80. package/dist/chunks/theme-DhorI2Hb.js +0 -43
  81. package/dist/chunks/vendor-ai-sdk-CSJ0bw9X.js +0 -1970
  82. package/dist/chunks/vendor-sentry-CqA9P3UG.js +0 -71910
package/dist/index.js CHANGED
@@ -1,13 +1,17 @@
1
1
  // OpenBuilder CLI - Built with Rollup
2
2
  import { query } from '@anthropic-ai/claude-agent-sdk';
3
3
  import { Codex } from '@openai/codex-sdk';
4
- import { a as streamLog, f as fileLog, i as initRunnerLogger, s as setFileLoggerTuiMode, b as getLogger } from './chunks/runner-logger-instance-nDWv2h2T.js';
4
+ import { a as streamLog, f as fileLog, i as initRunnerLogger, s as setFileLoggerTuiMode, b as getLogger$1 } from './chunks/runner-logger-instance-nDWv2h2T.js';
5
5
  import { config as config$1 } from 'dotenv';
6
6
  import require$$1, { resolve, relative, isAbsolute, dirname, join as join$1 } from 'node:path';
7
7
  import { fileURLToPath } from 'node:url';
8
8
  import { generateText, streamText } from 'ai';
9
- import { c as claudeCode } from './chunks/vendor-ai-sdk-CSJ0bw9X.js';
10
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
9
+ import 'zod/v4';
10
+ import 'zod/v3';
11
+ import { parse } from 'jsonc-parser';
12
+ import { z } from 'zod';
13
+ import { existsSync, mkdirSync as mkdirSync$1 } from 'fs';
14
+ import { existsSync as existsSync$1, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
11
15
  import { readFile } from 'fs/promises';
12
16
  import * as path from 'path';
13
17
  import { join } from 'path';
@@ -18,8 +22,7 @@ import { pgTable, timestamp, boolean, text, uuid, index, uniqueIndex, integer, j
18
22
  import { sql, eq, and, desc, isNull } from 'drizzle-orm';
19
23
  import { randomUUID, createHash } from 'crypto';
20
24
  import { migrate } from 'drizzle-orm/node-postgres/migrator';
21
- import { z } from 'zod';
22
- import { a as addBreadcrumb, c as captureException, g as getActiveSpan, b as getTraceData, s as startInactiveSpan, f as flush, d as continueTrace, e as startSpan, j as setTag, k as count, l as distribution, m as info, n as fmt } from './chunks/vendor-sentry-CqA9P3UG.js';
25
+ import { ak as addBreadcrumb, aa as captureException, a as getActiveSpan, a0 as getTraceData, ap as startInactiveSpan, bh as flush, bn as continueTrace, af as startSpan, by as setTag, bF as count, bG as distribution, bH as info, bI as fmt } from './chunks/exports-ij9sv4UM.js';
23
26
  import os__default from 'node:os';
24
27
  import { randomUUID as randomUUID$1 } from 'node:crypto';
25
28
  import express from 'express';
@@ -29,40 +32,1974 @@ import { createServer, createConnection } from 'node:net';
29
32
  import { readFile as readFile$1, rm, writeFile, readdir } from 'node:fs/promises';
30
33
  import { simpleGit } from 'simple-git';
31
34
  import * as os from 'os';
32
- import { existsSync as existsSync$1, mkdirSync as mkdirSync$1 } from 'fs';
33
35
  import { tunnelManager } from './chunks/manager-CvGX9qqe.js';
34
36
  import 'chalk';
35
- import 'zod/v4';
36
- import 'zod/v3';
37
- import 'jsonc-parser';
38
- import 'url';
39
- import 'tty';
40
- import 'util';
41
- import 'worker_threads';
42
- import 'process';
43
- import 'node:module';
44
- import 'async_hooks';
45
- import 'diagnostics_channel';
46
- import './chunks/vendor-react-CXgiD1Dl.js';
47
- import 'module';
48
- import 'events';
49
- import 'assert';
50
- import 'react-devtools-core';
51
- import 'node:stream';
52
- import 'node:process';
53
- import 'node:buffer';
54
- import 'node:diagnostics_channel';
55
37
  import 'node:util';
56
- import 'node:readline';
57
- import 'node:worker_threads';
58
- import 'node:http';
59
- import 'node:https';
60
- import 'node:zlib';
61
- import 'node:tls';
62
38
  import 'http';
63
39
  import 'http-proxy';
64
40
  import 'zlib';
65
41
 
42
+ // src/errors/ai-sdk-error.ts
43
+ var marker = "vercel.ai.error";
44
+ var symbol = Symbol.for(marker);
45
+ var _a;
46
+ var _AISDKError = class _AISDKError extends Error {
47
+ /**
48
+ * Creates an AI SDK Error.
49
+ *
50
+ * @param {Object} params - The parameters for creating the error.
51
+ * @param {string} params.name - The name of the error.
52
+ * @param {string} params.message - The error message.
53
+ * @param {unknown} [params.cause] - The underlying cause of the error.
54
+ */
55
+ constructor({
56
+ name: name14,
57
+ message,
58
+ cause
59
+ }) {
60
+ super(message);
61
+ this[_a] = true;
62
+ this.name = name14;
63
+ this.cause = cause;
64
+ }
65
+ /**
66
+ * Checks if the given error is an AI SDK Error.
67
+ * @param {unknown} error - The error to check.
68
+ * @returns {boolean} True if the error is an AI SDK Error, false otherwise.
69
+ */
70
+ static isInstance(error) {
71
+ return _AISDKError.hasMarker(error, marker);
72
+ }
73
+ static hasMarker(error, marker15) {
74
+ const markerSymbol = Symbol.for(marker15);
75
+ return error != null && typeof error === "object" && markerSymbol in error && typeof error[markerSymbol] === "boolean" && error[markerSymbol] === true;
76
+ }
77
+ };
78
+ _a = symbol;
79
+ var AISDKError = _AISDKError;
80
+
81
+ // src/errors/api-call-error.ts
82
+ var name = "AI_APICallError";
83
+ var marker2 = `vercel.ai.error.${name}`;
84
+ var symbol2 = Symbol.for(marker2);
85
+ var _a2;
86
+ var APICallError = class extends AISDKError {
87
+ constructor({
88
+ message,
89
+ url,
90
+ requestBodyValues,
91
+ statusCode,
92
+ responseHeaders,
93
+ responseBody,
94
+ cause,
95
+ isRetryable = statusCode != null && (statusCode === 408 || // request timeout
96
+ statusCode === 409 || // conflict
97
+ statusCode === 429 || // too many requests
98
+ statusCode >= 500),
99
+ // server error
100
+ data
101
+ }) {
102
+ super({ name, message, cause });
103
+ this[_a2] = true;
104
+ this.url = url;
105
+ this.requestBodyValues = requestBodyValues;
106
+ this.statusCode = statusCode;
107
+ this.responseHeaders = responseHeaders;
108
+ this.responseBody = responseBody;
109
+ this.isRetryable = isRetryable;
110
+ this.data = data;
111
+ }
112
+ static isInstance(error) {
113
+ return AISDKError.hasMarker(error, marker2);
114
+ }
115
+ };
116
+ _a2 = symbol2;
117
+
118
+ // src/errors/invalid-argument-error.ts
119
+ var name3 = "AI_InvalidArgumentError";
120
+ var marker4 = `vercel.ai.error.${name3}`;
121
+ var symbol4 = Symbol.for(marker4);
122
+ var _a4;
123
+ var InvalidArgumentError = class extends AISDKError {
124
+ constructor({
125
+ message,
126
+ cause,
127
+ argument
128
+ }) {
129
+ super({ name: name3, message, cause });
130
+ this[_a4] = true;
131
+ this.argument = argument;
132
+ }
133
+ static isInstance(error) {
134
+ return AISDKError.hasMarker(error, marker4);
135
+ }
136
+ };
137
+ _a4 = symbol4;
138
+
139
+ // src/errors/load-api-key-error.ts
140
+ var name7 = "AI_LoadAPIKeyError";
141
+ var marker8 = `vercel.ai.error.${name7}`;
142
+ var symbol8 = Symbol.for(marker8);
143
+ var _a8;
144
+ var LoadAPIKeyError = class extends AISDKError {
145
+ // used in isInstance
146
+ constructor({ message }) {
147
+ super({ name: name7, message });
148
+ this[_a8] = true;
149
+ }
150
+ static isInstance(error) {
151
+ return AISDKError.hasMarker(error, marker8);
152
+ }
153
+ };
154
+ _a8 = symbol8;
155
+
156
+ // src/errors/no-such-model-error.ts
157
+ var name10 = "AI_NoSuchModelError";
158
+ var marker11 = `vercel.ai.error.${name10}`;
159
+ var symbol11 = Symbol.for(marker11);
160
+ var _a11;
161
+ var NoSuchModelError = class extends AISDKError {
162
+ constructor({
163
+ errorName = name10,
164
+ modelId,
165
+ modelType,
166
+ message = `No such ${modelType}: ${modelId}`
167
+ }) {
168
+ super({ name: errorName, message });
169
+ this[_a11] = true;
170
+ this.modelId = modelId;
171
+ this.modelType = modelType;
172
+ }
173
+ static isInstance(error) {
174
+ return AISDKError.hasMarker(error, marker11);
175
+ }
176
+ };
177
+ _a11 = symbol11;
178
+
179
+ // src/combine-headers.ts
180
+ var createIdGenerator = ({
181
+ prefix,
182
+ size = 16,
183
+ alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
184
+ separator = "-"
185
+ } = {}) => {
186
+ const generator = () => {
187
+ const alphabetLength = alphabet.length;
188
+ const chars = new Array(size);
189
+ for (let i = 0; i < size; i++) {
190
+ chars[i] = alphabet[Math.random() * alphabetLength | 0];
191
+ }
192
+ return chars.join("");
193
+ };
194
+ if (prefix == null) {
195
+ return generator;
196
+ }
197
+ if (alphabet.includes(separator)) {
198
+ throw new InvalidArgumentError({
199
+ argument: "separator",
200
+ message: `The separator "${separator}" must not be part of the alphabet "${alphabet}".`
201
+ });
202
+ }
203
+ return () => `${prefix}${separator}${generator()}`;
204
+ };
205
+ var generateId = createIdGenerator();
206
+ new Set(
207
+ "ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789"
208
+ );
209
+
210
+ // src/claude-code-provider.ts
211
+
212
+ // src/convert-to-claude-code-messages.ts
213
+ var IMAGE_URL_WARNING = "Image URLs are not supported by this provider; supply base64/data URLs.";
214
+ var IMAGE_CONVERSION_WARNING = "Unable to convert image content; supply base64/data URLs.";
215
+ function normalizeBase64(base64) {
216
+ return base64.replace(/\s+/g, "");
217
+ }
218
+ function isImageMimeType(mimeType) {
219
+ return typeof mimeType === "string" && mimeType.trim().toLowerCase().startsWith("image/");
220
+ }
221
+ function createImageContent(mediaType, data) {
222
+ const trimmedType = mediaType.trim();
223
+ const trimmedData = normalizeBase64(data.trim());
224
+ if (!trimmedType || !trimmedData) {
225
+ return void 0;
226
+ }
227
+ return {
228
+ type: "image",
229
+ source: {
230
+ type: "base64",
231
+ media_type: trimmedType,
232
+ data: trimmedData
233
+ }
234
+ };
235
+ }
236
+ function extractMimeType(candidate) {
237
+ if (typeof candidate === "string" && candidate.trim()) {
238
+ return candidate.trim();
239
+ }
240
+ return void 0;
241
+ }
242
+ function parseObjectImage(imageObj, fallbackMimeType) {
243
+ const data = typeof imageObj.data === "string" ? imageObj.data : void 0;
244
+ const mimeType = extractMimeType(
245
+ imageObj.mimeType ?? imageObj.mediaType ?? imageObj.media_type ?? fallbackMimeType
246
+ );
247
+ if (!data || !mimeType) {
248
+ return void 0;
249
+ }
250
+ return createImageContent(mimeType, data);
251
+ }
252
+ function parseStringImage(value, fallbackMimeType) {
253
+ const trimmed = value.trim();
254
+ if (/^https?:\/\//i.test(trimmed)) {
255
+ return { warning: IMAGE_URL_WARNING };
256
+ }
257
+ const dataUrlMatch = trimmed.match(/^data:([^;]+);base64,(.+)$/i);
258
+ if (dataUrlMatch) {
259
+ const [, mediaType, data] = dataUrlMatch;
260
+ const content = createImageContent(mediaType, data);
261
+ return content ? { content } : { warning: IMAGE_CONVERSION_WARNING };
262
+ }
263
+ const base64Match = trimmed.match(/^base64:([^,]+),(.+)$/i);
264
+ if (base64Match) {
265
+ const [, explicitMimeType, data] = base64Match;
266
+ const content = createImageContent(explicitMimeType, data);
267
+ return content ? { content } : { warning: IMAGE_CONVERSION_WARNING };
268
+ }
269
+ if (fallbackMimeType) {
270
+ const content = createImageContent(fallbackMimeType, trimmed);
271
+ if (content) {
272
+ return { content };
273
+ }
274
+ }
275
+ return { warning: IMAGE_CONVERSION_WARNING };
276
+ }
277
+ function parseImagePart(part) {
278
+ if (!part || typeof part !== "object") {
279
+ return { warning: IMAGE_CONVERSION_WARNING };
280
+ }
281
+ const imageValue = part.image;
282
+ const mimeType = extractMimeType(part.mimeType);
283
+ if (typeof imageValue === "string") {
284
+ return parseStringImage(imageValue, mimeType);
285
+ }
286
+ if (imageValue && typeof imageValue === "object") {
287
+ const content = parseObjectImage(imageValue, mimeType);
288
+ return content ? { content } : { warning: IMAGE_CONVERSION_WARNING };
289
+ }
290
+ return { warning: IMAGE_CONVERSION_WARNING };
291
+ }
292
+ function convertBinaryToBase64(data) {
293
+ if (typeof Buffer !== "undefined") {
294
+ const buffer = data instanceof Uint8Array ? Buffer.from(data) : Buffer.from(new Uint8Array(data));
295
+ return buffer.toString("base64");
296
+ }
297
+ if (typeof btoa === "function") {
298
+ const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);
299
+ let binary = "";
300
+ const chunkSize = 32768;
301
+ for (let i = 0; i < bytes.length; i += chunkSize) {
302
+ const chunk = bytes.subarray(i, i + chunkSize);
303
+ binary += String.fromCharCode(...chunk);
304
+ }
305
+ return btoa(binary);
306
+ }
307
+ return void 0;
308
+ }
309
+ function parseFilePart(part) {
310
+ const mimeType = extractMimeType(part.mediaType ?? part.mimeType);
311
+ if (!mimeType || !isImageMimeType(mimeType)) {
312
+ return {};
313
+ }
314
+ const data = part.data;
315
+ if (typeof data === "string") {
316
+ const content = createImageContent(mimeType, data);
317
+ return content ? { content } : { warning: IMAGE_CONVERSION_WARNING };
318
+ }
319
+ if (data instanceof Uint8Array || typeof ArrayBuffer !== "undefined" && data instanceof ArrayBuffer) {
320
+ const base64 = convertBinaryToBase64(data);
321
+ if (!base64) {
322
+ return { warning: IMAGE_CONVERSION_WARNING };
323
+ }
324
+ const content = createImageContent(mimeType, base64);
325
+ return content ? { content } : { warning: IMAGE_CONVERSION_WARNING };
326
+ }
327
+ return { warning: IMAGE_CONVERSION_WARNING };
328
+ }
329
+ function convertToClaudeCodeMessages(prompt, mode = { type: "regular" }, jsonSchema) {
330
+ const messages = [];
331
+ const warnings = [];
332
+ let systemPrompt;
333
+ const streamingSegments = [];
334
+ const imageMap = /* @__PURE__ */ new Map();
335
+ let hasImageParts = false;
336
+ const addSegment = (formatted) => {
337
+ streamingSegments.push({ formatted });
338
+ return streamingSegments.length - 1;
339
+ };
340
+ const addImageForSegment = (segmentIndex, content) => {
341
+ hasImageParts = true;
342
+ if (!imageMap.has(segmentIndex)) {
343
+ imageMap.set(segmentIndex, []);
344
+ }
345
+ imageMap.get(segmentIndex)?.push(content);
346
+ };
347
+ for (const message of prompt) {
348
+ switch (message.role) {
349
+ case "system":
350
+ systemPrompt = message.content;
351
+ if (typeof message.content === "string" && message.content.trim().length > 0) {
352
+ addSegment(message.content);
353
+ } else {
354
+ addSegment("");
355
+ }
356
+ break;
357
+ case "user":
358
+ if (typeof message.content === "string") {
359
+ messages.push(message.content);
360
+ addSegment(`Human: ${message.content}`);
361
+ } else {
362
+ const textParts = message.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
363
+ const segmentIndex = addSegment(textParts ? `Human: ${textParts}` : "");
364
+ if (textParts) {
365
+ messages.push(textParts);
366
+ }
367
+ for (const part of message.content) {
368
+ if (part.type === "image") {
369
+ const { content, warning } = parseImagePart(part);
370
+ if (content) {
371
+ addImageForSegment(segmentIndex, content);
372
+ } else if (warning) {
373
+ warnings.push(warning);
374
+ }
375
+ } else if (part.type === "file") {
376
+ const { content, warning } = parseFilePart(part);
377
+ if (content) {
378
+ addImageForSegment(segmentIndex, content);
379
+ } else if (warning) {
380
+ warnings.push(warning);
381
+ }
382
+ }
383
+ }
384
+ }
385
+ break;
386
+ case "assistant": {
387
+ let assistantContent = "";
388
+ if (typeof message.content === "string") {
389
+ assistantContent = message.content;
390
+ } else {
391
+ const textParts = message.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
392
+ if (textParts) {
393
+ assistantContent = textParts;
394
+ }
395
+ const toolCalls = message.content.filter((part) => part.type === "tool-call");
396
+ if (toolCalls.length > 0) {
397
+ assistantContent += `
398
+ [Tool calls made]`;
399
+ }
400
+ }
401
+ const formattedAssistant = `Assistant: ${assistantContent}`;
402
+ messages.push(formattedAssistant);
403
+ addSegment(formattedAssistant);
404
+ break;
405
+ }
406
+ case "tool":
407
+ for (const tool3 of message.content) {
408
+ const resultText = tool3.output.type === "text" ? tool3.output.value : JSON.stringify(tool3.output.value);
409
+ const formattedToolResult = `Tool Result (${tool3.toolName}): ${resultText}`;
410
+ messages.push(formattedToolResult);
411
+ addSegment(formattedToolResult);
412
+ }
413
+ break;
414
+ }
415
+ }
416
+ let finalPrompt = "";
417
+ if (systemPrompt) {
418
+ finalPrompt = systemPrompt;
419
+ }
420
+ if (messages.length > 0) {
421
+ const formattedMessages = [];
422
+ for (let i = 0; i < messages.length; i++) {
423
+ const msg = messages[i];
424
+ if (msg.startsWith("Assistant:") || msg.startsWith("Tool Result")) {
425
+ formattedMessages.push(msg);
426
+ } else {
427
+ formattedMessages.push(`Human: ${msg}`);
428
+ }
429
+ }
430
+ if (finalPrompt) {
431
+ const joinedMessages = formattedMessages.join("\n\n");
432
+ finalPrompt = joinedMessages ? `${finalPrompt}
433
+
434
+ ${joinedMessages}` : finalPrompt;
435
+ } else {
436
+ finalPrompt = formattedMessages.join("\n\n");
437
+ }
438
+ }
439
+ let streamingParts = [];
440
+ const imagePartsInOrder = [];
441
+ const appendImagesForIndex = (index) => {
442
+ const images = imageMap.get(index);
443
+ if (!images) {
444
+ return;
445
+ }
446
+ images.forEach((image) => {
447
+ streamingParts.push(image);
448
+ imagePartsInOrder.push(image);
449
+ });
450
+ };
451
+ if (streamingSegments.length > 0) {
452
+ let accumulatedText = "";
453
+ let emittedText = false;
454
+ const flushText = () => {
455
+ if (!accumulatedText) {
456
+ return;
457
+ }
458
+ streamingParts.push({ type: "text", text: accumulatedText });
459
+ accumulatedText = "";
460
+ emittedText = true;
461
+ };
462
+ streamingSegments.forEach((segment, index) => {
463
+ const segmentText = segment.formatted;
464
+ if (segmentText) {
465
+ if (!accumulatedText) {
466
+ accumulatedText = emittedText ? `
467
+
468
+ ${segmentText}` : segmentText;
469
+ } else {
470
+ accumulatedText += `
471
+
472
+ ${segmentText}`;
473
+ }
474
+ }
475
+ if (imageMap.has(index)) {
476
+ flushText();
477
+ appendImagesForIndex(index);
478
+ }
479
+ });
480
+ flushText();
481
+ }
482
+ if (mode?.type === "object-json" && jsonSchema) {
483
+ const schemaStr = JSON.stringify(jsonSchema, null, 2);
484
+ finalPrompt = `CRITICAL: You MUST respond with ONLY a JSON object. NO other text, NO explanations, NO questions.
485
+
486
+ Your response MUST start with { and end with }
487
+
488
+ The JSON MUST match this EXACT schema:
489
+ ${schemaStr}
490
+
491
+ Now, based on the following conversation, generate ONLY the JSON object with the exact fields specified above:
492
+
493
+ ${finalPrompt}
494
+
495
+ Remember: Your ENTIRE response must be ONLY the JSON object, starting with { and ending with }`;
496
+ streamingParts = [{ type: "text", text: finalPrompt }, ...imagePartsInOrder];
497
+ }
498
+ return {
499
+ messagesPrompt: finalPrompt,
500
+ systemPrompt,
501
+ ...warnings.length > 0 && { warnings },
502
+ streamingContentParts: streamingParts.length > 0 ? streamingParts : [
503
+ { type: "text", text: finalPrompt },
504
+ ...imagePartsInOrder
505
+ ],
506
+ hasImageParts
507
+ };
508
+ }
509
+ function extractJson(text) {
510
+ let content = text.trim();
511
+ const fenceMatch = /```(?:json)?\s*([\s\S]*?)\s*```/i.exec(content);
512
+ if (fenceMatch) {
513
+ content = fenceMatch[1];
514
+ }
515
+ const varMatch = /^\s*(?:const|let|var)\s+\w+\s*=\s*([\s\S]*)/i.exec(content);
516
+ if (varMatch) {
517
+ content = varMatch[1];
518
+ if (content.trim().endsWith(";")) {
519
+ content = content.trim().slice(0, -1);
520
+ }
521
+ }
522
+ const firstObj = content.indexOf("{");
523
+ const firstArr = content.indexOf("[");
524
+ if (firstObj === -1 && firstArr === -1) {
525
+ return text;
526
+ }
527
+ const start = firstArr === -1 ? firstObj : firstObj === -1 ? firstArr : Math.min(firstObj, firstArr);
528
+ content = content.slice(start);
529
+ const tryParse = (value) => {
530
+ const errors = [];
531
+ try {
532
+ const result = parse(value, errors, { allowTrailingComma: true });
533
+ if (errors.length === 0) {
534
+ return JSON.stringify(result, null, 2);
535
+ }
536
+ } catch {
537
+ }
538
+ return void 0;
539
+ };
540
+ const parsed = tryParse(content);
541
+ if (parsed !== void 0) {
542
+ return parsed;
543
+ }
544
+ const openChar = content[0];
545
+ const closeChar = openChar === "{" ? "}" : "]";
546
+ const closingPositions = [];
547
+ let depth = 0;
548
+ let inString = false;
549
+ let escapeNext = false;
550
+ for (let i = 0; i < content.length; i++) {
551
+ const char = content[i];
552
+ if (escapeNext) {
553
+ escapeNext = false;
554
+ continue;
555
+ }
556
+ if (char === "\\") {
557
+ escapeNext = true;
558
+ continue;
559
+ }
560
+ if (char === '"' && !inString) {
561
+ inString = true;
562
+ continue;
563
+ }
564
+ if (char === '"' && inString) {
565
+ inString = false;
566
+ continue;
567
+ }
568
+ if (inString) continue;
569
+ if (char === openChar) {
570
+ depth++;
571
+ } else if (char === closeChar) {
572
+ depth--;
573
+ if (depth === 0) {
574
+ closingPositions.push(i + 1);
575
+ }
576
+ }
577
+ }
578
+ for (let i = closingPositions.length - 1; i >= 0; i--) {
579
+ const attempt = tryParse(content.slice(0, closingPositions[i]));
580
+ if (attempt !== void 0) {
581
+ return attempt;
582
+ }
583
+ }
584
+ const searchStart = Math.max(0, content.length - 1e3);
585
+ for (let end = content.length - 1; end > searchStart; end--) {
586
+ const attempt = tryParse(content.slice(0, end));
587
+ if (attempt !== void 0) {
588
+ return attempt;
589
+ }
590
+ }
591
+ return text;
592
+ }
593
+ function createAPICallError({
594
+ message,
595
+ code,
596
+ exitCode,
597
+ stderr,
598
+ promptExcerpt,
599
+ isRetryable = false
600
+ }) {
601
+ const metadata = {
602
+ code,
603
+ exitCode,
604
+ stderr,
605
+ promptExcerpt
606
+ };
607
+ return new APICallError({
608
+ message,
609
+ isRetryable,
610
+ url: "claude-code-cli://command",
611
+ requestBodyValues: promptExcerpt ? { prompt: promptExcerpt } : void 0,
612
+ data: metadata
613
+ });
614
+ }
615
+ function createAuthenticationError({ message }) {
616
+ return new LoadAPIKeyError({
617
+ message: message || "Authentication failed. Please ensure Claude Code SDK is properly authenticated."
618
+ });
619
+ }
620
+ function createTimeoutError({
621
+ message,
622
+ promptExcerpt,
623
+ timeoutMs
624
+ }) {
625
+ const metadata = {
626
+ code: "TIMEOUT",
627
+ promptExcerpt
628
+ };
629
+ return new APICallError({
630
+ message,
631
+ isRetryable: true,
632
+ url: "claude-code-cli://command",
633
+ requestBodyValues: promptExcerpt ? { prompt: promptExcerpt } : void 0,
634
+ data: timeoutMs !== void 0 ? { ...metadata, timeoutMs } : metadata
635
+ });
636
+ }
637
+
638
+ // src/map-claude-code-finish-reason.ts
639
+ function mapClaudeCodeFinishReason(subtype) {
640
+ switch (subtype) {
641
+ case "success":
642
+ return "stop";
643
+ case "error_max_turns":
644
+ return "length";
645
+ case "error_during_execution":
646
+ return "error";
647
+ default:
648
+ return "stop";
649
+ }
650
+ }
651
+ var loggerFunctionSchema = z.object({
652
+ debug: z.any().refine((val) => typeof val === "function", {
653
+ message: "debug must be a function"
654
+ }),
655
+ info: z.any().refine((val) => typeof val === "function", {
656
+ message: "info must be a function"
657
+ }),
658
+ warn: z.any().refine((val) => typeof val === "function", {
659
+ message: "warn must be a function"
660
+ }),
661
+ error: z.any().refine((val) => typeof val === "function", {
662
+ message: "error must be a function"
663
+ })
664
+ });
665
+ var claudeCodeSettingsSchema = z.object({
666
+ pathToClaudeCodeExecutable: z.string().optional(),
667
+ customSystemPrompt: z.string().optional(),
668
+ appendSystemPrompt: z.string().optional(),
669
+ systemPrompt: z.union([
670
+ z.string(),
671
+ z.object({
672
+ type: z.literal("preset"),
673
+ preset: z.literal("claude_code"),
674
+ append: z.string().optional()
675
+ })
676
+ ]).optional(),
677
+ maxTurns: z.number().int().min(1).max(100).optional(),
678
+ maxThinkingTokens: z.number().int().positive().max(1e5).optional(),
679
+ cwd: z.string().refine(
680
+ (val) => {
681
+ if (typeof process === "undefined" || !process.versions?.node) {
682
+ return true;
683
+ }
684
+ return !val || existsSync(val);
685
+ },
686
+ { message: "Working directory must exist" }
687
+ ).optional(),
688
+ executable: z.enum(["bun", "deno", "node"]).optional(),
689
+ executableArgs: z.array(z.string()).optional(),
690
+ permissionMode: z.enum(["default", "acceptEdits", "bypassPermissions", "plan"]).optional(),
691
+ permissionPromptToolName: z.string().optional(),
692
+ continue: z.boolean().optional(),
693
+ resume: z.string().optional(),
694
+ allowedTools: z.array(z.string()).optional(),
695
+ disallowedTools: z.array(z.string()).optional(),
696
+ settingSources: z.array(z.enum(["user", "project", "local"])).optional(),
697
+ streamingInput: z.enum(["auto", "always", "off"]).optional(),
698
+ // Hooks and tool-permission callback (permissive validation of shapes)
699
+ canUseTool: z.any().refine((v) => v === void 0 || typeof v === "function", {
700
+ message: "canUseTool must be a function"
701
+ }).optional(),
702
+ hooks: z.record(
703
+ z.string(),
704
+ z.array(
705
+ z.object({
706
+ matcher: z.string().optional(),
707
+ hooks: z.array(z.any()).nonempty()
708
+ })
709
+ )
710
+ ).optional(),
711
+ mcpServers: z.record(
712
+ z.string(),
713
+ z.union([
714
+ // McpStdioServerConfig
715
+ z.object({
716
+ type: z.literal("stdio").optional(),
717
+ command: z.string(),
718
+ args: z.array(z.string()).optional(),
719
+ env: z.record(z.string(), z.string()).optional()
720
+ }),
721
+ // McpSSEServerConfig
722
+ z.object({
723
+ type: z.literal("sse"),
724
+ url: z.string(),
725
+ headers: z.record(z.string(), z.string()).optional()
726
+ }),
727
+ // McpHttpServerConfig
728
+ z.object({
729
+ type: z.literal("http"),
730
+ url: z.string(),
731
+ headers: z.record(z.string(), z.string()).optional()
732
+ }),
733
+ // McpSdkServerConfig (in-process custom tools)
734
+ z.object({
735
+ type: z.literal("sdk"),
736
+ name: z.string(),
737
+ instance: z.any()
738
+ })
739
+ ])
740
+ ).optional(),
741
+ verbose: z.boolean().optional(),
742
+ logger: z.union([z.literal(false), loggerFunctionSchema]).optional(),
743
+ env: z.record(z.string(), z.string().optional()).optional(),
744
+ additionalDirectories: z.array(z.string()).optional(),
745
+ agents: z.record(
746
+ z.string(),
747
+ z.object({
748
+ description: z.string(),
749
+ tools: z.array(z.string()).optional(),
750
+ prompt: z.string(),
751
+ model: z.enum(["sonnet", "opus", "haiku", "inherit"]).optional()
752
+ })
753
+ ).optional(),
754
+ includePartialMessages: z.boolean().optional(),
755
+ fallbackModel: z.string().optional(),
756
+ forkSession: z.boolean().optional(),
757
+ stderr: z.any().refine((val) => val === void 0 || typeof val === "function", {
758
+ message: "stderr must be a function"
759
+ }).optional(),
760
+ strictMcpConfig: z.boolean().optional(),
761
+ extraArgs: z.record(z.string(), z.union([z.string(), z.null()])).optional(),
762
+ queryFunction: z.any().refine((val) => val === void 0 || typeof val === "function", {
763
+ message: "queryFunction must be a function"
764
+ }).optional()
765
+ }).strict();
766
+ function validateModelId(modelId) {
767
+ const knownModels = ["opus", "sonnet", "haiku"];
768
+ if (!modelId || modelId.trim() === "") {
769
+ throw new Error("Model ID cannot be empty");
770
+ }
771
+ if (!knownModels.includes(modelId)) {
772
+ return `Unknown model ID: '${modelId}'. Proceeding with custom model. Known models are: ${knownModels.join(", ")}`;
773
+ }
774
+ return void 0;
775
+ }
776
+ function validateSettings(settings) {
777
+ const warnings = [];
778
+ const errors = [];
779
+ try {
780
+ const result = claudeCodeSettingsSchema.safeParse(settings);
781
+ if (!result.success) {
782
+ const errorObject = result.error;
783
+ const issues = errorObject.errors || errorObject.issues || [];
784
+ issues.forEach((err) => {
785
+ const path = err.path.join(".");
786
+ errors.push(`${path ? `${path}: ` : ""}${err.message}`);
787
+ });
788
+ return { valid: false, warnings, errors };
789
+ }
790
+ const validSettings = result.data;
791
+ if (validSettings.maxTurns && validSettings.maxTurns > 20) {
792
+ warnings.push(
793
+ `High maxTurns value (${validSettings.maxTurns}) may lead to long-running conversations`
794
+ );
795
+ }
796
+ if (validSettings.maxThinkingTokens && validSettings.maxThinkingTokens > 5e4) {
797
+ warnings.push(
798
+ `Very high maxThinkingTokens (${validSettings.maxThinkingTokens}) may increase response time`
799
+ );
800
+ }
801
+ if (validSettings.allowedTools && validSettings.disallowedTools) {
802
+ warnings.push(
803
+ "Both allowedTools and disallowedTools are specified. Only allowedTools will be used."
804
+ );
805
+ }
806
+ const validateToolNames = (tools, type) => {
807
+ tools.forEach((tool3) => {
808
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*(\([^)]*\))?$/.test(tool3) && !tool3.startsWith("mcp__")) {
809
+ warnings.push(`Unusual ${type} tool name format: '${tool3}'`);
810
+ }
811
+ });
812
+ };
813
+ if (validSettings.allowedTools) {
814
+ validateToolNames(validSettings.allowedTools, "allowed");
815
+ }
816
+ if (validSettings.disallowedTools) {
817
+ validateToolNames(validSettings.disallowedTools, "disallowed");
818
+ }
819
+ return { valid: true, warnings, errors };
820
+ } catch (error) {
821
+ errors.push(`Validation error: ${error instanceof Error ? error.message : String(error)}`);
822
+ return { valid: false, warnings, errors };
823
+ }
824
+ }
825
+ function validatePrompt(prompt) {
826
+ const MAX_PROMPT_LENGTH = 1e5;
827
+ if (prompt.length > MAX_PROMPT_LENGTH) {
828
+ return `Very long prompt (${prompt.length} characters) may cause performance issues or timeouts`;
829
+ }
830
+ return void 0;
831
+ }
832
+ function validateSessionId(sessionId) {
833
+ if (sessionId && !/^[a-zA-Z0-9-_]+$/.test(sessionId)) {
834
+ return `Unusual session ID format. This may cause issues with session resumption.`;
835
+ }
836
+ return void 0;
837
+ }
838
+
839
+ // src/logger.ts
840
+ var defaultLogger = {
841
+ debug: (message) => console.debug(`[DEBUG] ${message}`),
842
+ info: (message) => console.info(`[INFO] ${message}`),
843
+ warn: (message) => console.warn(`[WARN] ${message}`),
844
+ error: (message) => console.error(`[ERROR] ${message}`)
845
+ };
846
+ var noopLogger = {
847
+ debug: () => {
848
+ },
849
+ info: () => {
850
+ },
851
+ warn: () => {
852
+ },
853
+ error: () => {
854
+ }
855
+ };
856
+ function getLogger(logger) {
857
+ if (logger === false) {
858
+ return noopLogger;
859
+ }
860
+ if (logger === void 0) {
861
+ return defaultLogger;
862
+ }
863
+ return logger;
864
+ }
865
+ function createVerboseLogger(logger, verbose = false) {
866
+ if (verbose) {
867
+ return logger;
868
+ }
869
+ return {
870
+ debug: () => {
871
+ },
872
+ // No-op when not verbose
873
+ info: () => {
874
+ },
875
+ // No-op when not verbose
876
+ warn: logger.warn.bind(logger),
877
+ error: logger.error.bind(logger)
878
+ };
879
+ }
880
+ var CLAUDE_CODE_TRUNCATION_WARNING = "Claude Code SDK output ended unexpectedly; returning truncated response from buffered text. Await upstream fix to avoid data loss.";
881
+ var MIN_TRUNCATION_LENGTH = 512;
882
+ function isClaudeCodeTruncationError(error, bufferedText) {
883
+ const isSyntaxError = error instanceof SyntaxError || // eslint-disable-next-line @typescript-eslint/no-explicit-any
884
+ typeof error?.name === "string" && // eslint-disable-next-line @typescript-eslint/no-explicit-any
885
+ error.name.toLowerCase() === "syntaxerror";
886
+ if (!isSyntaxError) {
887
+ return false;
888
+ }
889
+ if (!bufferedText) {
890
+ return false;
891
+ }
892
+ const rawMessage = typeof error?.message === "string" ? error.message : "";
893
+ const message = rawMessage.toLowerCase();
894
+ const truncationIndicators = [
895
+ "unexpected end of json input",
896
+ "unexpected end of input",
897
+ "unexpected end of string",
898
+ "unexpected eof",
899
+ "end of file",
900
+ "unterminated string",
901
+ "unterminated string constant"
902
+ ];
903
+ if (!truncationIndicators.some((indicator) => message.includes(indicator))) {
904
+ return false;
905
+ }
906
+ if (bufferedText.length < MIN_TRUNCATION_LENGTH) {
907
+ return false;
908
+ }
909
+ return true;
910
+ }
911
+ function isAbortError(err) {
912
+ if (err && typeof err === "object") {
913
+ const e = err;
914
+ if (typeof e.name === "string" && e.name === "AbortError") return true;
915
+ if (typeof e.code === "string" && e.code.toUpperCase() === "ABORT_ERR") return true;
916
+ }
917
+ return false;
918
+ }
919
+ var STREAMING_FEATURE_WARNING = "Claude Agent SDK features (hooks/MCP/images) require streaming input. Set `streamingInput: 'always'` or provide `canUseTool` (auto streams only when canUseTool is set).";
920
+ function toAsyncIterablePrompt(messagesPrompt, outputStreamEnded, sessionId, contentParts) {
921
+ const content = contentParts && contentParts.length > 0 ? contentParts : [{ type: "text", text: messagesPrompt }];
922
+ const msg = {
923
+ type: "user",
924
+ message: {
925
+ role: "user",
926
+ content
927
+ },
928
+ parent_tool_use_id: null,
929
+ session_id: sessionId ?? ""
930
+ };
931
+ return {
932
+ async *[Symbol.asyncIterator]() {
933
+ yield msg;
934
+ await outputStreamEnded;
935
+ }
936
+ };
937
+ }
938
+ var modelMap = {
939
+ opus: "opus",
940
+ sonnet: "sonnet",
941
+ haiku: "haiku"
942
+ };
943
+ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
944
+ specificationVersion = "v2";
945
+ defaultObjectGenerationMode = "json";
946
+ supportsImageUrls = false;
947
+ supportedUrls = {};
948
+ supportsStructuredOutputs = false;
949
+ // Fallback/magic string constants
950
+ static UNKNOWN_TOOL_NAME = "unknown-tool";
951
+ // Tool input safety limits
952
+ static MAX_TOOL_INPUT_SIZE = 1048576;
953
+ // 1MB hard limit
954
+ static MAX_TOOL_INPUT_WARN = 102400;
955
+ // 100KB warning threshold
956
+ static MAX_DELTA_CALC_SIZE = 1e4;
957
+ // 10KB delta computation threshold
958
+ modelId;
959
+ settings;
960
+ sessionId;
961
+ modelValidationWarning;
962
+ settingsValidationWarnings;
963
+ logger;
964
+ queryFn;
965
+ constructor(options) {
966
+ this.modelId = options.id;
967
+ this.settings = options.settings ?? {};
968
+ this.settingsValidationWarnings = options.settingsValidationWarnings ?? [];
969
+ this.queryFn = this.settings.queryFunction ?? query;
970
+ const baseLogger = getLogger(this.settings.logger);
971
+ this.logger = createVerboseLogger(baseLogger, this.settings.verbose ?? false);
972
+ if (!this.modelId || typeof this.modelId !== "string" || this.modelId.trim() === "") {
973
+ throw new NoSuchModelError({
974
+ modelId: this.modelId,
975
+ modelType: "languageModel"
976
+ });
977
+ }
978
+ this.modelValidationWarning = validateModelId(this.modelId);
979
+ if (this.modelValidationWarning) {
980
+ this.logger.warn(`Claude Code Model: ${this.modelValidationWarning}`);
981
+ }
982
+ }
983
+ get provider() {
984
+ return "claude-code";
985
+ }
986
+ getModel() {
987
+ const mapped = modelMap[this.modelId];
988
+ return mapped ?? this.modelId;
989
+ }
990
+ extractToolUses(content) {
991
+ if (!Array.isArray(content)) {
992
+ return [];
993
+ }
994
+ return content.filter(
995
+ (item) => typeof item === "object" && item !== null && "type" in item && item.type === "tool_use"
996
+ ).map((item) => {
997
+ const { id, name, input } = item;
998
+ return {
999
+ id: typeof id === "string" && id.length > 0 ? id : generateId(),
1000
+ name: typeof name === "string" && name.length > 0 ? name : _ClaudeCodeLanguageModel.UNKNOWN_TOOL_NAME,
1001
+ input
1002
+ };
1003
+ });
1004
+ }
1005
+ extractToolResults(content) {
1006
+ if (!Array.isArray(content)) {
1007
+ return [];
1008
+ }
1009
+ return content.filter(
1010
+ (item) => typeof item === "object" && item !== null && "type" in item && item.type === "tool_result"
1011
+ ).map((item) => {
1012
+ const { tool_use_id, content: content2, is_error, name } = item;
1013
+ return {
1014
+ id: typeof tool_use_id === "string" && tool_use_id.length > 0 ? tool_use_id : generateId(),
1015
+ name: typeof name === "string" && name.length > 0 ? name : void 0,
1016
+ result: content2,
1017
+ isError: Boolean(is_error)
1018
+ };
1019
+ });
1020
+ }
1021
+ extractToolErrors(content) {
1022
+ if (!Array.isArray(content)) {
1023
+ return [];
1024
+ }
1025
+ return content.filter(
1026
+ (item) => typeof item === "object" && item !== null && "type" in item && item.type === "tool_error"
1027
+ ).map((item) => {
1028
+ const { tool_use_id, error, name } = item;
1029
+ return {
1030
+ id: typeof tool_use_id === "string" && tool_use_id.length > 0 ? tool_use_id : generateId(),
1031
+ name: typeof name === "string" && name.length > 0 ? name : void 0,
1032
+ error
1033
+ };
1034
+ });
1035
+ }
1036
+ serializeToolInput(input) {
1037
+ if (typeof input === "string") {
1038
+ return this.checkInputSize(input);
1039
+ }
1040
+ if (input === void 0) {
1041
+ return "";
1042
+ }
1043
+ try {
1044
+ const serialized = JSON.stringify(input);
1045
+ return this.checkInputSize(serialized);
1046
+ } catch {
1047
+ const fallback = String(input);
1048
+ return this.checkInputSize(fallback);
1049
+ }
1050
+ }
1051
+ checkInputSize(str) {
1052
+ const length = str.length;
1053
+ if (length > _ClaudeCodeLanguageModel.MAX_TOOL_INPUT_SIZE) {
1054
+ throw new Error(
1055
+ `Tool input exceeds maximum size of ${_ClaudeCodeLanguageModel.MAX_TOOL_INPUT_SIZE} bytes (got ${length} bytes). This may indicate a malformed request or an attempt to process excessively large data.`
1056
+ );
1057
+ }
1058
+ if (length > _ClaudeCodeLanguageModel.MAX_TOOL_INPUT_WARN) {
1059
+ this.logger.warn(
1060
+ `[claude-code] Large tool input detected: ${length} bytes. Performance may be impacted. Consider chunking or reducing input size.`
1061
+ );
1062
+ }
1063
+ return str;
1064
+ }
1065
+ normalizeToolResult(result) {
1066
+ if (typeof result === "string") {
1067
+ try {
1068
+ return JSON.parse(result);
1069
+ } catch {
1070
+ return result;
1071
+ }
1072
+ }
1073
+ return result;
1074
+ }
1075
+ generateAllWarnings(options, prompt) {
1076
+ const warnings = [];
1077
+ const unsupportedParams = [];
1078
+ if (options.temperature !== void 0) unsupportedParams.push("temperature");
1079
+ if (options.topP !== void 0) unsupportedParams.push("topP");
1080
+ if (options.topK !== void 0) unsupportedParams.push("topK");
1081
+ if (options.presencePenalty !== void 0) unsupportedParams.push("presencePenalty");
1082
+ if (options.frequencyPenalty !== void 0) unsupportedParams.push("frequencyPenalty");
1083
+ if (options.stopSequences !== void 0 && options.stopSequences.length > 0)
1084
+ unsupportedParams.push("stopSequences");
1085
+ if (options.seed !== void 0) unsupportedParams.push("seed");
1086
+ if (unsupportedParams.length > 0) {
1087
+ for (const param of unsupportedParams) {
1088
+ warnings.push({
1089
+ type: "unsupported-setting",
1090
+ setting: param,
1091
+ details: `Claude Code SDK does not support the ${param} parameter. It will be ignored.`
1092
+ });
1093
+ }
1094
+ }
1095
+ if (this.modelValidationWarning) {
1096
+ warnings.push({
1097
+ type: "other",
1098
+ message: this.modelValidationWarning
1099
+ });
1100
+ }
1101
+ this.settingsValidationWarnings.forEach((warning) => {
1102
+ warnings.push({
1103
+ type: "other",
1104
+ message: warning
1105
+ });
1106
+ });
1107
+ const promptWarning = validatePrompt(prompt);
1108
+ if (promptWarning) {
1109
+ warnings.push({
1110
+ type: "other",
1111
+ message: promptWarning
1112
+ });
1113
+ }
1114
+ return warnings;
1115
+ }
1116
+ handleJsonExtraction(text, warnings) {
1117
+ const extracted = extractJson(text);
1118
+ const validation = this.validateJsonExtraction(text, extracted);
1119
+ if (!validation.valid && validation.warning) {
1120
+ warnings.push(validation.warning);
1121
+ }
1122
+ return extracted;
1123
+ }
1124
+ createQueryOptions(abortController) {
1125
+ const opts = {
1126
+ model: this.getModel(),
1127
+ abortController,
1128
+ resume: this.settings.resume ?? this.sessionId,
1129
+ pathToClaudeCodeExecutable: this.settings.pathToClaudeCodeExecutable,
1130
+ maxTurns: this.settings.maxTurns,
1131
+ maxThinkingTokens: this.settings.maxThinkingTokens,
1132
+ cwd: this.settings.cwd,
1133
+ executable: this.settings.executable,
1134
+ executableArgs: this.settings.executableArgs,
1135
+ permissionMode: this.settings.permissionMode,
1136
+ permissionPromptToolName: this.settings.permissionPromptToolName,
1137
+ continue: this.settings.continue,
1138
+ allowedTools: this.settings.allowedTools,
1139
+ disallowedTools: this.settings.disallowedTools,
1140
+ mcpServers: this.settings.mcpServers,
1141
+ canUseTool: this.settings.canUseTool
1142
+ };
1143
+ if (this.settings.systemPrompt !== void 0) {
1144
+ opts.systemPrompt = this.settings.systemPrompt;
1145
+ } else if (this.settings.customSystemPrompt !== void 0) {
1146
+ this.logger.warn(
1147
+ "[claude-code] 'customSystemPrompt' is deprecated and will be removed in a future major release. Please use 'systemPrompt' instead (string or { type: 'preset', preset: 'claude_code', append? })."
1148
+ );
1149
+ opts.systemPrompt = this.settings.customSystemPrompt;
1150
+ } else if (this.settings.appendSystemPrompt !== void 0) {
1151
+ this.logger.warn(
1152
+ "[claude-code] 'appendSystemPrompt' is deprecated and will be removed in a future major release. Please use 'systemPrompt: { type: 'preset', preset: 'claude_code', append: <text> }' instead."
1153
+ );
1154
+ opts.systemPrompt = {
1155
+ type: "preset",
1156
+ preset: "claude_code",
1157
+ append: this.settings.appendSystemPrompt
1158
+ };
1159
+ }
1160
+ if (this.settings.settingSources !== void 0) {
1161
+ opts.settingSources = this.settings.settingSources;
1162
+ }
1163
+ if (this.settings.additionalDirectories !== void 0) {
1164
+ opts.additionalDirectories = this.settings.additionalDirectories;
1165
+ }
1166
+ if (this.settings.agents !== void 0) {
1167
+ opts.agents = this.settings.agents;
1168
+ }
1169
+ if (this.settings.includePartialMessages !== void 0) {
1170
+ opts.includePartialMessages = this.settings.includePartialMessages;
1171
+ }
1172
+ if (this.settings.fallbackModel !== void 0) {
1173
+ opts.fallbackModel = this.settings.fallbackModel;
1174
+ }
1175
+ if (this.settings.forkSession !== void 0) {
1176
+ opts.forkSession = this.settings.forkSession;
1177
+ }
1178
+ if (this.settings.stderr !== void 0) {
1179
+ opts.stderr = this.settings.stderr;
1180
+ }
1181
+ if (this.settings.strictMcpConfig !== void 0) {
1182
+ opts.strictMcpConfig = this.settings.strictMcpConfig;
1183
+ }
1184
+ if (this.settings.extraArgs !== void 0) {
1185
+ opts.extraArgs = this.settings.extraArgs;
1186
+ }
1187
+ if (this.settings.hooks) {
1188
+ opts.hooks = this.settings.hooks;
1189
+ }
1190
+ if (this.settings.env !== void 0) {
1191
+ opts.env = { ...process.env, ...this.settings.env };
1192
+ }
1193
+ return opts;
1194
+ }
1195
+ handleClaudeCodeError(error, messagesPrompt) {
1196
+ if (isAbortError(error)) {
1197
+ throw error;
1198
+ }
1199
+ const isErrorWithMessage = (err) => {
1200
+ return typeof err === "object" && err !== null && "message" in err;
1201
+ };
1202
+ const isErrorWithCode = (err) => {
1203
+ return typeof err === "object" && err !== null;
1204
+ };
1205
+ const authErrorPatterns = [
1206
+ "not logged in",
1207
+ "authentication",
1208
+ "unauthorized",
1209
+ "auth failed",
1210
+ "please login",
1211
+ "claude login"
1212
+ ];
1213
+ const errorMessage = isErrorWithMessage(error) && error.message ? error.message.toLowerCase() : "";
1214
+ const exitCode = isErrorWithCode(error) && typeof error.exitCode === "number" ? error.exitCode : void 0;
1215
+ const isAuthError = authErrorPatterns.some((pattern) => errorMessage.includes(pattern)) || exitCode === 401;
1216
+ if (isAuthError) {
1217
+ return createAuthenticationError({
1218
+ message: isErrorWithMessage(error) && error.message ? error.message : "Authentication failed. Please ensure Claude Code SDK is properly authenticated."
1219
+ });
1220
+ }
1221
+ const errorCode = isErrorWithCode(error) && typeof error.code === "string" ? error.code : "";
1222
+ if (errorCode === "ETIMEDOUT" || errorMessage.includes("timeout")) {
1223
+ return createTimeoutError({
1224
+ message: isErrorWithMessage(error) && error.message ? error.message : "Request timed out",
1225
+ promptExcerpt: messagesPrompt.substring(0, 200)
1226
+ // Don't specify timeoutMs since we don't know the actual timeout value
1227
+ // It's controlled by the consumer via AbortSignal
1228
+ });
1229
+ }
1230
+ const isRetryable = errorCode === "ENOENT" || errorCode === "ECONNREFUSED" || errorCode === "ETIMEDOUT" || errorCode === "ECONNRESET";
1231
+ return createAPICallError({
1232
+ message: isErrorWithMessage(error) && error.message ? error.message : "Claude Code SDK error",
1233
+ code: errorCode || void 0,
1234
+ exitCode,
1235
+ stderr: isErrorWithCode(error) && typeof error.stderr === "string" ? error.stderr : void 0,
1236
+ promptExcerpt: messagesPrompt.substring(0, 200),
1237
+ isRetryable
1238
+ });
1239
+ }
1240
+ setSessionId(sessionId) {
1241
+ this.sessionId = sessionId;
1242
+ const warning = validateSessionId(sessionId);
1243
+ if (warning) {
1244
+ this.logger.warn(`Claude Code Session: ${warning}`);
1245
+ }
1246
+ }
1247
+ validateJsonExtraction(originalText, extractedJson) {
1248
+ if (extractedJson === originalText) {
1249
+ return {
1250
+ valid: false,
1251
+ warning: {
1252
+ type: "other",
1253
+ message: "JSON extraction from model response may be incomplete or modified. The model may not have returned valid JSON."
1254
+ }
1255
+ };
1256
+ }
1257
+ try {
1258
+ JSON.parse(extractedJson);
1259
+ return { valid: true };
1260
+ } catch {
1261
+ return {
1262
+ valid: false,
1263
+ warning: {
1264
+ type: "other",
1265
+ message: "JSON extraction resulted in invalid JSON. The response may be malformed."
1266
+ }
1267
+ };
1268
+ }
1269
+ }
1270
+ async doGenerate(options) {
1271
+ this.logger.debug(`[claude-code] Starting doGenerate request with model: ${this.modelId}`);
1272
+ const mode = options.responseFormat?.type === "json" ? { type: "object-json" } : { type: "regular" };
1273
+ this.logger.debug(
1274
+ `[claude-code] Request mode: ${mode.type}, response format: ${options.responseFormat?.type ?? "none"}`
1275
+ );
1276
+ const {
1277
+ messagesPrompt,
1278
+ warnings: messageWarnings,
1279
+ streamingContentParts,
1280
+ hasImageParts
1281
+ } = convertToClaudeCodeMessages(
1282
+ options.prompt,
1283
+ mode,
1284
+ options.responseFormat?.type === "json" ? options.responseFormat.schema : void 0
1285
+ );
1286
+ this.logger.debug(
1287
+ `[claude-code] Converted ${options.prompt.length} messages, hasImageParts: ${hasImageParts}`
1288
+ );
1289
+ const abortController = new AbortController();
1290
+ let abortListener;
1291
+ if (options.abortSignal?.aborted) {
1292
+ abortController.abort(options.abortSignal.reason);
1293
+ } else if (options.abortSignal) {
1294
+ abortListener = () => abortController.abort(options.abortSignal?.reason);
1295
+ options.abortSignal.addEventListener("abort", abortListener, { once: true });
1296
+ }
1297
+ const queryOptions = this.createQueryOptions(abortController);
1298
+ let text = "";
1299
+ let usage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
1300
+ let finishReason = "stop";
1301
+ let wasTruncated = false;
1302
+ let costUsd;
1303
+ let durationMs;
1304
+ let rawUsage;
1305
+ const warnings = this.generateAllWarnings(
1306
+ options,
1307
+ messagesPrompt
1308
+ );
1309
+ if (messageWarnings) {
1310
+ messageWarnings.forEach((warning) => {
1311
+ warnings.push({
1312
+ type: "other",
1313
+ message: warning
1314
+ });
1315
+ });
1316
+ }
1317
+ const modeSetting = this.settings.streamingInput ?? "auto";
1318
+ const wantsStreamInput = modeSetting === "always" || modeSetting === "auto" && !!this.settings.canUseTool;
1319
+ if (!wantsStreamInput && hasImageParts) {
1320
+ warnings.push({
1321
+ type: "other",
1322
+ message: STREAMING_FEATURE_WARNING
1323
+ });
1324
+ }
1325
+ let done = () => {
1326
+ };
1327
+ const outputStreamEnded = new Promise((resolve) => {
1328
+ done = () => resolve(void 0);
1329
+ });
1330
+ try {
1331
+ if (this.settings.canUseTool && this.settings.permissionPromptToolName) {
1332
+ throw new Error(
1333
+ "canUseTool requires streamingInput mode ('auto' or 'always') and cannot be used with permissionPromptToolName (SDK constraint). Set streamingInput: 'auto' (or 'always') and remove permissionPromptToolName, or remove canUseTool."
1334
+ );
1335
+ }
1336
+ const sdkPrompt = wantsStreamInput ? toAsyncIterablePrompt(
1337
+ messagesPrompt,
1338
+ outputStreamEnded,
1339
+ this.settings.resume ?? this.sessionId,
1340
+ streamingContentParts
1341
+ ) : messagesPrompt;
1342
+ this.logger.debug(
1343
+ `[claude-code] Executing query with streamingInput: ${wantsStreamInput}, session: ${this.settings.resume ?? this.sessionId ?? "new"}`
1344
+ );
1345
+ const response = this.queryFn({
1346
+ prompt: sdkPrompt,
1347
+ options: queryOptions
1348
+ });
1349
+ for await (const message of response) {
1350
+ this.logger.debug(`[claude-code] Received message type: ${message.type}`);
1351
+ if (message.type === "assistant") {
1352
+ text += message.message.content.map((c) => c.type === "text" ? c.text : "").join("");
1353
+ } else if (message.type === "result") {
1354
+ done();
1355
+ this.setSessionId(message.session_id);
1356
+ costUsd = message.total_cost_usd;
1357
+ durationMs = message.duration_ms;
1358
+ this.logger.info(
1359
+ `[claude-code] Request completed - Session: ${message.session_id}, Cost: $${costUsd?.toFixed(4) ?? "N/A"}, Duration: ${durationMs ?? "N/A"}ms`
1360
+ );
1361
+ if ("usage" in message) {
1362
+ rawUsage = message.usage;
1363
+ usage = {
1364
+ inputTokens: (message.usage.cache_creation_input_tokens ?? 0) + (message.usage.cache_read_input_tokens ?? 0) + (message.usage.input_tokens ?? 0),
1365
+ outputTokens: message.usage.output_tokens ?? 0,
1366
+ totalTokens: (message.usage.cache_creation_input_tokens ?? 0) + (message.usage.cache_read_input_tokens ?? 0) + (message.usage.input_tokens ?? 0) + (message.usage.output_tokens ?? 0)
1367
+ };
1368
+ this.logger.debug(
1369
+ `[claude-code] Token usage - Input: ${usage.inputTokens}, Output: ${usage.outputTokens}, Total: ${usage.totalTokens}`
1370
+ );
1371
+ }
1372
+ finishReason = mapClaudeCodeFinishReason(message.subtype);
1373
+ this.logger.debug(`[claude-code] Finish reason: ${finishReason}`);
1374
+ } else if (message.type === "system" && message.subtype === "init") {
1375
+ this.setSessionId(message.session_id);
1376
+ this.logger.info(`[claude-code] Session initialized: ${message.session_id}`);
1377
+ }
1378
+ }
1379
+ } catch (error) {
1380
+ done();
1381
+ this.logger.debug(
1382
+ `[claude-code] Error during doGenerate: ${error instanceof Error ? error.message : String(error)}`
1383
+ );
1384
+ if (isAbortError(error)) {
1385
+ this.logger.debug("[claude-code] Request aborted by user");
1386
+ throw options.abortSignal?.aborted ? options.abortSignal.reason : error;
1387
+ }
1388
+ if (isClaudeCodeTruncationError(error, text)) {
1389
+ this.logger.warn(
1390
+ `[claude-code] Detected truncated response, returning ${text.length} characters of buffered text`
1391
+ );
1392
+ wasTruncated = true;
1393
+ finishReason = "length";
1394
+ warnings.push({
1395
+ type: "other",
1396
+ message: CLAUDE_CODE_TRUNCATION_WARNING
1397
+ });
1398
+ } else {
1399
+ throw this.handleClaudeCodeError(error, messagesPrompt);
1400
+ }
1401
+ } finally {
1402
+ if (options.abortSignal && abortListener) {
1403
+ options.abortSignal.removeEventListener("abort", abortListener);
1404
+ }
1405
+ }
1406
+ if (options.responseFormat?.type === "json" && text) {
1407
+ text = this.handleJsonExtraction(text, warnings);
1408
+ }
1409
+ return {
1410
+ content: [{ type: "text", text }],
1411
+ usage,
1412
+ finishReason,
1413
+ warnings,
1414
+ response: {
1415
+ id: generateId(),
1416
+ timestamp: /* @__PURE__ */ new Date(),
1417
+ modelId: this.modelId
1418
+ },
1419
+ request: {
1420
+ body: messagesPrompt
1421
+ },
1422
+ providerMetadata: {
1423
+ "claude-code": {
1424
+ ...this.sessionId !== void 0 && { sessionId: this.sessionId },
1425
+ ...costUsd !== void 0 && { costUsd },
1426
+ ...durationMs !== void 0 && { durationMs },
1427
+ ...rawUsage !== void 0 && { rawUsage },
1428
+ ...wasTruncated && { truncated: true }
1429
+ }
1430
+ }
1431
+ };
1432
+ }
1433
+ async doStream(options) {
1434
+ this.logger.debug(`[claude-code] Starting doStream request with model: ${this.modelId}`);
1435
+ const mode = options.responseFormat?.type === "json" ? { type: "object-json" } : { type: "regular" };
1436
+ this.logger.debug(
1437
+ `[claude-code] Stream mode: ${mode.type}, response format: ${options.responseFormat?.type ?? "none"}`
1438
+ );
1439
+ const {
1440
+ messagesPrompt,
1441
+ warnings: messageWarnings,
1442
+ streamingContentParts,
1443
+ hasImageParts
1444
+ } = convertToClaudeCodeMessages(
1445
+ options.prompt,
1446
+ mode,
1447
+ options.responseFormat?.type === "json" ? options.responseFormat.schema : void 0
1448
+ );
1449
+ this.logger.debug(
1450
+ `[claude-code] Converted ${options.prompt.length} messages for streaming, hasImageParts: ${hasImageParts}`
1451
+ );
1452
+ const abortController = new AbortController();
1453
+ let abortListener;
1454
+ if (options.abortSignal?.aborted) {
1455
+ abortController.abort(options.abortSignal.reason);
1456
+ } else if (options.abortSignal) {
1457
+ abortListener = () => abortController.abort(options.abortSignal?.reason);
1458
+ options.abortSignal.addEventListener("abort", abortListener, { once: true });
1459
+ }
1460
+ const queryOptions = this.createQueryOptions(abortController);
1461
+ const warnings = this.generateAllWarnings(
1462
+ options,
1463
+ messagesPrompt
1464
+ );
1465
+ if (messageWarnings) {
1466
+ messageWarnings.forEach((warning) => {
1467
+ warnings.push({
1468
+ type: "other",
1469
+ message: warning
1470
+ });
1471
+ });
1472
+ }
1473
+ const modeSetting = this.settings.streamingInput ?? "auto";
1474
+ const wantsStreamInput = modeSetting === "always" || modeSetting === "auto" && !!this.settings.canUseTool;
1475
+ if (!wantsStreamInput && hasImageParts) {
1476
+ warnings.push({
1477
+ type: "other",
1478
+ message: STREAMING_FEATURE_WARNING
1479
+ });
1480
+ }
1481
+ const stream = new ReadableStream({
1482
+ start: async (controller) => {
1483
+ let done = () => {
1484
+ };
1485
+ const outputStreamEnded = new Promise((resolve) => {
1486
+ done = () => resolve(void 0);
1487
+ });
1488
+ const toolStates = /* @__PURE__ */ new Map();
1489
+ const streamWarnings = [];
1490
+ const closeToolInput = (toolId, state) => {
1491
+ if (!state.inputClosed && state.inputStarted) {
1492
+ controller.enqueue({
1493
+ type: "tool-input-end",
1494
+ id: toolId
1495
+ });
1496
+ state.inputClosed = true;
1497
+ }
1498
+ };
1499
+ const emitToolCall = (toolId, state) => {
1500
+ if (state.callEmitted) {
1501
+ return;
1502
+ }
1503
+ closeToolInput(toolId, state);
1504
+ controller.enqueue({
1505
+ type: "tool-call",
1506
+ toolCallId: toolId,
1507
+ toolName: state.name,
1508
+ input: state.lastSerializedInput ?? "",
1509
+ providerExecuted: true,
1510
+ dynamic: true,
1511
+ // V3 field: indicates tool is provider-defined (not in user's tools map)
1512
+ providerMetadata: {
1513
+ "claude-code": {
1514
+ // rawInput preserves the original serialized format before AI SDK normalization.
1515
+ // Use this if you need the exact string sent to the Claude CLI, which may differ
1516
+ // from the `input` field after AI SDK processing.
1517
+ rawInput: state.lastSerializedInput ?? ""
1518
+ }
1519
+ }
1520
+ });
1521
+ state.callEmitted = true;
1522
+ };
1523
+ const finalizeToolCalls = () => {
1524
+ for (const [toolId, state] of toolStates) {
1525
+ emitToolCall(toolId, state);
1526
+ }
1527
+ toolStates.clear();
1528
+ };
1529
+ let usage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
1530
+ let accumulatedText = "";
1531
+ let textPartId;
1532
+ try {
1533
+ controller.enqueue({ type: "stream-start", warnings });
1534
+ if (this.settings.canUseTool && this.settings.permissionPromptToolName) {
1535
+ throw new Error(
1536
+ "canUseTool requires streamingInput mode ('auto' or 'always') and cannot be used with permissionPromptToolName (SDK constraint). Set streamingInput: 'auto' (or 'always') and remove permissionPromptToolName, or remove canUseTool."
1537
+ );
1538
+ }
1539
+ const sdkPrompt = wantsStreamInput ? toAsyncIterablePrompt(
1540
+ messagesPrompt,
1541
+ outputStreamEnded,
1542
+ this.settings.resume ?? this.sessionId,
1543
+ streamingContentParts
1544
+ ) : messagesPrompt;
1545
+ this.logger.debug(
1546
+ `[claude-code] Starting stream query with streamingInput: ${wantsStreamInput}, session: ${this.settings.resume ?? this.sessionId ?? "new"}`
1547
+ );
1548
+ const response = this.queryFn({
1549
+ prompt: sdkPrompt,
1550
+ options: queryOptions
1551
+ });
1552
+ for await (const message of response) {
1553
+ this.logger.debug(`[claude-code] Stream received message type: ${message.type}`);
1554
+ if (message.type === "assistant") {
1555
+ if (!message.message?.content) {
1556
+ this.logger.warn(
1557
+ `[claude-code] Unexpected assistant message structure: missing content field. Message type: ${message.type}. This may indicate an SDK protocol violation.`
1558
+ );
1559
+ continue;
1560
+ }
1561
+ const content = message.message.content;
1562
+ for (const tool3 of this.extractToolUses(content)) {
1563
+ const toolId = tool3.id;
1564
+ let state = toolStates.get(toolId);
1565
+ if (!state) {
1566
+ state = {
1567
+ name: tool3.name,
1568
+ inputStarted: false,
1569
+ inputClosed: false,
1570
+ callEmitted: false
1571
+ };
1572
+ toolStates.set(toolId, state);
1573
+ this.logger.debug(
1574
+ `[claude-code] New tool use detected - Tool: ${tool3.name}, ID: ${toolId}`
1575
+ );
1576
+ }
1577
+ state.name = tool3.name;
1578
+ if (!state.inputStarted) {
1579
+ this.logger.debug(
1580
+ `[claude-code] Tool input started - Tool: ${tool3.name}, ID: ${toolId}`
1581
+ );
1582
+ controller.enqueue({
1583
+ type: "tool-input-start",
1584
+ id: toolId,
1585
+ toolName: tool3.name,
1586
+ providerExecuted: true,
1587
+ dynamic: true
1588
+ // V3 field: indicates tool is provider-defined
1589
+ });
1590
+ state.inputStarted = true;
1591
+ }
1592
+ const serializedInput = this.serializeToolInput(tool3.input);
1593
+ if (serializedInput) {
1594
+ let deltaPayload = "";
1595
+ if (state.lastSerializedInput === void 0) {
1596
+ if (serializedInput.length <= _ClaudeCodeLanguageModel.MAX_DELTA_CALC_SIZE) {
1597
+ deltaPayload = serializedInput;
1598
+ }
1599
+ } else if (serializedInput.length <= _ClaudeCodeLanguageModel.MAX_DELTA_CALC_SIZE && state.lastSerializedInput.length <= _ClaudeCodeLanguageModel.MAX_DELTA_CALC_SIZE && serializedInput.startsWith(state.lastSerializedInput)) {
1600
+ deltaPayload = serializedInput.slice(state.lastSerializedInput.length);
1601
+ } else if (serializedInput !== state.lastSerializedInput) {
1602
+ deltaPayload = "";
1603
+ }
1604
+ if (deltaPayload) {
1605
+ controller.enqueue({
1606
+ type: "tool-input-delta",
1607
+ id: toolId,
1608
+ delta: deltaPayload
1609
+ });
1610
+ }
1611
+ state.lastSerializedInput = serializedInput;
1612
+ }
1613
+ }
1614
+ const text = content.map((c) => c.type === "text" ? c.text : "").join("");
1615
+ if (text) {
1616
+ accumulatedText += text;
1617
+ if (options.responseFormat?.type !== "json") {
1618
+ if (!textPartId) {
1619
+ textPartId = generateId();
1620
+ controller.enqueue({
1621
+ type: "text-start",
1622
+ id: textPartId
1623
+ });
1624
+ }
1625
+ controller.enqueue({
1626
+ type: "text-delta",
1627
+ id: textPartId,
1628
+ delta: text
1629
+ });
1630
+ }
1631
+ }
1632
+ } else if (message.type === "user") {
1633
+ if (!message.message?.content) {
1634
+ this.logger.warn(
1635
+ `[claude-code] Unexpected user message structure: missing content field. Message type: ${message.type}. This may indicate an SDK protocol violation.`
1636
+ );
1637
+ continue;
1638
+ }
1639
+ const content = message.message.content;
1640
+ for (const result of this.extractToolResults(content)) {
1641
+ let state = toolStates.get(result.id);
1642
+ const toolName = result.name ?? state?.name ?? _ClaudeCodeLanguageModel.UNKNOWN_TOOL_NAME;
1643
+ this.logger.debug(
1644
+ `[claude-code] Tool result received - Tool: ${toolName}, ID: ${result.id}`
1645
+ );
1646
+ if (!state) {
1647
+ this.logger.warn(
1648
+ `[claude-code] Received tool result for unknown tool ID: ${result.id}`
1649
+ );
1650
+ state = {
1651
+ name: toolName,
1652
+ inputStarted: false,
1653
+ inputClosed: false,
1654
+ callEmitted: false
1655
+ };
1656
+ toolStates.set(result.id, state);
1657
+ if (!state.inputStarted) {
1658
+ controller.enqueue({
1659
+ type: "tool-input-start",
1660
+ id: result.id,
1661
+ toolName,
1662
+ providerExecuted: true,
1663
+ dynamic: true
1664
+ // V3 field: indicates tool is provider-defined
1665
+ });
1666
+ state.inputStarted = true;
1667
+ }
1668
+ if (!state.inputClosed) {
1669
+ controller.enqueue({
1670
+ type: "tool-input-end",
1671
+ id: result.id
1672
+ });
1673
+ state.inputClosed = true;
1674
+ }
1675
+ }
1676
+ state.name = toolName;
1677
+ const normalizedResult = this.normalizeToolResult(result.result);
1678
+ const rawResult = typeof result.result === "string" ? result.result : (() => {
1679
+ try {
1680
+ return JSON.stringify(result.result);
1681
+ } catch {
1682
+ return String(result.result);
1683
+ }
1684
+ })();
1685
+ emitToolCall(result.id, state);
1686
+ controller.enqueue({
1687
+ type: "tool-result",
1688
+ toolCallId: result.id,
1689
+ toolName,
1690
+ result: normalizedResult,
1691
+ isError: result.isError,
1692
+ providerExecuted: true,
1693
+ dynamic: true,
1694
+ // V3 field: indicates tool is provider-defined
1695
+ providerMetadata: {
1696
+ "claude-code": {
1697
+ // rawResult preserves the original CLI output string before JSON parsing.
1698
+ // Use this when you need the exact string returned by the tool, especially
1699
+ // if the `result` field has been parsed/normalized and you need the original format.
1700
+ rawResult
1701
+ }
1702
+ }
1703
+ });
1704
+ }
1705
+ for (const error of this.extractToolErrors(content)) {
1706
+ let state = toolStates.get(error.id);
1707
+ const toolName = error.name ?? state?.name ?? _ClaudeCodeLanguageModel.UNKNOWN_TOOL_NAME;
1708
+ this.logger.debug(
1709
+ `[claude-code] Tool error received - Tool: ${toolName}, ID: ${error.id}`
1710
+ );
1711
+ if (!state) {
1712
+ this.logger.warn(
1713
+ `[claude-code] Received tool error for unknown tool ID: ${error.id}`
1714
+ );
1715
+ state = {
1716
+ name: toolName,
1717
+ inputStarted: true,
1718
+ inputClosed: true,
1719
+ callEmitted: false
1720
+ };
1721
+ toolStates.set(error.id, state);
1722
+ }
1723
+ emitToolCall(error.id, state);
1724
+ const rawError = typeof error.error === "string" ? error.error : typeof error.error === "object" && error.error !== null ? (() => {
1725
+ try {
1726
+ return JSON.stringify(error.error);
1727
+ } catch {
1728
+ return String(error.error);
1729
+ }
1730
+ })() : String(error.error);
1731
+ controller.enqueue({
1732
+ type: "tool-error",
1733
+ toolCallId: error.id,
1734
+ toolName,
1735
+ error: rawError,
1736
+ providerExecuted: true,
1737
+ dynamic: true,
1738
+ // V3 field: indicates tool is provider-defined
1739
+ providerMetadata: {
1740
+ "claude-code": {
1741
+ rawError
1742
+ }
1743
+ }
1744
+ });
1745
+ }
1746
+ } else if (message.type === "result") {
1747
+ done();
1748
+ this.logger.info(
1749
+ `[claude-code] Stream completed - Session: ${message.session_id}, Cost: $${message.total_cost_usd?.toFixed(4) ?? "N/A"}, Duration: ${message.duration_ms ?? "N/A"}ms`
1750
+ );
1751
+ let rawUsage;
1752
+ if ("usage" in message) {
1753
+ rawUsage = message.usage;
1754
+ usage = {
1755
+ inputTokens: (message.usage.cache_creation_input_tokens ?? 0) + (message.usage.cache_read_input_tokens ?? 0) + (message.usage.input_tokens ?? 0),
1756
+ outputTokens: message.usage.output_tokens ?? 0,
1757
+ totalTokens: (message.usage.cache_creation_input_tokens ?? 0) + (message.usage.cache_read_input_tokens ?? 0) + (message.usage.input_tokens ?? 0) + (message.usage.output_tokens ?? 0)
1758
+ };
1759
+ this.logger.debug(
1760
+ `[claude-code] Stream token usage - Input: ${usage.inputTokens}, Output: ${usage.outputTokens}, Total: ${usage.totalTokens}`
1761
+ );
1762
+ }
1763
+ const finishReason = mapClaudeCodeFinishReason(
1764
+ message.subtype
1765
+ );
1766
+ this.logger.debug(`[claude-code] Stream finish reason: ${finishReason}`);
1767
+ this.setSessionId(message.session_id);
1768
+ if (options.responseFormat?.type === "json" && accumulatedText) {
1769
+ const extractedJson = this.handleJsonExtraction(accumulatedText, streamWarnings);
1770
+ const jsonTextId = generateId();
1771
+ controller.enqueue({
1772
+ type: "text-start",
1773
+ id: jsonTextId
1774
+ });
1775
+ controller.enqueue({
1776
+ type: "text-delta",
1777
+ id: jsonTextId,
1778
+ delta: extractedJson
1779
+ });
1780
+ controller.enqueue({
1781
+ type: "text-end",
1782
+ id: jsonTextId
1783
+ });
1784
+ } else if (textPartId) {
1785
+ controller.enqueue({
1786
+ type: "text-end",
1787
+ id: textPartId
1788
+ });
1789
+ }
1790
+ finalizeToolCalls();
1791
+ const warningsJson = this.serializeWarningsForMetadata(streamWarnings);
1792
+ controller.enqueue({
1793
+ type: "finish",
1794
+ finishReason,
1795
+ usage,
1796
+ providerMetadata: {
1797
+ "claude-code": {
1798
+ sessionId: message.session_id,
1799
+ ...message.total_cost_usd !== void 0 && {
1800
+ costUsd: message.total_cost_usd
1801
+ },
1802
+ ...message.duration_ms !== void 0 && { durationMs: message.duration_ms },
1803
+ ...rawUsage !== void 0 && { rawUsage },
1804
+ // JSON validation warnings are collected during streaming and included
1805
+ // in providerMetadata since the AI SDK's finish event doesn't support
1806
+ // a top-level warnings field (unlike stream-start which was already emitted)
1807
+ ...streamWarnings.length > 0 && {
1808
+ warnings: warningsJson
1809
+ }
1810
+ }
1811
+ }
1812
+ });
1813
+ } else if (message.type === "system" && message.subtype === "init") {
1814
+ this.setSessionId(message.session_id);
1815
+ this.logger.info(`[claude-code] Stream session initialized: ${message.session_id}`);
1816
+ controller.enqueue({
1817
+ type: "response-metadata",
1818
+ id: message.session_id,
1819
+ timestamp: /* @__PURE__ */ new Date(),
1820
+ modelId: this.modelId
1821
+ });
1822
+ }
1823
+ }
1824
+ finalizeToolCalls();
1825
+ this.logger.debug("[claude-code] Stream finalized, closing stream");
1826
+ controller.close();
1827
+ } catch (error) {
1828
+ done();
1829
+ this.logger.debug(
1830
+ `[claude-code] Error during doStream: ${error instanceof Error ? error.message : String(error)}`
1831
+ );
1832
+ if (isClaudeCodeTruncationError(error, accumulatedText)) {
1833
+ this.logger.warn(
1834
+ `[claude-code] Detected truncated stream response, returning ${accumulatedText.length} characters of buffered text`
1835
+ );
1836
+ const truncationWarning = {
1837
+ type: "other",
1838
+ message: CLAUDE_CODE_TRUNCATION_WARNING
1839
+ };
1840
+ streamWarnings.push(truncationWarning);
1841
+ const emitJsonText = () => {
1842
+ const extractedJson = this.handleJsonExtraction(accumulatedText, streamWarnings);
1843
+ const jsonTextId = generateId();
1844
+ controller.enqueue({
1845
+ type: "text-start",
1846
+ id: jsonTextId
1847
+ });
1848
+ controller.enqueue({
1849
+ type: "text-delta",
1850
+ id: jsonTextId,
1851
+ delta: extractedJson
1852
+ });
1853
+ controller.enqueue({
1854
+ type: "text-end",
1855
+ id: jsonTextId
1856
+ });
1857
+ };
1858
+ if (options.responseFormat?.type === "json") {
1859
+ emitJsonText();
1860
+ } else if (textPartId) {
1861
+ controller.enqueue({
1862
+ type: "text-end",
1863
+ id: textPartId
1864
+ });
1865
+ } else if (accumulatedText) {
1866
+ const fallbackTextId = generateId();
1867
+ controller.enqueue({
1868
+ type: "text-start",
1869
+ id: fallbackTextId
1870
+ });
1871
+ controller.enqueue({
1872
+ type: "text-delta",
1873
+ id: fallbackTextId,
1874
+ delta: accumulatedText
1875
+ });
1876
+ controller.enqueue({
1877
+ type: "text-end",
1878
+ id: fallbackTextId
1879
+ });
1880
+ }
1881
+ finalizeToolCalls();
1882
+ const warningsJson = this.serializeWarningsForMetadata(streamWarnings);
1883
+ controller.enqueue({
1884
+ type: "finish",
1885
+ finishReason: "length",
1886
+ usage,
1887
+ providerMetadata: {
1888
+ "claude-code": {
1889
+ ...this.sessionId !== void 0 && { sessionId: this.sessionId },
1890
+ truncated: true,
1891
+ ...streamWarnings.length > 0 && {
1892
+ warnings: warningsJson
1893
+ }
1894
+ }
1895
+ }
1896
+ });
1897
+ controller.close();
1898
+ return;
1899
+ }
1900
+ finalizeToolCalls();
1901
+ let errorToEmit;
1902
+ if (isAbortError(error)) {
1903
+ errorToEmit = options.abortSignal?.aborted ? options.abortSignal.reason : error;
1904
+ } else {
1905
+ errorToEmit = this.handleClaudeCodeError(error, messagesPrompt);
1906
+ }
1907
+ controller.enqueue({
1908
+ type: "error",
1909
+ error: errorToEmit
1910
+ });
1911
+ controller.close();
1912
+ } finally {
1913
+ if (options.abortSignal && abortListener) {
1914
+ options.abortSignal.removeEventListener("abort", abortListener);
1915
+ }
1916
+ }
1917
+ },
1918
+ cancel: () => {
1919
+ if (options.abortSignal && abortListener) {
1920
+ options.abortSignal.removeEventListener("abort", abortListener);
1921
+ }
1922
+ }
1923
+ });
1924
+ return {
1925
+ stream,
1926
+ request: {
1927
+ body: messagesPrompt
1928
+ }
1929
+ };
1930
+ }
1931
+ serializeWarningsForMetadata(warnings) {
1932
+ const result = warnings.map((w) => {
1933
+ const base = { type: w.type };
1934
+ if ("message" in w) {
1935
+ const m = w.message;
1936
+ if (m !== void 0) base.message = String(m);
1937
+ }
1938
+ if (w.type === "unsupported-setting") {
1939
+ const setting = w.setting;
1940
+ if (setting !== void 0) base.setting = String(setting);
1941
+ if ("details" in w) {
1942
+ const d = w.details;
1943
+ if (d !== void 0) base.details = String(d);
1944
+ }
1945
+ }
1946
+ return base;
1947
+ });
1948
+ return result;
1949
+ }
1950
+ };
1951
+
1952
+ // src/claude-code-provider.ts
1953
+ function createClaudeCode(options = {}) {
1954
+ const logger = getLogger(options.defaultSettings?.logger);
1955
+ if (options.defaultSettings) {
1956
+ const validation = validateSettings(options.defaultSettings);
1957
+ if (!validation.valid) {
1958
+ throw new Error(`Invalid default settings: ${validation.errors.join(", ")}`);
1959
+ }
1960
+ if (validation.warnings.length > 0) {
1961
+ validation.warnings.forEach((warning) => logger.warn(`Claude Code Provider: ${warning}`));
1962
+ }
1963
+ }
1964
+ const createModel = (modelId, settings = {}) => {
1965
+ const mergedSettings = {
1966
+ ...options.defaultSettings,
1967
+ ...settings
1968
+ };
1969
+ const validation = validateSettings(mergedSettings);
1970
+ if (!validation.valid) {
1971
+ throw new Error(`Invalid settings: ${validation.errors.join(", ")}`);
1972
+ }
1973
+ return new ClaudeCodeLanguageModel({
1974
+ id: modelId,
1975
+ settings: mergedSettings,
1976
+ settingsValidationWarnings: validation.warnings
1977
+ });
1978
+ };
1979
+ const provider = function(modelId, settings) {
1980
+ if (new.target) {
1981
+ throw new Error("The Claude Code model function cannot be called with the new keyword.");
1982
+ }
1983
+ return createModel(modelId, settings);
1984
+ };
1985
+ provider.languageModel = createModel;
1986
+ provider.chat = createModel;
1987
+ provider.textEmbeddingModel = (modelId) => {
1988
+ throw new NoSuchModelError({
1989
+ modelId,
1990
+ modelType: "textEmbeddingModel"
1991
+ });
1992
+ };
1993
+ provider.imageModel = (modelId) => {
1994
+ throw new NoSuchModelError({
1995
+ modelId,
1996
+ modelType: "imageModel"
1997
+ });
1998
+ };
1999
+ return provider;
2000
+ }
2001
+ var claudeCode = createClaudeCode();
2002
+
66
2003
  /**
67
2004
  * Creates a permission handler that restricts Claude to a specific project directory
68
2005
  *
@@ -4546,34 +6483,34 @@ var AVAILABLE_ICONS = [
4546
6483
  ];
4547
6484
 
4548
6485
  var AgentCore = /*#__PURE__*/Object.freeze({
4549
- __proto__: null,
4550
- AVAILABLE_ICONS: AVAILABLE_ICONS,
4551
- CLAUDE_SYSTEM_PROMPT: CLAUDE_SYSTEM_PROMPT,
4552
- CODEX_SYSTEM_PROMPT: CODEX_SYSTEM_PROMPT,
4553
- DEFAULT_AGENT_ID: DEFAULT_AGENT_ID,
4554
- DEFAULT_CLAUDE_MODEL_ID: DEFAULT_CLAUDE_MODEL_ID,
4555
- DEFAULT_OPENCODE_MODEL_ID: DEFAULT_OPENCODE_MODEL_ID,
4556
- GITHUB_CHAT_MESSAGES: GITHUB_CHAT_MESSAGES,
4557
- LEGACY_MODEL_MAP: LEGACY_MODEL_MAP,
4558
- MODEL_METADATA: MODEL_METADATA,
4559
- NEONDB_CHAT_MESSAGES: NEONDB_CHAT_MESSAGES,
4560
- ProjectMetadataSchema: ProjectMetadataSchema,
4561
- ProjectNamingSchema: ProjectNamingSchema,
4562
- TemplateAnalysisSchema: TemplateAnalysisSchema,
4563
- buildLogger: buildLogger$2,
4564
- buildWebSocketServer: buildWebSocketServer,
4565
- db: db,
4566
- getDb: getDb,
4567
- getModelLabel: getModelLabel,
4568
- initializeDatabase: initializeDatabase,
4569
- isRunnerCommand: isRunnerCommand,
4570
- isRunnerEvent: isRunnerEvent,
4571
- normalizeModelId: normalizeModelId,
4572
- parseModelId: parseModelId,
4573
- resetDatabase: resetDatabase,
4574
- resolveAgentStrategy: resolveAgentStrategy$1,
4575
- runMigrations: runMigrations,
4576
- setTemplatesPath: setTemplatesPath$1
6486
+ __proto__: null,
6487
+ AVAILABLE_ICONS: AVAILABLE_ICONS,
6488
+ CLAUDE_SYSTEM_PROMPT: CLAUDE_SYSTEM_PROMPT,
6489
+ CODEX_SYSTEM_PROMPT: CODEX_SYSTEM_PROMPT,
6490
+ DEFAULT_AGENT_ID: DEFAULT_AGENT_ID,
6491
+ DEFAULT_CLAUDE_MODEL_ID: DEFAULT_CLAUDE_MODEL_ID,
6492
+ DEFAULT_OPENCODE_MODEL_ID: DEFAULT_OPENCODE_MODEL_ID,
6493
+ GITHUB_CHAT_MESSAGES: GITHUB_CHAT_MESSAGES,
6494
+ LEGACY_MODEL_MAP: LEGACY_MODEL_MAP,
6495
+ MODEL_METADATA: MODEL_METADATA,
6496
+ NEONDB_CHAT_MESSAGES: NEONDB_CHAT_MESSAGES,
6497
+ ProjectMetadataSchema: ProjectMetadataSchema,
6498
+ ProjectNamingSchema: ProjectNamingSchema,
6499
+ TemplateAnalysisSchema: TemplateAnalysisSchema,
6500
+ buildLogger: buildLogger$2,
6501
+ buildWebSocketServer: buildWebSocketServer,
6502
+ db: db,
6503
+ getDb: getDb,
6504
+ getModelLabel: getModelLabel,
6505
+ initializeDatabase: initializeDatabase,
6506
+ isRunnerCommand: isRunnerCommand,
6507
+ isRunnerEvent: isRunnerEvent,
6508
+ normalizeModelId: normalizeModelId,
6509
+ parseModelId: parseModelId,
6510
+ resetDatabase: resetDatabase,
6511
+ resolveAgentStrategy: resolveAgentStrategy$1,
6512
+ runMigrations: runMigrations,
6513
+ setTemplatesPath: setTemplatesPath$1
4577
6514
  });
4578
6515
 
4579
6516
  /**
@@ -4724,7 +6661,7 @@ function createNativeClaudeQuery(modelId = DEFAULT_CLAUDE_MODEL_ID, abortControl
4724
6661
  }
4725
6662
  const appendedSystemPrompt = systemPromptSegments.join('\n\n');
4726
6663
  // Ensure working directory exists
4727
- if (!existsSync(workingDirectory)) {
6664
+ if (!existsSync$1(workingDirectory)) {
4728
6665
  console.log(`[native-sdk] Creating working directory: ${workingDirectory}`);
4729
6666
  mkdirSync(workingDirectory, { recursive: true });
4730
6667
  }
@@ -5002,7 +6939,7 @@ function createOpenCodeQuery(modelId = DEFAULT_OPENCODE_MODEL_ID) {
5002
6939
  debugLog$3(`[runner] [opencode-sdk] Working dir: ${workingDirectory}`);
5003
6940
  debugLog$3(`[runner] [opencode-sdk] Prompt length: ${prompt.length}`);
5004
6941
  // Ensure working directory exists
5005
- if (!existsSync(workingDirectory)) {
6942
+ if (!existsSync$1(workingDirectory)) {
5006
6943
  console.log(`[opencode-sdk] Creating working directory: ${workingDirectory}`);
5007
6944
  mkdirSync(workingDirectory, { recursive: true });
5008
6945
  }
@@ -6921,7 +8858,7 @@ async function createBuildStream(options) {
6921
8858
  if (process.env.DEBUG_BUILD === '1')
6922
8859
  console.log(`[engine] Strategy adjusted CWD to: ${actualWorkingDir}`);
6923
8860
  }
6924
- else if (!existsSync(workingDirectory)) {
8861
+ else if (!existsSync$1(workingDirectory)) {
6925
8862
  mkdirSync(workingDirectory, { recursive: true });
6926
8863
  }
6927
8864
  if (!resolvedDir) {
@@ -7197,7 +9134,7 @@ function classifyStartupError(error, processInfo) {
7197
9134
  suggestion: 'Check file permissions and ownership'
7198
9135
  };
7199
9136
  }
7200
- if (processInfo.cwd && !existsSync(processInfo.cwd)) {
9137
+ if (processInfo.cwd && !existsSync$1(processInfo.cwd)) {
7201
9138
  return {
7202
9139
  reason: FailureReason.DIRECTORY_MISSING,
7203
9140
  message: `Working directory does not exist: ${processInfo.cwd}`,
@@ -7261,7 +9198,7 @@ function startDevServer(options) {
7261
9198
  buildLogger$1.processManager.processStarting(projectId, command, cwd);
7262
9199
  const emitter = new EventEmitter();
7263
9200
  // Verify CWD exists
7264
- if (!existsSync(cwd)) {
9201
+ if (!existsSync$1(cwd)) {
7265
9202
  const error = new Error(`Working directory does not exist: ${cwd}`);
7266
9203
  buildLogger$1.processManager.error('Failed to spawn process', error, { projectId });
7267
9204
  emitter.emit('error', error);
@@ -7498,7 +9435,7 @@ async function waitForPortRelease(port, maxWaitMs = 10000, pollIntervalMs = 500)
7498
9435
  */
7499
9436
  function fixPackageJsonPort(cwd, targetPort) {
7500
9437
  const packageJsonPath = join$1(cwd, 'package.json');
7501
- if (!existsSync(packageJsonPath)) {
9438
+ if (!existsSync$1(packageJsonPath)) {
7502
9439
  buildLogger$1.log('debug', 'process-manager', 'No package.json found to fix', { cwd });
7503
9440
  return false;
7504
9441
  }
@@ -7625,19 +9562,19 @@ async function stopAllDevServers(tunnelManager) {
7625
9562
  }
7626
9563
 
7627
9564
  var processManager = /*#__PURE__*/Object.freeze({
7628
- __proto__: null,
7629
- get FailureReason () { return FailureReason; },
7630
- get ProcessState () { return ProcessState; },
7631
- checkPortInUse: checkPortInUse,
7632
- findAvailablePort: findAvailablePort,
7633
- getAllActiveProjectIds: getAllActiveProjectIds,
7634
- runHealthCheck: runHealthCheck,
7635
- setSilentMode: setSilentMode$1,
7636
- startDevServer: startDevServer,
7637
- startDevServerAsync: startDevServerAsync,
7638
- stopAllDevServers: stopAllDevServers,
7639
- stopDevServer: stopDevServer,
7640
- waitForPortRelease: waitForPortRelease
9565
+ __proto__: null,
9566
+ get FailureReason () { return FailureReason; },
9567
+ get ProcessState () { return ProcessState; },
9568
+ checkPortInUse: checkPortInUse,
9569
+ findAvailablePort: findAvailablePort,
9570
+ getAllActiveProjectIds: getAllActiveProjectIds,
9571
+ runHealthCheck: runHealthCheck,
9572
+ setSilentMode: setSilentMode$1,
9573
+ startDevServer: startDevServer,
9574
+ startDevServerAsync: startDevServerAsync,
9575
+ stopAllDevServers: stopAllDevServers,
9576
+ stopDevServer: stopDevServer,
9577
+ waitForPortRelease: waitForPortRelease
7641
9578
  });
7642
9579
 
7643
9580
  /**
@@ -7647,7 +9584,7 @@ var processManager = /*#__PURE__*/Object.freeze({
7647
9584
  function getWorkspaceRoot() {
7648
9585
  // Check environment variable first
7649
9586
  const envWorkspace = process.env.WORKSPACE_ROOT;
7650
- if (envWorkspace && existsSync(envWorkspace)) {
9587
+ if (envWorkspace && existsSync$1(envWorkspace)) {
7651
9588
  return resolve(envWorkspace);
7652
9589
  }
7653
9590
  // Default to a workspace directory in the user's home
@@ -9139,10 +11076,10 @@ async function selectTemplateFromPrompt(userPrompt) {
9139
11076
  }
9140
11077
 
9141
11078
  var config = /*#__PURE__*/Object.freeze({
9142
- __proto__: null,
9143
- getAllTemplates: getAllTemplates,
9144
- loadTemplateConfig: loadTemplateConfig,
9145
- selectTemplateFromPrompt: selectTemplateFromPrompt
11079
+ __proto__: null,
11080
+ getAllTemplates: getAllTemplates,
11081
+ loadTemplateConfig: loadTemplateConfig,
11082
+ selectTemplateFromPrompt: selectTemplateFromPrompt
9146
11083
  });
9147
11084
 
9148
11085
  /**
@@ -9160,7 +11097,7 @@ async function downloadTemplate(template, targetPath) {
9160
11097
  console.log(` Target: ${targetPath}`);
9161
11098
  // Check if target already exists and add random suffix if needed
9162
11099
  let finalTargetPath = targetPath;
9163
- if (existsSync(targetPath)) {
11100
+ if (existsSync$1(targetPath)) {
9164
11101
  // Generate a unique 4-character suffix
9165
11102
  const randomSuffix = Math.random().toString(36).substring(2, 6);
9166
11103
  finalTargetPath = `${targetPath}-${randomSuffix}`;
@@ -9232,12 +11169,12 @@ async function downloadTemplateWithGit(template, targetPath) {
9232
11169
  // Handle multi-package projects with client/server subdirectories
9233
11170
  const clientPkgPath = join$1(targetPath, 'client', 'package.json');
9234
11171
  const serverPkgPath = join$1(targetPath, 'server', 'package.json');
9235
- if (existsSync(clientPkgPath)) {
11172
+ if (existsSync$1(clientPkgPath)) {
9236
11173
  await updatePackageName(join$1(targetPath, 'client'), `${projectName}-client`);
9237
11174
  await removeHardcodedPorts(join$1(targetPath, 'client'));
9238
11175
  await ensureVitePortConfig(join$1(targetPath, 'client'));
9239
11176
  }
9240
- if (existsSync(serverPkgPath)) {
11177
+ if (existsSync$1(serverPkgPath)) {
9241
11178
  await updatePackageName(join$1(targetPath, 'server'), `${projectName}-server`);
9242
11179
  await removeHardcodedPorts(join$1(targetPath, 'server'));
9243
11180
  await ensureVitePortConfig(join$1(targetPath, 'server'));
@@ -9272,7 +11209,7 @@ shamefully-hoist=false
9272
11209
  */
9273
11210
  async function updatePackageName(projectPath, newName) {
9274
11211
  const pkgPath = join$1(projectPath, 'package.json');
9275
- if (!existsSync(pkgPath)) {
11212
+ if (!existsSync$1(pkgPath)) {
9276
11213
  if (process.env.DEBUG_BUILD === '1')
9277
11214
  console.log(` No package.json found in ${projectPath}, skipping name update`);
9278
11215
  return;
@@ -9295,7 +11232,7 @@ async function updatePackageName(projectPath, newName) {
9295
11232
  */
9296
11233
  async function removeHardcodedPorts(projectPath) {
9297
11234
  const pkgPath = join$1(projectPath, 'package.json');
9298
- if (!existsSync(pkgPath)) {
11235
+ if (!existsSync$1(pkgPath)) {
9299
11236
  return;
9300
11237
  }
9301
11238
  try {
@@ -9344,11 +11281,11 @@ async function ensureVitePortConfig(projectPath) {
9344
11281
  const viteConfigJs = join$1(projectPath, 'vite.config.js');
9345
11282
  const viteConfigMts = join$1(projectPath, 'vite.config.mts');
9346
11283
  let configPath = null;
9347
- if (existsSync(viteConfigTs))
11284
+ if (existsSync$1(viteConfigTs))
9348
11285
  configPath = viteConfigTs;
9349
- else if (existsSync(viteConfigMts))
11286
+ else if (existsSync$1(viteConfigMts))
9350
11287
  configPath = viteConfigMts;
9351
- else if (existsSync(viteConfigJs))
11288
+ else if (existsSync$1(viteConfigJs))
9352
11289
  configPath = viteConfigJs;
9353
11290
  if (!configPath)
9354
11291
  return;
@@ -9486,7 +11423,7 @@ async function orchestrateBuild(context) {
9486
11423
  }
9487
11424
  // Verify directory state for logging
9488
11425
  try {
9489
- if (existsSync(workingDirectory)) {
11426
+ if (existsSync$1(workingDirectory)) {
9490
11427
  const files = await readdir(workingDirectory);
9491
11428
  if (process.env.DEBUG_BUILD === '1')
9492
11429
  console.log(`[orchestrator] Directory status: ${files.length} files found`);
@@ -9973,7 +11910,7 @@ function getCleanEnv() {
9973
11910
  * Ensure a directory exists
9974
11911
  */
9975
11912
  function ensureDir(dir) {
9976
- if (!existsSync$1(dir)) {
11913
+ if (!existsSync(dir)) {
9977
11914
  mkdirSync$1(dir, { recursive: true });
9978
11915
  }
9979
11916
  }
@@ -10407,10 +12344,10 @@ async function waitForPort(port, maxRetries = 10, delayMs = 500) {
10407
12344
  }
10408
12345
 
10409
12346
  var portChecker = /*#__PURE__*/Object.freeze({
10410
- __proto__: null,
10411
- isPortReady: isPortReady,
10412
- setSilentMode: setSilentMode,
10413
- waitForPort: waitForPort
12347
+ __proto__: null,
12348
+ isPortReady: isPortReady,
12349
+ setSilentMode: setSilentMode,
12350
+ waitForPort: waitForPort
10414
12351
  });
10415
12352
 
10416
12353
  /**
@@ -10587,7 +12524,7 @@ const DEBUG_BUILD = process.env.DEBUG_BUILD === "1" || false;
10587
12524
  const log = (...args) => {
10588
12525
  const message = args.map(a => typeof a === 'string' ? a : JSON.stringify(a)).join(' ');
10589
12526
  try {
10590
- const logger = getLogger();
12527
+ const logger = getLogger$1();
10591
12528
  logger.info('system', message);
10592
12529
  }
10593
12530
  catch {
@@ -10601,7 +12538,7 @@ const log = (...args) => {
10601
12538
  const buildLog = (...args) => {
10602
12539
  const message = args.map(a => typeof a === 'string' ? a : JSON.stringify(a)).join(' ');
10603
12540
  try {
10604
- const logger = getLogger();
12541
+ const logger = getLogger$1();
10605
12542
  logger.info('build', message);
10606
12543
  }
10607
12544
  catch {
@@ -10617,7 +12554,7 @@ const debugLog = (...args) => {
10617
12554
  return;
10618
12555
  const message = args.map(a => typeof a === 'string' ? a : JSON.stringify(a)).join(' ');
10619
12556
  try {
10620
- const logger = getLogger();
12557
+ const logger = getLogger$1();
10621
12558
  logger.debug('system', message);
10622
12559
  }
10623
12560
  catch {
@@ -10660,7 +12597,7 @@ function createClaudeQuery(modelId = DEFAULT_CLAUDE_MODEL_ID) {
10660
12597
  // Use the full model ID as-is (claude-haiku-4-5, claude-sonnet-4-5, claude-opus-4-5)
10661
12598
  const aiSdkModelId = modelId || "claude-haiku-4-5";
10662
12599
  // Ensure working directory exists before passing to Claude Code
10663
- if (!existsSync(workingDirectory)) {
12600
+ if (!existsSync$1(workingDirectory)) {
10664
12601
  console.log(`[createClaudeQuery] Creating working directory: ${workingDirectory}`);
10665
12602
  mkdirSync(workingDirectory, { recursive: true });
10666
12603
  }
@@ -11141,7 +13078,7 @@ async function startRunner(options = {}) {
11141
13078
  }
11142
13079
  const runnerSharedSecret = SHARED_SECRET; // Guaranteed to be string after validation check
11143
13080
  // Ensure workspace directory exists
11144
- if (!existsSync(WORKSPACE_ROOT)) {
13081
+ if (!existsSync$1(WORKSPACE_ROOT)) {
11145
13082
  console.log(`📁 Creating workspace directory: ${WORKSPACE_ROOT}`);
11146
13083
  mkdirSync(WORKSPACE_ROOT, { recursive: true });
11147
13084
  }
@@ -11172,14 +13109,14 @@ async function startRunner(options = {}) {
11172
13109
  id: RUNNER_ID,
11173
13110
  connected: socket?.readyState === WebSocket$1.OPEN,
11174
13111
  workspace: WORKSPACE_ROOT,
11175
- workspaceExists: existsSync(WORKSPACE_ROOT),
13112
+ workspaceExists: existsSync$1(WORKSPACE_ROOT),
11176
13113
  },
11177
13114
  uptime: process.uptime(),
11178
13115
  timestamp: new Date().toISOString(),
11179
13116
  });
11180
13117
  });
11181
13118
  healthApp.get('/ready', (req, res) => {
11182
- const isReady = socket?.readyState === WebSocket$1.OPEN && existsSync(WORKSPACE_ROOT);
13119
+ const isReady = socket?.readyState === WebSocket$1.OPEN && existsSync$1(WORKSPACE_ROOT);
11183
13120
  res.status(isReady ? 200 : 503).json({
11184
13121
  ready: isReady,
11185
13122
  runnerId: RUNNER_ID,
@@ -12616,7 +14553,7 @@ async function startRunner(options = {}) {
12616
14553
  // Detect framework from generated files
12617
14554
  let detectedFramework = null;
12618
14555
  try {
12619
- const { detectFrameworkFromFilesystem } = await import('./chunks/port-allocator-B0q7xkLs.js');
14556
+ const { detectFrameworkFromFilesystem } = await import('./chunks/port-allocator-Ct3ioni4.js');
12620
14557
  const framework = await detectFrameworkFromFilesystem(projectDirectory);
12621
14558
  detectedFramework = framework;
12622
14559
  if (framework) {
@@ -13274,3 +15211,4 @@ if (import.meta.url === `file://${process.argv[1]}`) {
13274
15211
  }
13275
15212
 
13276
15213
  export { startRunner };
15214
+ //# sourceMappingURL=index.js.map