@k-leumas/queque-cli 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/app.js CHANGED
@@ -83,7 +83,7 @@ var init_uuid = __esm({
83
83
  });
84
84
 
85
85
  // node_modules/.pnpm/@anthropic-ai+sdk@0.92.0_zod@4.1.5/node_modules/@anthropic-ai/sdk/internal/errors.mjs
86
- function isAbortError(err) {
86
+ function isAbortError2(err) {
87
87
  return typeof err === "object" && err !== null && // Spec-compliant fetch implementations
88
88
  ("name" in err && err.name === "AbortError" || // Expo fetch
89
89
  "message" in err && String(err.message).includes("FetchRequestCanceledException"));
@@ -841,7 +841,7 @@ var init_streaming = __esm({
841
841
  }
842
842
  done = true;
843
843
  } catch (e) {
844
- if (isAbortError(e))
844
+ if (isAbortError2(e))
845
845
  return;
846
846
  throw e;
847
847
  } finally {
@@ -884,7 +884,7 @@ var init_streaming = __esm({
884
884
  }
885
885
  done = true;
886
886
  } catch (e) {
887
- if (isAbortError(e))
887
+ if (isAbortError2(e))
888
888
  return;
889
889
  throw e;
890
890
  } finally {
@@ -3225,7 +3225,7 @@ var init_BetaMessageStream = __esm({
3225
3225
  _BetaMessageStream_logger.set(this, void 0);
3226
3226
  _BetaMessageStream_handleError.set(this, (error43) => {
3227
3227
  __classPrivateFieldSet(this, _BetaMessageStream_errored, true, "f");
3228
- if (isAbortError(error43)) {
3228
+ if (isAbortError2(error43)) {
3229
3229
  error43 = new APIUserAbortError();
3230
3230
  }
3231
3231
  if (error43 instanceof APIUserAbortError) {
@@ -5424,7 +5424,7 @@ var init_MessageStream = __esm({
5424
5424
  _MessageStream_logger.set(this, void 0);
5425
5425
  _MessageStream_handleError.set(this, (error43) => {
5426
5426
  __classPrivateFieldSet(this, _MessageStream_errored, true, "f");
5427
- if (isAbortError(error43)) {
5427
+ if (isAbortError2(error43)) {
5428
5428
  error43 = new APIUserAbortError();
5429
5429
  }
5430
5430
  if (error43 instanceof APIUserAbortError) {
@@ -6559,7 +6559,7 @@ var init_client = __esm({
6559
6559
  if (options.signal?.aborted) {
6560
6560
  throw new APIUserAbortError();
6561
6561
  }
6562
- const isTimeout = isAbortError(response) || /timed? ?out/i.test(String(response) + ("cause" in response ? String(response.cause) : ""));
6562
+ const isTimeout = isAbortError2(response) || /timed? ?out/i.test(String(response) + ("cause" in response ? String(response.cause) : ""));
6563
6563
  if (retriesRemaining) {
6564
6564
  loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? "timed out" : "failed"} - ${retryMessage}`);
6565
6565
  loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? "timed out" : "failed"} (${retryMessage})`, formatRequestDetails({
@@ -33239,7 +33239,7 @@ var require_websocket = __commonJS({
33239
33239
  var http = __require("http");
33240
33240
  var net4 = __require("net");
33241
33241
  var tls = __require("tls");
33242
- var { randomBytes, createHash } = __require("crypto");
33242
+ var { randomBytes, createHash: createHash2 } = __require("crypto");
33243
33243
  var { Duplex, Readable } = __require("stream");
33244
33244
  var { URL: URL2 } = __require("url");
33245
33245
  var PerMessageDeflate2 = require_permessage_deflate();
@@ -33899,7 +33899,7 @@ var require_websocket = __commonJS({
33899
33899
  abortHandshake(websocket, socket, "Invalid Upgrade header");
33900
33900
  return;
33901
33901
  }
33902
- const digest = createHash("sha1").update(key + GUID).digest("base64");
33902
+ const digest = createHash2("sha1").update(key + GUID).digest("base64");
33903
33903
  if (res.headers["sec-websocket-accept"] !== digest) {
33904
33904
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
33905
33905
  return;
@@ -34266,7 +34266,7 @@ var require_websocket_server = __commonJS({
34266
34266
  var EventEmitter3 = __require("events");
34267
34267
  var http = __require("http");
34268
34268
  var { Duplex } = __require("stream");
34269
- var { createHash } = __require("crypto");
34269
+ var { createHash: createHash2 } = __require("crypto");
34270
34270
  var extension2 = require_extension();
34271
34271
  var PerMessageDeflate2 = require_permessage_deflate();
34272
34272
  var subprotocol2 = require_subprotocol();
@@ -34567,7 +34567,7 @@ var require_websocket_server = __commonJS({
34567
34567
  );
34568
34568
  }
34569
34569
  if (this._state > RUNNING) return abortHandshake(socket, 503);
34570
- const digest = createHash("sha1").update(key + GUID).digest("base64");
34570
+ const digest = createHash2("sha1").update(key + GUID).digest("base64");
34571
34571
  const headers = [
34572
34572
  "HTTP/1.1 101 Switching Protocols",
34573
34573
  "Upgrade: websocket",
@@ -34669,10 +34669,10 @@ var init_wrapper = __esm({
34669
34669
  }
34670
34670
  });
34671
34671
 
34672
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/devtools-window-polyfill.js
34672
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/devtools-window-polyfill.js
34673
34673
  var customGlobal;
34674
34674
  var init_devtools_window_polyfill = __esm({
34675
- "node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/devtools-window-polyfill.js"() {
34675
+ "node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/devtools-window-polyfill.js"() {
34676
34676
  "use strict";
34677
34677
  init_wrapper();
34678
34678
  customGlobal = globalThis;
@@ -34748,11 +34748,11 @@ var init_react_devtools_core = __esm({
34748
34748
  }
34749
34749
  });
34750
34750
 
34751
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/devtools.js
34751
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/devtools.js
34752
34752
  var devtools_exports = {};
34753
34753
  var isDevToolsReachable;
34754
34754
  var init_devtools = __esm({
34755
- async "node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/devtools.js"() {
34755
+ async "node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/devtools.js"() {
34756
34756
  "use strict";
34757
34757
  init_devtools_window_polyfill();
34758
34758
  init_wrapper();
@@ -48088,7 +48088,14 @@ var privacyConfigSchema = external_exports.object({
48088
48088
  var safetyConfigSchema = external_exports.object({
48089
48089
  destructiveCommandPatterns: external_exports.array(external_exports.string()).optional()
48090
48090
  }).optional();
48091
+ var EFFORT_LEVELS = ["low", "medium", "high", "xhigh", "max"];
48092
+ var DEFAULT_EFFORT = "low";
48093
+ var effortSchema = external_exports.preprocess(
48094
+ (value) => typeof value === "string" ? value.trim().toLowerCase() : value,
48095
+ external_exports.enum(EFFORT_LEVELS)
48096
+ ).optional().catch(void 0);
48091
48097
  var qqConfigFileSchema = external_exports.object({
48098
+ effort: effortSchema,
48092
48099
  privacy: privacyConfigSchema,
48093
48100
  safety: safetyConfigSchema
48094
48101
  });
@@ -48153,10 +48160,14 @@ function loadQqConfig() {
48153
48160
  sensitivePathRegexes: compilePatterns(sensitivePatterns),
48154
48161
  redactLogKeys: new Set(redactKeys),
48155
48162
  allowFileRead,
48156
- destructiveCommandRegexes: compilePatterns(destructivePatterns)
48163
+ destructiveCommandRegexes: compilePatterns(destructivePatterns),
48164
+ effort: file2.effort ?? DEFAULT_EFFORT
48157
48165
  };
48158
48166
  return cachedConfig;
48159
48167
  }
48168
+ function resolveEffort() {
48169
+ return loadQqConfig().effort;
48170
+ }
48160
48171
 
48161
48172
  // src/shared/privacy-filter.ts
48162
48173
  function isSensitivePath(path5) {
@@ -48411,6 +48422,113 @@ function readEnvValueFromDotEnvLocal(key, startDir = process.cwd()) {
48411
48422
  return result;
48412
48423
  }
48413
48424
 
48425
+ // src/providers/candidate-stream.ts
48426
+ var MAX_STREAMED_CANDIDATES = 5;
48427
+ function createCandidateScanner(onCandidate) {
48428
+ let started = false;
48429
+ let finished = false;
48430
+ let depth = 0;
48431
+ let inString = false;
48432
+ let escaped = false;
48433
+ let inObject = false;
48434
+ let objectText = "";
48435
+ let emitted = 0;
48436
+ const emit = (text) => {
48437
+ let parsed;
48438
+ try {
48439
+ parsed = JSON.parse(text);
48440
+ } catch {
48441
+ return;
48442
+ }
48443
+ const candidate = commandCandidateSchema.safeParse(parsed);
48444
+ if (!candidate.success) {
48445
+ return;
48446
+ }
48447
+ emitted++;
48448
+ onCandidate(candidate.data);
48449
+ if (emitted >= MAX_STREAMED_CANDIDATES) {
48450
+ finished = true;
48451
+ }
48452
+ };
48453
+ return (text) => {
48454
+ for (const ch of text) {
48455
+ if (finished) {
48456
+ return;
48457
+ }
48458
+ if (!started) {
48459
+ if (ch === "[") {
48460
+ started = true;
48461
+ depth = 1;
48462
+ }
48463
+ continue;
48464
+ }
48465
+ if (inObject) {
48466
+ objectText += ch;
48467
+ }
48468
+ if (inString) {
48469
+ if (escaped) {
48470
+ escaped = false;
48471
+ } else if (ch === "\\") {
48472
+ escaped = true;
48473
+ } else if (ch === '"') {
48474
+ inString = false;
48475
+ }
48476
+ continue;
48477
+ }
48478
+ if (ch === '"') {
48479
+ inString = true;
48480
+ } else if (ch === "[" || ch === "{") {
48481
+ depth++;
48482
+ if (ch === "{" && depth === 2) {
48483
+ inObject = true;
48484
+ objectText = ch;
48485
+ }
48486
+ } else if (ch === "]" || ch === "}") {
48487
+ depth--;
48488
+ if (ch === "}" && depth === 1 && inObject) {
48489
+ const closed = objectText;
48490
+ inObject = false;
48491
+ objectText = "";
48492
+ emit(closed);
48493
+ } else if (depth <= 0) {
48494
+ finished = true;
48495
+ }
48496
+ }
48497
+ }
48498
+ };
48499
+ }
48500
+ function stripJsonCodeFence(raw) {
48501
+ const match = raw.trim().match(/^```(?:json)?\s*\n?([\s\S]*?)\n?```\s*$/);
48502
+ return match ? match[1].trim() : raw.trim();
48503
+ }
48504
+ function parseStrictCandidateList(text) {
48505
+ let parsed;
48506
+ try {
48507
+ parsed = JSON.parse(stripJsonCodeFence(text));
48508
+ } catch {
48509
+ return void 0;
48510
+ }
48511
+ const list = candidateListSchema.safeParse(parsed);
48512
+ return list.success ? list.data : void 0;
48513
+ }
48514
+
48515
+ // src/providers/provider.ts
48516
+ function abortError() {
48517
+ const error43 = new Error("QueQue: request aborted");
48518
+ error43.name = "AbortError";
48519
+ return error43;
48520
+ }
48521
+ function isNormalStopReason(stopReason) {
48522
+ return stopReason === "end_turn" || stopReason === "stop_sequence";
48523
+ }
48524
+ function isAbortError(error43) {
48525
+ if (error43 === null || typeof error43 !== "object") {
48526
+ return false;
48527
+ }
48528
+ const name = error43.name;
48529
+ return name === "AbortError" || name === "APIUserAbortError";
48530
+ }
48531
+
48414
48532
  // src/shared/tool-catalog.ts
48415
48533
  var CATALOG = Object.freeze(
48416
48534
  `
@@ -48480,6 +48598,8 @@ ${buildSteeringText(chunk.payload.tools)}`;
48480
48598
 
48481
48599
  // src/providers/claude.ts
48482
48600
  var DEFAULT_MODEL = "claude-sonnet-5";
48601
+ var SDK_MAX_TOKENS = 16e3;
48602
+ var TRUNCATED_RESPONSE_MESSAGE = "QueQue: Claude response was truncated";
48483
48603
  var cachedAnthropic;
48484
48604
  async function getAnthropicClient(apiKey) {
48485
48605
  if (cachedAnthropic?.apiKey === apiKey) {
@@ -48492,12 +48612,26 @@ async function getAnthropicClient(apiKey) {
48492
48612
  cachedAnthropic = { apiKey, client: new AnthropicSdk({ apiKey }) };
48493
48613
  return cachedAnthropic.client;
48494
48614
  }
48615
+ var EFFORT_UNSUPPORTED_MODEL_RE = /haiku|claude-3|sonnet-4-5(?!\d)|(?:sonnet|opus)-4-(?:0|1|2025\d*)(?!\d)/i;
48616
+ function sdkOutputConfig(model, effort) {
48617
+ if (EFFORT_UNSUPPORTED_MODEL_RE.test(model)) {
48618
+ return void 0;
48619
+ }
48620
+ return { effort };
48621
+ }
48495
48622
  function resolveModel() {
48496
48623
  return process.env.QQ_MODEL ?? readEnvValueFromDotEnvLocal("QQ_MODEL") ?? DEFAULT_MODEL;
48497
48624
  }
48498
48625
  function extractText(content) {
48499
48626
  return content.filter((block) => block.type === "text" && typeof block.text === "string").map((block) => block.text ?? "").join("").trim();
48500
48627
  }
48628
+ function completeCandidates(text) {
48629
+ const rows = [];
48630
+ createCandidateScanner((candidate) => {
48631
+ rows.push(candidate);
48632
+ })(text);
48633
+ return rows;
48634
+ }
48501
48635
  function stripCodeFence(raw) {
48502
48636
  const m = raw.trim().match(/^```(?:json)?\s*\n?([\s\S]*?)\n?```\s*$/);
48503
48637
  return m ? m[1].trim() : raw.trim();
@@ -48516,6 +48650,24 @@ function parseCandidates(text) {
48516
48650
  return [{ command: 'echo ""', explanation: "QueQue: unexpected response format" }];
48517
48651
  }
48518
48652
  }
48653
+ function finalCandidateList(text, streamed, finishedNormally, logFields = {}) {
48654
+ const strict = parseStrictCandidateList(text);
48655
+ if (strict) {
48656
+ return strict;
48657
+ }
48658
+ if (streamed.length > 0) {
48659
+ return streamed;
48660
+ }
48661
+ if (!finishedNormally) {
48662
+ const complete = completeCandidates(text);
48663
+ if (complete.length === 0) {
48664
+ void appendDebugLog("provider", "response truncated", logFields);
48665
+ throw new Error(TRUNCATED_RESPONSE_MESSAGE);
48666
+ }
48667
+ return complete;
48668
+ }
48669
+ return parseCandidates(text);
48670
+ }
48519
48671
  function shouldForceSelector() {
48520
48672
  const configured = process.env.QQ_FORCE_SELECTOR ?? readEnvValueFromDotEnvLocal("QQ_FORCE_SELECTOR");
48521
48673
  return configured === "1" || configured === "true";
@@ -48559,7 +48711,7 @@ function buildPrompt(envelope) {
48559
48711
  )
48560
48712
  ].join("\n");
48561
48713
  }
48562
- async function fetchCandidates(envelope, rbuffer = "", timeoutMs = 25e3) {
48714
+ async function fetchCandidates(envelope, rbuffer = "", timeoutMs = 25e3, options = {}) {
48563
48715
  const apiKey = usableSecret(process.env.ANTHROPIC_API_KEY) ?? usableSecret(readEnvValueFromDotEnvLocal("ANTHROPIC_API_KEY"));
48564
48716
  if (!apiKey) {
48565
48717
  throw new Error("ANTHROPIC_API_KEY is required in the environment or .env.local");
@@ -48567,33 +48719,57 @@ async function fetchCandidates(envelope, rbuffer = "", timeoutMs = 25e3) {
48567
48719
  const client = await getAnthropicClient(apiKey);
48568
48720
  const prompt = buildPrompt(envelope);
48569
48721
  const model = resolveModel();
48722
+ const outputConfig = sdkOutputConfig(model, resolveEffort());
48570
48723
  void appendDebugLog("provider", "request start", {
48571
48724
  model,
48725
+ effort: outputConfig?.effort ?? "none",
48572
48726
  cwd: envelope.base.cwd,
48573
48727
  rbufferLength: rbuffer.length,
48574
48728
  extras: envelope.extras.map((chunk) => chunk.kind)
48575
48729
  });
48730
+ const { onCandidate, signal } = options;
48731
+ const streamed = [];
48576
48732
  try {
48577
- const response = await client.messages.create(
48733
+ const stream = client.messages.stream(
48578
48734
  {
48579
48735
  model,
48580
- max_tokens: 1024,
48736
+ max_tokens: SDK_MAX_TOKENS,
48581
48737
  system: buildSystemPrompt(envelope),
48582
- messages: [{ role: "user", content: prompt }]
48738
+ messages: [{ role: "user", content: prompt }],
48739
+ ...outputConfig ? { output_config: outputConfig } : {}
48583
48740
  },
48584
- {
48585
- timeout: timeoutMs
48586
- }
48741
+ { timeout: timeoutMs, signal: options.signal }
48587
48742
  );
48588
- const text = extractText(response.content);
48589
- const candidates = ensureSelectableCandidates(parseCandidates(text));
48743
+ if (onCandidate) {
48744
+ const scan = createCandidateScanner((candidate) => {
48745
+ streamed.push(candidate);
48746
+ if (!signal?.aborted) {
48747
+ onCandidate(candidate);
48748
+ }
48749
+ });
48750
+ stream.on("text", (textDelta) => {
48751
+ scan(textDelta);
48752
+ });
48753
+ }
48754
+ const message = await stream.finalMessage();
48755
+ const text = extractText(message.content);
48756
+ const finalList = finalCandidateList(text, streamed, isNormalStopReason(message.stop_reason), {
48757
+ model,
48758
+ stopReason: message.stop_reason
48759
+ });
48760
+ const candidates = ensureSelectableCandidates(finalList);
48590
48761
  void appendDebugLog("provider", "response parsed", {
48591
48762
  model,
48592
48763
  candidateCount: candidates.length,
48764
+ streamedCount: streamed.length,
48593
48765
  forceSelector: shouldForceSelector()
48594
48766
  });
48595
48767
  return candidates;
48596
48768
  } catch (error43) {
48769
+ if (isAbortError(error43) || signal?.aborted) {
48770
+ void appendDebugLog("provider", "request aborted", { model });
48771
+ throw abortError();
48772
+ }
48597
48773
  void appendDebugLog("provider", "request failed", {
48598
48774
  model,
48599
48775
  message: error43 instanceof Error ? error43.message : String(error43)
@@ -48602,158 +48778,636 @@ async function fetchCandidates(envelope, rbuffer = "", timeoutMs = 25e3) {
48602
48778
  }
48603
48779
  }
48604
48780
  var claudeAdapter = {
48605
- fetchCandidates
48781
+ fetchCandidates: (envelope, options) => fetchCandidates(envelope, "", 25e3, options)
48606
48782
  };
48607
48783
 
48608
- // src/providers/claude-exec.ts
48784
+ // src/providers/claude-prewarm.ts
48785
+ import { createHash } from "crypto";
48786
+
48787
+ // src/providers/claude-process.ts
48609
48788
  import { spawn } from "child_process";
48610
- async function execFileAsync3(file2, args, options = {}) {
48611
- const encoding = options.encoding ?? "utf8";
48612
- const maxBuffer = options.maxBuffer ?? 1024 * 1024;
48613
- const killSignal = options.killSignal ?? "SIGTERM";
48614
- const stdio = options.stdio ?? ["ignore", "pipe", "pipe"];
48615
- const timeoutMs = options.timeout;
48616
- if (typeof timeoutMs === "number" && timeoutMs <= 0) {
48617
- const error43 = Object.assign(new Error(`Command timed out: ${file2}`), {
48618
- killed: true,
48619
- signal: killSignal,
48620
- code: null,
48621
- stdout: "",
48622
- stderr: ""
48623
- });
48624
- throw error43;
48789
+ import { StringDecoder } from "string_decoder";
48790
+
48791
+ // src/providers/stream-json.ts
48792
+ var STREAM_JSON_CARRY_CAP_BYTES = 1024 * 1024;
48793
+ var streamJsonResultSchema = external_exports.object({
48794
+ type: external_exports.literal("result"),
48795
+ is_error: external_exports.boolean(),
48796
+ result: external_exports.string().optional(),
48797
+ subtype: external_exports.string().optional(),
48798
+ duration_api_ms: external_exports.number().optional(),
48799
+ /**
48800
+ * Claude Code 2.1.285 records it on `result` (Probe 2, `"end_turn"`); older builds and the
48801
+ * Probe 3 auth result leave it out. Null is kept so the runner can fail closed on it.
48802
+ */
48803
+ stop_reason: external_exports.string().nullable().optional()
48804
+ });
48805
+ function isRecord(value) {
48806
+ return value !== null && typeof value === "object";
48807
+ }
48808
+ function createLineParser(onEvent, options = {}) {
48809
+ const maxCarryBytes = options.maxCarryBytes ?? STREAM_JSON_CARRY_CAP_BYTES;
48810
+ let carry = "";
48811
+ let carryBytes = 0;
48812
+ let overflowed = false;
48813
+ return (chunk) => {
48814
+ if (overflowed) {
48815
+ return;
48816
+ }
48817
+ carry += chunk;
48818
+ let nl = carry.indexOf("\n");
48819
+ if (nl === -1) {
48820
+ carryBytes += Buffer.byteLength(chunk, "utf8");
48821
+ } else {
48822
+ while (nl !== -1) {
48823
+ const line = carry.slice(0, nl).trim();
48824
+ carry = carry.slice(nl + 1);
48825
+ nl = carry.indexOf("\n");
48826
+ if (!line) {
48827
+ continue;
48828
+ }
48829
+ let event;
48830
+ try {
48831
+ event = JSON.parse(line);
48832
+ } catch {
48833
+ continue;
48834
+ }
48835
+ onEvent(event);
48836
+ }
48837
+ carryBytes = Buffer.byteLength(carry, "utf8");
48838
+ }
48839
+ if (carryBytes > maxCarryBytes) {
48840
+ overflowed = true;
48841
+ carry = "";
48842
+ carryBytes = 0;
48843
+ options.onOverflow?.();
48844
+ }
48845
+ };
48846
+ }
48847
+ function textDeltaOf(event) {
48848
+ if (!isRecord(event) || event.type !== "stream_event") {
48849
+ return void 0;
48850
+ }
48851
+ const inner = event.event;
48852
+ if (!isRecord(inner) || inner.type !== "content_block_delta") {
48853
+ return void 0;
48854
+ }
48855
+ const delta = inner.delta;
48856
+ if (!isRecord(delta) || delta.type !== "text_delta" || typeof delta.text !== "string") {
48857
+ return void 0;
48858
+ }
48859
+ return delta.text;
48860
+ }
48861
+ function isInitEvent(event) {
48862
+ return isRecord(event) && event.type === "system" && event.subtype === "init";
48863
+ }
48864
+ function buildStreamJsonUserLine(prompt) {
48865
+ return `${JSON.stringify({ type: "user", message: { role: "user", content: prompt } })}
48866
+ `;
48867
+ }
48868
+
48869
+ // src/providers/claude-process.ts
48870
+ var SIGKILL_GRACE_MS = 1500;
48871
+ var POST_RESULT_BACKSTOP_MS = 2e3;
48872
+ var STDERR_CAP_BYTES = 64 * 1024;
48873
+ function turnFailure(message, reason, sawInit, fields) {
48874
+ return Object.assign(new Error(message), { ...fields, reason, sawInit });
48875
+ }
48876
+ function timeoutFailure(stderr, sawInit) {
48877
+ return turnFailure("Command timed out: claude", "timeout", sawInit, {
48878
+ killed: true,
48879
+ signal: "SIGTERM",
48880
+ code: null,
48881
+ stdout: "",
48882
+ stderr
48883
+ });
48884
+ }
48885
+ function isRunning(child) {
48886
+ return child.pid !== void 0 && child.exitCode === null && child.signalCode === null;
48887
+ }
48888
+ function isRecord2(value) {
48889
+ return value !== null && typeof value === "object";
48890
+ }
48891
+ function spawnClaudeChild(command, argv, cwd2, env3) {
48892
+ return spawn(command, [...argv], {
48893
+ cwd: cwd2,
48894
+ env: env3,
48895
+ stdio: ["pipe", "pipe", "pipe"],
48896
+ shell: false,
48897
+ windowsHide: true
48898
+ });
48899
+ }
48900
+ function terminateChild(child, graceMs = SIGKILL_GRACE_MS) {
48901
+ if (child.exitCode !== null || child.signalCode !== null) {
48902
+ return;
48903
+ }
48904
+ child.kill("SIGTERM");
48905
+ const killTimer = setTimeout(() => {
48906
+ if (child.exitCode === null && child.signalCode === null) {
48907
+ child.kill("SIGKILL");
48908
+ }
48909
+ }, graceMs);
48910
+ killTimer.unref();
48911
+ child.once("exit", () => {
48912
+ clearTimeout(killTimer);
48913
+ });
48914
+ }
48915
+ function runClaudeTurn(options) {
48916
+ const { command, argv, cwd: cwd2, env: env3, prompt, budgetMs, signal, onTextDelta, onStage } = options;
48917
+ const backstopMs = options.backstopMs ?? POST_RESULT_BACKSTOP_MS;
48918
+ const killGraceMs = options.killGraceMs ?? SIGKILL_GRACE_MS;
48919
+ const prewarmed = options.child;
48920
+ if (signal?.aborted) {
48921
+ if (prewarmed) {
48922
+ terminateChild(prewarmed, killGraceMs);
48923
+ }
48924
+ return Promise.reject(abortError());
48925
+ }
48926
+ if (budgetMs <= 0) {
48927
+ if (prewarmed) {
48928
+ terminateChild(prewarmed, killGraceMs);
48929
+ }
48930
+ return Promise.reject(timeoutFailure("", false));
48931
+ }
48932
+ if (prewarmed && !isRunning(prewarmed)) {
48933
+ return Promise.reject(
48934
+ turnFailure("Command failed: claude", "exit-without-result", false, {
48935
+ code: prewarmed.exitCode,
48936
+ killed: false,
48937
+ signal: prewarmed.signalCode,
48938
+ stdout: "",
48939
+ stderr: ""
48940
+ })
48941
+ );
48625
48942
  }
48626
48943
  return new Promise((resolve3, reject) => {
48627
48944
  let settled = false;
48628
- const finish = (callback) => {
48945
+ let sawInit = false;
48946
+ let sawDelta = false;
48947
+ let stderr = "";
48948
+ let stderrBytes = 0;
48949
+ let budgetTimer;
48950
+ let initTimer;
48951
+ let backstopArmed = false;
48952
+ const child = prewarmed ?? spawnClaudeChild(command, argv, cwd2, env3);
48953
+ const onAbort = () => {
48954
+ if (settled) {
48955
+ return;
48956
+ }
48957
+ onStage?.("aborted");
48958
+ terminateChild(child, killGraceMs);
48959
+ finish(() => reject(abortError()));
48960
+ };
48961
+ const collectStderr = (chunk) => {
48962
+ if (stderrBytes >= STDERR_CAP_BYTES) {
48963
+ return;
48964
+ }
48965
+ const bytes = Buffer.byteLength(chunk, "utf8");
48966
+ if (stderrBytes + bytes <= STDERR_CAP_BYTES) {
48967
+ stderr += chunk;
48968
+ stderrBytes += bytes;
48969
+ return;
48970
+ }
48971
+ const room = STDERR_CAP_BYTES - stderrBytes;
48972
+ stderr += new StringDecoder("utf8").write(Buffer.from(chunk, "utf8").subarray(0, room));
48973
+ stderrBytes = STDERR_CAP_BYTES;
48974
+ };
48975
+ const armBackstop = () => {
48976
+ if (backstopArmed) {
48977
+ return;
48978
+ }
48979
+ backstopArmed = true;
48980
+ const backstopTimer = setTimeout(() => {
48981
+ terminateChild(child, killGraceMs);
48982
+ }, backstopMs);
48983
+ backstopTimer.unref();
48984
+ child.once("exit", () => {
48985
+ clearTimeout(backstopTimer);
48986
+ });
48987
+ };
48988
+ const onOverflow = () => {
48989
+ if (settled) {
48990
+ return;
48991
+ }
48992
+ terminateChild(child, killGraceMs);
48993
+ finish(
48994
+ () => reject(
48995
+ turnFailure("Command failed: claude", "invalid-result", sawInit, {
48996
+ code: null,
48997
+ killed: false,
48998
+ signal: null,
48999
+ stdout: "",
49000
+ stderr
49001
+ })
49002
+ )
49003
+ );
49004
+ };
49005
+ function finish(callback) {
48629
49006
  if (settled) {
48630
49007
  return;
48631
49008
  }
48632
49009
  settled = true;
49010
+ if (budgetTimer) {
49011
+ clearTimeout(budgetTimer);
49012
+ }
49013
+ if (initTimer) {
49014
+ clearTimeout(initTimer);
49015
+ }
49016
+ signal?.removeEventListener("abort", onAbort);
48633
49017
  callback();
48634
- };
48635
- const child = spawn(file2, [...args], {
48636
- cwd: options.cwd,
48637
- env: options.env,
48638
- stdio,
48639
- windowsHide: options.windowsHide ?? true,
48640
- shell: options.shell ?? false
48641
- });
48642
- const stdoutChunks = [];
48643
- const stderrChunks = [];
48644
- let exceededBuffer = false;
48645
- let timedOut = false;
48646
- let timer;
48647
- function combined(chunks) {
48648
- return Buffer.concat(chunks).toString(encoding);
48649
49018
  }
48650
- function pushChunk(chunks, chunk) {
48651
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
48652
- if (Buffer.concat(chunks).length > maxBuffer) {
48653
- exceededBuffer = true;
48654
- child.kill(killSignal);
49019
+ const handleEvent = (event) => {
49020
+ if (settled) {
49021
+ return;
48655
49022
  }
48656
- }
48657
- if (typeof timeoutMs === "number") {
48658
- timer = setTimeout(() => {
48659
- timedOut = true;
48660
- child.kill(killSignal);
48661
- }, timeoutMs);
48662
- }
48663
- child.stdout?.on("data", (chunk) => {
48664
- pushChunk(stdoutChunks, chunk);
48665
- });
48666
- child.stderr?.on("data", (chunk) => {
48667
- pushChunk(stderrChunks, chunk);
48668
- });
48669
- child.on("error", (error43) => {
48670
- if (timer) {
48671
- clearTimeout(timer);
49023
+ if (isInitEvent(event)) {
49024
+ if (!sawInit) {
49025
+ sawInit = true;
49026
+ if (initTimer) {
49027
+ clearTimeout(initTimer);
49028
+ }
49029
+ onStage?.("init");
49030
+ }
49031
+ return;
48672
49032
  }
48673
- finish(() => {
48674
- reject(error43);
48675
- });
48676
- });
48677
- child.on("close", (code, signal) => {
48678
- if (timer) {
48679
- clearTimeout(timer);
49033
+ const text = textDeltaOf(event);
49034
+ if (text !== void 0) {
49035
+ if (!sawDelta) {
49036
+ sawDelta = true;
49037
+ onStage?.("first-delta");
49038
+ }
49039
+ if (!settled) {
49040
+ onTextDelta?.(text);
49041
+ }
49042
+ return;
48680
49043
  }
48681
- const stdout = combined(stdoutChunks);
48682
- const stderr = combined(stderrChunks);
48683
- if (exceededBuffer || timedOut) {
48684
- const error43 = Object.assign(new Error(`Command timed out: ${file2}`), {
48685
- killed: true,
48686
- signal: signal ?? killSignal,
48687
- code: null,
48688
- stdout,
48689
- stderr
48690
- });
48691
- finish(() => {
48692
- reject(error43);
48693
- });
49044
+ if (!isRecord2(event) || event.type !== "result") {
48694
49045
  return;
48695
49046
  }
48696
- if (code !== 0 && code !== null) {
48697
- const error43 = Object.assign(new Error(`Command failed: ${file2}`), {
48698
- code,
48699
- killed: false,
48700
- signal,
48701
- stdout,
48702
- stderr
48703
- });
48704
- finish(() => {
48705
- reject(error43);
48706
- });
49047
+ armBackstop();
49048
+ const parsed = streamJsonResultSchema.safeParse(event);
49049
+ if (!parsed.success) {
49050
+ finish(
49051
+ () => reject(
49052
+ turnFailure("Command failed: claude", "invalid-result", sawInit, {
49053
+ code: null,
49054
+ killed: false,
49055
+ signal: null,
49056
+ stdout: "",
49057
+ stderr
49058
+ })
49059
+ )
49060
+ );
48707
49061
  return;
48708
49062
  }
48709
- if (signal) {
48710
- const error43 = Object.assign(new Error(`Command killed: ${file2}`), {
48711
- killed: true,
48712
- signal,
48713
- code: null,
48714
- stdout,
48715
- stderr
48716
- });
48717
- finish(() => {
48718
- reject(error43);
48719
- });
49063
+ if (parsed.data.is_error) {
49064
+ finish(
49065
+ () => reject(
49066
+ turnFailure("Command failed: claude", "is-error", sawInit, {
49067
+ code: 1,
49068
+ killed: false,
49069
+ signal: null,
49070
+ stdout: parsed.data.result ?? "",
49071
+ stderr
49072
+ })
49073
+ )
49074
+ );
48720
49075
  return;
48721
49076
  }
48722
- finish(() => {
48723
- resolve3({ stdout, stderr });
48724
- });
49077
+ const stopReason = parsed.data.stop_reason;
49078
+ if (stopReason !== void 0 && !isNormalStopReason(parsed.data.stop_reason)) {
49079
+ finish(
49080
+ () => reject(
49081
+ turnFailure("Command failed: claude", "truncated", sawInit, {
49082
+ code: null,
49083
+ killed: false,
49084
+ signal: null,
49085
+ stdout: parsed.data.result ?? "",
49086
+ stderr,
49087
+ stopReason
49088
+ })
49089
+ )
49090
+ );
49091
+ return;
49092
+ }
49093
+ onStage?.("result");
49094
+ finish(() => resolve3(parsed.data.result ?? ""));
49095
+ };
49096
+ if (!prewarmed && child.pid !== void 0) {
49097
+ onStage?.("spawned", { pid: child.pid });
49098
+ }
49099
+ child.stdout.setEncoding("utf8");
49100
+ child.stdout.on("data", createLineParser(handleEvent, { onOverflow }));
49101
+ child.stderr.setEncoding("utf8");
49102
+ child.stderr.on("data", collectStderr);
49103
+ child.on("error", (error43) => {
49104
+ finish(() => reject(Object.assign(error43, { reason: "spawn-error", sawInit })));
49105
+ });
49106
+ child.on("exit", (code, exitSignal) => {
49107
+ onStage?.("exit", { code, signal: exitSignal });
49108
+ });
49109
+ child.on("close", (code, closeSignal) => {
49110
+ finish(
49111
+ () => reject(
49112
+ turnFailure("Command failed: claude", "exit-without-result", sawInit, {
49113
+ code,
49114
+ killed: false,
49115
+ signal: closeSignal,
49116
+ stdout: "",
49117
+ stderr
49118
+ })
49119
+ )
49120
+ );
49121
+ });
49122
+ budgetTimer = setTimeout(() => {
49123
+ if (settled) {
49124
+ return;
49125
+ }
49126
+ onStage?.("timed-out");
49127
+ terminateChild(child, killGraceMs);
49128
+ finish(() => reject(timeoutFailure(stderr, sawInit)));
49129
+ }, budgetMs);
49130
+ budgetTimer.unref();
49131
+ if (options.initDeadlineMs !== void 0) {
49132
+ const initDeadlineMs = options.initDeadlineMs;
49133
+ initTimer = setTimeout(() => {
49134
+ if (settled || sawInit) {
49135
+ return;
49136
+ }
49137
+ onStage?.("init-timed-out");
49138
+ terminateChild(child, killGraceMs);
49139
+ finish(
49140
+ () => reject(
49141
+ turnFailure("Command failed: claude", "stale-prewarm", false, {
49142
+ code: null,
49143
+ killed: false,
49144
+ signal: null,
49145
+ stdout: "",
49146
+ stderr
49147
+ })
49148
+ )
49149
+ );
49150
+ }, initDeadlineMs);
49151
+ initTimer.unref();
49152
+ }
49153
+ signal?.addEventListener("abort", onAbort, { once: true });
49154
+ child.stdin.on("error", () => {
49155
+ });
49156
+ child.stdin.write(buildStreamJsonUserLine(prompt));
49157
+ child.stdin.end();
49158
+ });
49159
+ }
49160
+
49161
+ // src/providers/claude-prewarm.ts
49162
+ var enabled = false;
49163
+ var slot;
49164
+ var diedIdle = false;
49165
+ function prewarmKey(spec) {
49166
+ return createHash("sha256").update(JSON.stringify({ command: spec.command, cwd: spec.cwd, argv: spec.argv })).digest("hex");
49167
+ }
49168
+ function enablePrewarm() {
49169
+ enabled = true;
49170
+ }
49171
+ function disablePrewarm() {
49172
+ retirePrewarmed();
49173
+ enabled = false;
49174
+ diedIdle = false;
49175
+ }
49176
+ function retireChild(child, graceMs) {
49177
+ if (!isRunning(child)) {
49178
+ return;
49179
+ }
49180
+ child.stdin.end();
49181
+ const killTimer = setTimeout(() => {
49182
+ if (isRunning(child)) {
49183
+ child.kill("SIGKILL");
49184
+ }
49185
+ }, graceMs);
49186
+ killTimer.unref();
49187
+ child.once("exit", () => {
49188
+ clearTimeout(killTimer);
49189
+ });
49190
+ }
49191
+ function retireSlot(graceMs) {
49192
+ const entry = slot;
49193
+ if (!entry) {
49194
+ return;
49195
+ }
49196
+ slot = void 0;
49197
+ entry.state = "retired";
49198
+ void appendDebugLog("provider", "prewarm retired", { pid: entry.child.pid ?? null });
49199
+ retireChild(entry.child, graceMs);
49200
+ }
49201
+ function schedulePrewarm(spec) {
49202
+ if (!enabled) {
49203
+ return;
49204
+ }
49205
+ const key = prewarmKey(spec);
49206
+ if (slot && slot.key === key && isRunning(slot.child)) {
49207
+ return;
49208
+ }
49209
+ retireSlot(SIGKILL_GRACE_MS);
49210
+ diedIdle = false;
49211
+ let child;
49212
+ try {
49213
+ child = spawnClaudeChild(spec.command, spec.argv, spec.cwd, process.env);
49214
+ } catch (error43) {
49215
+ void appendDebugLog("provider", "prewarm spawn failed", {
49216
+ code: error43.code ?? null
48725
49217
  });
49218
+ return;
49219
+ }
49220
+ const entry = { child, cwd: spec.cwd, key, state: "idle", spawnedAt: Date.now() };
49221
+ slot = entry;
49222
+ const clearIfIdle = () => {
49223
+ if (slot === entry) {
49224
+ slot = void 0;
49225
+ diedIdle = true;
49226
+ }
49227
+ };
49228
+ child.on("error", (error43) => {
49229
+ const wasIdle = entry.state === "idle";
49230
+ clearIfIdle();
49231
+ if (wasIdle) {
49232
+ void appendDebugLog("provider", "prewarm error", { code: error43.code ?? null });
49233
+ }
49234
+ });
49235
+ child.stdin.on("error", () => {
49236
+ });
49237
+ child.on("exit", (code, signal) => {
49238
+ clearIfIdle();
49239
+ if (entry.state !== "taken") {
49240
+ void appendDebugLog("provider", "prewarm exit", {
49241
+ pid: child.pid ?? null,
49242
+ code,
49243
+ signal,
49244
+ retired: entry.state === "retired"
49245
+ });
49246
+ }
48726
49247
  });
49248
+ if (child.pid !== void 0) {
49249
+ void appendDebugLog("provider", "prewarm spawned", { pid: child.pid });
49250
+ }
49251
+ }
49252
+ function takePrewarmed(spec) {
49253
+ if (!enabled) {
49254
+ return { miss: "disabled" };
49255
+ }
49256
+ const entry = slot;
49257
+ if (!entry) {
49258
+ const reason = diedIdle ? "dead" : "empty";
49259
+ diedIdle = false;
49260
+ return { miss: reason };
49261
+ }
49262
+ if (!isRunning(entry.child)) {
49263
+ slot = void 0;
49264
+ entry.state = "retired";
49265
+ diedIdle = false;
49266
+ return { miss: "dead" };
49267
+ }
49268
+ if (entry.cwd !== spec.cwd) {
49269
+ retireSlot(SIGKILL_GRACE_MS);
49270
+ return { miss: "cwd" };
49271
+ }
49272
+ if (entry.key !== prewarmKey(spec)) {
49273
+ retireSlot(SIGKILL_GRACE_MS);
49274
+ return { miss: "prompt" };
49275
+ }
49276
+ slot = void 0;
49277
+ entry.state = "taken";
49278
+ return { child: entry.child, spawnedAt: entry.spawnedAt };
49279
+ }
49280
+ function retirePrewarmed(graceMs = SIGKILL_GRACE_MS) {
49281
+ retireSlot(graceMs);
48727
49282
  }
48728
49283
 
48729
49284
  // src/providers/claude-cli.ts
48730
- async function fetchClaudeCliCandidates(envelope, remainingBudgetMs) {
48731
- const prompt = buildPrompt(envelope);
48732
- const args = [
49285
+ var WARM_INIT_DEADLINE_MS = 1500;
49286
+ var PREWARM_BOOT_ALLOWANCE_MS = 3e3;
49287
+ function warmInitDeadlineMs(spawnedAt, now = Date.now()) {
49288
+ const ageMs = Math.max(0, now - spawnedAt);
49289
+ return WARM_INIT_DEADLINE_MS + Math.max(0, PREWARM_BOOT_ALLOWANCE_MS - ageMs);
49290
+ }
49291
+ var CLAUDE_COMMAND = "claude";
49292
+ function buildClaudeCliArgv(envelope) {
49293
+ return [
48733
49294
  "-p",
49295
+ "--input-format",
49296
+ "stream-json",
48734
49297
  "--output-format",
48735
- "text",
49298
+ "stream-json",
49299
+ "--verbose",
49300
+ "--include-partial-messages",
49301
+ "--effort",
49302
+ resolveEffort(),
48736
49303
  "--safe-mode",
48737
49304
  "--tools",
48738
49305
  "",
48739
49306
  "--no-session-persistence",
48740
49307
  "--system-prompt",
48741
- buildSystemPrompt(envelope),
48742
- prompt
49308
+ buildSystemPrompt(envelope)
48743
49309
  ];
48744
- const options = {
48745
- encoding: "utf8",
48746
- timeout: remainingBudgetMs,
48747
- killSignal: "SIGTERM",
48748
- maxBuffer: 1024 * 1024,
48749
- cwd: envelope.base.cwd,
48750
- env: process.env,
48751
- windowsHide: true,
48752
- shell: false,
48753
- stdio: ["ignore", "pipe", "pipe"]
49310
+ }
49311
+ async function fetchClaudeCliCandidates(envelope, remainingBudgetMs, options = {}) {
49312
+ const startedAt = Date.now();
49313
+ const deadline = startedAt + remainingBudgetMs;
49314
+ const streamed = [];
49315
+ const { onCandidate, signal } = options;
49316
+ const spec = {
49317
+ command: CLAUDE_COMMAND,
49318
+ argv: buildClaudeCliArgv(envelope),
49319
+ cwd: envelope.base.cwd
48754
49320
  };
48755
- const { stdout } = await execFileAsync3("claude", args, options);
48756
- return ensureSelectableCandidates(parseCandidates(stdout));
49321
+ const prompt = buildPrompt(envelope);
49322
+ const createTextDeltaHandler = () => onCandidate ? createCandidateScanner((candidate) => {
49323
+ streamed.push(candidate);
49324
+ if (streamed.length === 1) {
49325
+ void appendDebugLog("provider", "cli first candidate", { ms: Date.now() - startedAt });
49326
+ }
49327
+ if (!signal?.aborted) {
49328
+ onCandidate(candidate);
49329
+ }
49330
+ }) : void 0;
49331
+ const runTurn = (child, budgetMs, initDeadlineMs) => runClaudeTurn({
49332
+ command: spec.command,
49333
+ argv: spec.argv,
49334
+ cwd: spec.cwd,
49335
+ env: process.env,
49336
+ prompt,
49337
+ budgetMs,
49338
+ signal,
49339
+ onTextDelta: createTextDeltaHandler(),
49340
+ onStage: (stage, detail) => {
49341
+ logTurnStage(stage, detail, Date.now() - startedAt, child !== void 0);
49342
+ },
49343
+ ...child ? { child } : {},
49344
+ ...initDeadlineMs === void 0 ? {} : { initDeadlineMs }
49345
+ });
49346
+ try {
49347
+ let text;
49348
+ let finishedNormally = true;
49349
+ let stopReason;
49350
+ try {
49351
+ const take = takePrewarmed(spec);
49352
+ if ("child" in take) {
49353
+ void appendDebugLog("provider", "prewarm hit");
49354
+ try {
49355
+ text = await runTurn(take.child, remainingBudgetMs, warmInitDeadlineMs(take.spawnedAt));
49356
+ } catch (error43) {
49357
+ const leftMs = deadline - Date.now();
49358
+ if (!isStalePrewarmFailure(error43) || streamed.length > 0 || signal?.aborted || leftMs <= 0) {
49359
+ throw error43;
49360
+ }
49361
+ void appendDebugLog("provider", "prewarm retry cold", { ms: Date.now() - startedAt });
49362
+ text = await runTurn(void 0, leftMs);
49363
+ }
49364
+ } else {
49365
+ void appendDebugLog("provider", "prewarm miss", { reason: take.miss });
49366
+ text = await runTurn(void 0, remainingBudgetMs);
49367
+ }
49368
+ } catch (error43) {
49369
+ if (!isTruncatedFailure(error43)) {
49370
+ throw error43;
49371
+ }
49372
+ const stdout = error43.stdout;
49373
+ text = typeof stdout === "string" ? stdout : "";
49374
+ finishedNormally = false;
49375
+ stopReason = error43.stopReason;
49376
+ }
49377
+ return ensureSelectableCandidates(
49378
+ finalCandidateList(text, streamed, finishedNormally, { stopReason })
49379
+ );
49380
+ } finally {
49381
+ schedulePrewarm(spec);
49382
+ }
49383
+ }
49384
+ function isStalePrewarmFailure(error43) {
49385
+ if (error43 === null || typeof error43 !== "object") {
49386
+ return false;
49387
+ }
49388
+ const reason = error43.reason;
49389
+ return reason === "exit-without-result" || reason === "stale-prewarm";
49390
+ }
49391
+ function isTruncatedFailure(error43) {
49392
+ if (error43 === null || typeof error43 !== "object") {
49393
+ return false;
49394
+ }
49395
+ const reason = error43.reason;
49396
+ return reason === "truncated";
49397
+ }
49398
+ var STAGE_LOG_NAMES = {
49399
+ spawned: "cli spawned",
49400
+ init: "cli init",
49401
+ "first-delta": "cli first delta",
49402
+ result: "cli result",
49403
+ exit: "cli exit",
49404
+ aborted: "cli aborted",
49405
+ "timed-out": "cli timed out",
49406
+ "init-timed-out": "cli init timed out"
49407
+ };
49408
+ function logTurnStage(stage, detail, ms, warm) {
49409
+ const fields = stage === "exit" ? { ms, warm, code: detail?.code ?? null, signal: detail?.signal ?? null } : { ms, warm };
49410
+ void appendDebugLog("provider", STAGE_LOG_NAMES[stage], fields);
48757
49411
  }
48758
49412
 
48759
49413
  // src/providers/claude-default.ts
@@ -48796,6 +49450,9 @@ function lookupApiKey() {
48796
49450
  return usableSecret(process.env.ANTHROPIC_API_KEY) ?? usableSecret(readEnvValueFromDotEnvLocal("ANTHROPIC_API_KEY"));
48797
49451
  }
48798
49452
  function hardError(error43) {
49453
+ if (error43 instanceof Error && error43.message === TRUNCATED_RESPONSE_MESSAGE) {
49454
+ return error43;
49455
+ }
48799
49456
  if (isEnoent(error43)) {
48800
49457
  return new Error(ENOENT_MESSAGE);
48801
49458
  }
@@ -48808,18 +49465,22 @@ function hardError(error43) {
48808
49465
  return new Error(D13_MESSAGE);
48809
49466
  }
48810
49467
  var claudeDefaultAdapter = {
48811
- async fetchCandidates(envelope) {
49468
+ async fetchCandidates(envelope, options) {
48812
49469
  const deadline = Date.now() + TOTAL_BUDGET_MS;
48813
49470
  const apiKey = lookupApiKey();
48814
49471
  if (apiKey) {
48815
49472
  void appendDebugLog("provider", "sdk path", {
48816
49473
  path: "sdk"
48817
49474
  });
48818
- return fetchCandidates(envelope, "", remainingMs(deadline));
49475
+ return fetchCandidates(envelope, "", remainingMs(deadline), options);
48819
49476
  }
48820
49477
  try {
48821
- return await fetchClaudeCliCandidates(envelope, remainingMs(deadline));
49478
+ return await fetchClaudeCliCandidates(envelope, remainingMs(deadline), options);
48822
49479
  } catch (error43) {
49480
+ if (isAbortError(error43)) {
49481
+ void appendDebugLog("provider", "claude-cli aborted");
49482
+ throw error43;
49483
+ }
48823
49484
  void appendDebugLog("provider", "claude-cli path", {
48824
49485
  path: "claude-cli",
48825
49486
  exitCode: exitCodeDetail(error43),
@@ -48916,11 +49577,11 @@ import * as fsp3 from "fs/promises";
48916
49577
  import * as path4 from "path";
48917
49578
  import * as tty3 from "tty";
48918
49579
 
48919
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/render.js
49580
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/render.js
48920
49581
  import { Stream as Stream2 } from "stream";
48921
49582
  import process13 from "process";
48922
49583
 
48923
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/ink.js
49584
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/ink.js
48924
49585
  var import_react16 = __toESM(require_react(), 1);
48925
49586
  import process12 from "process";
48926
49587
 
@@ -49281,7 +49942,7 @@ function autoBind(self, { include, exclude } = {}) {
49281
49942
  return self;
49282
49943
  }
49283
49944
 
49284
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/ink.js
49945
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/ink.js
49285
49946
  var import_signal_exit2 = __toESM(require_signal_exit(), 1);
49286
49947
 
49287
49948
  // node_modules/.pnpm/patch-console@2.0.0/node_modules/patch-console/dist/index.js
@@ -49330,7 +49991,7 @@ var patchConsole = (callback) => {
49330
49991
  };
49331
49992
  var dist_default = patchConsole;
49332
49993
 
49333
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/ink.js
49994
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/ink.js
49334
49995
  var import_constants4 = __toESM(require_constants(), 1);
49335
49996
 
49336
49997
  // node_modules/.pnpm/yoga-layout@3.2.1/node_modules/yoga-layout/dist/binaries/yoga-wasm-base64-esm.js
@@ -51745,7 +52406,7 @@ var resize = () => {
51745
52406
  }
51746
52407
  };
51747
52408
 
51748
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/utils.js
52409
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/utils.js
51749
52410
  var getWindowSize = (stdout) => {
51750
52411
  const { columns, rows } = stdout;
51751
52412
  if (columns && rows) {
@@ -51758,7 +52419,7 @@ var getWindowSize = (stdout) => {
51758
52419
  };
51759
52420
  };
51760
52421
 
51761
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/reconciler.js
52422
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/reconciler.js
51762
52423
  var import_react_reconciler = __toESM(require_react_reconciler(), 1);
51763
52424
  var import_constants3 = __toESM(require_constants(), 1);
51764
52425
  var Scheduler = __toESM(require_scheduler(), 1);
@@ -51774,7 +52435,7 @@ function widestLine(string4) {
51774
52435
  return lineWidth;
51775
52436
  }
51776
52437
 
51777
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/measure-text.js
52438
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/measure-text.js
51778
52439
  var cache = /* @__PURE__ */ new Map();
51779
52440
  var measureText = (text) => {
51780
52441
  if (text.length === 0) {
@@ -52765,7 +53426,7 @@ function cliTruncate(text, columns, options = {}) {
52765
53426
  throw new Error(`Expected \`options.position\` to be either \`start\`, \`middle\` or \`end\`, got ${position}`);
52766
53427
  }
52767
53428
 
52768
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/wrap-text.js
53429
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/wrap-text.js
52769
53430
  var cache2 = {};
52770
53431
  var wrapText = (text, maxWidth, wrapType) => {
52771
53432
  const cacheKey = text + String(maxWidth) + String(wrapType);
@@ -52802,7 +53463,7 @@ var wrapText = (text, maxWidth, wrapType) => {
52802
53463
  };
52803
53464
  var wrap_text_default = wrapText;
52804
53465
 
52805
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/ansi-tokenizer.js
53466
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/ansi-tokenizer.js
52806
53467
  var bellCharacter = "\x07";
52807
53468
  var escapeCharacter = "\x1B";
52808
53469
  var stringTerminatorCharacter = "\x9C";
@@ -53109,7 +53770,7 @@ var tokenizeAnsi2 = (text) => {
53109
53770
  return tokens;
53110
53771
  };
53111
53772
 
53112
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/sanitize-ansi.js
53773
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/sanitize-ansi.js
53113
53774
  var sgrParametersRegex = /^[\d:;]*$/;
53114
53775
  var sanitizeAnsi = (text) => {
53115
53776
  if (!hasAnsiControlCharacters(text)) {
@@ -53129,7 +53790,7 @@ var sanitizeAnsi = (text) => {
53129
53790
  };
53130
53791
  var sanitize_ansi_default = sanitizeAnsi;
53131
53792
 
53132
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/squash-text-nodes.js
53793
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/squash-text-nodes.js
53133
53794
  var squashTextNodes = (node) => {
53134
53795
  let text = "";
53135
53796
  for (let index = 0; index < node.childNodes.length; index++) {
@@ -53154,7 +53815,7 @@ var squashTextNodes = (node) => {
53154
53815
  };
53155
53816
  var squash_text_nodes_default = squashTextNodes;
53156
53817
 
53157
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/dom.js
53818
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/dom.js
53158
53819
  var createNode = (nodeName) => {
53159
53820
  const node = {
53160
53821
  nodeName,
@@ -53278,7 +53939,7 @@ var emitLayoutListeners = (rootNode) => {
53278
53939
  }
53279
53940
  };
53280
53941
 
53281
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/styles.js
53942
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/styles.js
53282
53943
  var positionEdges = [
53283
53944
  ["top", src_default.EDGE_TOP],
53284
53945
  ["right", src_default.EDGE_RIGHT],
@@ -53565,7 +54226,7 @@ var styles2 = (node, style = {}, currentStyle = style) => {
53565
54226
  };
53566
54227
  var styles_default = styles2;
53567
54228
 
53568
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/reconciler.js
54229
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/reconciler.js
53569
54230
  if (process4.env["DEV"] === "true") {
53570
54231
  let isDevtoolsInstalled = false;
53571
54232
  try {
@@ -53647,6 +54308,12 @@ var reconciler_default = (0, import_react_reconciler.default)({
53647
54308
  rootNode.onComputeLayout();
53648
54309
  }
53649
54310
  emitLayoutListeners(rootNode);
54311
+ if (rootNode.staticNode !== rootNode.previousStaticNode) {
54312
+ rootNode.previousStaticNode = rootNode.staticNode;
54313
+ if (typeof rootNode.onStaticChange === "function") {
54314
+ rootNode.onStaticChange();
54315
+ }
54316
+ }
53650
54317
  if (rootNode.isStaticDirty) {
53651
54318
  rootNode.isStaticDirty = false;
53652
54319
  if (typeof rootNode.onImmediateRender === "function") {
@@ -53756,7 +54423,7 @@ var reconciler_default = (0, import_react_reconciler.default)({
53756
54423
  removeChildFromContainer(node, removeNode) {
53757
54424
  removeChildNode(node, removeNode);
53758
54425
  cleanupYogaNode(removeNode.yogaNode);
53759
- if (removeNode.internal_static && currentRootNode) {
54426
+ if (removeNode.internal_static && currentRootNode?.staticNode === removeNode) {
53760
54427
  currentRootNode.staticNode = void 0;
53761
54428
  }
53762
54429
  },
@@ -53796,7 +54463,7 @@ var reconciler_default = (0, import_react_reconciler.default)({
53796
54463
  removeChild(node, removeNode) {
53797
54464
  removeChildNode(node, removeNode);
53798
54465
  cleanupYogaNode(removeNode.yogaNode);
53799
- if (removeNode.internal_static && currentRootNode) {
54466
+ if (removeNode.internal_static && currentRootNode?.staticNode === removeNode) {
53800
54467
  currentRootNode.staticNode = void 0;
53801
54468
  }
53802
54469
  },
@@ -53879,7 +54546,7 @@ function indentString(string4, count = 1, options = {}) {
53879
54546
  return string4.replace(regex2, indent.repeat(count));
53880
54547
  }
53881
54548
 
53882
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/get-max-width.js
54549
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/get-max-width.js
53883
54550
  var getMaxWidth = (yogaNode) => {
53884
54551
  return yogaNode.getComputedWidth() - yogaNode.getComputedPadding(src_default.EDGE_LEFT) - yogaNode.getComputedPadding(src_default.EDGE_RIGHT) - yogaNode.getComputedBorder(src_default.EDGE_LEFT) - yogaNode.getComputedBorder(src_default.EDGE_RIGHT);
53885
54552
  };
@@ -54467,7 +55134,7 @@ var chalk = createChalk();
54467
55134
  var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
54468
55135
  var source_default = chalk;
54469
55136
 
54470
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/colorize.js
55137
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/colorize.js
54471
55138
  var rgbRegex = /^rgb\(\s?(\d+),\s?(\d+),\s?(\d+)\s?\)$/;
54472
55139
  var ansiRegex2 = /^ansi256\(\s?(\d+)\s?\)$/;
54473
55140
  var isNamedColor = (color) => {
@@ -54509,7 +55176,7 @@ var colorize = (str, color, type) => {
54509
55176
  };
54510
55177
  var colorize_default = colorize;
54511
55178
 
54512
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/render-border.js
55179
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/render-border.js
54513
55180
  var stylePiece = (segment, fg, bg, dim) => {
54514
55181
  let styled = colorize_default(segment, fg, "foreground");
54515
55182
  styled = colorize_default(styled, bg, "background");
@@ -54580,7 +55247,7 @@ var renderBorder = (x, y, node, output) => {
54580
55247
  };
54581
55248
  var render_border_default = renderBorder;
54582
55249
 
54583
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/render-background.js
55250
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/render-background.js
54584
55251
  var renderBackground = (x, y, node, output) => {
54585
55252
  if (!node.style.backgroundColor) {
54586
55253
  return;
@@ -54603,7 +55270,7 @@ var renderBackground = (x, y, node, output) => {
54603
55270
  };
54604
55271
  var render_background_default = renderBackground;
54605
55272
 
54606
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/render-node-to-output.js
55273
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/render-node-to-output.js
54607
55274
  var applyPaddingToText = (node, text) => {
54608
55275
  const yogaNode = node.childNodes[0]?.yogaNode;
54609
55276
  if (yogaNode) {
@@ -55009,7 +55676,7 @@ function tokenize2(str, endChar = Number.POSITIVE_INFINITY) {
55009
55676
  return ret;
55010
55677
  }
55011
55678
 
55012
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/output.js
55679
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/output.js
55013
55680
  var OutputCaches = class {
55014
55681
  widths = /* @__PURE__ */ new Map();
55015
55682
  blockWidths = /* @__PURE__ */ new Map();
@@ -55197,7 +55864,7 @@ var Output = class {
55197
55864
  }
55198
55865
  };
55199
55866
 
55200
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/renderer.js
55867
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/renderer.js
55201
55868
  var renderer = (node, isScreenReaderEnabled) => {
55202
55869
  if (node.yogaNode) {
55203
55870
  if (isScreenReaderEnabled) {
@@ -55253,7 +55920,7 @@ var renderer = (node, isScreenReaderEnabled) => {
55253
55920
  };
55254
55921
  var renderer_default = renderer;
55255
55922
 
55256
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/cursor-helpers.js
55923
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/cursor-helpers.js
55257
55924
  var showCursorEscape = "\x1B[?25h";
55258
55925
  var hideCursorEscape = "\x1B[?25l";
55259
55926
  var cursorPositionChanged = (a, b) => a?.x !== b?.x || a?.y !== b?.y;
@@ -55328,7 +55995,7 @@ cliCursor.toggle = (force, writableStream) => {
55328
55995
  };
55329
55996
  var cli_cursor_default = cliCursor;
55330
55997
 
55331
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/log-update.js
55998
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/log-update.js
55332
55999
  var visibleLineCount = (lines, str) => str.endsWith("\n") ? lines.length - 1 : lines.length;
55333
56000
  var createStandard = (stream, { showCursor = false } = {}) => {
55334
56001
  let previousLineCount = 0;
@@ -55558,23 +56225,23 @@ var create2 = (stream, { showCursor = false, incremental = false } = {}) => {
55558
56225
  var logUpdate = { create: create2 };
55559
56226
  var log_update_default = logUpdate;
55560
56227
 
55561
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/write-synchronized.js
56228
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/write-synchronized.js
55562
56229
  var bsu = "\x1B[?2026h";
55563
56230
  var esu = "\x1B[?2026l";
55564
56231
  function shouldSynchronize(stream, interactive) {
55565
56232
  return "isTTY" in stream && stream.isTTY && (interactive ?? !is_in_ci_default);
55566
56233
  }
55567
56234
 
55568
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/instances.js
56235
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/instances.js
55569
56236
  var instances = /* @__PURE__ */ new WeakMap();
55570
56237
  var instances_default = instances;
55571
56238
 
55572
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/App.js
56239
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/App.js
55573
56240
  var import_react15 = __toESM(require_react(), 1);
55574
56241
  import { EventEmitter as EventEmitter2 } from "events";
55575
56242
  import process11 from "process";
55576
56243
 
55577
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/input-parser.js
56244
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/input-parser.js
55578
56245
  var escape = "\x1B";
55579
56246
  var pasteStart = "\x1B[200~";
55580
56247
  var pasteEnd = "\x1B[201~";
@@ -55759,19 +56426,32 @@ var createInputParser = () => {
55759
56426
  };
55760
56427
  };
55761
56428
 
55762
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/AppContext.js
56429
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/AppContext.js
55763
56430
  var import_react2 = __toESM(require_react(), 1);
56431
+ var noopSuspension = {
56432
+ async resume() {
56433
+ },
56434
+ async [Symbol.asyncDispose]() {
56435
+ }
56436
+ };
55764
56437
  var defaultValue = {
55765
56438
  exit(_errorOrResult) {
55766
56439
  },
55767
56440
  async waitUntilRenderFlush() {
55768
- }
56441
+ },
56442
+ suspendTerminal: (async (callback) => {
56443
+ if (callback) {
56444
+ await callback();
56445
+ return void 0;
56446
+ }
56447
+ return noopSuspension;
56448
+ })
55769
56449
  };
55770
56450
  var AppContext = (0, import_react2.createContext)(defaultValue);
55771
56451
  AppContext.displayName = "InternalAppContext";
55772
56452
  var AppContext_default = AppContext;
55773
56453
 
55774
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/StdinContext.js
56454
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/StdinContext.js
55775
56455
  var import_react3 = __toESM(require_react(), 1);
55776
56456
  import { EventEmitter } from "events";
55777
56457
  import process8 from "process";
@@ -55790,7 +56470,7 @@ var StdinContext = (0, import_react3.createContext)({
55790
56470
  StdinContext.displayName = "InternalStdinContext";
55791
56471
  var StdinContext_default = StdinContext;
55792
56472
 
55793
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/StdoutContext.js
56473
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/StdoutContext.js
55794
56474
  var import_react4 = __toESM(require_react(), 1);
55795
56475
  import process9 from "process";
55796
56476
  var StdoutContext = (0, import_react4.createContext)({
@@ -55801,7 +56481,7 @@ var StdoutContext = (0, import_react4.createContext)({
55801
56481
  StdoutContext.displayName = "InternalStdoutContext";
55802
56482
  var StdoutContext_default = StdoutContext;
55803
56483
 
55804
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/StderrContext.js
56484
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/StderrContext.js
55805
56485
  var import_react5 = __toESM(require_react(), 1);
55806
56486
  import process10 from "process";
55807
56487
  var StderrContext = (0, import_react5.createContext)({
@@ -55812,7 +56492,7 @@ var StderrContext = (0, import_react5.createContext)({
55812
56492
  StderrContext.displayName = "InternalStderrContext";
55813
56493
  var StderrContext_default = StderrContext;
55814
56494
 
55815
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/FocusContext.js
56495
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/FocusContext.js
55816
56496
  var import_react6 = __toESM(require_react(), 1);
55817
56497
  var FocusContext = (0, import_react6.createContext)({
55818
56498
  activeId: void 0,
@@ -55838,7 +56518,7 @@ var FocusContext = (0, import_react6.createContext)({
55838
56518
  FocusContext.displayName = "InternalFocusContext";
55839
56519
  var FocusContext_default = FocusContext;
55840
56520
 
55841
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/AnimationContext.js
56521
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/AnimationContext.js
55842
56522
  var import_react7 = __toESM(require_react(), 1);
55843
56523
  var animationContext = (0, import_react7.createContext)({
55844
56524
  renderThrottleMs: 0,
@@ -55853,7 +56533,7 @@ var animationContext = (0, import_react7.createContext)({
55853
56533
  animationContext.displayName = "InternalAnimationContext";
55854
56534
  var AnimationContext_default = animationContext;
55855
56535
 
55856
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/CursorContext.js
56536
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/CursorContext.js
55857
56537
  var import_react8 = __toESM(require_react(), 1);
55858
56538
  var CursorContext = (0, import_react8.createContext)({
55859
56539
  setCursorPosition() {
@@ -55862,10 +56542,10 @@ var CursorContext = (0, import_react8.createContext)({
55862
56542
  CursorContext.displayName = "InternalCursorContext";
55863
56543
  var CursorContext_default = CursorContext;
55864
56544
 
55865
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/ErrorBoundary.js
56545
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/ErrorBoundary.js
55866
56546
  var import_react14 = __toESM(require_react(), 1);
55867
56547
 
55868
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/ErrorOverview.js
56548
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/ErrorOverview.js
55869
56549
  var import_react13 = __toESM(require_react(), 1);
55870
56550
  var import_stack_utils = __toESM(require_stack_utils(), 1);
55871
56551
  import * as fs2 from "fs";
@@ -55903,20 +56583,20 @@ var codeExcerpt = (source, line, options = {}) => {
55903
56583
  };
55904
56584
  var dist_default3 = codeExcerpt;
55905
56585
 
55906
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/Box.js
56586
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/Box.js
55907
56587
  var import_react11 = __toESM(require_react(), 1);
55908
56588
 
55909
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/AccessibilityContext.js
56589
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/AccessibilityContext.js
55910
56590
  var import_react9 = __toESM(require_react(), 1);
55911
56591
  var accessibilityContext = (0, import_react9.createContext)({
55912
56592
  isScreenReaderEnabled: false
55913
56593
  });
55914
56594
 
55915
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/BackgroundContext.js
56595
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/BackgroundContext.js
55916
56596
  var import_react10 = __toESM(require_react(), 1);
55917
56597
  var backgroundContext = (0, import_react10.createContext)(void 0);
55918
56598
 
55919
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/Box.js
56599
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/Box.js
55920
56600
  var Box = (0, import_react11.forwardRef)(({ children, backgroundColor, "aria-label": ariaLabel, "aria-hidden": ariaHidden, "aria-role": role, "aria-state": ariaState, ...style }, ref) => {
55921
56601
  const { isScreenReaderEnabled } = (0, import_react11.useContext)(accessibilityContext);
55922
56602
  const label = ariaLabel ? import_react11.default.createElement("ink-text", null, ariaLabel) : void 0;
@@ -55944,7 +56624,7 @@ var Box = (0, import_react11.forwardRef)(({ children, backgroundColor, "aria-lab
55944
56624
  Box.displayName = "Box";
55945
56625
  var Box_default = Box;
55946
56626
 
55947
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/Text.js
56627
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/Text.js
55948
56628
  var import_react12 = __toESM(require_react(), 1);
55949
56629
  function Text({ color, backgroundColor, dimColor = false, bold = false, italic = false, underline = false, strikethrough = false, inverse = false, wrap = "wrap", children, "aria-label": ariaLabel, "aria-hidden": ariaHidden = false }) {
55950
56630
  const { isScreenReaderEnabled } = (0, import_react12.useContext)(accessibilityContext);
@@ -55987,7 +56667,7 @@ function Text({ color, backgroundColor, dimColor = false, bold = false, italic =
55987
56667
  return import_react12.default.createElement("ink-text", { style: { flexGrow: 0, flexShrink: 1, flexDirection: "row", textWrap: wrap }, internal_transform: transform2 }, childrenOrAriaLabel);
55988
56668
  }
55989
56669
 
55990
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/ErrorOverview.js
56670
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/ErrorOverview.js
55991
56671
  var cleanupPath = (path5) => {
55992
56672
  return path5?.replace(`file://${cwd()}/`, "");
55993
56673
  };
@@ -56001,6 +56681,7 @@ function ErrorOverview({ error: error43 }) {
56001
56681
  const filePath = cleanupPath(origin?.file);
56002
56682
  let excerpt;
56003
56683
  let lineWidth = 0;
56684
+ const stackLineCounts = /* @__PURE__ */ new Map();
56004
56685
  if (filePath && origin?.line && fs2.existsSync(filePath)) {
56005
56686
  const sourceCode = fs2.readFileSync(filePath, "utf8");
56006
56687
  excerpt = dist_default3(sourceCode, origin.line);
@@ -56060,10 +56741,13 @@ function ErrorOverview({ error: error43 }) {
56060
56741
  ))) : null,
56061
56742
  error43.stack ? import_react13.default.createElement(Box_default, { marginTop: 1, flexDirection: "column" }, error43.stack.split("\n").slice(1).map((line) => {
56062
56743
  const parsedLine = stackUtils.parseLine(line);
56063
- if (!parsedLine) {
56744
+ const lineCount = stackLineCounts.get(line) ?? 0;
56745
+ stackLineCounts.set(line, lineCount + 1);
56746
+ const key = `${line}-${lineCount}`;
56747
+ if (!parsedLine?.file || !parsedLine.line || !parsedLine.column) {
56064
56748
  return import_react13.default.createElement(
56065
56749
  Box_default,
56066
- { key: line },
56750
+ { key },
56067
56751
  import_react13.default.createElement(Text, { dimColor: true }, "- "),
56068
56752
  import_react13.default.createElement(
56069
56753
  Text,
@@ -56076,7 +56760,7 @@ function ErrorOverview({ error: error43 }) {
56076
56760
  }
56077
56761
  return import_react13.default.createElement(
56078
56762
  Box_default,
56079
- { key: line },
56763
+ { key },
56080
56764
  import_react13.default.createElement(Text, { dimColor: true }, "- "),
56081
56765
  import_react13.default.createElement(Text, { dimColor: true, bold: true }, parsedLine.function),
56082
56766
  import_react13.default.createElement(
@@ -56096,7 +56780,7 @@ function ErrorOverview({ error: error43 }) {
56096
56780
  );
56097
56781
  }
56098
56782
 
56099
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/ErrorBoundary.js
56783
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/ErrorBoundary.js
56100
56784
  var ErrorBoundary = class extends import_react14.PureComponent {
56101
56785
  static displayName = "InternalErrorBoundary";
56102
56786
  static getDerivedStateFromError(error43) {
@@ -56116,11 +56800,11 @@ var ErrorBoundary = class extends import_react14.PureComponent {
56116
56800
  }
56117
56801
  };
56118
56802
 
56119
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/App.js
56803
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/App.js
56120
56804
  var tab = " ";
56121
56805
  var shiftTab = "\x1B[Z";
56122
56806
  var escape2 = "\x1B";
56123
- function App({ children, stdin, stdout, stderr, writeToStdout, writeToStderr, exitOnCtrlC, onExit, onWaitUntilRenderFlush, setCursorPosition, interactive, renderThrottleMs }) {
56807
+ function App({ children, stdin, stdout, stderr, writeToStdout, writeToStderr, exitOnCtrlC, onExit, onWaitUntilRenderFlush, onSuspendTerminal, onRegisterInputControl, setCursorPosition, interactive, renderThrottleMs }) {
56124
56808
  const [isFocusEnabled, setIsFocusEnabled] = (0, import_react15.useState)(true);
56125
56809
  const [activeFocusId, setActiveFocusId] = (0, import_react15.useState)(void 0);
56126
56810
  const [, setFocusables] = (0, import_react15.useState)([]);
@@ -56128,6 +56812,7 @@ function App({ children, stdin, stdout, stderr, writeToStdout, writeToStderr, ex
56128
56812
  const animationSubscribersRef = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
56129
56813
  const animationTimerRef = (0, import_react15.useRef)(void 0);
56130
56814
  const rawModeEnabledCount = (0, import_react15.useRef)(0);
56815
+ const pendingDisableRawModeRef = (0, import_react15.useRef)(false);
56131
56816
  const bracketedPasteModeEnabledCount = (0, import_react15.useRef)(0);
56132
56817
  const internal_eventEmitter = (0, import_react15.useRef)(new EventEmitter2());
56133
56818
  internal_eventEmitter.current.setMaxListeners(Infinity);
@@ -56208,16 +56893,20 @@ function App({ children, stdin, stdout, stderr, writeToStdout, writeToStderr, ex
56208
56893
  stdin.removeListener("readable", readableListenerRef.current);
56209
56894
  readableListenerRef.current = void 0;
56210
56895
  }, [stdin]);
56896
+ const clearInputState = (0, import_react15.useCallback)(() => {
56897
+ inputParserRef.current.reset();
56898
+ clearPendingInputFlush();
56899
+ detachReadableListener();
56900
+ }, [clearPendingInputFlush, detachReadableListener]);
56211
56901
  const disableRawMode = (0, import_react15.useCallback)(() => {
56902
+ pendingDisableRawModeRef.current = false;
56212
56903
  stdin.setRawMode(false);
56213
- detachReadableListener();
56214
56904
  stdin.unref();
56215
56905
  rawModeEnabledCount.current = 0;
56216
- inputParserRef.current.reset();
56217
- clearPendingInputFlush();
56218
- }, [stdin, detachReadableListener, clearPendingInputFlush]);
56906
+ clearInputState();
56907
+ }, [stdin, clearInputState]);
56219
56908
  const handleExit = (0, import_react15.useCallback)((errorOrResult) => {
56220
- if (isRawModeSupported && rawModeEnabledCount.current > 0) {
56909
+ if (isRawModeSupported && (rawModeEnabledCount.current > 0 || pendingDisableRawModeRef.current)) {
56221
56910
  disableRawMode();
56222
56911
  }
56223
56912
  onExit(errorOrResult);
@@ -56267,6 +56956,13 @@ function App({ children, stdin, stdout, stderr, writeToStdout, writeToStderr, ex
56267
56956
  schedulePendingInputFlush();
56268
56957
  }
56269
56958
  }, [stdin, emitInput, clearPendingInputFlush, schedulePendingInputFlush]);
56959
+ const attachReadableListener = (0, import_react15.useCallback)(() => {
56960
+ if (readableListenerRef.current) {
56961
+ return;
56962
+ }
56963
+ readableListenerRef.current = handleReadable;
56964
+ stdin.addListener("readable", handleReadable);
56965
+ }, [stdin, handleReadable]);
56270
56966
  const handleSetRawMode = (0, import_react15.useCallback)((isEnabled) => {
56271
56967
  if (!isRawModeSupported) {
56272
56968
  if (stdin === process11.stdin) {
@@ -56278,10 +56974,13 @@ function App({ children, stdin, stdout, stderr, writeToStdout, writeToStderr, ex
56278
56974
  stdin.setEncoding("utf8");
56279
56975
  if (isEnabled) {
56280
56976
  if (rawModeEnabledCount.current === 0) {
56281
- stdin.ref();
56282
- stdin.setRawMode(true);
56283
- readableListenerRef.current = handleReadable;
56284
- stdin.addListener("readable", handleReadable);
56977
+ const isRawModeAlreadyEnabled = pendingDisableRawModeRef.current;
56978
+ pendingDisableRawModeRef.current = false;
56979
+ if (!isRawModeAlreadyEnabled) {
56980
+ stdin.ref();
56981
+ stdin.setRawMode(true);
56982
+ }
56983
+ attachReadableListener();
56285
56984
  }
56286
56985
  rawModeEnabledCount.current++;
56287
56986
  return;
@@ -56290,9 +56989,22 @@ function App({ children, stdin, stdout, stderr, writeToStdout, writeToStderr, ex
56290
56989
  return;
56291
56990
  }
56292
56991
  if (--rawModeEnabledCount.current === 0) {
56293
- disableRawMode();
56992
+ clearInputState();
56993
+ pendingDisableRawModeRef.current = true;
56994
+ queueMicrotask(() => {
56995
+ if (!pendingDisableRawModeRef.current) {
56996
+ return;
56997
+ }
56998
+ disableRawMode();
56999
+ });
56294
57000
  }
56295
- }, [isRawModeSupported, stdin, handleReadable, disableRawMode]);
57001
+ }, [
57002
+ isRawModeSupported,
57003
+ stdin,
57004
+ attachReadableListener,
57005
+ clearInputState,
57006
+ disableRawMode
57007
+ ]);
56296
57008
  const handleSetBracketedPasteMode = (0, import_react15.useCallback)((isEnabled) => {
56297
57009
  if (!stdout.isTTY) {
56298
57010
  return;
@@ -56311,6 +57023,47 @@ function App({ children, stdin, stdout, stderr, writeToStdout, writeToStderr, ex
56311
57023
  stdout.write("\x1B[?2004l");
56312
57024
  }
56313
57025
  }, [stdout]);
57026
+ const suspendedInputStateRef = (0, import_react15.useRef)({
57027
+ rawMode: false,
57028
+ bracketedPaste: false
57029
+ });
57030
+ const pauseInput = (0, import_react15.useCallback)(() => {
57031
+ const wasRawMode = isRawModeSupported && rawModeEnabledCount.current > 0;
57032
+ const wasBracketedPaste = bracketedPasteModeEnabledCount.current > 0;
57033
+ suspendedInputStateRef.current = {
57034
+ rawMode: wasRawMode,
57035
+ bracketedPaste: wasBracketedPaste
57036
+ };
57037
+ if (wasBracketedPaste && stdout.isTTY) {
57038
+ try {
57039
+ stdout.write("\x1B[?2004l");
57040
+ } catch {
57041
+ }
57042
+ }
57043
+ if (wasRawMode) {
57044
+ stdin.setRawMode(false);
57045
+ stdin.unref();
57046
+ clearInputState();
57047
+ }
57048
+ }, [isRawModeSupported, stdin, stdout, clearInputState]);
57049
+ const resumeInput = (0, import_react15.useCallback)(() => {
57050
+ const { rawMode, bracketedPaste } = suspendedInputStateRef.current;
57051
+ if (rawMode) {
57052
+ stdin.setEncoding("utf8");
57053
+ stdin.ref();
57054
+ stdin.setRawMode(true);
57055
+ attachReadableListener();
57056
+ }
57057
+ if (bracketedPaste && stdout.isTTY) {
57058
+ try {
57059
+ stdout.write("\x1B[?2004h");
57060
+ } catch {
57061
+ }
57062
+ }
57063
+ }, [stdin, stdout, attachReadableListener]);
57064
+ (0, import_react15.useInsertionEffect)(() => {
57065
+ onRegisterInputControl(pauseInput, resumeInput);
57066
+ }, [onRegisterInputControl, pauseInput, resumeInput]);
56314
57067
  const findNextFocusable = (0, import_react15.useCallback)((currentFocusables, currentActiveFocusId) => {
56315
57068
  const activeIndex = currentFocusables.findIndex((focusable) => {
56316
57069
  return focusable.id === currentActiveFocusId;
@@ -56456,7 +57209,7 @@ function App({ children, stdin, stdout, stderr, writeToStdout, writeToStderr, ex
56456
57209
  if (interactive && canWriteToStdout) {
56457
57210
  cli_cursor_default.show(stdout);
56458
57211
  }
56459
- if (isRawModeSupported && rawModeEnabledCount.current > 0) {
57212
+ if (isRawModeSupported && (rawModeEnabledCount.current > 0 || pendingDisableRawModeRef.current)) {
56460
57213
  disableRawMode();
56461
57214
  }
56462
57215
  if (bracketedPasteModeEnabledCount.current > 0) {
@@ -56469,8 +57222,9 @@ function App({ children, stdin, stdout, stderr, writeToStdout, writeToStderr, ex
56469
57222
  }, [stdout, isRawModeSupported, disableRawMode, interactive]);
56470
57223
  const appContextValue = (0, import_react15.useMemo)(() => ({
56471
57224
  exit: handleExit,
56472
- waitUntilRenderFlush: onWaitUntilRenderFlush
56473
- }), [handleExit, onWaitUntilRenderFlush]);
57225
+ waitUntilRenderFlush: onWaitUntilRenderFlush,
57226
+ suspendTerminal: onSuspendTerminal
57227
+ }), [handleExit, onWaitUntilRenderFlush, onSuspendTerminal]);
56474
57228
  const stdinContextValue = (0, import_react15.useMemo)(() => ({
56475
57229
  stdin,
56476
57230
  setRawMode: handleSetRawMode,
@@ -56558,7 +57312,7 @@ function App({ children, stdin, stdout, stderr, writeToStdout, writeToStderr, ex
56558
57312
  App.displayName = "InternalApp";
56559
57313
  var App_default = App;
56560
57314
 
56561
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/kitty-keyboard.js
57315
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/kitty-keyboard.js
56562
57316
  var kittyFlags = {
56563
57317
  disambiguateEscapeCodes: 1,
56564
57318
  reportEventTypes: 2,
@@ -56584,7 +57338,7 @@ var kittyModifiers = {
56584
57338
  numLock: 128
56585
57339
  };
56586
57340
 
56587
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/ink.js
57341
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/ink.js
56588
57342
  var noop2 = () => {
56589
57343
  };
56590
57344
  var textEncoder = new TextEncoder();
@@ -56644,6 +57398,7 @@ var stripKittyQueryResponsesAndTrailingPartial = (buffer) => {
56644
57398
  }
56645
57399
  return keptBytes;
56646
57400
  };
57401
+ var isWindowsConsole = process12.platform === "win32";
56647
57402
  var shouldClearTerminalForFrame = ({ isTty, viewportRows, previousOutputHeight, nextOutputHeight, isUnmounting }) => {
56648
57403
  if (!isTty) {
56649
57404
  return false;
@@ -56652,8 +57407,12 @@ var shouldClearTerminalForFrame = ({ isTty, viewportRows, previousOutputHeight,
56652
57407
  const wasFullscreen = previousOutputHeight >= viewportRows;
56653
57408
  const wasOverflowing = previousOutputHeight > viewportRows;
56654
57409
  const isOverflowing = nextOutputHeight > viewportRows;
57410
+ const isFullscreen = nextOutputHeight >= viewportRows;
56655
57411
  const isLeavingFullscreen = wasFullscreen && nextOutputHeight < viewportRows;
56656
57412
  const shouldClearOnUnmount = isUnmounting && wasFullscreen;
57413
+ if (isWindowsConsole && (wasFullscreen || isFullscreen)) {
57414
+ return true;
57415
+ }
56657
57416
  return (
56658
57417
  // Overflowing frames still need full clear fallback.
56659
57418
  wasOverflowing || isOverflowing && hadPreviousFrame || // Clear when shrinking from fullscreen to non-fullscreen output.
@@ -56717,8 +57476,15 @@ var Ink = class {
56717
57476
  throttledOnRender;
56718
57477
  hasPendingThrottledRender = false;
56719
57478
  kittyProtocolEnabled = false;
57479
+ kittyFlags;
56720
57480
  cancelKittyDetection;
56721
57481
  nextRenderCommit;
57482
+ // Set while suspendTerminal() has handed the terminal to a child process.
57483
+ isSuspended = false;
57484
+ // Input pause/resume hooks registered by the App component, which owns raw
57485
+ // mode and bracketed paste state.
57486
+ pauseInput;
57487
+ resumeInput;
56722
57488
  constructor(options) {
56723
57489
  autoBind(this);
56724
57490
  this.options = options;
@@ -56746,6 +57512,7 @@ var Ink = class {
56746
57512
  this.throttledOnRender = throttled;
56747
57513
  }
56748
57514
  this.rootNode.onImmediateRender = this.onRender;
57515
+ this.rootNode.onStaticChange = this.handleStaticChange;
56749
57516
  this.log = log_update_default.create(options.stdout, {
56750
57517
  incremental: options.incrementalRendering
56751
57518
  });
@@ -56807,6 +57574,7 @@ var Ink = class {
56807
57574
  this.lastOutputToRender = "";
56808
57575
  }
56809
57576
  this.calculateLayout();
57577
+ emitLayoutListeners(this.rootNode);
56810
57578
  this.onRender();
56811
57579
  this.lastTerminalWidth = currentWidth;
56812
57580
  };
@@ -56843,11 +57611,22 @@ var Ink = class {
56843
57611
  this.rootNode.yogaNode.setWidth(terminalWidth);
56844
57612
  this.rootNode.yogaNode.calculateLayout(void 0, void 0, src_default.DIRECTION_LTR);
56845
57613
  };
57614
+ // Resets `fullStaticOutput` when the <Static> identity changes so stale items from a previous instance are not replayed on future rewrites.
57615
+ handleStaticChange = () => {
57616
+ this.fullStaticOutput = "";
57617
+ };
56846
57618
  onRender = () => {
56847
57619
  this.hasPendingThrottledRender = false;
56848
57620
  if (this.isUnmounted) {
56849
57621
  return;
56850
57622
  }
57623
+ if (this.isSuspended) {
57624
+ if (this.nextRenderCommit) {
57625
+ this.nextRenderCommit.resolve();
57626
+ this.nextRenderCommit = void 0;
57627
+ }
57628
+ return;
57629
+ }
56851
57630
  if (this.nextRenderCommit) {
56852
57631
  this.nextRenderCommit.resolve();
56853
57632
  this.nextRenderCommit = void 0;
@@ -56919,7 +57698,7 @@ var Ink = class {
56919
57698
  const tree = import_react16.default.createElement(
56920
57699
  accessibilityContext.Provider,
56921
57700
  { value: { isScreenReaderEnabled: this.isScreenReaderEnabled } },
56922
- import_react16.default.createElement(App_default, { stdin: this.options.stdin, stdout: this.options.stdout, stderr: this.options.stderr, exitOnCtrlC: this.options.exitOnCtrlC, interactive: this.interactive, renderThrottleMs: this.renderThrottleMs, writeToStdout: this.writeToStdout, writeToStderr: this.writeToStderr, setCursorPosition: this.setCursorPosition, onExit: this.handleAppExit, onWaitUntilRenderFlush: this.waitUntilRenderFlush }, node)
57701
+ import_react16.default.createElement(App_default, { stdin: this.options.stdin, stdout: this.options.stdout, stderr: this.options.stderr, exitOnCtrlC: this.options.exitOnCtrlC, interactive: this.interactive, renderThrottleMs: this.renderThrottleMs, writeToStdout: this.writeToStdout, writeToStderr: this.writeToStderr, setCursorPosition: this.setCursorPosition, onExit: this.handleAppExit, onWaitUntilRenderFlush: this.waitUntilRenderFlush, onSuspendTerminal: this.suspendTerminal, onRegisterInputControl: this.registerInputControl }, node)
56923
57702
  );
56924
57703
  if (this.options.concurrent) {
56925
57704
  reconciler_default.updateContainer(tree, this.container, null, noop2);
@@ -56932,6 +57711,9 @@ var Ink = class {
56932
57711
  if (this.isUnmounted) {
56933
57712
  return;
56934
57713
  }
57714
+ if (this.isSuspended) {
57715
+ return;
57716
+ }
56935
57717
  if (this.options.debug) {
56936
57718
  this.options.stdout.write(data + this.fullStaticOutput + this.lastOutput);
56937
57719
  return;
@@ -56955,6 +57737,9 @@ var Ink = class {
56955
57737
  if (this.isUnmounted) {
56956
57738
  return;
56957
57739
  }
57740
+ if (this.isSuspended) {
57741
+ return;
57742
+ }
56958
57743
  if (this.options.debug) {
56959
57744
  this.options.stderr.write(data);
56960
57745
  this.options.stdout.write(this.fullStaticOutput + this.lastOutput);
@@ -57118,8 +57903,27 @@ var Ink = class {
57118
57903
  }
57119
57904
  });
57120
57905
  }
57121
- setAlternateScreen(enabled) {
57122
- this.alternateScreen = this.resolveAlternateScreenOption(enabled, this.interactive);
57906
+ registerInputControl(pauseInput, resumeInput) {
57907
+ this.pauseInput = pauseInput;
57908
+ this.resumeInput = resumeInput;
57909
+ }
57910
+ async suspendTerminal(callback) {
57911
+ this.beginSuspend();
57912
+ if (callback) {
57913
+ try {
57914
+ await callback();
57915
+ } finally {
57916
+ await this.endSuspend();
57917
+ }
57918
+ return void 0;
57919
+ }
57920
+ const resume = async () => {
57921
+ await this.endSuspend();
57922
+ };
57923
+ return { resume, [Symbol.asyncDispose]: resume };
57924
+ }
57925
+ setAlternateScreen(enabled2) {
57926
+ this.alternateScreen = this.resolveAlternateScreenOption(enabled2, this.interactive);
57123
57927
  if (this.alternateScreen) {
57124
57928
  this.writeBestEffort(this.options.stdout, base_exports.enterAlternativeScreen);
57125
57929
  this.writeBestEffort(this.options.stdout, hideCursorEscape);
@@ -57181,7 +57985,7 @@ var Ink = class {
57181
57985
  if (sync) {
57182
57986
  this.options.stdout.write(bsu);
57183
57987
  }
57184
- this.options.stdout.write(base_exports.clearTerminal + this.fullStaticOutput + output);
57988
+ this.options.stdout.write(base_exports.clearTerminal + this.fullStaticOutput + outputToRender);
57185
57989
  this.lastOutput = output;
57186
57990
  this.lastOutputToRender = outputToRender;
57187
57991
  this.lastOutputHeight = outputHeight;
@@ -57263,10 +58067,74 @@ var Ink = class {
57263
58067
  enableKittyProtocol(flags) {
57264
58068
  this.options.stdout.write(`\x1B[>${resolveFlags(flags)}u`);
57265
58069
  this.kittyProtocolEnabled = true;
58070
+ this.kittyFlags = flags;
58071
+ }
58072
+ beginSuspend() {
58073
+ if (this.isSuspended) {
58074
+ throw new Error("The terminal is already suspended. Resume the current suspension before suspending again.");
58075
+ }
58076
+ this.isSuspended = true;
58077
+ if (!this.interactive || this.isUnmounted || this.isUnmounting) {
58078
+ return;
58079
+ }
58080
+ try {
58081
+ const stdout = this.options.stdout;
58082
+ const { canWriteToStdout } = getWritableStreamState(stdout);
58083
+ settleThrottle(this.throttledOnRender, canWriteToStdout);
58084
+ settleThrottle(this.throttledLog, canWriteToStdout);
58085
+ if (canWriteToStdout) {
58086
+ this.log.clear();
58087
+ this.log.done();
58088
+ if (this.kittyProtocolEnabled) {
58089
+ this.writeBestEffort(this.options.stdout, "\x1B[<u");
58090
+ }
58091
+ if (this.alternateScreen) {
58092
+ this.writeBestEffort(this.options.stdout, base_exports.exitAlternativeScreen);
58093
+ }
58094
+ }
58095
+ this.pauseInput?.();
58096
+ } catch (error43) {
58097
+ this.isSuspended = false;
58098
+ try {
58099
+ this.resumeInput?.();
58100
+ } catch {
58101
+ }
58102
+ throw error43;
58103
+ }
58104
+ }
58105
+ async endSuspend() {
58106
+ if (!this.isSuspended) {
58107
+ return;
58108
+ }
58109
+ this.isSuspended = false;
58110
+ this.resumeInput?.();
58111
+ if (!this.interactive || this.isUnmounted || this.isUnmounting) {
58112
+ return;
58113
+ }
58114
+ const stdout = this.options.stdout;
58115
+ const { canWriteToStdout } = getWritableStreamState(stdout);
58116
+ if (canWriteToStdout) {
58117
+ if (this.alternateScreen) {
58118
+ this.writeBestEffort(this.options.stdout, base_exports.enterAlternativeScreen);
58119
+ }
58120
+ if (this.kittyProtocolEnabled && this.kittyFlags) {
58121
+ this.writeBestEffort(this.options.stdout, `\x1B[>${resolveFlags(this.kittyFlags)}u`);
58122
+ }
58123
+ }
58124
+ this.lastOutput = "";
58125
+ this.lastOutputToRender = "";
58126
+ this.lastOutputHeight = 0;
58127
+ this.log.reset();
58128
+ try {
58129
+ this.calculateLayout();
58130
+ this.onRender();
58131
+ await this.waitUntilRenderFlush();
58132
+ } catch {
58133
+ }
57266
58134
  }
57267
58135
  };
57268
58136
 
57269
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/render.js
58137
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/render.js
57270
58138
  var render = (node, options) => {
57271
58139
  const inkOptions = {
57272
58140
  stdout: process13.stdout,
@@ -57317,25 +58185,25 @@ var getInstance = (stdout, createInstance) => {
57317
58185
  return instance;
57318
58186
  };
57319
58187
 
57320
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/render-to-string.js
58188
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/render-to-string.js
57321
58189
  var import_constants5 = __toESM(require_constants(), 1);
57322
58190
 
57323
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/Static.js
58191
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/Static.js
57324
58192
  var import_react17 = __toESM(require_react(), 1);
57325
58193
 
57326
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/Transform.js
58194
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/Transform.js
57327
58195
  var import_react18 = __toESM(require_react(), 1);
57328
58196
 
57329
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/Newline.js
58197
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/Newline.js
57330
58198
  var import_react19 = __toESM(require_react(), 1);
57331
58199
 
57332
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/Spacer.js
58200
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/components/Spacer.js
57333
58201
  var import_react20 = __toESM(require_react(), 1);
57334
58202
 
57335
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-input.js
58203
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-input.js
57336
58204
  var import_react22 = __toESM(require_react(), 1);
57337
58205
 
57338
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/parse-keypress.js
58206
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/parse-keypress.js
57339
58207
  var textDecoder = new TextDecoder();
57340
58208
  var metaKeyCodeRe = /^(?:\x1b)([a-zA-Z0-9])$/;
57341
58209
  var fnKeyRe = /^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/;
@@ -57767,13 +58635,13 @@ var parseKeypress = (s = "") => {
57767
58635
  };
57768
58636
  var parse_keypress_default = parseKeypress;
57769
58637
 
57770
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-stdin.js
58638
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-stdin.js
57771
58639
  var import_react21 = __toESM(require_react(), 1);
57772
58640
  var useStdin = () => (0, import_react21.useContext)(StdinContext_default);
57773
58641
  var useStdinContext = () => (0, import_react21.useContext)(StdinContext_default);
57774
58642
  var use_stdin_default = useStdin;
57775
58643
 
57776
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-input.js
58644
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-input.js
57777
58645
  var useInput = (inputHandler, options = {}) => {
57778
58646
  const { setRawMode, internal_exitOnCtrlC, internal_eventEmitter } = useStdinContext();
57779
58647
  (0, import_react22.useEffect)(() => {
@@ -57853,39 +58721,39 @@ var useInput = (inputHandler, options = {}) => {
57853
58721
  };
57854
58722
  var use_input_default = useInput;
57855
58723
 
57856
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-paste.js
58724
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-paste.js
57857
58725
  var import_react23 = __toESM(require_react(), 1);
57858
58726
 
57859
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-app.js
58727
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-app.js
57860
58728
  var import_react24 = __toESM(require_react(), 1);
57861
58729
 
57862
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-stdout.js
58730
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-stdout.js
57863
58731
  var import_react25 = __toESM(require_react(), 1);
57864
58732
  var useStdout = () => (0, import_react25.useContext)(StdoutContext_default);
57865
58733
  var use_stdout_default = useStdout;
57866
58734
 
57867
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-stderr.js
58735
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-stderr.js
57868
58736
  var import_react26 = __toESM(require_react(), 1);
57869
58737
 
57870
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-focus.js
58738
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-focus.js
57871
58739
  var import_react27 = __toESM(require_react(), 1);
57872
58740
 
57873
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-focus-manager.js
58741
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-focus-manager.js
57874
58742
  var import_react28 = __toESM(require_react(), 1);
57875
58743
 
57876
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-is-screen-reader-enabled.js
58744
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-is-screen-reader-enabled.js
57877
58745
  var import_react29 = __toESM(require_react(), 1);
57878
58746
 
57879
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-cursor.js
58747
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-cursor.js
57880
58748
  var import_react30 = __toESM(require_react(), 1);
57881
58749
 
57882
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-animation.js
58750
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-animation.js
57883
58751
  var import_react31 = __toESM(require_react(), 1);
57884
58752
 
57885
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-window-size.js
58753
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-window-size.js
57886
58754
  var import_react32 = __toESM(require_react(), 1);
57887
58755
 
57888
- // node_modules/.pnpm/ink@7.0.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-box-metrics.js
58756
+ // node_modules/.pnpm/ink@7.1.1_@types+react@19.2.14_react@19.2.0/node_modules/ink/build/hooks/use-box-metrics.js
57889
58757
  var import_react33 = __toESM(require_react(), 1);
57890
58758
 
57891
58759
  // src/client/run-foreground.ts
@@ -58127,7 +58995,10 @@ var ipcRequestSchema = external_exports.discriminatedUnion("kind", [
58127
58995
  }),
58128
58996
  external_exports.object({
58129
58997
  kind: external_exports.literal("fetch-candidates"),
58130
- envelope: contextEnvelopeSchema
58998
+ envelope: contextEnvelopeSchema,
58999
+ // The client wants one `candidate` message per parsed row before the final
59000
+ // `candidates` message (Phase 09.1). Old daemons strip the key and reply once.
59001
+ stream: external_exports.literal(true).optional()
58131
59002
  })
58132
59003
  ]);
58133
59004
  var ipcResponseSchema = external_exports.discriminatedUnion("kind", [
@@ -58135,7 +59006,9 @@ var ipcResponseSchema = external_exports.discriminatedUnion("kind", [
58135
59006
  kind: external_exports.literal("pong"),
58136
59007
  fetchCandidates: external_exports.literal(true).optional(),
58137
59008
  // Daemon accepts envelopes carrying the `installed-tools` chunk (Phase 9).
58138
- installedTools: external_exports.literal(true).optional()
59009
+ installedTools: external_exports.literal(true).optional(),
59010
+ // Daemon streams `candidate` messages to a `stream: true` request (Phase 09.1).
59011
+ streamCandidates: external_exports.literal(true).optional()
58139
59012
  }),
58140
59013
  external_exports.object({
58141
59014
  kind: external_exports.literal("session-ready"),
@@ -58148,6 +59021,12 @@ var ipcResponseSchema = external_exports.discriminatedUnion("kind", [
58148
59021
  external_exports.object({
58149
59022
  kind: external_exports.literal("fetch-accepted")
58150
59023
  }),
59024
+ // One streamed row, sent only when the request carried `stream: true`.
59025
+ external_exports.object({
59026
+ kind: external_exports.literal("candidate"),
59027
+ candidate: commandCandidateSchema
59028
+ }),
59029
+ // The done signal and the authoritative final list, for every request.
58151
59030
  external_exports.object({
58152
59031
  kind: external_exports.literal("candidates"),
58153
59032
  candidates: candidateListSchema
@@ -58240,7 +59119,7 @@ function pingDaemonFetchCap(socketPath2) {
58240
59119
  done("unknown");
58241
59120
  return;
58242
59121
  }
58243
- const current2 = response.data.fetchCandidates === true && response.data.installedTools === true;
59122
+ const current2 = response.data.fetchCandidates === true && response.data.installedTools === true && response.data.streamCandidates === true;
58244
59123
  done(current2 ? "yes" : "no");
58245
59124
  });
58246
59125
  client.on("error", () => {
@@ -58361,12 +59240,19 @@ var IpcTransportError = class extends Error {
58361
59240
  this.name = "IpcTransportError";
58362
59241
  }
58363
59242
  };
58364
- function requestDaemonFetch(socketPath2, envelope, timeoutMs = FETCH_TIMEOUT_MS) {
59243
+ function requestDaemonFetch(socketPath2, envelope, timeoutMs = FETCH_TIMEOUT_MS, options = {}) {
59244
+ const { signal } = options;
59245
+ if (signal?.aborted) {
59246
+ return Promise.reject(abortError());
59247
+ }
58365
59248
  return new Promise((resolve3, reject) => {
58366
59249
  const client = net2.createConnection(socketPath2);
58367
59250
  let buf = "";
58368
59251
  let settled = false;
58369
59252
  let accepted = false;
59253
+ const onAbort = () => {
59254
+ finish(abortError());
59255
+ };
58370
59256
  const finish = (error43, candidates) => {
58371
59257
  if (settled) {
58372
59258
  return;
@@ -58374,6 +59260,7 @@ function requestDaemonFetch(socketPath2, envelope, timeoutMs = FETCH_TIMEOUT_MS)
58374
59260
  settled = true;
58375
59261
  clearTimeout(ackTimer);
58376
59262
  clearTimeout(timer);
59263
+ signal?.removeEventListener("abort", onAbort);
58377
59264
  client.destroy();
58378
59265
  if (error43) {
58379
59266
  reject(error43);
@@ -58389,6 +59276,7 @@ function requestDaemonFetch(socketPath2, envelope, timeoutMs = FETCH_TIMEOUT_MS)
58389
59276
  const timer = setTimeout(() => {
58390
59277
  finish(new IpcTransportError("daemon fetch timed out"));
58391
59278
  }, timeoutMs);
59279
+ signal?.addEventListener("abort", onAbort, { once: true });
58392
59280
  const handleResponse = (parsed) => {
58393
59281
  const response = ipcResponseSchema.safeParse(parsed);
58394
59282
  if (!response.success) {
@@ -58400,6 +59288,12 @@ function requestDaemonFetch(socketPath2, envelope, timeoutMs = FETCH_TIMEOUT_MS)
58400
59288
  clearTimeout(ackTimer);
58401
59289
  return;
58402
59290
  }
59291
+ if (response.data.kind === "candidate") {
59292
+ accepted = true;
59293
+ clearTimeout(ackTimer);
59294
+ options.onCandidate?.(response.data.candidate);
59295
+ return;
59296
+ }
58403
59297
  if (response.data.kind === "candidates") {
58404
59298
  accepted = true;
58405
59299
  finish(void 0, response.data.candidates);
@@ -58413,11 +59307,12 @@ function requestDaemonFetch(socketPath2, envelope, timeoutMs = FETCH_TIMEOUT_MS)
58413
59307
  finish(new IpcTransportError("unexpected daemon fetch response"));
58414
59308
  };
58415
59309
  client.on("connect", () => {
58416
- client.write(`${JSON.stringify({ kind: "fetch-candidates", envelope })}
59310
+ client.write(`${JSON.stringify({ kind: "fetch-candidates", envelope, stream: true })}
58417
59311
  `);
58418
59312
  });
59313
+ client.setEncoding("utf8");
58419
59314
  client.on("data", (chunk) => {
58420
- buf += chunk.toString();
59315
+ buf += String(chunk);
58421
59316
  let nl = buf.indexOf("\n");
58422
59317
  while (nl !== -1) {
58423
59318
  const line = buf.slice(0, nl).trim();
@@ -58442,19 +59337,36 @@ function requestDaemonFetch(socketPath2, envelope, timeoutMs = FETCH_TIMEOUT_MS)
58442
59337
  client.on("error", (error43) => {
58443
59338
  finish(new IpcTransportError(error43.message));
58444
59339
  });
59340
+ client.on("close", () => {
59341
+ finish(new IpcTransportError("daemon connection closed"));
59342
+ });
58445
59343
  });
58446
59344
  }
58447
- async function fetchCandidatesForUi(socketPath2, envelope) {
59345
+ async function fetchCandidatesForUi(socketPath2, envelope, options = {}) {
59346
+ let forwarded = 0;
59347
+ const daemonOptions = {
59348
+ signal: options.signal,
59349
+ onCandidate: (candidate) => {
59350
+ forwarded++;
59351
+ options.onCandidate?.(candidate);
59352
+ }
59353
+ };
58448
59354
  try {
58449
- const candidates = await requestDaemonFetch(socketPath2, envelope);
59355
+ const candidates = await requestDaemonFetch(socketPath2, envelope, void 0, daemonOptions);
58450
59356
  void appendDebugLog("client", "candidates from daemon", { count: candidates.length });
58451
59357
  return candidates;
58452
59358
  } catch (error43) {
58453
59359
  if (!(error43 instanceof IpcTransportError)) {
58454
59360
  throw error43;
58455
59361
  }
59362
+ if (options.signal?.aborted) {
59363
+ throw abortError();
59364
+ }
59365
+ if (forwarded > 0) {
59366
+ throw error43;
59367
+ }
58456
59368
  void appendDebugLog("client", "daemon fetch fallback", { message: error43.message });
58457
- return resolveClaudeDefaultAdapter().fetchCandidates(envelope);
59369
+ return resolveClaudeDefaultAdapter().fetchCandidates(envelope, options);
58458
59370
  }
58459
59371
  }
58460
59372
 
@@ -59214,6 +60126,8 @@ function filterCandidates(candidates, query) {
59214
60126
  );
59215
60127
  }
59216
60128
  var MODAL_VIEWPORT_LINES = 18;
60129
+ var INCOMPLETE_LIST_NOTE = "list may be incomplete";
60130
+ var LIST_STATUS_ROW_LINES = 1;
59217
60131
  var MARK_COLUMNS = 2;
59218
60132
  function estimateCandidateSelectLines(input) {
59219
60133
  let lines = 0;
@@ -59244,6 +60158,9 @@ function estimateCandidateSelectLines(input) {
59244
60158
  lines += 1;
59245
60159
  }
59246
60160
  }
60161
+ if (input.listState === "arriving" || input.listState === "partial") {
60162
+ lines += LIST_STATUS_ROW_LINES;
60163
+ }
59247
60164
  }
59248
60165
  const visible = input.candidates !== null && input.error !== true ? filterCandidates(input.candidates, input.query) : [];
59249
60166
  const selectedCandidate = visible[input.selectedIndex];
@@ -59303,30 +60220,42 @@ function CandidateSelect({
59303
60220
  onSelect,
59304
60221
  onCancel,
59305
60222
  error: error43,
59306
- onLayoutLinesChange
60223
+ onLayoutLinesChange,
60224
+ listState = "complete"
59307
60225
  }) {
59308
60226
  const { isRawModeSupported } = use_stdin_default();
59309
60227
  const { stdout } = use_stdout_default();
59310
60228
  const modalWidth = Math.min(MODAL_MAX_WIDTH, stdout.columns || MODAL_MAX_WIDTH);
59311
60229
  const contentWidth = modalWidth - MODAL_PADDING_X - ROW_GUTTER.length;
59312
60230
  const [selectedIndex, setSelectedIndex] = (0, import_react35.useState)(0);
59313
- const [query, setQuery] = (0, import_react35.useState)(initialQuery ?? "");
60231
+ const [query, setQuery] = (0, import_react35.useState)("");
59314
60232
  const [installToggled, setInstallToggled] = (0, import_react35.useState)(/* @__PURE__ */ new Set());
59315
60233
  const [prevCandidates, setPrevCandidates] = (0, import_react35.useState)(null);
59316
60234
  const paneHold = (0, import_react35.useRef)({
59317
60235
  candidates: null,
59318
60236
  lines: 0
59319
60237
  });
60238
+ const pendingInput = (0, import_react35.useRef)(null);
60239
+ const renderToken = {};
59320
60240
  if (candidates !== prevCandidates) {
59321
60241
  setPrevCandidates(candidates);
59322
- if (selectedIndex !== 0) {
59323
- setSelectedIndex(0);
59324
- }
59325
- if (installToggled.size > 0) {
59326
- setInstallToggled(/* @__PURE__ */ new Set());
59327
- }
59328
- if (candidates && candidates.length > 0 && filterCandidates(candidates, query).length === 0) {
59329
- setQuery("");
60242
+ if (prevCandidates === null) {
60243
+ if (selectedIndex !== 0) {
60244
+ setSelectedIndex(0);
60245
+ }
60246
+ if (installToggled.size > 0) {
60247
+ setInstallToggled(/* @__PURE__ */ new Set());
60248
+ }
60249
+ } else if (candidates !== null) {
60250
+ const highlighted = filterCandidates(prevCandidates, query)[selectedIndex];
60251
+ const visible = filterCandidates(candidates, query);
60252
+ const highlightedKey = highlighted === void 0 ? void 0 : candidateKey(highlighted);
60253
+ const kept = highlightedKey === void 0 ? -1 : visible.findIndex((candidate) => candidateKey(candidate) === highlightedKey);
60254
+ const current2 = Number.isFinite(selectedIndex) && selectedIndex >= 0 ? selectedIndex : 0;
60255
+ const nextIndex = kept >= 0 ? kept : Math.max(0, Math.min(current2, visible.length - 1));
60256
+ if (nextIndex !== selectedIndex) {
60257
+ setSelectedIndex(nextIndex);
60258
+ }
59330
60259
  }
59331
60260
  }
59332
60261
  (0, import_react35.useEffect)(() => {
@@ -59334,9 +60263,18 @@ function CandidateSelect({
59334
60263
  onCancel();
59335
60264
  }
59336
60265
  }, [isRawModeSupported, onCancel]);
59337
- (0, import_react35.useEffect)(() => {
59338
- setSelectedIndex(0);
59339
- }, [query]);
60266
+ const applyInput = (live, next) => {
60267
+ pendingInput.current = next;
60268
+ if (next.query !== live.query) {
60269
+ setQuery(next.query);
60270
+ }
60271
+ if (next.selectedIndex !== live.selectedIndex) {
60272
+ setSelectedIndex(next.selectedIndex);
60273
+ }
60274
+ if (next.installToggled !== live.installToggled) {
60275
+ setInstallToggled(next.installToggled);
60276
+ }
60277
+ };
59340
60278
  const includeDevFooter = process.env.QQ_DEV_ROOT != null;
59341
60279
  (0, import_react35.useEffect)(() => {
59342
60280
  if (!onLayoutLinesChange) {
@@ -59345,6 +60283,9 @@ function CandidateSelect({
59345
60283
  if (candidates === null && error43 !== true) {
59346
60284
  return;
59347
60285
  }
60286
+ if (listState === "arriving" && error43 !== true) {
60287
+ return;
60288
+ }
59348
60289
  const layout = {
59349
60290
  candidates,
59350
60291
  initialQuery,
@@ -59353,7 +60294,8 @@ function CandidateSelect({
59353
60294
  error: error43,
59354
60295
  contentWidth,
59355
60296
  includeDevFooter,
59356
- installToggled
60297
+ installToggled,
60298
+ listState
59357
60299
  };
59358
60300
  const previousHeld = paneHold.current.candidates === candidates ? paneHold.current.lines : 0;
59359
60301
  const lines = heldPaneLines(previousHeld, layout);
@@ -59368,57 +60310,63 @@ function CandidateSelect({
59368
60310
  contentWidth,
59369
60311
  includeDevFooter,
59370
60312
  installToggled,
60313
+ listState,
59371
60314
  onLayoutLinesChange
59372
60315
  ]);
59373
60316
  use_input_default(
59374
60317
  (input, key) => {
60318
+ const live = pendingInput.current?.render === renderToken ? pendingInput.current : { render: renderToken, query, selectedIndex, installToggled };
59375
60319
  if (key.escape) {
59376
60320
  onCancel();
59377
60321
  return;
59378
60322
  }
59379
60323
  if (key.backspace) {
59380
- setQuery((q) => q.slice(0, -1));
60324
+ if (live.query === "") {
60325
+ return;
60326
+ }
60327
+ applyInput(live, { ...live, query: live.query.slice(0, -1), selectedIndex: 0 });
59381
60328
  return;
59382
60329
  }
59383
60330
  if (key.tab) {
59384
60331
  if (!candidates) return;
59385
- const visible = filterCandidates(candidates, query);
59386
- const selected = visible[selectedIndex] ?? visible[0];
60332
+ const visible = filterCandidates(candidates, live.query);
60333
+ const selected = visible[live.selectedIndex] ?? visible[0];
59387
60334
  if (selected?.install?.form == null) return;
59388
60335
  const id = candidateKey(selected);
59389
- setInstallToggled((previous) => {
59390
- const next = new Set(previous);
59391
- if (next.has(id)) {
59392
- next.delete(id);
59393
- } else {
59394
- next.add(id);
59395
- }
59396
- return next;
59397
- });
60336
+ const toggled = new Set(live.installToggled);
60337
+ if (toggled.has(id)) {
60338
+ toggled.delete(id);
60339
+ } else {
60340
+ toggled.add(id);
60341
+ }
60342
+ applyInput(live, { ...live, installToggled: toggled });
59398
60343
  return;
59399
60344
  }
59400
60345
  if (key.return && candidates) {
59401
- const visible = filterCandidates(candidates, query);
60346
+ const visible = filterCandidates(candidates, live.query);
59402
60347
  if (visible.length === 0) return;
59403
- const selected = visible[selectedIndex] ?? visible[0];
59404
- const command = displayedCommand(selected, installToggled);
60348
+ const selected = visible[live.selectedIndex] ?? visible[0];
60349
+ const command = displayedCommand(selected, live.installToggled);
59405
60350
  const original = normalizeCommand2(selected.command);
59406
60351
  const explanation = selected.explanation || `see man ${original.split(" ")[0]}`;
59407
60352
  onSelect(command, explanation);
59408
60353
  return;
59409
60354
  }
59410
60355
  if (input && !key.ctrl && !key.meta) {
59411
- setQuery((q) => q + input);
60356
+ applyInput(live, { ...live, query: live.query + input, selectedIndex: 0 });
59412
60357
  return;
59413
60358
  }
59414
60359
  if (key.upArrow && candidates) {
59415
- const visible = filterCandidates(candidates, query);
59416
- setSelectedIndex((i) => i === 0 ? visible.length - 1 : i - 1);
60360
+ const visible = filterCandidates(candidates, live.query);
60361
+ if (visible.length === 0) return;
60362
+ const index = live.selectedIndex;
60363
+ applyInput(live, { ...live, selectedIndex: index <= 0 ? visible.length - 1 : index - 1 });
59417
60364
  return;
59418
60365
  }
59419
60366
  if (key.downArrow && candidates) {
59420
- const visible = filterCandidates(candidates, query);
59421
- setSelectedIndex((i) => (i + 1) % visible.length);
60367
+ const visible = filterCandidates(candidates, live.query);
60368
+ if (visible.length === 0) return;
60369
+ applyInput(live, { ...live, selectedIndex: (live.selectedIndex + 1) % visible.length });
59422
60370
  return;
59423
60371
  }
59424
60372
  },
@@ -59477,13 +60425,15 @@ function CandidateSelect({
59477
60425
  initialQuery && initialQuery.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { flexGrow: 0, height: 1, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, wrap: "truncate", children: `queque \u203A ${initialQuery}` }) }),
59478
60426
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SearchInput, { query }),
59479
60427
  content,
60428
+ candidates !== null && error43 !== true && listState === "arriving" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(LoadingSpinner, {}),
60429
+ candidates !== null && error43 !== true && listState === "partial" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: INCOMPLETE_LIST_NOTE }),
59480
60430
  showDestructiveWarning && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "yellow", children: DESTRUCTIVE_WARNING_TEXT }) }),
59481
60431
  legend !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { marginTop: 1, children: [
59482
60432
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "cyan", children: MISSING_TOOL_MARK }),
59483
60433
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: legend.slice(MISSING_TOOL_MARK.length) })
59484
60434
  ] }),
59485
60435
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ControlsLine, {}),
59486
- process.env.QQ_DEV_ROOT != null && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { justifyContent: "flex-end", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "yellow", children: `dev v${"0.5.1"} ${"2414347"}` }) })
60436
+ process.env.QQ_DEV_ROOT != null && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { justifyContent: "flex-end", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "yellow", children: `dev v${"0.6.0"} ${"3d6ffbb"}` }) })
59487
60437
  ] });
59488
60438
  }
59489
60439
 
@@ -59833,13 +60783,17 @@ async function runForegroundClient(args) {
59833
60783
  await new Promise((resolve3) => {
59834
60784
  let unmount;
59835
60785
  let resolved = false;
59836
- const buildCandidateElement = (candidates, errorState) => import_react36.default.createElement(CandidateSelect, {
60786
+ const fetchAbort = new AbortController();
60787
+ const streamed = [];
60788
+ const buildCandidateElement = (candidates, errorState, listState = "complete") => import_react36.default.createElement(CandidateSelect, {
59837
60789
  candidates,
59838
60790
  initialQuery: request.lbuffer,
59839
60791
  error: errorState,
60792
+ listState,
59840
60793
  onSelect: async (command, explanation) => {
59841
60794
  if (resolved) return;
59842
60795
  resolved = true;
60796
+ fetchAbort.abort();
59843
60797
  const { lbuffer, rbuffer } = buildShellBuffers(command, explanation);
59844
60798
  await writeShellResult(resultFile, {
59845
60799
  kind: "replace-buffer",
@@ -59852,6 +60806,7 @@ async function runForegroundClient(args) {
59852
60806
  onCancel: async () => {
59853
60807
  if (resolved) return;
59854
60808
  resolved = true;
60809
+ fetchAbort.abort();
59855
60810
  await writeShellResult(resultFile, { kind: "cancel" });
59856
60811
  unmount?.();
59857
60812
  },
@@ -59868,6 +60823,7 @@ async function runForegroundClient(args) {
59868
60823
  }
59869
60824
  };
59870
60825
  const cleanupOnSignal = () => {
60826
+ fetchAbort.abort();
59871
60827
  app.unmount();
59872
60828
  clearScrollReserve();
59873
60829
  process.exit(0);
@@ -59881,17 +60837,50 @@ async function runForegroundClient(args) {
59881
60837
  if (!skipClear) clearScrollReserve();
59882
60838
  resolve3();
59883
60839
  };
59884
- fetchCandidatesForUi(socketPath2, envelope).then((candidates) => {
60840
+ const onCandidate = (candidate) => {
60841
+ if (resolved) return;
60842
+ streamed.push(candidate);
60843
+ if (streamed.length === 1) {
60844
+ void appendDebugLog("client", "first candidate received");
60845
+ }
60846
+ app.rerender(
60847
+ buildCandidateElement(
60848
+ annotateCandidates([...streamed], toolInventory),
60849
+ void 0,
60850
+ "arriving"
60851
+ )
60852
+ );
60853
+ };
60854
+ fetchCandidatesForUi(socketPath2, envelope, { signal: fetchAbort.signal, onCandidate }).then((candidates) => {
60855
+ if (resolved) return;
59885
60856
  const displayCandidates = annotateCandidates(candidates, toolInventory);
59886
60857
  void appendDebugLog("client", "candidates received", {
59887
60858
  count: candidates.length,
60859
+ streamed: streamed.length,
59888
60860
  flagged: displayCandidates.filter((c) => c.missingTools !== void 0).length
59889
60861
  });
59890
- app.rerender(buildCandidateElement(displayCandidates));
60862
+ app.rerender(buildCandidateElement(displayCandidates, void 0, "complete"));
59891
60863
  }).catch(async (err) => {
60864
+ if (isAbortError(err)) {
60865
+ void appendDebugLog("client", "fetch aborted");
60866
+ return;
60867
+ }
59892
60868
  const message = err instanceof Error ? err.message : String(err);
59893
60869
  void appendDebugLog("client", "llm request failed", { message });
59894
60870
  if (resolved) return;
60871
+ if (streamed.length > 0) {
60872
+ void appendDebugLog("client", "llm request failed after rows", {
60873
+ count: streamed.length
60874
+ });
60875
+ app.rerender(
60876
+ buildCandidateElement(
60877
+ annotateCandidates([...streamed], toolInventory),
60878
+ void 0,
60879
+ "partial"
60880
+ )
60881
+ );
60882
+ return;
60883
+ }
59895
60884
  resolved = true;
59896
60885
  takeover?.clearNow();
59897
60886
  const errorMsg = formatFifoError(message);
@@ -59945,6 +60934,8 @@ function startDaemonServer(socketPath2) {
59945
60934
  const MAX_BUF_BYTES = 256 * 1024;
59946
60935
  const server = net3.createServer((socket) => {
59947
60936
  let buf = "";
60937
+ const connectionAbort = new AbortController();
60938
+ socket.setEncoding("utf8");
59948
60939
  void appendDebugLog("daemon", "socket connected", { socketPath: socketPath2 });
59949
60940
  const writeJson = (payload) => {
59950
60941
  if (socket.destroyed) {
@@ -59954,11 +60945,11 @@ function startDaemonServer(socketPath2) {
59954
60945
  `);
59955
60946
  };
59956
60947
  socket.on("data", (chunk) => {
59957
- if (buf.length + chunk.length > MAX_BUF_BYTES) {
60948
+ if (Buffer.byteLength(buf) + Buffer.byteLength(chunk) > MAX_BUF_BYTES) {
59958
60949
  socket.destroy(new Error("IPC message too large"));
59959
60950
  return;
59960
60951
  }
59961
- buf += chunk.toString();
60952
+ buf += chunk;
59962
60953
  let nl = buf.indexOf("\n");
59963
60954
  while (nl !== -1) {
59964
60955
  const line = buf.slice(0, nl).trim();
@@ -59980,7 +60971,12 @@ function startDaemonServer(socketPath2) {
59980
60971
  void appendDebugLog("daemon", "request received", { kind: req.kind });
59981
60972
  switch (req.kind) {
59982
60973
  case "ping": {
59983
- writeJson({ kind: "pong", fetchCandidates: true, installedTools: true });
60974
+ writeJson({
60975
+ kind: "pong",
60976
+ fetchCandidates: true,
60977
+ installedTools: true,
60978
+ streamCandidates: true
60979
+ });
59984
60980
  void appendDebugLog("daemon", "replied pong");
59985
60981
  break;
59986
60982
  }
@@ -59997,14 +60993,42 @@ function startDaemonServer(socketPath2) {
59997
60993
  }
59998
60994
  case "fetch-candidates": {
59999
60995
  writeJson({ kind: "fetch-accepted" });
60000
- bootstrapBuiltins();
60001
- const adapter = resolveClaudeDefaultAdapter();
60002
- void adapter.fetchCandidates(req.envelope).then((candidates) => {
60996
+ const envelope = req.envelope;
60997
+ let streamedIndex = 0;
60998
+ const onCandidate = req.stream === true ? (candidate) => {
60999
+ const index = streamedIndex++;
61000
+ if (connectionAbort.signal.aborted) {
61001
+ void appendDebugLog("daemon", "candidate dropped", { index });
61002
+ return;
61003
+ }
61004
+ const row = commandCandidateSchema.safeParse(candidate);
61005
+ if (!row.success) {
61006
+ return;
61007
+ }
61008
+ writeJson({ kind: "candidate", candidate: row.data });
61009
+ void appendDebugLog("daemon", "replied candidate", { index });
61010
+ } : void 0;
61011
+ void Promise.resolve().then(() => {
61012
+ bootstrapBuiltins();
61013
+ const adapter = resolveClaudeDefaultAdapter();
61014
+ return adapter.fetchCandidates(envelope, {
61015
+ signal: connectionAbort.signal,
61016
+ onCandidate
61017
+ });
61018
+ }).then((candidates) => {
61019
+ if (connectionAbort.signal.aborted) {
61020
+ void appendDebugLog("daemon", "fetch aborted");
61021
+ return;
61022
+ }
60003
61023
  writeJson({ kind: "candidates", candidates });
60004
61024
  void appendDebugLog("daemon", "replied candidates", {
60005
61025
  count: candidates.length
60006
61026
  });
60007
61027
  }).catch((error43) => {
61028
+ if (connectionAbort.signal.aborted) {
61029
+ void appendDebugLog("daemon", "fetch aborted");
61030
+ return;
61031
+ }
60008
61032
  const message = error43 instanceof Error ? error43.message : String(error43);
60009
61033
  writeJson({ kind: "fetch-error", message });
60010
61034
  void appendDebugLog("daemon", "replied fetch-error", { message });
@@ -60016,6 +61040,9 @@ function startDaemonServer(socketPath2) {
60016
61040
  });
60017
61041
  socket.on("error", () => {
60018
61042
  });
61043
+ socket.on("close", () => {
61044
+ connectionAbort.abort();
61045
+ });
60019
61046
  });
60020
61047
  server.on("error", reject);
60021
61048
  server.listen(socketPath2, () => {
@@ -60026,6 +61053,32 @@ function startDaemonServer(socketPath2) {
60026
61053
  }
60027
61054
 
60028
61055
  // src/cli/commands/daemon.ts
61056
+ function trackConnections(server) {
61057
+ const connections = /* @__PURE__ */ new Set();
61058
+ server.on("connection", (socket) => {
61059
+ connections.add(socket);
61060
+ socket.once("close", () => {
61061
+ connections.delete(socket);
61062
+ });
61063
+ });
61064
+ return connections;
61065
+ }
61066
+ function shutdownDaemon(server, connections, options = {}) {
61067
+ const exit = options.exit ?? (() => process.exit(0));
61068
+ const graceMs = options.graceMs ?? SIGKILL_GRACE_MS + 100;
61069
+ disablePrewarm();
61070
+ const inFlight = connections.size;
61071
+ server.close(() => {
61072
+ if (inFlight === 0) {
61073
+ exit();
61074
+ return;
61075
+ }
61076
+ setTimeout(exit, graceMs);
61077
+ });
61078
+ for (const socket of connections) {
61079
+ socket.destroy();
61080
+ }
61081
+ }
60029
61082
  async function daemonCommand(options) {
60030
61083
  const sock = options.socket ?? socketPath();
60031
61084
  void appendDebugLog("daemon", "command start", { socket: sock, ensure: options.ensure });
@@ -60035,12 +61088,12 @@ async function daemonCommand(options) {
60035
61088
  return;
60036
61089
  }
60037
61090
  const server = await startDaemonServer(sock);
61091
+ const connections = trackConnections(server);
60038
61092
  void appendDebugLog("daemon", "server started", { socket: sock });
61093
+ enablePrewarm();
60039
61094
  const shutdown = () => {
60040
- void appendDebugLog("daemon", "shutdown", { socket: sock });
60041
- server.close(() => {
60042
- process.exit(0);
60043
- });
61095
+ void appendDebugLog("daemon", "shutdown", { socket: sock, inFlight: connections.size });
61096
+ shutdownDaemon(server, connections);
60044
61097
  };
60045
61098
  process.once("SIGTERM", shutdown);
60046
61099
  process.once("SIGINT", shutdown);
@@ -60129,6 +61182,7 @@ async function main(argv = process.argv.slice(2)) {
60129
61182
  const requestFile = requiredOption("--request-file", options.requestFile);
60130
61183
  const resultFile = requiredOption("--result-file", options.resultFile);
60131
61184
  await clientCommand({ requestFile, resultFile, resultMode: options.resultMode });
61185
+ process.exit(process.exitCode ?? 0);
60132
61186
  });
60133
61187
  cli.command(
60134
61188
  "init <shell>",