@corbat-tech/coco 2.27.2 → 2.27.3

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/index.js CHANGED
@@ -791,8 +791,8 @@ async function requestDeviceCode(provider) {
791
791
  }
792
792
  const contentType = response.headers.get("content-type") || "";
793
793
  if (!contentType.includes("application/json")) {
794
- const text14 = await response.text();
795
- if (text14.includes("<!DOCTYPE") || text14.includes("<html")) {
794
+ const text15 = await response.text();
795
+ if (text15.includes("<!DOCTYPE") || text15.includes("<html")) {
796
796
  throw new Error(
797
797
  "OAuth service returned HTML instead of JSON.\n The service may be temporarily unavailable.\n Please use an API key instead, or try again later."
798
798
  );
@@ -3377,25 +3377,25 @@ var init_anthropic = __esm({
3377
3377
  *
3378
3378
  * This heuristic analyzes the text to provide a better estimate.
3379
3379
  */
3380
- countTokens(text14) {
3381
- if (!text14) return 0;
3380
+ countTokens(text15) {
3381
+ if (!text15) return 0;
3382
3382
  const codePatterns = /[{}[\]();=<>!&|+\-*/]/g;
3383
3383
  const whitespacePattern = /\s/g;
3384
3384
  const wordPattern = /\b\w+\b/g;
3385
- const codeChars = (text14.match(codePatterns) || []).length;
3386
- const whitespace = (text14.match(whitespacePattern) || []).length;
3387
- const words = (text14.match(wordPattern) || []).length;
3388
- const isCodeLike = codeChars > text14.length * 0.05;
3385
+ const codeChars = (text15.match(codePatterns) || []).length;
3386
+ const whitespace = (text15.match(whitespacePattern) || []).length;
3387
+ const words = (text15.match(wordPattern) || []).length;
3388
+ const isCodeLike = codeChars > text15.length * 0.05;
3389
3389
  let charsPerToken;
3390
3390
  if (isCodeLike) {
3391
3391
  charsPerToken = 3.5;
3392
- } else if (whitespace > text14.length * 0.3) {
3392
+ } else if (whitespace > text15.length * 0.3) {
3393
3393
  charsPerToken = 5;
3394
3394
  } else {
3395
3395
  charsPerToken = 4.5;
3396
3396
  }
3397
3397
  const wordBasedEstimate = words * 1.3;
3398
- const charBasedEstimate = text14.length / charsPerToken;
3398
+ const charBasedEstimate = text15.length / charsPerToken;
3399
3399
  return Math.ceil((wordBasedEstimate + charBasedEstimate) / 2);
3400
3400
  }
3401
3401
  /**
@@ -3444,8 +3444,8 @@ var init_anthropic = __esm({
3444
3444
  const systemMsg = messages.find((m) => m.role === "system");
3445
3445
  if (!systemMsg) return void 0;
3446
3446
  if (typeof systemMsg.content === "string") return systemMsg.content;
3447
- const text14 = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
3448
- return text14 || void 0;
3447
+ const text15 = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
3448
+ return text15 || void 0;
3449
3449
  }
3450
3450
  /**
3451
3451
  * Convert messages to Anthropic format
@@ -3633,15 +3633,15 @@ var init_tool_call_normalizer = __esm({
3633
3633
  if (delta.function?.name) {
3634
3634
  builder.name = delta.function.name;
3635
3635
  }
3636
- const text14 = delta.function?.arguments ?? "";
3637
- if (!text14) return { started };
3638
- builder.arguments += text14;
3636
+ const text15 = delta.function?.arguments ?? "";
3637
+ if (!text15) return { started };
3638
+ builder.arguments += text15;
3639
3639
  return {
3640
3640
  started,
3641
3641
  argumentDelta: {
3642
3642
  id: builder.id,
3643
3643
  name: builder.name,
3644
- text: text14
3644
+ text: text15
3645
3645
  }
3646
3646
  };
3647
3647
  }
@@ -4230,23 +4230,23 @@ var init_openai = __esm({
4230
4230
  * For accurate counting, use the model's native tokenizer.
4231
4231
  * This heuristic provides a reasonable estimate without dependencies.
4232
4232
  */
4233
- countTokens(text14) {
4234
- if (!text14) return 0;
4233
+ countTokens(text15) {
4234
+ if (!text15) return 0;
4235
4235
  const codePatterns = /[{}[\]();=<>!&|+\-*/]/g;
4236
4236
  const whitespacePattern = /\s/g;
4237
4237
  const wordPattern = /\b\w+\b/g;
4238
4238
  const nonAsciiPattern = /[^\x00-\x7F]/g;
4239
- const codeChars = (text14.match(codePatterns) || []).length;
4240
- const whitespace = (text14.match(whitespacePattern) || []).length;
4241
- const words = (text14.match(wordPattern) || []).length;
4242
- const nonAscii = (text14.match(nonAsciiPattern) || []).length;
4243
- const isCodeLike = codeChars > text14.length * 0.05;
4239
+ const codeChars = (text15.match(codePatterns) || []).length;
4240
+ const whitespace = (text15.match(whitespacePattern) || []).length;
4241
+ const words = (text15.match(wordPattern) || []).length;
4242
+ const nonAscii = (text15.match(nonAsciiPattern) || []).length;
4243
+ const isCodeLike = codeChars > text15.length * 0.05;
4244
4244
  const isLocal = this.isLocalModel();
4245
4245
  let charsPerToken;
4246
4246
  if (isLocal) {
4247
4247
  if (isCodeLike) {
4248
4248
  charsPerToken = 3.2;
4249
- } else if (nonAscii > text14.length * 0.1) {
4249
+ } else if (nonAscii > text15.length * 0.1) {
4250
4250
  charsPerToken = 2;
4251
4251
  } else {
4252
4252
  charsPerToken = 3.5;
@@ -4254,7 +4254,7 @@ var init_openai = __esm({
4254
4254
  } else {
4255
4255
  if (isCodeLike) {
4256
4256
  charsPerToken = 3.3;
4257
- } else if (whitespace > text14.length * 0.3) {
4257
+ } else if (whitespace > text15.length * 0.3) {
4258
4258
  charsPerToken = 4.5;
4259
4259
  } else {
4260
4260
  charsPerToken = 4;
@@ -4262,7 +4262,7 @@ var init_openai = __esm({
4262
4262
  }
4263
4263
  const tokensPerWord = isLocal ? 1.4 : 1.3;
4264
4264
  const wordBasedEstimate = words * tokensPerWord;
4265
- const charBasedEstimate = text14.length / charsPerToken;
4265
+ const charBasedEstimate = text15.length / charsPerToken;
4266
4266
  const weight = isCodeLike ? 0.7 : 0.5;
4267
4267
  return Math.ceil(charBasedEstimate * weight + wordBasedEstimate * (1 - weight));
4268
4268
  }
@@ -5043,8 +5043,8 @@ var init_codex = __esm({
5043
5043
  * Count tokens in text (approximate)
5044
5044
  * Uses GPT-4 approximation: ~4 chars per token
5045
5045
  */
5046
- countTokens(text14) {
5047
- return Math.ceil(text14.length / 4);
5046
+ countTokens(text15) {
5047
+ return Math.ceil(text15.length / 4);
5048
5048
  }
5049
5049
  /**
5050
5050
  * Check if provider is available (has valid OAuth tokens)
@@ -5712,9 +5712,9 @@ var init_copilot2 = __esm({
5712
5712
  /**
5713
5713
  * Count tokens (approximate — Copilot models vary in tokenizer)
5714
5714
  */
5715
- countTokens(text14) {
5716
- if (!text14) return 0;
5717
- return Math.ceil(text14.length / 3.5);
5715
+ countTokens(text15) {
5716
+ if (!text15) return 0;
5717
+ return Math.ceil(text15.length / 3.5);
5718
5718
  }
5719
5719
  /**
5720
5720
  * Get context window for the current model
@@ -5812,9 +5812,9 @@ var init_gemini = __esm({
5812
5812
  });
5813
5813
  let streamStopReason = "end_turn";
5814
5814
  for await (const chunk of stream) {
5815
- const text14 = chunk.text;
5816
- if (text14) {
5817
- yield { type: "text", text: text14 };
5815
+ const text15 = chunk.text;
5816
+ if (text15) {
5817
+ yield { type: "text", text: text15 };
5818
5818
  }
5819
5819
  const finishReason = chunk.candidates?.[0]?.finishReason;
5820
5820
  if (finishReason) {
@@ -5838,9 +5838,9 @@ var init_gemini = __esm({
5838
5838
  let fallbackToolCounter = 0;
5839
5839
  const emittedToolIds = /* @__PURE__ */ new Set();
5840
5840
  for await (const chunk of stream) {
5841
- const text14 = chunk.text;
5842
- if (text14) {
5843
- yield { type: "text", text: text14 };
5841
+ const text15 = chunk.text;
5842
+ if (text15) {
5843
+ yield { type: "text", text: text15 };
5844
5844
  }
5845
5845
  const functionCalls = this.extractFunctionCalls(chunk);
5846
5846
  for (const functionCall of functionCalls) {
@@ -5876,9 +5876,9 @@ var init_gemini = __esm({
5876
5876
  throw this.handleError(error);
5877
5877
  }
5878
5878
  }
5879
- countTokens(text14) {
5880
- if (!text14) return 0;
5881
- return Math.ceil(text14.length / 3.5);
5879
+ countTokens(text15) {
5880
+ if (!text15) return 0;
5881
+ return Math.ceil(text15.length / 3.5);
5882
5882
  }
5883
5883
  getContextWindow() {
5884
5884
  const model = this.config.model ?? DEFAULT_MODEL5;
@@ -5926,8 +5926,8 @@ var init_gemini = __esm({
5926
5926
  const systemMsg = messages.find((m) => m.role === "system");
5927
5927
  if (!systemMsg) return void 0;
5928
5928
  if (typeof systemMsg.content === "string") return systemMsg.content;
5929
- const text14 = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
5930
- return text14 || void 0;
5929
+ const text15 = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
5930
+ return text15 || void 0;
5931
5931
  }
5932
5932
  convertContents(messages) {
5933
5933
  const toolNameByUseId = this.buildToolUseNameMap(messages);
@@ -6224,8 +6224,8 @@ var init_vertex = __esm({
6224
6224
  }
6225
6225
  yield { type: "done", stopReason };
6226
6226
  }
6227
- countTokens(text14) {
6228
- return Math.ceil(text14.length / 4);
6227
+ countTokens(text15) {
6228
+ return Math.ceil(text15.length / 4);
6229
6229
  }
6230
6230
  getContextWindow() {
6231
6231
  return CONTEXT_WINDOWS6[this.config.model ?? DEFAULT_MODEL6] ?? 1048576;
@@ -6287,8 +6287,8 @@ var init_vertex = __esm({
6287
6287
  const systemMsg = messages.find((m) => m.role === "system");
6288
6288
  if (!systemMsg) return void 0;
6289
6289
  if (typeof systemMsg.content === "string") return systemMsg.content;
6290
- const text14 = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
6291
- return text14 || void 0;
6290
+ const text15 = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
6291
+ return text15 || void 0;
6292
6292
  }
6293
6293
  buildToolUseNameMap(messages) {
6294
6294
  const map = /* @__PURE__ */ new Map();
@@ -6465,10 +6465,10 @@ var init_vertex = __esm({
6465
6465
  }
6466
6466
  parseResponse(response, model) {
6467
6467
  const candidate = response.candidates?.[0];
6468
- const text14 = (candidate?.content?.parts ?? []).filter((part) => part.text).map((part) => part.text).join("");
6468
+ const text15 = (candidate?.content?.parts ?? []).filter((part) => part.text).map((part) => part.text).join("");
6469
6469
  return {
6470
6470
  id: `vertex-${Date.now()}`,
6471
- content: text14,
6471
+ content: text15,
6472
6472
  stopReason: this.mapFinishReason(candidate?.finishReason),
6473
6473
  usage: {
6474
6474
  inputTokens: response.usageMetadata?.promptTokenCount ?? 0,
@@ -6854,7 +6854,7 @@ var init_fallback = __esm({
6854
6854
  */
6855
6855
  async initialize(config) {
6856
6856
  const results = await Promise.allSettled(
6857
- this.providers.map((p45) => p45.provider.initialize(config))
6857
+ this.providers.map((p46) => p46.provider.initialize(config))
6858
6858
  );
6859
6859
  const anySuccess = results.some((r) => r.status === "fulfilled");
6860
6860
  if (!anySuccess) {
@@ -6951,9 +6951,9 @@ var init_fallback = __esm({
6951
6951
  * @param text - Text to count tokens for
6952
6952
  * @returns Estimated token count
6953
6953
  */
6954
- countTokens(text14) {
6954
+ countTokens(text15) {
6955
6955
  const provider = this.getCurrentProvider();
6956
- return provider.provider.countTokens(text14);
6956
+ return provider.provider.countTokens(text15);
6957
6957
  }
6958
6958
  /**
6959
6959
  * Get context window from current provider
@@ -6976,11 +6976,11 @@ var init_fallback = __esm({
6976
6976
  */
6977
6977
  async isAvailable() {
6978
6978
  const results = await Promise.all(
6979
- this.providers.map(async (p45) => {
6980
- if (p45.breaker.isOpen()) {
6979
+ this.providers.map(async (p46) => {
6980
+ if (p46.breaker.isOpen()) {
6981
6981
  return false;
6982
6982
  }
6983
- return p45.provider.isAvailable();
6983
+ return p46.provider.isAvailable();
6984
6984
  })
6985
6985
  );
6986
6986
  return results.some((available) => available);
@@ -7011,10 +7011,10 @@ var init_fallback = __esm({
7011
7011
  * @returns Array of provider status objects
7012
7012
  */
7013
7013
  getCircuitStatus() {
7014
- return this.providers.map((p45) => ({
7015
- providerId: p45.provider.id,
7016
- state: p45.breaker.getState(),
7017
- failureCount: p45.breaker.getFailureCount()
7014
+ return this.providers.map((p46) => ({
7015
+ providerId: p46.provider.id,
7016
+ state: p46.breaker.getState(),
7017
+ failureCount: p46.breaker.getFailureCount()
7018
7018
  }));
7019
7019
  }
7020
7020
  /**
@@ -7024,8 +7024,8 @@ var init_fallback = __esm({
7024
7024
  * previously failing providers to be tried again.
7025
7025
  */
7026
7026
  resetCircuits() {
7027
- for (const p45 of this.providers) {
7028
- p45.breaker.reset();
7027
+ for (const p46 of this.providers) {
7028
+ p46.breaker.reset();
7029
7029
  }
7030
7030
  }
7031
7031
  /**
@@ -7169,8 +7169,8 @@ var init_resilient = __esm({
7169
7169
  async *streamWithTools(messages, options) {
7170
7170
  yield* this.streamWithPolicy(() => this.provider.streamWithTools(messages, options));
7171
7171
  }
7172
- countTokens(text14) {
7173
- return this.provider.countTokens(text14);
7172
+ countTokens(text15) {
7173
+ return this.provider.countTokens(text15);
7174
7174
  }
7175
7175
  getContextWindow() {
7176
7176
  return this.provider.getContextWindow();
@@ -8483,8 +8483,8 @@ function tokenOverlap(queryTokens, targetTokens) {
8483
8483
  }
8484
8484
  return hits / queryTokens.length;
8485
8485
  }
8486
- function tokenize(text14) {
8487
- return text14.toLowerCase().replace(/[^a-z0-9\s-]/g, " ").split(/[\s-]+/).filter((word) => word.length > 1 && !STOP_WORDS.has(word)).map(stem);
8486
+ function tokenize(text15) {
8487
+ return text15.toLowerCase().replace(/[^a-z0-9\s-]/g, " ").split(/[\s-]+/).filter((word) => word.length > 1 && !STOP_WORDS.has(word)).map(stem);
8488
8488
  }
8489
8489
  function stem(word) {
8490
8490
  if (word.length < 4) return word;
@@ -9581,8 +9581,8 @@ ${tail}`
9581
9581
  estimateTokens(messages, provider) {
9582
9582
  let total = 0;
9583
9583
  for (const message of messages) {
9584
- const text14 = this.extractTextContent(message.content);
9585
- total += provider.countTokens(text14);
9584
+ const text15 = this.extractTextContent(message.content);
9585
+ total += provider.countTokens(text15);
9586
9586
  }
9587
9587
  return total;
9588
9588
  }
@@ -11616,7 +11616,7 @@ function humanizeError(message, toolName) {
11616
11616
  return msg;
11617
11617
  }
11618
11618
  function looksLikeTechnicalJargon(message) {
11619
- return JARGON_PATTERNS.some((p45) => p45.test(message));
11619
+ return JARGON_PATTERNS.some((p46) => p46.test(message));
11620
11620
  }
11621
11621
  async function humanizeWithLLM(errorMessage, toolName, provider) {
11622
11622
  const prompt = [
@@ -12377,9 +12377,9 @@ function renderFileBlock(file, opts) {
12377
12377
  );
12378
12378
  }
12379
12379
  const pairs = pairAdjacentLines(hunk.lines);
12380
- const pairedDeleteIndices = new Set(pairs.map((p45) => p45.deleteIdx));
12381
- const pairedAddIndices = new Set(pairs.map((p45) => p45.addIdx));
12382
- const pairByAdd = new Map(pairs.map((p45) => [p45.addIdx, p45.deleteIdx]));
12380
+ const pairedDeleteIndices = new Set(pairs.map((p46) => p46.deleteIdx));
12381
+ const pairedAddIndices = new Set(pairs.map((p46) => p46.addIdx));
12382
+ const pairByAdd = new Map(pairs.map((p46) => [p46.addIdx, p46.deleteIdx]));
12383
12383
  const wordHighlights = /* @__PURE__ */ new Map();
12384
12384
  for (const pair of pairs) {
12385
12385
  const delLine = hunk.lines[pair.deleteIdx];
@@ -12835,10 +12835,10 @@ var init_coverage = __esm({
12835
12835
  join(this.projectPath, ".coverage", "coverage-summary.json"),
12836
12836
  join(this.projectPath, "coverage", "lcov-report", "coverage-summary.json")
12837
12837
  ];
12838
- for (const p45 of possiblePaths) {
12838
+ for (const p46 of possiblePaths) {
12839
12839
  try {
12840
- await access(p45, constants.R_OK);
12841
- const content = await readFile(p45, "utf-8");
12840
+ await access(p46, constants.R_OK);
12841
+ const content = await readFile(p46, "utf-8");
12842
12842
  const report = JSON.parse(content);
12843
12843
  return parseCoverageSummary(report);
12844
12844
  } catch {
@@ -18672,15 +18672,15 @@ ${message}
18672
18672
  let stdoutBuffer = "";
18673
18673
  let stderrBuffer = "";
18674
18674
  subprocess.stdout?.on("data", (chunk) => {
18675
- const text14 = chunk.toString();
18676
- stdoutBuffer += text14;
18677
- process.stdout.write(text14);
18675
+ const text15 = chunk.toString();
18676
+ stdoutBuffer += text15;
18677
+ process.stdout.write(text15);
18678
18678
  heartbeat.activity();
18679
18679
  });
18680
18680
  subprocess.stderr?.on("data", (chunk) => {
18681
- const text14 = chunk.toString();
18682
- stderrBuffer += text14;
18683
- process.stderr.write(text14);
18681
+ const text15 = chunk.toString();
18682
+ stderrBuffer += text15;
18683
+ process.stderr.write(text15);
18684
18684
  heartbeat.activity();
18685
18685
  });
18686
18686
  const result = await subprocess;
@@ -20641,11 +20641,11 @@ function isBlockedPath(absolute) {
20641
20641
  return void 0;
20642
20642
  }
20643
20643
  function isBlockedExecFile(filePath) {
20644
- return BLOCKED_EXEC_PATTERNS.some((p45) => p45.test(filePath));
20644
+ return BLOCKED_EXEC_PATTERNS.some((p46) => p46.test(filePath));
20645
20645
  }
20646
20646
  function hasDangerousArgs(args) {
20647
20647
  const joined = args.join(" ");
20648
- return DANGEROUS_ARG_PATTERNS.some((p45) => p45.test(joined));
20648
+ return DANGEROUS_ARG_PATTERNS.some((p46) => p46.test(joined));
20649
20649
  }
20650
20650
  function getInterpreter(ext) {
20651
20651
  return INTERPRETER_MAP[ext.toLowerCase()];
@@ -23146,22 +23146,22 @@ var init_types7 = __esm({
23146
23146
  });
23147
23147
 
23148
23148
  // src/cli/repl/interruptions/classifier.ts
23149
- function matchPatterns(text14, patterns) {
23149
+ function matchPatterns(text15, patterns) {
23150
23150
  for (let i = 0; i < patterns.length; i++) {
23151
- if (patterns[i].test(text14)) {
23151
+ if (patterns[i].test(text15)) {
23152
23152
  return 1 - i * 0.1;
23153
23153
  }
23154
23154
  }
23155
23155
  return 0;
23156
23156
  }
23157
23157
  function classifyInterruption(message) {
23158
- const text14 = message.text;
23159
- const abortConf = matchPatterns(text14, ABORT_PATTERNS);
23160
- const modifyConf = matchPatterns(text14, MODIFY_PATTERNS);
23161
- const correctConf = matchPatterns(text14, CORRECT_PATTERNS);
23158
+ const text15 = message.text;
23159
+ const abortConf = matchPatterns(text15, ABORT_PATTERNS);
23160
+ const modifyConf = matchPatterns(text15, MODIFY_PATTERNS);
23161
+ const correctConf = matchPatterns(text15, CORRECT_PATTERNS);
23162
23162
  if (abortConf > 0 && abortConf >= modifyConf && abortConf >= correctConf) {
23163
23163
  return {
23164
- text: text14,
23164
+ text: text15,
23165
23165
  type: "abort" /* Abort */,
23166
23166
  confidence: Math.min(1, abortConf),
23167
23167
  timestamp: message.timestamp
@@ -23169,7 +23169,7 @@ function classifyInterruption(message) {
23169
23169
  }
23170
23170
  if (modifyConf > 0 && modifyConf >= correctConf) {
23171
23171
  return {
23172
- text: text14,
23172
+ text: text15,
23173
23173
  type: "modify" /* Modify */,
23174
23174
  confidence: Math.min(1, modifyConf),
23175
23175
  timestamp: message.timestamp
@@ -23177,14 +23177,14 @@ function classifyInterruption(message) {
23177
23177
  }
23178
23178
  if (correctConf > 0) {
23179
23179
  return {
23180
- text: text14,
23180
+ text: text15,
23181
23181
  type: "correct" /* Correct */,
23182
23182
  confidence: Math.min(1, correctConf),
23183
23183
  timestamp: message.timestamp
23184
23184
  };
23185
23185
  }
23186
23186
  return {
23187
- text: text14,
23187
+ text: text15,
23188
23188
  type: "info" /* Info */,
23189
23189
  confidence: 0.5,
23190
23190
  timestamp: message.timestamp
@@ -25692,10 +25692,10 @@ function inferTargetUsers(session) {
25692
25692
  /(?:for|by)\s+(developers?|users?|administrators?|customers?)/gi,
25693
25693
  /(developers?|users?|administrators?|customers?)\s+(?:can|will|should)/gi
25694
25694
  ];
25695
- const text14 = session.requirements.map((r) => r.description).join(" ");
25695
+ const text15 = session.requirements.map((r) => r.description).join(" ");
25696
25696
  for (const pattern of userPatterns) {
25697
25697
  let match;
25698
- while ((match = pattern.exec(text14)) !== null) {
25698
+ while ((match = pattern.exec(text15)) !== null) {
25699
25699
  const user = match[1]?.toLowerCase();
25700
25700
  if (user && !users.includes(user)) {
25701
25701
  users.push(user);
@@ -25708,13 +25708,13 @@ function inferTargetUsers(session) {
25708
25708
  return users;
25709
25709
  }
25710
25710
  function inferProjectType(session) {
25711
- const text14 = session.initialInput.toLowerCase();
25712
- if (text14.includes("cli") || text14.includes("command line")) return "cli";
25713
- if (text14.includes("api") || text14.includes("rest") || text14.includes("graphql")) return "api";
25714
- if (text14.includes("web app") || text14.includes("frontend")) return "web_app";
25715
- if (text14.includes("library") || text14.includes("package")) return "library";
25716
- if (text14.includes("service") || text14.includes("daemon")) return "service";
25717
- if (text14.includes("full stack") || text14.includes("fullstack")) return "full_stack";
25711
+ const text15 = session.initialInput.toLowerCase();
25712
+ if (text15.includes("cli") || text15.includes("command line")) return "cli";
25713
+ if (text15.includes("api") || text15.includes("rest") || text15.includes("graphql")) return "api";
25714
+ if (text15.includes("web app") || text15.includes("frontend")) return "web_app";
25715
+ if (text15.includes("library") || text15.includes("package")) return "library";
25716
+ if (text15.includes("service") || text15.includes("daemon")) return "service";
25717
+ if (text15.includes("full stack") || text15.includes("fullstack")) return "full_stack";
25718
25718
  return "unknown";
25719
25719
  }
25720
25720
  function assessComplexity(session) {
@@ -30095,7 +30095,7 @@ function getProviderDefinition(type) {
30095
30095
  return PROVIDER_DEFINITIONS[type];
30096
30096
  }
30097
30097
  function getAllProviders() {
30098
- return Object.values(PROVIDER_DEFINITIONS).filter((p45) => !p45.internal);
30098
+ return Object.values(PROVIDER_DEFINITIONS).filter((p46) => !p46.internal);
30099
30099
  }
30100
30100
  function getRecommendedModel(type) {
30101
30101
  const provider = PROVIDER_DEFINITIONS[type];
@@ -30116,20 +30116,20 @@ function hasLocalProviderConfig(type) {
30116
30116
  return process.env["COCO_PROVIDER"] === "ollama" || !!process.env["OLLAMA_MODEL"] || !!process.env["OLLAMA_BASE_URL"];
30117
30117
  }
30118
30118
  function getConfiguredProviders() {
30119
- return getAllProviders().filter((p45) => {
30120
- if (p45.id === "copilot") {
30119
+ return getAllProviders().filter((p46) => {
30120
+ if (p46.id === "copilot") {
30121
30121
  return !!process.env["GITHUB_TOKEN"] || !!process.env["GH_TOKEN"] || hasCopilotCredentials();
30122
30122
  }
30123
- if (p45.id === "openai") {
30124
- return !!process.env[p45.envVar] || !!process.env["OPENAI_CODEX_TOKEN"] || !!process.env["OPENAI_ACCESS_TOKEN"];
30123
+ if (p46.id === "openai") {
30124
+ return !!process.env[p46.envVar] || !!process.env["OPENAI_CODEX_TOKEN"] || !!process.env["OPENAI_ACCESS_TOKEN"];
30125
30125
  }
30126
- if (p45.id === "lmstudio" || p45.id === "ollama") {
30127
- return hasLocalProviderConfig(p45.id);
30126
+ if (p46.id === "lmstudio" || p46.id === "ollama") {
30127
+ return hasLocalProviderConfig(p46.id);
30128
30128
  }
30129
- if (p45.id === "vertex") {
30129
+ if (p46.id === "vertex") {
30130
30130
  return !!(process.env["VERTEX_API_KEY"] ?? process.env["GOOGLE_API_KEY"] ?? process.env["VERTEX_PROJECT"] ?? process.env["GOOGLE_CLOUD_PROJECT"] ?? process.env["GCLOUD_PROJECT"]);
30131
30131
  }
30132
- return !!process.env[p45.envVar];
30132
+ return !!process.env[p46.envVar];
30133
30133
  });
30134
30134
  }
30135
30135
  function isProviderConfigured(type) {
@@ -31264,8 +31264,8 @@ ${suggestionsHtml}
31264
31264
  return filePath;
31265
31265
  }
31266
31266
  // ── Private helpers ───────────────────────────────────────────────────────
31267
- htmlEscape(text14) {
31268
- return text14.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
31267
+ htmlEscape(text15) {
31268
+ return text15.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
31269
31269
  }
31270
31270
  markdownIssue(issue) {
31271
31271
  const severity = issue.severity === "critical" ? "\u{1F534}" : issue.severity === "major" ? "\u{1F7E1}" : "\u{1F535}";
@@ -31787,12 +31787,12 @@ Return only JSON: { "score": <number 1-10>, "reasoning": "<brief explanation>" }
31787
31787
  }
31788
31788
  return classifyFeatureHeuristic(feature);
31789
31789
  }
31790
- function extractJsonScore(text14) {
31790
+ function extractJsonScore(text15) {
31791
31791
  try {
31792
- const stripped = text14.replace(/^```(?:json)?\s*\n?/, "").replace(/\n?```\s*$/, "").trim();
31792
+ const stripped = text15.replace(/^```(?:json)?\s*\n?/, "").replace(/\n?```\s*$/, "").trim();
31793
31793
  return JSON.parse(stripped);
31794
31794
  } catch {
31795
- const match = text14.match(/\{[\s\S]*?\}/);
31795
+ const match = text15.match(/\{[\s\S]*?\}/);
31796
31796
  if (match) {
31797
31797
  try {
31798
31798
  return JSON.parse(match[0]);
@@ -32016,25 +32016,25 @@ Rules:
32016
32016
  }
32017
32017
  }
32018
32018
  async function defaultPromptHandler(q) {
32019
- const p45 = await import('@clack/prompts');
32019
+ const p46 = await import('@clack/prompts');
32020
32020
  if (q.options && q.options.length > 0) {
32021
- const result = await p45.select({
32021
+ const result = await p46.select({
32022
32022
  message: q.question,
32023
32023
  options: [
32024
32024
  ...q.options.map((o) => ({ value: o, label: o })),
32025
32025
  { value: q.assumedAnswer, label: `${q.assumedAnswer} (default)` }
32026
32026
  ]
32027
32027
  });
32028
- if (p45.isCancel(result)) {
32028
+ if (p46.isCancel(result)) {
32029
32029
  return q.assumedAnswer;
32030
32030
  }
32031
32031
  return result;
32032
32032
  } else {
32033
- const result = await p45.text({
32033
+ const result = await p46.text({
32034
32034
  message: q.question,
32035
32035
  placeholder: q.assumedAnswer
32036
32036
  });
32037
- if (p45.isCancel(result) || !result) {
32037
+ if (p46.isCancel(result) || !result) {
32038
32038
  return q.assumedAnswer;
32039
32039
  }
32040
32040
  return result;
@@ -33005,12 +33005,12 @@ function computeGlobalScore(results) {
33005
33005
  const total = results.reduce((sum, r) => sum + r.reviewScore, 0);
33006
33006
  return Math.round(total / results.length);
33007
33007
  }
33008
- function extractJson(text14) {
33008
+ function extractJson(text15) {
33009
33009
  try {
33010
- const stripped = text14.replace(/^```(?:json)?\s*\n?/, "").replace(/\n?```\s*$/, "").trim();
33010
+ const stripped = text15.replace(/^```(?:json)?\s*\n?/, "").replace(/\n?```\s*$/, "").trim();
33011
33011
  return JSON.parse(stripped);
33012
33012
  } catch {
33013
- const match = text14.match(/\{[\s\S]*\}/);
33013
+ const match = text15.match(/\{[\s\S]*\}/);
33014
33014
  if (match) {
33015
33015
  try {
33016
33016
  return JSON.parse(match[0]);
@@ -33357,7 +33357,7 @@ init_env();
33357
33357
 
33358
33358
  // src/cli/repl/quality-loop.ts
33359
33359
  init_paths();
33360
- var qualityLoopEnabled = true;
33360
+ var qualityLoopEnabled = false;
33361
33361
  var hintShown = false;
33362
33362
  function isQualityLoop() {
33363
33363
  return qualityLoopEnabled;
@@ -33395,7 +33395,7 @@ function looksLikeFeatureRequest(input) {
33395
33395
  return featureKeywords.some((re) => re.test(trimmed));
33396
33396
  }
33397
33397
  function formatQualityLoopHint() {
33398
- return chalk.dim(" tip: ") + chalk.magenta("/quality") + chalk.dim(" enables auto-test & iterate until quality converges");
33398
+ return chalk.dim(" tip: ") + chalk.magenta("/quality on") + chalk.dim(" enables Coco quality mode: auto-test, self-review, and iterate until robust");
33399
33399
  }
33400
33400
  function formatQualityResult(result) {
33401
33401
  const lines = [];
@@ -33439,7 +33439,8 @@ async function loadQualityLoopPreference() {
33439
33439
  }
33440
33440
  } catch {
33441
33441
  }
33442
- return true;
33442
+ qualityLoopEnabled = false;
33443
+ return false;
33443
33444
  }
33444
33445
  async function saveQualityLoopPreference(enabled) {
33445
33446
  try {
@@ -33569,7 +33570,7 @@ async function renderStartupPanel(session, gitCtx, mcpServers = []) {
33569
33570
  if (gitCtx) {
33570
33571
  console.log(` ${formatGitLine(gitCtx)}`);
33571
33572
  }
33572
- const cocoStatus = isQualityLoop() ? chalk.magenta(" \u{1F504} quality mode: ") + chalk.green.bold("on") + chalk.dim(" \u2014 iterates until quality \u2265 85. /quality to disable") : chalk.dim(" \u{1F4A1} /quality on \u2014 enable auto-test & quality iteration");
33573
+ const cocoStatus = isQualityLoop() ? chalk.magenta(" \u{1F504} quality mode: ") + chalk.green.bold("on") + chalk.dim(" \u2014 iterates until quality \u2265 85. /quality to disable") : chalk.dim(" \u{1F4A1} quality mode is Coco's edge for robust code. Enable with /quality on");
33573
33574
  console.log(cocoStatus);
33574
33575
  const skillTotal = session.skillRegistry?.size ?? 0;
33575
33576
  const hasSomething = skillTotal > 0 || mcpServers.length > 0;
@@ -33995,7 +33996,7 @@ async function runOnboardingV2() {
33995
33996
  console.log(chalk.magenta(" \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F"));
33996
33997
  console.log();
33997
33998
  p26.log.info(
33998
- `Found ${configuredProviders.length} configured provider(s): ${configuredProviders.map((p45) => p45.emoji + " " + p45.name).join(", ")}`
33999
+ `Found ${configuredProviders.length} configured provider(s): ${configuredProviders.map((p46) => p46.emoji + " " + p46.name).join(", ")}`
33999
34000
  );
34000
34001
  const useExisting = await p26.confirm({
34001
34002
  message: "Use an existing provider?",
@@ -34680,9 +34681,9 @@ async function setupOllamaProvider(port) {
34680
34681
  return setupLocalProvider("ollama", port);
34681
34682
  }
34682
34683
  async function selectExistingProvider(providers) {
34683
- const options = providers.map((p45) => ({
34684
- value: p45.id,
34685
- label: `${p45.emoji} ${p45.name}`,
34684
+ const options = providers.map((p46) => ({
34685
+ value: p46.id,
34686
+ label: `${p46.emoji} ${p46.name}`,
34686
34687
  hint: "Configured"
34687
34688
  }));
34688
34689
  options.push({ value: "__new__", label: "\u2795 Setup new provider", hint: "" });
@@ -35074,7 +35075,7 @@ async function ensureConfiguredV2(config) {
35074
35075
  } catch {
35075
35076
  }
35076
35077
  }
35077
- const preferredProviderDef = providers.find((p45) => p45.id === config.provider.type);
35078
+ const preferredProviderDef = providers.find((p46) => p46.id === config.provider.type);
35078
35079
  const preferredIsLocal = preferredProviderDef?.requiresApiKey === false && preferredProviderDef?.id !== "copilot";
35079
35080
  const preferredHasApiKey = preferredProviderDef ? !!process.env[preferredProviderDef.envVar] : false;
35080
35081
  const preferredHasOpenAIOAuth = preferredProviderDef?.id === "openai" && hasOpenAIOAuthTokens;
@@ -35104,12 +35105,12 @@ async function ensureConfiguredV2(config) {
35104
35105
  preferredUnavailableWasLocal = preferredIsLocal;
35105
35106
  }
35106
35107
  if (!preferredWasConfiguredButUnavailable || !preferredUnavailableWasLocal) {
35107
- const configuredProviders = providers.filter((p45) => {
35108
- if (p45.id === "copilot") return isProviderConfigured();
35109
- if (p45.id === "openai") {
35110
- return hasOpenAIOAuthTokens || !!process.env[p45.envVar];
35108
+ const configuredProviders = providers.filter((p46) => {
35109
+ if (p46.id === "copilot") return isProviderConfigured();
35110
+ if (p46.id === "openai") {
35111
+ return hasOpenAIOAuthTokens || !!process.env[p46.envVar];
35111
35112
  }
35112
- return p45.requiresApiKey === false || !!process.env[p45.envVar];
35113
+ return p46.requiresApiKey === false || !!process.env[p46.envVar];
35113
35114
  });
35114
35115
  for (const prov of configuredProviders) {
35115
35116
  try {
@@ -35182,7 +35183,7 @@ init_auth();
35182
35183
  init_env();
35183
35184
  async function selectProviderInteractively(providers, currentProviderId) {
35184
35185
  return new Promise((resolve4) => {
35185
- let selectedIndex = providers.findIndex((p45) => p45.id === currentProviderId);
35186
+ let selectedIndex = providers.findIndex((p46) => p46.id === currentProviderId);
35186
35187
  if (selectedIndex === -1) selectedIndex = 0;
35187
35188
  let lastTotalLines = 0;
35188
35189
  const clearPrevious = () => {
@@ -35280,12 +35281,12 @@ var providerCommand = {
35280
35281
  `));
35281
35282
  const allProviders2 = getAllProviders();
35282
35283
  const configuredProviders = getConfiguredProviders();
35283
- const providerOptions = allProviders2.map((p45) => ({
35284
- id: p45.id,
35285
- name: p45.name,
35286
- emoji: p45.emoji,
35287
- description: p45.description,
35288
- isConfigured: configuredProviders.some((cp) => cp.id === p45.id)
35284
+ const providerOptions = allProviders2.map((p46) => ({
35285
+ id: p46.id,
35286
+ name: p46.name,
35287
+ emoji: p46.emoji,
35288
+ description: p46.description,
35289
+ isConfigured: configuredProviders.some((cp) => cp.id === p46.id)
35289
35290
  }));
35290
35291
  const selectedProviderId = await selectProviderInteractively(
35291
35292
  providerOptions,
@@ -35300,15 +35301,15 @@ var providerCommand = {
35300
35301
  `));
35301
35302
  return false;
35302
35303
  }
35303
- const newProvider2 = allProviders2.find((p45) => p45.id === selectedProviderId);
35304
+ const newProvider2 = allProviders2.find((p46) => p46.id === selectedProviderId);
35304
35305
  return await switchProvider(newProvider2, session);
35305
35306
  }
35306
35307
  const newProviderId = args[0]?.toLowerCase();
35307
35308
  const allProviders = getAllProviders();
35308
- const newProvider = allProviders.find((p45) => p45.id === newProviderId);
35309
+ const newProvider = allProviders.find((p46) => p46.id === newProviderId);
35309
35310
  if (!newProvider) {
35310
35311
  console.log(chalk.red(`Unknown provider: ${newProviderId}`));
35311
- console.log(chalk.dim(`Available: ${allProviders.map((p45) => p45.id).join(", ")}
35312
+ console.log(chalk.dim(`Available: ${allProviders.map((p46) => p46.id).join(", ")}
35312
35313
  `));
35313
35314
  return false;
35314
35315
  }
@@ -36345,7 +36346,7 @@ async function showTrustStatus(session, trustStore) {
36345
36346
  }
36346
36347
  const level = trustStore.getLevel(projectPath);
36347
36348
  const list = trustStore.list();
36348
- const project = list.find((p45) => p45.path === projectPath);
36349
+ const project = list.find((p46) => p46.path === projectPath);
36349
36350
  p26.log.message("");
36350
36351
  p26.log.message(`\u{1F510} Project Trust Status`);
36351
36352
  p26.log.message(` Path: ${projectPath}`);
@@ -38312,8 +38313,8 @@ var STARTUP_TIMEOUT_MS = 5500;
38312
38313
  var CACHE_DIR = path39__default.join(os4__default.homedir(), ".coco");
38313
38314
  var CACHE_FILE = path39__default.join(CACHE_DIR, "version-check-cache.json");
38314
38315
  function compareVersions(a, b) {
38315
- const partsA = a.replace(/^v/, "").split(".").map((p45) => Number(p45.replace(/-.*$/, "")));
38316
- const partsB = b.replace(/^v/, "").split(".").map((p45) => Number(p45.replace(/-.*$/, "")));
38316
+ const partsA = a.replace(/^v/, "").split(".").map((p46) => Number(p46.replace(/-.*$/, "")));
38317
+ const partsB = b.replace(/^v/, "").split(".").map((p46) => Number(p46.replace(/-.*$/, "")));
38317
38318
  for (let i = 0; i < 3; i++) {
38318
38319
  const numA = partsA[i] ?? 0;
38319
38320
  const numB = partsB[i] ?? 0;
@@ -38437,13 +38438,13 @@ async function checkForUpdatesInteractive() {
38437
38438
  ]);
38438
38439
  clearTimeout(startupTimerId);
38439
38440
  if (!updateInfo) return;
38440
- const p45 = await import('@clack/prompts');
38441
+ const p46 = await import('@clack/prompts');
38441
38442
  printUpdateBanner(updateInfo);
38442
- const answer = await p45.confirm({
38443
+ const answer = await p46.confirm({
38443
38444
  message: "Exit now to update?",
38444
38445
  initialValue: true
38445
38446
  });
38446
- if (!p45.isCancel(answer) && answer) {
38447
+ if (!p46.isCancel(answer) && answer) {
38447
38448
  console.log();
38448
38449
  console.log(chalk.dim(` Running: ${updateInfo.updateCommand}`));
38449
38450
  console.log();
@@ -38572,7 +38573,7 @@ function getClipboardCommand() {
38572
38573
  }
38573
38574
  return null;
38574
38575
  }
38575
- async function copyToClipboard(text14) {
38576
+ async function copyToClipboard(text15) {
38576
38577
  const clipboardCmd = getClipboardCommand();
38577
38578
  if (!clipboardCmd) {
38578
38579
  return false;
@@ -38593,7 +38594,7 @@ async function copyToClipboard(text14) {
38593
38594
  });
38594
38595
  xselProc.on("error", () => resolve4(false));
38595
38596
  xselProc.on("close", (code) => resolve4(code === 0));
38596
- xselProc.stdin.write(text14);
38597
+ xselProc.stdin.write(text15);
38597
38598
  xselProc.stdin.end();
38598
38599
  } catch {
38599
38600
  resolve4(false);
@@ -38609,7 +38610,7 @@ async function copyToClipboard(text14) {
38609
38610
  });
38610
38611
  proc.stdin.on("error", () => {
38611
38612
  });
38612
- proc.stdin.write(text14);
38613
+ proc.stdin.write(text15);
38613
38614
  proc.stdin.end();
38614
38615
  } catch {
38615
38616
  resolve4(false);
@@ -39369,7 +39370,7 @@ async function shouldShowPermissionSuggestion(projectPath = process.cwd()) {
39369
39370
  }
39370
39371
  async function applyRecommendedPermissions(projectPath = process.cwd()) {
39371
39372
  for (const tool of [...RECOMMENDED_GLOBAL, ...RECOMMENDED_PROJECT]) {
39372
- await saveTrustedTool(tool, null, true);
39373
+ await saveTrustedTool(tool, projectPath, false);
39373
39374
  }
39374
39375
  await saveProjectPermissionPreference("recommendedAllowlistAppliedProjects", projectPath, true);
39375
39376
  await saveProjectPermissionPreference(
@@ -39382,7 +39383,7 @@ async function showPermissionSuggestion(projectPath = process.cwd()) {
39382
39383
  console.log();
39383
39384
  console.log(chalk.magenta.bold(" \u{1F4CB} Recommended Permissions"));
39384
39385
  console.log();
39385
- console.log(chalk.dim(" Coco has a curated set of tool permissions for developers:"));
39386
+ console.log(chalk.dim(" Coco has a curated set of tool permissions for this project:"));
39386
39387
  console.log(chalk.dim(" \u2022 Allow: file read/write, search, git staging, build, tests..."));
39387
39388
  console.log(
39388
39389
  chalk.dim(" \u2022 Ask each time: git commit, curl, rm, git pull, docker exec, cloud...")
@@ -39391,12 +39392,17 @@ async function showPermissionSuggestion(projectPath = process.cwd()) {
39391
39392
  console.log();
39392
39393
  console.log(chalk.dim(" Stored in ~/.coco/trusted-tools.json \u2014 edit manually or let"));
39393
39394
  console.log(chalk.dim(" Coco manage it when you approve actions from the prompt."));
39395
+ console.log(chalk.dim(" Note: applying here affects only the current project."));
39394
39396
  console.log();
39395
39397
  const action = await p26.select({
39396
39398
  message: "Apply recommended permissions?",
39397
39399
  options: [
39398
39400
  { value: "view", label: "View details", hint: "See the full list before deciding" },
39399
- { value: "apply", label: "Apply", hint: "Apply recommended permissions now" },
39401
+ {
39402
+ value: "apply",
39403
+ label: "Apply",
39404
+ hint: "Apply recommended permissions for this project"
39405
+ },
39400
39406
  { value: "later", label: "Later", hint: "Remind me next time" },
39401
39407
  { value: "dismiss", label: "No thanks", hint: "Don't show again" }
39402
39408
  ]
@@ -40208,9 +40214,9 @@ var UserCancelledError = class extends Error {
40208
40214
  var SPEC_AGENT_SYSTEM = `You are a senior technical product manager specialising in rapid MVP delivery.
40209
40215
  Your job is to help a developer plan a software project efficiently and honestly.
40210
40216
  Always respond with valid JSON only \u2014 no markdown fences, no prose outside JSON.`;
40211
- function extractJson2(text14) {
40212
- const match = text14.match(/```(?:json)?\s*([\s\S]*?)```/) ?? text14.match(/(\{[\s\S]*\})/);
40213
- return match ? (match[1] ?? text14).trim() : text14.trim();
40217
+ function extractJson2(text15) {
40218
+ const match = text15.match(/```(?:json)?\s*([\s\S]*?)```/) ?? text15.match(/(\{[\s\S]*\})/);
40219
+ return match ? (match[1] ?? text15).trim() : text15.trim();
40214
40220
  }
40215
40221
  function validateBacklogSpec(raw) {
40216
40222
  if (!raw.sprints || raw.sprints.length === 0) {
@@ -43851,15 +43857,15 @@ ${message}
43851
43857
  let stdoutBuffer = "";
43852
43858
  let stderrBuffer = "";
43853
43859
  subprocess.stdout?.on("data", (chunk) => {
43854
- const text14 = chunk.toString();
43855
- stdoutBuffer += text14;
43856
- process.stdout.write(text14);
43860
+ const text15 = chunk.toString();
43861
+ stdoutBuffer += text15;
43862
+ process.stdout.write(text15);
43857
43863
  heartbeat.activity();
43858
43864
  });
43859
43865
  subprocess.stderr?.on("data", (chunk) => {
43860
- const text14 = chunk.toString();
43861
- stderrBuffer += text14;
43862
- process.stderr.write(text14);
43866
+ const text15 = chunk.toString();
43867
+ stderrBuffer += text15;
43868
+ process.stderr.write(text15);
43863
43869
  heartbeat.activity();
43864
43870
  });
43865
43871
  const result = await subprocess;
@@ -43976,15 +43982,15 @@ ${message}
43976
43982
  let stdoutBuffer = "";
43977
43983
  let stderrBuffer = "";
43978
43984
  subprocess.stdout?.on("data", (chunk) => {
43979
- const text14 = chunk.toString();
43980
- stdoutBuffer += text14;
43981
- process.stdout.write(text14);
43985
+ const text15 = chunk.toString();
43986
+ stdoutBuffer += text15;
43987
+ process.stdout.write(text15);
43982
43988
  heartbeat.activity();
43983
43989
  });
43984
43990
  subprocess.stderr?.on("data", (chunk) => {
43985
- const text14 = chunk.toString();
43986
- stderrBuffer += text14;
43987
- process.stderr.write(text14);
43991
+ const text15 = chunk.toString();
43992
+ stderrBuffer += text15;
43993
+ process.stderr.write(text15);
43988
43994
  heartbeat.activity();
43989
43995
  });
43990
43996
  const result = await subprocess;
@@ -44078,15 +44084,15 @@ ${message}
44078
44084
  let stdoutBuffer = "";
44079
44085
  let stderrBuffer = "";
44080
44086
  subprocess.stdout?.on("data", (chunk) => {
44081
- const text14 = chunk.toString();
44082
- stdoutBuffer += text14;
44083
- process.stdout.write(text14);
44087
+ const text15 = chunk.toString();
44088
+ stdoutBuffer += text15;
44089
+ process.stdout.write(text15);
44084
44090
  heartbeat.activity();
44085
44091
  });
44086
44092
  subprocess.stderr?.on("data", (chunk) => {
44087
- const text14 = chunk.toString();
44088
- stderrBuffer += text14;
44089
- process.stderr.write(text14);
44093
+ const text15 = chunk.toString();
44094
+ stderrBuffer += text15;
44095
+ process.stderr.write(text15);
44090
44096
  heartbeat.activity();
44091
44097
  });
44092
44098
  const result = await subprocess;
@@ -44181,15 +44187,15 @@ ${message}
44181
44187
  let stdoutBuffer = "";
44182
44188
  let stderrBuffer = "";
44183
44189
  subprocess.stdout?.on("data", (chunk) => {
44184
- const text14 = chunk.toString();
44185
- stdoutBuffer += text14;
44186
- process.stdout.write(text14);
44190
+ const text15 = chunk.toString();
44191
+ stdoutBuffer += text15;
44192
+ process.stdout.write(text15);
44187
44193
  heartbeat.activity();
44188
44194
  });
44189
44195
  subprocess.stderr?.on("data", (chunk) => {
44190
- const text14 = chunk.toString();
44191
- stderrBuffer += text14;
44192
- process.stderr.write(text14);
44196
+ const text15 = chunk.toString();
44197
+ stderrBuffer += text15;
44198
+ process.stderr.write(text15);
44193
44199
  heartbeat.activity();
44194
44200
  });
44195
44201
  const result = await subprocess;
@@ -44285,15 +44291,15 @@ ${message}
44285
44291
  let stdoutBuffer = "";
44286
44292
  let stderrBuffer = "";
44287
44293
  subprocess.stdout?.on("data", (chunk) => {
44288
- const text14 = chunk.toString();
44289
- stdoutBuffer += text14;
44290
- process.stdout.write(text14);
44294
+ const text15 = chunk.toString();
44295
+ stdoutBuffer += text15;
44296
+ process.stdout.write(text15);
44291
44297
  heartbeat.activity();
44292
44298
  });
44293
44299
  subprocess.stderr?.on("data", (chunk) => {
44294
- const text14 = chunk.toString();
44295
- stderrBuffer += text14;
44296
- process.stderr.write(text14);
44300
+ const text15 = chunk.toString();
44301
+ stderrBuffer += text15;
44302
+ process.stderr.write(text15);
44297
44303
  heartbeat.activity();
44298
44304
  });
44299
44305
  const result = await subprocess;
@@ -44372,15 +44378,15 @@ ${message}
44372
44378
  let stdoutBuffer = "";
44373
44379
  let stderrBuffer = "";
44374
44380
  subprocess.stdout?.on("data", (chunk) => {
44375
- const text14 = chunk.toString();
44376
- stdoutBuffer += text14;
44377
- process.stdout.write(text14);
44381
+ const text15 = chunk.toString();
44382
+ stdoutBuffer += text15;
44383
+ process.stdout.write(text15);
44378
44384
  heartbeat.activity();
44379
44385
  });
44380
44386
  subprocess.stderr?.on("data", (chunk) => {
44381
- const text14 = chunk.toString();
44382
- stderrBuffer += text14;
44383
- process.stderr.write(text14);
44387
+ const text15 = chunk.toString();
44388
+ stderrBuffer += text15;
44389
+ process.stderr.write(text15);
44384
44390
  heartbeat.activity();
44385
44391
  });
44386
44392
  const result = await subprocess;
@@ -44871,16 +44877,16 @@ function htmlToMarkdown(html) {
44871
44877
  const prefix = "#".repeat(i);
44872
44878
  const regex = new RegExp(`<h${i}[^>]*>([\\s\\S]*?)<\\/h${i}>`, "gi");
44873
44879
  md = md.replace(regex, (_, content) => {
44874
- const text14 = content.replace(/<[^>]*>/g, "").trim();
44875
- return text14 ? `
44880
+ const text15 = content.replace(/<[^>]*>/g, "").trim();
44881
+ return text15 ? `
44876
44882
 
44877
- ${prefix} ${text14}
44883
+ ${prefix} ${text15}
44878
44884
 
44879
44885
  ` : "";
44880
44886
  });
44881
44887
  }
44882
- md = md.replace(/<a\s+[^>]*href=["']([^"']+)["'][^>]*>([\s\S]*?)<\/a>/gi, (_, href, text14) => {
44883
- const cleanText = text14.replace(/<[^>]*>/g, "").trim();
44888
+ md = md.replace(/<a\s+[^>]*href=["']([^"']+)["'][^>]*>([\s\S]*?)<\/a>/gi, (_, href, text15) => {
44889
+ const cleanText = text15.replace(/<[^>]*>/g, "").trim();
44884
44890
  if (!cleanText) return "";
44885
44891
  if (href.startsWith("#") || href.startsWith("javascript:")) return cleanText;
44886
44892
  return `[${cleanText}](${href})`;
@@ -44907,8 +44913,8 @@ ${decoded.trim()}
44907
44913
  });
44908
44914
  md = md.replace(/<ul[^>]*>([\s\S]*?)<\/ul>/gi, (_, items) => {
44909
44915
  return "\n" + items.replace(/<li[^>]*>([\s\S]*?)<\/li>/gi, (_2, item) => {
44910
- const text14 = item.replace(/<[^>]*>/g, "").trim();
44911
- return text14 ? `- ${text14}
44916
+ const text15 = item.replace(/<[^>]*>/g, "").trim();
44917
+ return text15 ? `- ${text15}
44912
44918
  ` : "";
44913
44919
  }) + "\n";
44914
44920
  });
@@ -44916,29 +44922,29 @@ ${decoded.trim()}
44916
44922
  let counter = 0;
44917
44923
  return "\n" + items.replace(/<li[^>]*>([\s\S]*?)<\/li>/gi, (_2, item) => {
44918
44924
  counter++;
44919
- const text14 = item.replace(/<[^>]*>/g, "").trim();
44920
- return text14 ? `${counter}. ${text14}
44925
+ const text15 = item.replace(/<[^>]*>/g, "").trim();
44926
+ return text15 ? `${counter}. ${text15}
44921
44927
  ` : "";
44922
44928
  }) + "\n";
44923
44929
  });
44924
44930
  md = md.replace(/<blockquote[^>]*>([\s\S]*?)<\/blockquote>/gi, (_, content) => {
44925
- const text14 = content.replace(/<[^>]*>/g, "").trim();
44926
- return text14 ? "\n" + text14.split("\n").map((line) => `> ${line.trim()}`).join("\n") + "\n" : "";
44931
+ const text15 = content.replace(/<[^>]*>/g, "").trim();
44932
+ return text15 ? "\n" + text15.split("\n").map((line) => `> ${line.trim()}`).join("\n") + "\n" : "";
44927
44933
  });
44928
44934
  md = md.replace(/<p[^>]*>([\s\S]*?)<\/p>/gi, (_, content) => {
44929
- const text14 = content.replace(/<[^>]*>/g, "").trim();
44930
- return text14 ? `
44935
+ const text15 = content.replace(/<[^>]*>/g, "").trim();
44936
+ return text15 ? `
44931
44937
 
44932
- ${text14}
44938
+ ${text15}
44933
44939
 
44934
44940
  ` : "";
44935
44941
  });
44936
44942
  md = md.replace(/<br\s*\/?>/gi, "\n");
44937
44943
  md = md.replace(
44938
44944
  /<(?:strong|b)[^>]*>([\s\S]*?)<\/(?:strong|b)>/gi,
44939
- (_, text14) => `**${text14.trim()}**`
44945
+ (_, text15) => `**${text15.trim()}**`
44940
44946
  );
44941
- md = md.replace(/<(?:em|i)[^>]*>([\s\S]*?)<\/(?:em|i)>/gi, (_, text14) => `*${text14.trim()}*`);
44947
+ md = md.replace(/<(?:em|i)[^>]*>([\s\S]*?)<\/(?:em|i)>/gi, (_, text15) => `*${text15.trim()}*`);
44942
44948
  md = md.replace(/<hr\s*\/?>/gi, "\n---\n");
44943
44949
  md = md.replace(/<table[^>]*>([\s\S]*?)<\/table>/gi, (_, tableContent) => {
44944
44950
  const rows = [];
@@ -46068,10 +46074,10 @@ function chunkContent(content, chunkSize) {
46068
46074
  const chunks = [];
46069
46075
  for (let i = 0; i < lines.length; i += chunkSize) {
46070
46076
  const chunkLines = lines.slice(i, Math.min(i + chunkSize, lines.length));
46071
- const text14 = chunkLines.join("\n").trim();
46072
- if (text14.length > 10) {
46077
+ const text15 = chunkLines.join("\n").trim();
46078
+ if (text15.length > 10) {
46073
46079
  chunks.push({
46074
- text: text14,
46080
+ text: text15,
46075
46081
  startLine: i + 1,
46076
46082
  endLine: Math.min(i + chunkSize, lines.length)
46077
46083
  });
@@ -46079,8 +46085,8 @@ function chunkContent(content, chunkSize) {
46079
46085
  }
46080
46086
  return chunks;
46081
46087
  }
46082
- function simpleEmbedding(text14) {
46083
- const words = text14.toLowerCase().replace(/[^\w\s]/g, " ").split(/\s+/).filter((w) => w.length > 1);
46088
+ function simpleEmbedding(text15) {
46089
+ const words = text15.toLowerCase().replace(/[^\w\s]/g, " ").split(/\s+/).filter((w) => w.length > 1);
46084
46090
  const freq = /* @__PURE__ */ new Map();
46085
46091
  for (const word of words) {
46086
46092
  freq.set(word, (freq.get(word) ?? 0) + 1);
@@ -46106,7 +46112,7 @@ function simpleEmbedding(text14) {
46106
46112
  }
46107
46113
  var embedFn = null;
46108
46114
  var usingFallbackEmbedding = false;
46109
- async function getEmbedding(text14) {
46115
+ async function getEmbedding(text15) {
46110
46116
  if (!embedFn) {
46111
46117
  try {
46112
46118
  const transformers = await import('@xenova/transformers');
@@ -46123,7 +46129,7 @@ async function getEmbedding(text14) {
46123
46129
  usingFallbackEmbedding = true;
46124
46130
  }
46125
46131
  }
46126
- return embedFn(text14);
46132
+ return embedFn(text15);
46127
46133
  }
46128
46134
  async function loadIndex2(indexDir) {
46129
46135
  try {
@@ -46676,23 +46682,23 @@ Examples:
46676
46682
  const pdfData = await pdfParse.default(dataBuffer, {
46677
46683
  max: maxPages
46678
46684
  });
46679
- let text14 = pdfData.text;
46685
+ let text15 = pdfData.text;
46680
46686
  let truncated = false;
46681
46687
  const totalPages = pdfData.numpages;
46682
46688
  if (pages) {
46683
46689
  const range = parsePageRange(pages, totalPages);
46684
- const pageTexts = text14.split(/\f/);
46690
+ const pageTexts = text15.split(/\f/);
46685
46691
  if (pageTexts.length > 1) {
46686
46692
  const selectedPages = pageTexts.slice(range.start - 1, range.end);
46687
- text14 = selectedPages.join("\n\n--- Page Break ---\n\n");
46693
+ text15 = selectedPages.join("\n\n--- Page Break ---\n\n");
46688
46694
  }
46689
46695
  }
46690
- if (text14.length > 5e5) {
46691
- text14 = text14.slice(0, 5e5);
46696
+ if (text15.length > 5e5) {
46697
+ text15 = text15.slice(0, 5e5);
46692
46698
  truncated = true;
46693
46699
  }
46694
46700
  return {
46695
- text: text14,
46701
+ text: text15,
46696
46702
  pages: totalPages,
46697
46703
  metadata: {
46698
46704
  title: pdfData.info?.Title,
@@ -47706,7 +47712,8 @@ var SuggestImprovementsSchema = z.object({
47706
47712
  context: z.string().optional().describe("Additional context about the code")
47707
47713
  });
47708
47714
  async function analyzeAndSuggest(filePath, _context) {
47709
- const content = await fs46.readFile(filePath, "utf-8");
47715
+ const rawContent = await fs46.readFile(filePath, "utf-8");
47716
+ const content = typeof rawContent === "string" ? rawContent : String(rawContent ?? "");
47710
47717
  const lines = content.split("\n");
47711
47718
  const suggestions = [];
47712
47719
  for (let i = 0; i < lines.length; i++) {
@@ -48071,11 +48078,11 @@ var getLearnedPatternsTool = defineTool({
48071
48078
  const patterns = store.getFrequentPatterns(typedInput.limit);
48072
48079
  return {
48073
48080
  totalPatterns: patterns.length,
48074
- patterns: patterns.map((p45) => ({
48075
- pattern: p45.pattern,
48076
- preference: p45.userPreference,
48077
- frequency: p45.frequency,
48078
- lastUsed: new Date(p45.lastUsed).toISOString()
48081
+ patterns: patterns.map((p46) => ({
48082
+ pattern: p46.pattern,
48083
+ preference: p46.userPreference,
48084
+ frequency: p46.frequency,
48085
+ lastUsed: new Date(p46.lastUsed).toISOString()
48079
48086
  }))
48080
48087
  };
48081
48088
  }
@@ -50119,24 +50126,24 @@ function formatHtmlLine(line) {
50119
50126
  }
50120
50127
  return null;
50121
50128
  }
50122
- function formatInlineMarkdown(text14) {
50123
- text14 = text14.replace(/\*\*\*(.+?)\*\*\*/g, (_, content) => chalk.bold.italic(content));
50124
- text14 = text14.replace(/\*\*(.+?)\*\*/g, (_, content) => chalk.bold(content));
50125
- text14 = text14.replace(/\*([^*]+)\*/g, (_, content) => chalk.italic(content));
50126
- text14 = text14.replace(/_([^_]+)_/g, (_, content) => chalk.italic(content));
50127
- text14 = text14.replace(/`([^`]+)`/g, (_, content) => chalk.cyan(content));
50128
- text14 = text14.replace(/~~(.+?)~~/g, (_, content) => chalk.strikethrough(content));
50129
- text14 = text14.replace(/\[([^\]]+)\]\([^)]+\)/g, (_, linkText) => chalk.blue.underline(linkText));
50130
- return text14;
50131
- }
50132
- function wrapText(text14, maxWidth) {
50133
- if (maxWidth <= 0) return [text14];
50134
- const plainText = stripAnsi(text14);
50129
+ function formatInlineMarkdown(text15) {
50130
+ text15 = text15.replace(/\*\*\*(.+?)\*\*\*/g, (_, content) => chalk.bold.italic(content));
50131
+ text15 = text15.replace(/\*\*(.+?)\*\*/g, (_, content) => chalk.bold(content));
50132
+ text15 = text15.replace(/\*([^*]+)\*/g, (_, content) => chalk.italic(content));
50133
+ text15 = text15.replace(/_([^_]+)_/g, (_, content) => chalk.italic(content));
50134
+ text15 = text15.replace(/`([^`]+)`/g, (_, content) => chalk.cyan(content));
50135
+ text15 = text15.replace(/~~(.+?)~~/g, (_, content) => chalk.strikethrough(content));
50136
+ text15 = text15.replace(/\[([^\]]+)\]\([^)]+\)/g, (_, linkText) => chalk.blue.underline(linkText));
50137
+ return text15;
50138
+ }
50139
+ function wrapText(text15, maxWidth) {
50140
+ if (maxWidth <= 0) return [text15];
50141
+ const plainText = stripAnsi(text15);
50135
50142
  if (plainText.length <= maxWidth) {
50136
- return [text14];
50143
+ return [text15];
50137
50144
  }
50138
50145
  const lines = [];
50139
- let remaining = text14;
50146
+ let remaining = text15;
50140
50147
  while (true) {
50141
50148
  const plain = stripAnsi(remaining);
50142
50149
  if (plain.length <= maxWidth) break;
@@ -50174,7 +50181,7 @@ function wrapText(text14, maxWidth) {
50174
50181
  if (remaining) {
50175
50182
  lines.push(remaining);
50176
50183
  }
50177
- return lines.length > 0 ? lines : [text14];
50184
+ return lines.length > 0 ? lines : [text15];
50178
50185
  }
50179
50186
  function stripAnsi(str) {
50180
50187
  return str.replace(/\x1b\[[0-9;]*m/g, "");
@@ -50326,9 +50333,9 @@ function printEditDiff(oldStr, newStr) {
50326
50333
  if (lines.length === 0) return;
50327
50334
  const truncate4 = (s) => s.length > termWidth - 2 ? s.slice(0, termWidth - 3) + "\u2026" : s;
50328
50335
  for (const l of lines) {
50329
- const text14 = `+ ${truncate4(l)}`;
50330
- const pad = Math.max(0, termWidth - stripAnsi(text14).length + 2);
50331
- console.log(" " + diffBgAdd(text14 + " ".repeat(pad)));
50336
+ const text15 = `+ ${truncate4(l)}`;
50337
+ const pad = Math.max(0, termWidth - stripAnsi(text15).length + 2);
50338
+ console.log(" " + diffBgAdd(text15 + " ".repeat(pad)));
50332
50339
  }
50333
50340
  return;
50334
50341
  }
@@ -50356,9 +50363,9 @@ function printEditDiff(oldStr, newStr) {
50356
50363
  }
50357
50364
  if (diffLineList.length === 0) return;
50358
50365
  const pairs = pairAdjacentDiffLines(diffLineList);
50359
- const pairedDeletes = new Set(pairs.map((p45) => p45.deleteIdx));
50360
- const pairedAdds = new Set(pairs.map((p45) => p45.addIdx));
50361
- const pairByAdd = new Map(pairs.map((p45) => [p45.addIdx, p45.deleteIdx]));
50366
+ const pairedDeletes = new Set(pairs.map((p46) => p46.deleteIdx));
50367
+ const pairedAdds = new Set(pairs.map((p46) => p46.addIdx));
50368
+ const pairByAdd = new Map(pairs.map((p46) => [p46.addIdx, p46.deleteIdx]));
50362
50369
  const wordHighlights = /* @__PURE__ */ new Map();
50363
50370
  for (const pair of pairs) {
50364
50371
  const del = diffLineList[pair.deleteIdx];
@@ -50784,10 +50791,10 @@ function findNextWordBoundary(line, pos) {
50784
50791
  while (i < line.length && line[i] === " ") i++;
50785
50792
  return i;
50786
50793
  }
50787
- function countVisualRows(text14, startCol, termCols) {
50794
+ function countVisualRows(text15, startCol, termCols) {
50788
50795
  let rows = 1;
50789
50796
  let col = startCol;
50790
- for (const char of text14) {
50797
+ for (const char of text15) {
50791
50798
  if (char === "\n") {
50792
50799
  if (col > 0) rows++;
50793
50800
  col = 0;
@@ -50801,11 +50808,11 @@ function countVisualRows(text14, startCol, termCols) {
50801
50808
  }
50802
50809
  return rows;
50803
50810
  }
50804
- function getCursorVisualPos(text14, cursorPos, promptLen, termCols) {
50811
+ function getCursorVisualPos(text15, cursorPos, promptLen, termCols) {
50805
50812
  let row = 0;
50806
50813
  let col = promptLen;
50807
50814
  for (let i = 0; i < cursorPos; i++) {
50808
- if (text14[i] === "\n") {
50815
+ if (text15[i] === "\n") {
50809
50816
  if (col > 0) row++;
50810
50817
  col = 0;
50811
50818
  } else {
@@ -50818,14 +50825,14 @@ function getCursorVisualPos(text14, cursorPos, promptLen, termCols) {
50818
50825
  }
50819
50826
  return { row, col };
50820
50827
  }
50821
- function computeWordWrap(text14, startCol, termCols) {
50828
+ function computeWordWrap(text15, startCol, termCols) {
50822
50829
  const passthrough = {
50823
- display: text14,
50824
- toDisplayPos: (p45) => p45,
50825
- toOrigPos: (p45) => p45
50830
+ display: text15,
50831
+ toDisplayPos: (p46) => p46,
50832
+ toOrigPos: (p46) => p46
50826
50833
  };
50827
- if (!text14 || termCols <= 1) return passthrough;
50828
- const origToDisp = new Int32Array(text14.length + 1);
50834
+ if (!text15 || termCols <= 1) return passthrough;
50835
+ const origToDisp = new Int32Array(text15.length + 1);
50829
50836
  const dispToOrig = [];
50830
50837
  let display = "";
50831
50838
  let col = startCol;
@@ -50841,15 +50848,15 @@ function computeWordWrap(text14, startCol, termCols) {
50841
50848
  col = 0;
50842
50849
  }
50843
50850
  let i = 0;
50844
- while (i < text14.length) {
50845
- const ch = text14[i];
50851
+ while (i < text15.length) {
50852
+ const ch = text15[i];
50846
50853
  if (ch === "\n") {
50847
50854
  emitChar("\n", i++);
50848
50855
  continue;
50849
50856
  }
50850
50857
  if (ch !== " ") {
50851
50858
  let wordEnd = i;
50852
- while (wordEnd < text14.length && text14[wordEnd] !== " " && text14[wordEnd] !== "\n") {
50859
+ while (wordEnd < text15.length && text15[wordEnd] !== " " && text15[wordEnd] !== "\n") {
50853
50860
  wordEnd++;
50854
50861
  }
50855
50862
  const wordLen = wordEnd - i;
@@ -50857,7 +50864,7 @@ function computeWordWrap(text14, startCol, termCols) {
50857
50864
  injectNewline();
50858
50865
  }
50859
50866
  for (let k = i; k < wordEnd; k++) {
50860
- emitChar(text14[k], k);
50867
+ emitChar(text15[k], k);
50861
50868
  if (col >= termCols && k + 1 < wordEnd) {
50862
50869
  injectNewline();
50863
50870
  }
@@ -50869,7 +50876,7 @@ function computeWordWrap(text14, startCol, termCols) {
50869
50876
  col = 0;
50870
50877
  } else {
50871
50878
  let nextWordEnd = i;
50872
- while (nextWordEnd < text14.length && text14[nextWordEnd] !== " " && text14[nextWordEnd] !== "\n") {
50879
+ while (nextWordEnd < text15.length && text15[nextWordEnd] !== " " && text15[nextWordEnd] !== "\n") {
50873
50880
  nextWordEnd++;
50874
50881
  }
50875
50882
  const nextWordLen = nextWordEnd - i;
@@ -50879,10 +50886,10 @@ function computeWordWrap(text14, startCol, termCols) {
50879
50886
  }
50880
50887
  }
50881
50888
  }
50882
- origToDisp[text14.length] = display.length;
50889
+ origToDisp[text15.length] = display.length;
50883
50890
  return {
50884
50891
  display,
50885
- toDisplayPos: (origPos) => origToDisp[Math.min(origPos, text14.length)] ?? display.length,
50892
+ toDisplayPos: (origPos) => origToDisp[Math.min(origPos, text15.length)] ?? display.length,
50886
50893
  toOrigPos: (displayPos) => {
50887
50894
  const dp = Math.max(0, Math.min(displayPos, dispToOrig.length - 1));
50888
50895
  for (let d = dp; d >= 0; d--) {
@@ -51015,11 +51022,11 @@ function createInputHandler(_session) {
51015
51022
  const item = visibleItems[itemIndex];
51016
51023
  const actualIndex = startIndex + itemIndex;
51017
51024
  const isSelected = actualIndex === selectedCompletion;
51018
- const text14 = ` ${item.cmd}`.padEnd(ITEM_WIDTH);
51025
+ const text15 = ` ${item.cmd}`.padEnd(ITEM_WIDTH);
51019
51026
  if (isSelected) {
51020
- output += chalk.bgBlue.white(text14);
51027
+ output += chalk.bgBlue.white(text15);
51021
51028
  } else {
51022
- output += chalk.cyan(text14);
51029
+ output += chalk.cyan(text15);
51023
51030
  }
51024
51031
  }
51025
51032
  }
@@ -51071,8 +51078,8 @@ function createInputHandler(_session) {
51071
51078
  process.stdout.write("\r" + ansiEscapes.eraseDown);
51072
51079
  lastMenuLines = 0;
51073
51080
  }
51074
- function insertTextAtCursor(text14) {
51075
- const cleaned = text14.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
51081
+ function insertTextAtCursor(text15) {
51082
+ const cleaned = text15.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
51076
51083
  const printable = cleaned.replace(/[^\n\x20-\x7E\u00A0-\uFFFF]/g, "");
51077
51084
  if (printable.length === 0) return;
51078
51085
  currentLine = currentLine.slice(0, cursorPos) + printable + currentLine.slice(cursorPos);
@@ -51975,10 +51982,10 @@ function formatWriteFilePreview(toolCall, maxLines = 10) {
51975
51982
  const footer = truncated ? chalk.dim(` \u2514\u2500 ... ${lines.length - maxLines} more lines`) : "";
51976
51983
  return formatted + (footer ? "\n" + footer : "");
51977
51984
  }
51978
- function wrapCommandText(text14, maxWidth = 70, indent = " ") {
51979
- if (text14.length <= maxWidth) return text14;
51985
+ function wrapCommandText(text15, maxWidth = 70, indent = " ") {
51986
+ if (text15.length <= maxWidth) return text15;
51980
51987
  const lines = [];
51981
- let remaining = text14;
51988
+ let remaining = text15;
51982
51989
  while (remaining.length > maxWidth) {
51983
51990
  let breakAt = maxWidth;
51984
51991
  const spaceIdx = remaining.lastIndexOf(" ", maxWidth);
@@ -52081,16 +52088,16 @@ function formatToolCallForConfirmation(toolCall, metadata) {
52081
52088
  const reason = input.reason ? String(input.reason) : void 0;
52082
52089
  const actionLabel = action === "allow" ? chalk.green.bold("ALLOW") : chalk.red.bold(action.toUpperCase());
52083
52090
  const scopeLabel = scope === "global" ? chalk.blue("Global (all projects)") : chalk.magenta("Project (current only)");
52084
- const patternList = patterns.map((p45) => chalk.cyan(p45)).join(", ");
52091
+ const patternList = patterns.map((p46) => chalk.cyan(p46)).join(", ");
52085
52092
  const lines = [`${actionLabel}: ${patternList}`];
52086
52093
  lines.push(`${chalk.dim(" Scope:")} ${scopeLabel}`);
52087
52094
  if (reason) {
52088
52095
  lines.push(`${chalk.dim(" Reason:")} ${reason}`);
52089
52096
  }
52090
- for (const p45 of patterns) {
52091
- lines.push(`${chalk.dim(" Risk:")} ${getRiskDescription(p45)}`);
52097
+ for (const p46 of patterns) {
52098
+ lines.push(`${chalk.dim(" Risk:")} ${getRiskDescription(p46)}`);
52092
52099
  lines.push(
52093
- `${chalk.dim(" Effect:")} ${getEffectDescription(action, p45, scope)}`
52100
+ `${chalk.dim(" Effect:")} ${getEffectDescription(action, p46, scope)}`
52094
52101
  );
52095
52102
  }
52096
52103
  description = lines.join("\n ");
@@ -52331,6 +52338,46 @@ async function confirmToolExecution(toolCall) {
52331
52338
  process.stdin.on("data", onData);
52332
52339
  });
52333
52340
  }
52341
+ async function confirmToolExecutionFallback(toolCall) {
52342
+ const { description } = formatToolCallForConfirmation(toolCall);
52343
+ const isBashExec = toolCall.name === "bash_exec";
52344
+ console.log();
52345
+ console.log(chalk.yellow(" \u26A0 Interactive tool selector unavailable. Using safe fallback."));
52346
+ const options = [
52347
+ { value: "yes", label: "yes", hint: "Allow once" },
52348
+ { value: "no", label: "no", hint: "Skip this action" },
52349
+ { value: "trust_project", label: "trust (project)", hint: "Always allow in this project" },
52350
+ { value: "trust_global", label: "trust (global)", hint: "Always allow everywhere" }
52351
+ ];
52352
+ if (isBashExec) {
52353
+ options.splice(2, 0, { value: "edit", label: "edit command", hint: "Modify before running" });
52354
+ }
52355
+ const choice = await p26.select({
52356
+ message: `Confirm tool action:
52357
+ ${description}`,
52358
+ options
52359
+ });
52360
+ if (p26.isCancel(choice)) return "abort";
52361
+ if (choice === "edit") {
52362
+ const currentCommand = String(toolCall.input.command ?? "");
52363
+ const edited = await p26.text({
52364
+ message: "Edit command:",
52365
+ placeholder: currentCommand,
52366
+ initialValue: currentCommand,
52367
+ validate: (value) => !value?.trim() ? "Command is required" : void 0
52368
+ });
52369
+ if (p26.isCancel(edited)) return "abort";
52370
+ return { type: "edit", newCommand: edited.trim() };
52371
+ }
52372
+ return choice;
52373
+ }
52374
+ async function confirmToolExecutionWithFallback(toolCall) {
52375
+ try {
52376
+ return await confirmToolExecution(toolCall);
52377
+ } catch {
52378
+ return await confirmToolExecutionFallback(toolCall);
52379
+ }
52380
+ }
52334
52381
 
52335
52382
  // src/cli/repl/parallel-executor.ts
52336
52383
  init_error_resilience();
@@ -53060,14 +53107,15 @@ ${tail}`;
53060
53107
  options.onBeforeConfirmation?.();
53061
53108
  let confirmResult;
53062
53109
  try {
53063
- confirmResult = await confirmToolExecution(toolCall);
53110
+ confirmResult = await confirmToolExecutionWithFallback(toolCall);
53064
53111
  } catch (confirmError) {
53065
53112
  options.onAfterConfirmation?.();
53066
- declinedTools.set(
53067
- toolCall.id,
53113
+ declinedTools.set(toolCall.id, "Confirmation failed");
53114
+ options.onToolSkipped?.(
53115
+ toolCall,
53068
53116
  `Confirmation failed: ${confirmError instanceof Error ? confirmError.message : String(confirmError)}`
53069
53117
  );
53070
- options.onToolSkipped?.(toolCall, "Confirmation error");
53118
+ turnAborted = true;
53071
53119
  continue;
53072
53120
  }
53073
53121
  options.onAfterConfirmation?.();
@@ -53137,29 +53185,29 @@ ${tail}`;
53137
53185
  const patterns = executed.input.patterns;
53138
53186
  const scope = executed.input.scope || "project";
53139
53187
  if (Array.isArray(patterns)) {
53140
- for (const p45 of patterns) {
53188
+ for (const p46 of patterns) {
53141
53189
  if (action === "allow") {
53142
- session.trustedTools.add(p45);
53190
+ session.trustedTools.add(p46);
53143
53191
  if (scope === "global") {
53144
- saveTrustedTool(p45, null, true).catch(() => {
53192
+ saveTrustedTool(p46, null, true).catch(() => {
53145
53193
  });
53146
53194
  } else {
53147
- saveTrustedTool(p45, session.projectPath, false).catch(() => {
53195
+ saveTrustedTool(p46, session.projectPath, false).catch(() => {
53148
53196
  });
53149
53197
  }
53150
- removeDeniedTool(p45, session.projectPath).catch(() => {
53198
+ removeDeniedTool(p46, session.projectPath).catch(() => {
53151
53199
  });
53152
53200
  } else if (action === "deny") {
53153
- session.trustedTools.delete(p45);
53201
+ session.trustedTools.delete(p46);
53154
53202
  if (scope === "global") {
53155
- removeTrustedTool(p45, session.projectPath, true).catch(() => {
53203
+ removeTrustedTool(p46, session.projectPath, true).catch(() => {
53156
53204
  });
53157
53205
  } else {
53158
- saveDeniedTool(p45, session.projectPath).catch(() => {
53206
+ saveDeniedTool(p46, session.projectPath).catch(() => {
53159
53207
  });
53160
53208
  }
53161
53209
  } else {
53162
- session.trustedTools.delete(p45);
53210
+ session.trustedTools.delete(p46);
53163
53211
  }
53164
53212
  }
53165
53213
  }
@@ -54207,14 +54255,14 @@ async function startRepl(options = {}) {
54207
54255
  imageCount++;
54208
54256
  }
54209
54257
  }
54210
- const text14 = textParts.join("\n\n").trim();
54211
- if (text14.length > 0) {
54258
+ const text15 = textParts.join("\n\n").trim();
54259
+ if (text15.length > 0) {
54212
54260
  if (imageCount > 0) {
54213
- return `${text14}
54261
+ return `${text15}
54214
54262
 
54215
54263
  [System: The original request included ${imageCount} image(s). Use the image context already provided in this conversation.]`;
54216
54264
  }
54217
- return text14;
54265
+ return text15;
54218
54266
  }
54219
54267
  if (imageCount > 0) {
54220
54268
  return `[System: Retry the previous image-based user request (${imageCount} image(s)). Use the existing image context in the conversation and do not repeat the same failed action.]`;
@@ -54233,8 +54281,8 @@ async function startRepl(options = {}) {
54233
54281
  };
54234
54282
  const getAutoSwitchCandidates = (current) => {
54235
54283
  const ordered = [];
54236
- const push = (p45) => {
54237
- if (p45 !== current && !ordered.includes(p45)) ordered.push(p45);
54284
+ const push = (p46) => {
54285
+ if (p46 !== current && !ordered.includes(p46)) ordered.push(p46);
54238
54286
  };
54239
54287
  if (current === "openai") {
54240
54288
  push("codex");
@@ -54272,7 +54320,7 @@ async function startRepl(options = {}) {
54272
54320
  "lmstudio",
54273
54321
  "ollama"
54274
54322
  ];
54275
- for (const p45 of genericOrder) push(p45);
54323
+ for (const p46 of genericOrder) push(p46);
54276
54324
  return ordered;
54277
54325
  };
54278
54326
  const attemptAutoProviderSwitch = async (reason, originalMessage) => {