@corbat-tech/coco 2.27.2 → 2.27.4
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 +461 -310
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +21 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
795
|
-
if (
|
|
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(
|
|
3381
|
-
if (!
|
|
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 = (
|
|
3386
|
-
const whitespace = (
|
|
3387
|
-
const words = (
|
|
3388
|
-
const isCodeLike = codeChars >
|
|
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 >
|
|
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 =
|
|
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
|
|
3448
|
-
return
|
|
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
|
|
3637
|
-
if (!
|
|
3638
|
-
builder.arguments +=
|
|
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:
|
|
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(
|
|
4234
|
-
if (!
|
|
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 = (
|
|
4240
|
-
const whitespace = (
|
|
4241
|
-
const words = (
|
|
4242
|
-
const nonAscii = (
|
|
4243
|
-
const isCodeLike = codeChars >
|
|
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 >
|
|
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 >
|
|
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 =
|
|
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(
|
|
5047
|
-
return Math.ceil(
|
|
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)
|
|
@@ -5597,23 +5597,35 @@ var init_copilot2 = __esm({
|
|
|
5597
5597
|
CONTEXT_WINDOWS4 = {
|
|
5598
5598
|
// Claude models — Copilot API caps these at 168 000 (not 200 000 like Anthropic direct)
|
|
5599
5599
|
"claude-sonnet-4.6": 168e3,
|
|
5600
|
+
"claude-sonnet-4": 168e3,
|
|
5600
5601
|
"claude-opus-4.6": 168e3,
|
|
5602
|
+
"claude-opus-4.6-fast": 168e3,
|
|
5601
5603
|
"claude-sonnet-4.5": 168e3,
|
|
5602
5604
|
"claude-opus-4.5": 168e3,
|
|
5603
5605
|
"claude-haiku-4.5": 168e3,
|
|
5604
5606
|
// OpenAI models — chat/completions
|
|
5605
5607
|
"gpt-4.1": 1048576,
|
|
5608
|
+
"gpt-4o": 128e3,
|
|
5606
5609
|
// OpenAI models — /responses API (Codex/GPT-5+)
|
|
5607
5610
|
"gpt-5.4-codex": 4e5,
|
|
5611
|
+
"gpt-5.4": 4e5,
|
|
5612
|
+
"gpt-5.4-mini": 4e5,
|
|
5608
5613
|
"gpt-5.3-codex": 4e5,
|
|
5609
5614
|
"gpt-5.2-codex": 4e5,
|
|
5610
5615
|
"gpt-5.1-codex-max": 4e5,
|
|
5616
|
+
"gpt-5-mini": 4e5,
|
|
5611
5617
|
"gpt-5.2": 4e5,
|
|
5612
5618
|
"gpt-5.1": 4e5,
|
|
5613
5619
|
// Google models
|
|
5620
|
+
"gemini-3.1-pro": 1e6,
|
|
5614
5621
|
"gemini-3.1-pro-preview": 1e6,
|
|
5622
|
+
"gemini-3-flash": 1e6,
|
|
5615
5623
|
"gemini-3-flash-preview": 1e6,
|
|
5616
|
-
"gemini-2.5-pro": 1048576
|
|
5624
|
+
"gemini-2.5-pro": 1048576,
|
|
5625
|
+
// Evaluation models
|
|
5626
|
+
"grok-code-fast-1": 4e5,
|
|
5627
|
+
"raptor-mini": 4e5,
|
|
5628
|
+
goldeneye: 4e5
|
|
5617
5629
|
};
|
|
5618
5630
|
DEFAULT_MODEL4 = "claude-sonnet-4.6";
|
|
5619
5631
|
COPILOT_HEADERS = {
|
|
@@ -5712,9 +5724,9 @@ var init_copilot2 = __esm({
|
|
|
5712
5724
|
/**
|
|
5713
5725
|
* Count tokens (approximate — Copilot models vary in tokenizer)
|
|
5714
5726
|
*/
|
|
5715
|
-
countTokens(
|
|
5716
|
-
if (!
|
|
5717
|
-
return Math.ceil(
|
|
5727
|
+
countTokens(text15) {
|
|
5728
|
+
if (!text15) return 0;
|
|
5729
|
+
return Math.ceil(text15.length / 3.5);
|
|
5718
5730
|
}
|
|
5719
5731
|
/**
|
|
5720
5732
|
* Get context window for the current model
|
|
@@ -5812,9 +5824,9 @@ var init_gemini = __esm({
|
|
|
5812
5824
|
});
|
|
5813
5825
|
let streamStopReason = "end_turn";
|
|
5814
5826
|
for await (const chunk of stream) {
|
|
5815
|
-
const
|
|
5816
|
-
if (
|
|
5817
|
-
yield { type: "text", text:
|
|
5827
|
+
const text15 = chunk.text;
|
|
5828
|
+
if (text15) {
|
|
5829
|
+
yield { type: "text", text: text15 };
|
|
5818
5830
|
}
|
|
5819
5831
|
const finishReason = chunk.candidates?.[0]?.finishReason;
|
|
5820
5832
|
if (finishReason) {
|
|
@@ -5838,9 +5850,9 @@ var init_gemini = __esm({
|
|
|
5838
5850
|
let fallbackToolCounter = 0;
|
|
5839
5851
|
const emittedToolIds = /* @__PURE__ */ new Set();
|
|
5840
5852
|
for await (const chunk of stream) {
|
|
5841
|
-
const
|
|
5842
|
-
if (
|
|
5843
|
-
yield { type: "text", text:
|
|
5853
|
+
const text15 = chunk.text;
|
|
5854
|
+
if (text15) {
|
|
5855
|
+
yield { type: "text", text: text15 };
|
|
5844
5856
|
}
|
|
5845
5857
|
const functionCalls = this.extractFunctionCalls(chunk);
|
|
5846
5858
|
for (const functionCall of functionCalls) {
|
|
@@ -5876,9 +5888,9 @@ var init_gemini = __esm({
|
|
|
5876
5888
|
throw this.handleError(error);
|
|
5877
5889
|
}
|
|
5878
5890
|
}
|
|
5879
|
-
countTokens(
|
|
5880
|
-
if (!
|
|
5881
|
-
return Math.ceil(
|
|
5891
|
+
countTokens(text15) {
|
|
5892
|
+
if (!text15) return 0;
|
|
5893
|
+
return Math.ceil(text15.length / 3.5);
|
|
5882
5894
|
}
|
|
5883
5895
|
getContextWindow() {
|
|
5884
5896
|
const model = this.config.model ?? DEFAULT_MODEL5;
|
|
@@ -5926,8 +5938,8 @@ var init_gemini = __esm({
|
|
|
5926
5938
|
const systemMsg = messages.find((m) => m.role === "system");
|
|
5927
5939
|
if (!systemMsg) return void 0;
|
|
5928
5940
|
if (typeof systemMsg.content === "string") return systemMsg.content;
|
|
5929
|
-
const
|
|
5930
|
-
return
|
|
5941
|
+
const text15 = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
5942
|
+
return text15 || void 0;
|
|
5931
5943
|
}
|
|
5932
5944
|
convertContents(messages) {
|
|
5933
5945
|
const toolNameByUseId = this.buildToolUseNameMap(messages);
|
|
@@ -6224,8 +6236,8 @@ var init_vertex = __esm({
|
|
|
6224
6236
|
}
|
|
6225
6237
|
yield { type: "done", stopReason };
|
|
6226
6238
|
}
|
|
6227
|
-
countTokens(
|
|
6228
|
-
return Math.ceil(
|
|
6239
|
+
countTokens(text15) {
|
|
6240
|
+
return Math.ceil(text15.length / 4);
|
|
6229
6241
|
}
|
|
6230
6242
|
getContextWindow() {
|
|
6231
6243
|
return CONTEXT_WINDOWS6[this.config.model ?? DEFAULT_MODEL6] ?? 1048576;
|
|
@@ -6287,8 +6299,8 @@ var init_vertex = __esm({
|
|
|
6287
6299
|
const systemMsg = messages.find((m) => m.role === "system");
|
|
6288
6300
|
if (!systemMsg) return void 0;
|
|
6289
6301
|
if (typeof systemMsg.content === "string") return systemMsg.content;
|
|
6290
|
-
const
|
|
6291
|
-
return
|
|
6302
|
+
const text15 = systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
6303
|
+
return text15 || void 0;
|
|
6292
6304
|
}
|
|
6293
6305
|
buildToolUseNameMap(messages) {
|
|
6294
6306
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -6465,10 +6477,10 @@ var init_vertex = __esm({
|
|
|
6465
6477
|
}
|
|
6466
6478
|
parseResponse(response, model) {
|
|
6467
6479
|
const candidate = response.candidates?.[0];
|
|
6468
|
-
const
|
|
6480
|
+
const text15 = (candidate?.content?.parts ?? []).filter((part) => part.text).map((part) => part.text).join("");
|
|
6469
6481
|
return {
|
|
6470
6482
|
id: `vertex-${Date.now()}`,
|
|
6471
|
-
content:
|
|
6483
|
+
content: text15,
|
|
6472
6484
|
stopReason: this.mapFinishReason(candidate?.finishReason),
|
|
6473
6485
|
usage: {
|
|
6474
6486
|
inputTokens: response.usageMetadata?.promptTokenCount ?? 0,
|
|
@@ -6854,7 +6866,7 @@ var init_fallback = __esm({
|
|
|
6854
6866
|
*/
|
|
6855
6867
|
async initialize(config) {
|
|
6856
6868
|
const results = await Promise.allSettled(
|
|
6857
|
-
this.providers.map((
|
|
6869
|
+
this.providers.map((p46) => p46.provider.initialize(config))
|
|
6858
6870
|
);
|
|
6859
6871
|
const anySuccess = results.some((r) => r.status === "fulfilled");
|
|
6860
6872
|
if (!anySuccess) {
|
|
@@ -6951,9 +6963,9 @@ var init_fallback = __esm({
|
|
|
6951
6963
|
* @param text - Text to count tokens for
|
|
6952
6964
|
* @returns Estimated token count
|
|
6953
6965
|
*/
|
|
6954
|
-
countTokens(
|
|
6966
|
+
countTokens(text15) {
|
|
6955
6967
|
const provider = this.getCurrentProvider();
|
|
6956
|
-
return provider.provider.countTokens(
|
|
6968
|
+
return provider.provider.countTokens(text15);
|
|
6957
6969
|
}
|
|
6958
6970
|
/**
|
|
6959
6971
|
* Get context window from current provider
|
|
@@ -6976,11 +6988,11 @@ var init_fallback = __esm({
|
|
|
6976
6988
|
*/
|
|
6977
6989
|
async isAvailable() {
|
|
6978
6990
|
const results = await Promise.all(
|
|
6979
|
-
this.providers.map(async (
|
|
6980
|
-
if (
|
|
6991
|
+
this.providers.map(async (p46) => {
|
|
6992
|
+
if (p46.breaker.isOpen()) {
|
|
6981
6993
|
return false;
|
|
6982
6994
|
}
|
|
6983
|
-
return
|
|
6995
|
+
return p46.provider.isAvailable();
|
|
6984
6996
|
})
|
|
6985
6997
|
);
|
|
6986
6998
|
return results.some((available) => available);
|
|
@@ -7011,10 +7023,10 @@ var init_fallback = __esm({
|
|
|
7011
7023
|
* @returns Array of provider status objects
|
|
7012
7024
|
*/
|
|
7013
7025
|
getCircuitStatus() {
|
|
7014
|
-
return this.providers.map((
|
|
7015
|
-
providerId:
|
|
7016
|
-
state:
|
|
7017
|
-
failureCount:
|
|
7026
|
+
return this.providers.map((p46) => ({
|
|
7027
|
+
providerId: p46.provider.id,
|
|
7028
|
+
state: p46.breaker.getState(),
|
|
7029
|
+
failureCount: p46.breaker.getFailureCount()
|
|
7018
7030
|
}));
|
|
7019
7031
|
}
|
|
7020
7032
|
/**
|
|
@@ -7024,8 +7036,8 @@ var init_fallback = __esm({
|
|
|
7024
7036
|
* previously failing providers to be tried again.
|
|
7025
7037
|
*/
|
|
7026
7038
|
resetCircuits() {
|
|
7027
|
-
for (const
|
|
7028
|
-
|
|
7039
|
+
for (const p46 of this.providers) {
|
|
7040
|
+
p46.breaker.reset();
|
|
7029
7041
|
}
|
|
7030
7042
|
}
|
|
7031
7043
|
/**
|
|
@@ -7169,8 +7181,8 @@ var init_resilient = __esm({
|
|
|
7169
7181
|
async *streamWithTools(messages, options) {
|
|
7170
7182
|
yield* this.streamWithPolicy(() => this.provider.streamWithTools(messages, options));
|
|
7171
7183
|
}
|
|
7172
|
-
countTokens(
|
|
7173
|
-
return this.provider.countTokens(
|
|
7184
|
+
countTokens(text15) {
|
|
7185
|
+
return this.provider.countTokens(text15);
|
|
7174
7186
|
}
|
|
7175
7187
|
getContextWindow() {
|
|
7176
7188
|
return this.provider.getContextWindow();
|
|
@@ -8483,8 +8495,8 @@ function tokenOverlap(queryTokens, targetTokens) {
|
|
|
8483
8495
|
}
|
|
8484
8496
|
return hits / queryTokens.length;
|
|
8485
8497
|
}
|
|
8486
|
-
function tokenize(
|
|
8487
|
-
return
|
|
8498
|
+
function tokenize(text15) {
|
|
8499
|
+
return text15.toLowerCase().replace(/[^a-z0-9\s-]/g, " ").split(/[\s-]+/).filter((word) => word.length > 1 && !STOP_WORDS.has(word)).map(stem);
|
|
8488
8500
|
}
|
|
8489
8501
|
function stem(word) {
|
|
8490
8502
|
if (word.length < 4) return word;
|
|
@@ -9581,8 +9593,8 @@ ${tail}`
|
|
|
9581
9593
|
estimateTokens(messages, provider) {
|
|
9582
9594
|
let total = 0;
|
|
9583
9595
|
for (const message of messages) {
|
|
9584
|
-
const
|
|
9585
|
-
total += provider.countTokens(
|
|
9596
|
+
const text15 = this.extractTextContent(message.content);
|
|
9597
|
+
total += provider.countTokens(text15);
|
|
9586
9598
|
}
|
|
9587
9599
|
return total;
|
|
9588
9600
|
}
|
|
@@ -11616,7 +11628,7 @@ function humanizeError(message, toolName) {
|
|
|
11616
11628
|
return msg;
|
|
11617
11629
|
}
|
|
11618
11630
|
function looksLikeTechnicalJargon(message) {
|
|
11619
|
-
return JARGON_PATTERNS.some((
|
|
11631
|
+
return JARGON_PATTERNS.some((p46) => p46.test(message));
|
|
11620
11632
|
}
|
|
11621
11633
|
async function humanizeWithLLM(errorMessage, toolName, provider) {
|
|
11622
11634
|
const prompt = [
|
|
@@ -12377,9 +12389,9 @@ function renderFileBlock(file, opts) {
|
|
|
12377
12389
|
);
|
|
12378
12390
|
}
|
|
12379
12391
|
const pairs = pairAdjacentLines(hunk.lines);
|
|
12380
|
-
const pairedDeleteIndices = new Set(pairs.map((
|
|
12381
|
-
const pairedAddIndices = new Set(pairs.map((
|
|
12382
|
-
const pairByAdd = new Map(pairs.map((
|
|
12392
|
+
const pairedDeleteIndices = new Set(pairs.map((p46) => p46.deleteIdx));
|
|
12393
|
+
const pairedAddIndices = new Set(pairs.map((p46) => p46.addIdx));
|
|
12394
|
+
const pairByAdd = new Map(pairs.map((p46) => [p46.addIdx, p46.deleteIdx]));
|
|
12383
12395
|
const wordHighlights = /* @__PURE__ */ new Map();
|
|
12384
12396
|
for (const pair of pairs) {
|
|
12385
12397
|
const delLine = hunk.lines[pair.deleteIdx];
|
|
@@ -12835,10 +12847,10 @@ var init_coverage = __esm({
|
|
|
12835
12847
|
join(this.projectPath, ".coverage", "coverage-summary.json"),
|
|
12836
12848
|
join(this.projectPath, "coverage", "lcov-report", "coverage-summary.json")
|
|
12837
12849
|
];
|
|
12838
|
-
for (const
|
|
12850
|
+
for (const p46 of possiblePaths) {
|
|
12839
12851
|
try {
|
|
12840
|
-
await access(
|
|
12841
|
-
const content = await readFile(
|
|
12852
|
+
await access(p46, constants.R_OK);
|
|
12853
|
+
const content = await readFile(p46, "utf-8");
|
|
12842
12854
|
const report = JSON.parse(content);
|
|
12843
12855
|
return parseCoverageSummary(report);
|
|
12844
12856
|
} catch {
|
|
@@ -18672,15 +18684,15 @@ ${message}
|
|
|
18672
18684
|
let stdoutBuffer = "";
|
|
18673
18685
|
let stderrBuffer = "";
|
|
18674
18686
|
subprocess.stdout?.on("data", (chunk) => {
|
|
18675
|
-
const
|
|
18676
|
-
stdoutBuffer +=
|
|
18677
|
-
process.stdout.write(
|
|
18687
|
+
const text15 = chunk.toString();
|
|
18688
|
+
stdoutBuffer += text15;
|
|
18689
|
+
process.stdout.write(text15);
|
|
18678
18690
|
heartbeat.activity();
|
|
18679
18691
|
});
|
|
18680
18692
|
subprocess.stderr?.on("data", (chunk) => {
|
|
18681
|
-
const
|
|
18682
|
-
stderrBuffer +=
|
|
18683
|
-
process.stderr.write(
|
|
18693
|
+
const text15 = chunk.toString();
|
|
18694
|
+
stderrBuffer += text15;
|
|
18695
|
+
process.stderr.write(text15);
|
|
18684
18696
|
heartbeat.activity();
|
|
18685
18697
|
});
|
|
18686
18698
|
const result = await subprocess;
|
|
@@ -20641,11 +20653,11 @@ function isBlockedPath(absolute) {
|
|
|
20641
20653
|
return void 0;
|
|
20642
20654
|
}
|
|
20643
20655
|
function isBlockedExecFile(filePath) {
|
|
20644
|
-
return BLOCKED_EXEC_PATTERNS.some((
|
|
20656
|
+
return BLOCKED_EXEC_PATTERNS.some((p46) => p46.test(filePath));
|
|
20645
20657
|
}
|
|
20646
20658
|
function hasDangerousArgs(args) {
|
|
20647
20659
|
const joined = args.join(" ");
|
|
20648
|
-
return DANGEROUS_ARG_PATTERNS.some((
|
|
20660
|
+
return DANGEROUS_ARG_PATTERNS.some((p46) => p46.test(joined));
|
|
20649
20661
|
}
|
|
20650
20662
|
function getInterpreter(ext) {
|
|
20651
20663
|
return INTERPRETER_MAP[ext.toLowerCase()];
|
|
@@ -23146,22 +23158,22 @@ var init_types7 = __esm({
|
|
|
23146
23158
|
});
|
|
23147
23159
|
|
|
23148
23160
|
// src/cli/repl/interruptions/classifier.ts
|
|
23149
|
-
function matchPatterns(
|
|
23161
|
+
function matchPatterns(text15, patterns) {
|
|
23150
23162
|
for (let i = 0; i < patterns.length; i++) {
|
|
23151
|
-
if (patterns[i].test(
|
|
23163
|
+
if (patterns[i].test(text15)) {
|
|
23152
23164
|
return 1 - i * 0.1;
|
|
23153
23165
|
}
|
|
23154
23166
|
}
|
|
23155
23167
|
return 0;
|
|
23156
23168
|
}
|
|
23157
23169
|
function classifyInterruption(message) {
|
|
23158
|
-
const
|
|
23159
|
-
const abortConf = matchPatterns(
|
|
23160
|
-
const modifyConf = matchPatterns(
|
|
23161
|
-
const correctConf = matchPatterns(
|
|
23170
|
+
const text15 = message.text;
|
|
23171
|
+
const abortConf = matchPatterns(text15, ABORT_PATTERNS);
|
|
23172
|
+
const modifyConf = matchPatterns(text15, MODIFY_PATTERNS);
|
|
23173
|
+
const correctConf = matchPatterns(text15, CORRECT_PATTERNS);
|
|
23162
23174
|
if (abortConf > 0 && abortConf >= modifyConf && abortConf >= correctConf) {
|
|
23163
23175
|
return {
|
|
23164
|
-
text:
|
|
23176
|
+
text: text15,
|
|
23165
23177
|
type: "abort" /* Abort */,
|
|
23166
23178
|
confidence: Math.min(1, abortConf),
|
|
23167
23179
|
timestamp: message.timestamp
|
|
@@ -23169,7 +23181,7 @@ function classifyInterruption(message) {
|
|
|
23169
23181
|
}
|
|
23170
23182
|
if (modifyConf > 0 && modifyConf >= correctConf) {
|
|
23171
23183
|
return {
|
|
23172
|
-
text:
|
|
23184
|
+
text: text15,
|
|
23173
23185
|
type: "modify" /* Modify */,
|
|
23174
23186
|
confidence: Math.min(1, modifyConf),
|
|
23175
23187
|
timestamp: message.timestamp
|
|
@@ -23177,14 +23189,14 @@ function classifyInterruption(message) {
|
|
|
23177
23189
|
}
|
|
23178
23190
|
if (correctConf > 0) {
|
|
23179
23191
|
return {
|
|
23180
|
-
text:
|
|
23192
|
+
text: text15,
|
|
23181
23193
|
type: "correct" /* Correct */,
|
|
23182
23194
|
confidence: Math.min(1, correctConf),
|
|
23183
23195
|
timestamp: message.timestamp
|
|
23184
23196
|
};
|
|
23185
23197
|
}
|
|
23186
23198
|
return {
|
|
23187
|
-
text:
|
|
23199
|
+
text: text15,
|
|
23188
23200
|
type: "info" /* Info */,
|
|
23189
23201
|
confidence: 0.5,
|
|
23190
23202
|
timestamp: message.timestamp
|
|
@@ -25692,10 +25704,10 @@ function inferTargetUsers(session) {
|
|
|
25692
25704
|
/(?:for|by)\s+(developers?|users?|administrators?|customers?)/gi,
|
|
25693
25705
|
/(developers?|users?|administrators?|customers?)\s+(?:can|will|should)/gi
|
|
25694
25706
|
];
|
|
25695
|
-
const
|
|
25707
|
+
const text15 = session.requirements.map((r) => r.description).join(" ");
|
|
25696
25708
|
for (const pattern of userPatterns) {
|
|
25697
25709
|
let match;
|
|
25698
|
-
while ((match = pattern.exec(
|
|
25710
|
+
while ((match = pattern.exec(text15)) !== null) {
|
|
25699
25711
|
const user = match[1]?.toLowerCase();
|
|
25700
25712
|
if (user && !users.includes(user)) {
|
|
25701
25713
|
users.push(user);
|
|
@@ -25708,13 +25720,13 @@ function inferTargetUsers(session) {
|
|
|
25708
25720
|
return users;
|
|
25709
25721
|
}
|
|
25710
25722
|
function inferProjectType(session) {
|
|
25711
|
-
const
|
|
25712
|
-
if (
|
|
25713
|
-
if (
|
|
25714
|
-
if (
|
|
25715
|
-
if (
|
|
25716
|
-
if (
|
|
25717
|
-
if (
|
|
25723
|
+
const text15 = session.initialInput.toLowerCase();
|
|
25724
|
+
if (text15.includes("cli") || text15.includes("command line")) return "cli";
|
|
25725
|
+
if (text15.includes("api") || text15.includes("rest") || text15.includes("graphql")) return "api";
|
|
25726
|
+
if (text15.includes("web app") || text15.includes("frontend")) return "web_app";
|
|
25727
|
+
if (text15.includes("library") || text15.includes("package")) return "library";
|
|
25728
|
+
if (text15.includes("service") || text15.includes("daemon")) return "service";
|
|
25729
|
+
if (text15.includes("full stack") || text15.includes("fullstack")) return "full_stack";
|
|
25718
25730
|
return "unknown";
|
|
25719
25731
|
}
|
|
25720
25732
|
function assessComplexity(session) {
|
|
@@ -29254,6 +29266,20 @@ var PROVIDER_DEFINITIONS = {
|
|
|
29254
29266
|
contextWindow: 2e5,
|
|
29255
29267
|
maxOutputTokens: 64e3
|
|
29256
29268
|
},
|
|
29269
|
+
{
|
|
29270
|
+
id: "claude-sonnet-4",
|
|
29271
|
+
name: "Claude Sonnet 4",
|
|
29272
|
+
description: "Previous balanced Claude model via Copilot \u2014 Premium x1",
|
|
29273
|
+
contextWindow: 2e5,
|
|
29274
|
+
maxOutputTokens: 64e3
|
|
29275
|
+
},
|
|
29276
|
+
{
|
|
29277
|
+
id: "claude-opus-4.6-fast",
|
|
29278
|
+
name: "Claude Opus 4.6 (Fast)",
|
|
29279
|
+
description: "Public preview fast Opus mode via Copilot \u2014 Premium x30",
|
|
29280
|
+
contextWindow: 2e5,
|
|
29281
|
+
maxOutputTokens: 128e3
|
|
29282
|
+
},
|
|
29257
29283
|
// OpenAI models (Codex/GPT-5+ use /responses API, others use /chat/completions)
|
|
29258
29284
|
{
|
|
29259
29285
|
id: "gpt-5.4-codex",
|
|
@@ -29278,40 +29304,111 @@ var PROVIDER_DEFINITIONS = {
|
|
|
29278
29304
|
maxOutputTokens: 128e3
|
|
29279
29305
|
},
|
|
29280
29306
|
{
|
|
29281
|
-
id: "gpt-5.
|
|
29282
|
-
name: "GPT-5.
|
|
29283
|
-
description: "
|
|
29307
|
+
id: "gpt-5.2",
|
|
29308
|
+
name: "GPT-5.2",
|
|
29309
|
+
description: "General GPT-5 model via Copilot \u2014 Premium x1",
|
|
29310
|
+
contextWindow: 4e5,
|
|
29311
|
+
maxOutputTokens: 128e3
|
|
29312
|
+
},
|
|
29313
|
+
{
|
|
29314
|
+
id: "gpt-5.4",
|
|
29315
|
+
name: "GPT-5.4",
|
|
29316
|
+
description: "Latest general GPT-5 model via Copilot \u2014 Premium x1",
|
|
29317
|
+
contextWindow: 4e5,
|
|
29318
|
+
maxOutputTokens: 128e3
|
|
29319
|
+
},
|
|
29320
|
+
{
|
|
29321
|
+
id: "gpt-5.4-mini",
|
|
29322
|
+
name: "GPT-5.4 mini",
|
|
29323
|
+
description: "Fast GPT-5.4 variant via Copilot \u2014 Premium x0.33",
|
|
29324
|
+
contextWindow: 4e5,
|
|
29325
|
+
maxOutputTokens: 128e3
|
|
29326
|
+
},
|
|
29327
|
+
{
|
|
29328
|
+
id: "gpt-5-mini",
|
|
29329
|
+
name: "GPT-5 mini",
|
|
29330
|
+
description: "Included model via Copilot paid plans \u2014 Premium x0",
|
|
29331
|
+
contextWindow: 4e5,
|
|
29332
|
+
maxOutputTokens: 128e3
|
|
29333
|
+
},
|
|
29334
|
+
{
|
|
29335
|
+
id: "gpt-5.1",
|
|
29336
|
+
name: "GPT-5.1",
|
|
29337
|
+
description: "Legacy GPT-5 model via Copilot \u2014 Premium x1",
|
|
29284
29338
|
contextWindow: 4e5,
|
|
29285
29339
|
maxOutputTokens: 128e3
|
|
29286
29340
|
},
|
|
29287
29341
|
{
|
|
29288
29342
|
id: "gpt-4.1",
|
|
29289
29343
|
name: "GPT-4.1",
|
|
29290
|
-
description: "OpenAI
|
|
29344
|
+
description: "Included OpenAI model via Copilot paid plans \u2014 Premium x0",
|
|
29291
29345
|
contextWindow: 1048576,
|
|
29292
29346
|
maxOutputTokens: 32768
|
|
29293
29347
|
},
|
|
29348
|
+
{
|
|
29349
|
+
id: "gpt-4o",
|
|
29350
|
+
name: "GPT-4o",
|
|
29351
|
+
description: "Included fallback/LTS OpenAI model via Copilot paid plans \u2014 Premium x0",
|
|
29352
|
+
contextWindow: 128e3,
|
|
29353
|
+
maxOutputTokens: 16384
|
|
29354
|
+
},
|
|
29294
29355
|
// Google models
|
|
29295
29356
|
{
|
|
29296
|
-
id: "gemini-3.1-pro
|
|
29357
|
+
id: "gemini-3.1-pro",
|
|
29297
29358
|
name: "Gemini 3.1 Pro",
|
|
29298
29359
|
description: "Google's latest model via Copilot (1M) \u2014 Premium x1",
|
|
29299
29360
|
contextWindow: 1e6,
|
|
29300
29361
|
maxOutputTokens: 64e3
|
|
29301
29362
|
},
|
|
29302
29363
|
{
|
|
29303
|
-
id: "gemini-3-
|
|
29364
|
+
id: "gemini-3.1-pro-preview",
|
|
29365
|
+
name: "Gemini 3.1 Pro (Preview ID)",
|
|
29366
|
+
description: "Compatibility alias for Gemini 3.1 Pro via Copilot \u2014 Premium x1",
|
|
29367
|
+
contextWindow: 1e6,
|
|
29368
|
+
maxOutputTokens: 64e3
|
|
29369
|
+
},
|
|
29370
|
+
{
|
|
29371
|
+
id: "gemini-3-flash",
|
|
29304
29372
|
name: "Gemini 3 Flash",
|
|
29305
29373
|
description: "Google's fast model via Copilot (1M) \u2014 Premium x0.33",
|
|
29306
29374
|
contextWindow: 1e6,
|
|
29307
29375
|
maxOutputTokens: 64e3
|
|
29308
29376
|
},
|
|
29377
|
+
{
|
|
29378
|
+
id: "gemini-3-flash-preview",
|
|
29379
|
+
name: "Gemini 3 Flash (Preview ID)",
|
|
29380
|
+
description: "Compatibility alias for Gemini 3 Flash via Copilot \u2014 Premium x0.33",
|
|
29381
|
+
contextWindow: 1e6,
|
|
29382
|
+
maxOutputTokens: 64e3
|
|
29383
|
+
},
|
|
29309
29384
|
{
|
|
29310
29385
|
id: "gemini-2.5-pro",
|
|
29311
29386
|
name: "Gemini 2.5 Pro",
|
|
29312
29387
|
description: "Google stable model via Copilot (1M) \u2014 Premium x1",
|
|
29313
29388
|
contextWindow: 1048576,
|
|
29314
29389
|
maxOutputTokens: 65536
|
|
29390
|
+
},
|
|
29391
|
+
// Evaluation models
|
|
29392
|
+
{
|
|
29393
|
+
id: "grok-code-fast-1",
|
|
29394
|
+
name: "Grok Code Fast 1",
|
|
29395
|
+
description: "xAI coding model via Copilot \u2014 Premium x0.25",
|
|
29396
|
+
contextWindow: 4e5,
|
|
29397
|
+
maxOutputTokens: 128e3
|
|
29398
|
+
},
|
|
29399
|
+
{
|
|
29400
|
+
id: "raptor-mini",
|
|
29401
|
+
name: "Raptor mini",
|
|
29402
|
+
description: "Fine-tuned GPT-5 mini via Copilot \u2014 Premium x0",
|
|
29403
|
+
contextWindow: 4e5,
|
|
29404
|
+
maxOutputTokens: 128e3
|
|
29405
|
+
},
|
|
29406
|
+
{
|
|
29407
|
+
id: "goldeneye",
|
|
29408
|
+
name: "Goldeneye",
|
|
29409
|
+
description: "Fine-tuned GPT-5.1-Codex via Copilot (Free x1)",
|
|
29410
|
+
contextWindow: 4e5,
|
|
29411
|
+
maxOutputTokens: 128e3
|
|
29315
29412
|
}
|
|
29316
29413
|
]
|
|
29317
29414
|
},
|
|
@@ -30095,7 +30192,7 @@ function getProviderDefinition(type) {
|
|
|
30095
30192
|
return PROVIDER_DEFINITIONS[type];
|
|
30096
30193
|
}
|
|
30097
30194
|
function getAllProviders() {
|
|
30098
|
-
return Object.values(PROVIDER_DEFINITIONS).filter((
|
|
30195
|
+
return Object.values(PROVIDER_DEFINITIONS).filter((p46) => !p46.internal);
|
|
30099
30196
|
}
|
|
30100
30197
|
function getRecommendedModel(type) {
|
|
30101
30198
|
const provider = PROVIDER_DEFINITIONS[type];
|
|
@@ -30116,20 +30213,20 @@ function hasLocalProviderConfig(type) {
|
|
|
30116
30213
|
return process.env["COCO_PROVIDER"] === "ollama" || !!process.env["OLLAMA_MODEL"] || !!process.env["OLLAMA_BASE_URL"];
|
|
30117
30214
|
}
|
|
30118
30215
|
function getConfiguredProviders() {
|
|
30119
|
-
return getAllProviders().filter((
|
|
30120
|
-
if (
|
|
30216
|
+
return getAllProviders().filter((p46) => {
|
|
30217
|
+
if (p46.id === "copilot") {
|
|
30121
30218
|
return !!process.env["GITHUB_TOKEN"] || !!process.env["GH_TOKEN"] || hasCopilotCredentials();
|
|
30122
30219
|
}
|
|
30123
|
-
if (
|
|
30124
|
-
return !!process.env[
|
|
30220
|
+
if (p46.id === "openai") {
|
|
30221
|
+
return !!process.env[p46.envVar] || !!process.env["OPENAI_CODEX_TOKEN"] || !!process.env["OPENAI_ACCESS_TOKEN"];
|
|
30125
30222
|
}
|
|
30126
|
-
if (
|
|
30127
|
-
return hasLocalProviderConfig(
|
|
30223
|
+
if (p46.id === "lmstudio" || p46.id === "ollama") {
|
|
30224
|
+
return hasLocalProviderConfig(p46.id);
|
|
30128
30225
|
}
|
|
30129
|
-
if (
|
|
30226
|
+
if (p46.id === "vertex") {
|
|
30130
30227
|
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
30228
|
}
|
|
30132
|
-
return !!process.env[
|
|
30229
|
+
return !!process.env[p46.envVar];
|
|
30133
30230
|
});
|
|
30134
30231
|
}
|
|
30135
30232
|
function isProviderConfigured(type) {
|
|
@@ -31264,8 +31361,8 @@ ${suggestionsHtml}
|
|
|
31264
31361
|
return filePath;
|
|
31265
31362
|
}
|
|
31266
31363
|
// ── Private helpers ───────────────────────────────────────────────────────
|
|
31267
|
-
htmlEscape(
|
|
31268
|
-
return
|
|
31364
|
+
htmlEscape(text15) {
|
|
31365
|
+
return text15.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
31269
31366
|
}
|
|
31270
31367
|
markdownIssue(issue) {
|
|
31271
31368
|
const severity = issue.severity === "critical" ? "\u{1F534}" : issue.severity === "major" ? "\u{1F7E1}" : "\u{1F535}";
|
|
@@ -31787,12 +31884,12 @@ Return only JSON: { "score": <number 1-10>, "reasoning": "<brief explanation>" }
|
|
|
31787
31884
|
}
|
|
31788
31885
|
return classifyFeatureHeuristic(feature);
|
|
31789
31886
|
}
|
|
31790
|
-
function extractJsonScore(
|
|
31887
|
+
function extractJsonScore(text15) {
|
|
31791
31888
|
try {
|
|
31792
|
-
const stripped =
|
|
31889
|
+
const stripped = text15.replace(/^```(?:json)?\s*\n?/, "").replace(/\n?```\s*$/, "").trim();
|
|
31793
31890
|
return JSON.parse(stripped);
|
|
31794
31891
|
} catch {
|
|
31795
|
-
const match =
|
|
31892
|
+
const match = text15.match(/\{[\s\S]*?\}/);
|
|
31796
31893
|
if (match) {
|
|
31797
31894
|
try {
|
|
31798
31895
|
return JSON.parse(match[0]);
|
|
@@ -32016,25 +32113,25 @@ Rules:
|
|
|
32016
32113
|
}
|
|
32017
32114
|
}
|
|
32018
32115
|
async function defaultPromptHandler(q) {
|
|
32019
|
-
const
|
|
32116
|
+
const p46 = await import('@clack/prompts');
|
|
32020
32117
|
if (q.options && q.options.length > 0) {
|
|
32021
|
-
const result = await
|
|
32118
|
+
const result = await p46.select({
|
|
32022
32119
|
message: q.question,
|
|
32023
32120
|
options: [
|
|
32024
32121
|
...q.options.map((o) => ({ value: o, label: o })),
|
|
32025
32122
|
{ value: q.assumedAnswer, label: `${q.assumedAnswer} (default)` }
|
|
32026
32123
|
]
|
|
32027
32124
|
});
|
|
32028
|
-
if (
|
|
32125
|
+
if (p46.isCancel(result)) {
|
|
32029
32126
|
return q.assumedAnswer;
|
|
32030
32127
|
}
|
|
32031
32128
|
return result;
|
|
32032
32129
|
} else {
|
|
32033
|
-
const result = await
|
|
32130
|
+
const result = await p46.text({
|
|
32034
32131
|
message: q.question,
|
|
32035
32132
|
placeholder: q.assumedAnswer
|
|
32036
32133
|
});
|
|
32037
|
-
if (
|
|
32134
|
+
if (p46.isCancel(result) || !result) {
|
|
32038
32135
|
return q.assumedAnswer;
|
|
32039
32136
|
}
|
|
32040
32137
|
return result;
|
|
@@ -33005,12 +33102,12 @@ function computeGlobalScore(results) {
|
|
|
33005
33102
|
const total = results.reduce((sum, r) => sum + r.reviewScore, 0);
|
|
33006
33103
|
return Math.round(total / results.length);
|
|
33007
33104
|
}
|
|
33008
|
-
function extractJson(
|
|
33105
|
+
function extractJson(text15) {
|
|
33009
33106
|
try {
|
|
33010
|
-
const stripped =
|
|
33107
|
+
const stripped = text15.replace(/^```(?:json)?\s*\n?/, "").replace(/\n?```\s*$/, "").trim();
|
|
33011
33108
|
return JSON.parse(stripped);
|
|
33012
33109
|
} catch {
|
|
33013
|
-
const match =
|
|
33110
|
+
const match = text15.match(/\{[\s\S]*\}/);
|
|
33014
33111
|
if (match) {
|
|
33015
33112
|
try {
|
|
33016
33113
|
return JSON.parse(match[0]);
|
|
@@ -33357,7 +33454,7 @@ init_env();
|
|
|
33357
33454
|
|
|
33358
33455
|
// src/cli/repl/quality-loop.ts
|
|
33359
33456
|
init_paths();
|
|
33360
|
-
var qualityLoopEnabled =
|
|
33457
|
+
var qualityLoopEnabled = false;
|
|
33361
33458
|
var hintShown = false;
|
|
33362
33459
|
function isQualityLoop() {
|
|
33363
33460
|
return qualityLoopEnabled;
|
|
@@ -33395,7 +33492,7 @@ function looksLikeFeatureRequest(input) {
|
|
|
33395
33492
|
return featureKeywords.some((re) => re.test(trimmed));
|
|
33396
33493
|
}
|
|
33397
33494
|
function formatQualityLoopHint() {
|
|
33398
|
-
return chalk.dim(" tip: ") + chalk.magenta("/quality") + chalk.dim(" enables auto-test
|
|
33495
|
+
return chalk.dim(" tip: ") + chalk.magenta("/quality on") + chalk.dim(" enables Coco quality mode: auto-test, self-review, and iterate until robust");
|
|
33399
33496
|
}
|
|
33400
33497
|
function formatQualityResult(result) {
|
|
33401
33498
|
const lines = [];
|
|
@@ -33439,7 +33536,8 @@ async function loadQualityLoopPreference() {
|
|
|
33439
33536
|
}
|
|
33440
33537
|
} catch {
|
|
33441
33538
|
}
|
|
33442
|
-
|
|
33539
|
+
qualityLoopEnabled = false;
|
|
33540
|
+
return false;
|
|
33443
33541
|
}
|
|
33444
33542
|
async function saveQualityLoopPreference(enabled) {
|
|
33445
33543
|
try {
|
|
@@ -33569,7 +33667,7 @@ async function renderStartupPanel(session, gitCtx, mcpServers = []) {
|
|
|
33569
33667
|
if (gitCtx) {
|
|
33570
33668
|
console.log(` ${formatGitLine(gitCtx)}`);
|
|
33571
33669
|
}
|
|
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}
|
|
33670
|
+
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
33671
|
console.log(cocoStatus);
|
|
33574
33672
|
const skillTotal = session.skillRegistry?.size ?? 0;
|
|
33575
33673
|
const hasSomething = skillTotal > 0 || mcpServers.length > 0;
|
|
@@ -33995,7 +34093,7 @@ async function runOnboardingV2() {
|
|
|
33995
34093
|
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
34094
|
console.log();
|
|
33997
34095
|
p26.log.info(
|
|
33998
|
-
`Found ${configuredProviders.length} configured provider(s): ${configuredProviders.map((
|
|
34096
|
+
`Found ${configuredProviders.length} configured provider(s): ${configuredProviders.map((p46) => p46.emoji + " " + p46.name).join(", ")}`
|
|
33999
34097
|
);
|
|
34000
34098
|
const useExisting = await p26.confirm({
|
|
34001
34099
|
message: "Use an existing provider?",
|
|
@@ -34680,9 +34778,9 @@ async function setupOllamaProvider(port) {
|
|
|
34680
34778
|
return setupLocalProvider("ollama", port);
|
|
34681
34779
|
}
|
|
34682
34780
|
async function selectExistingProvider(providers) {
|
|
34683
|
-
const options = providers.map((
|
|
34684
|
-
value:
|
|
34685
|
-
label: `${
|
|
34781
|
+
const options = providers.map((p46) => ({
|
|
34782
|
+
value: p46.id,
|
|
34783
|
+
label: `${p46.emoji} ${p46.name}`,
|
|
34686
34784
|
hint: "Configured"
|
|
34687
34785
|
}));
|
|
34688
34786
|
options.push({ value: "__new__", label: "\u2795 Setup new provider", hint: "" });
|
|
@@ -35074,7 +35172,7 @@ async function ensureConfiguredV2(config) {
|
|
|
35074
35172
|
} catch {
|
|
35075
35173
|
}
|
|
35076
35174
|
}
|
|
35077
|
-
const preferredProviderDef = providers.find((
|
|
35175
|
+
const preferredProviderDef = providers.find((p46) => p46.id === config.provider.type);
|
|
35078
35176
|
const preferredIsLocal = preferredProviderDef?.requiresApiKey === false && preferredProviderDef?.id !== "copilot";
|
|
35079
35177
|
const preferredHasApiKey = preferredProviderDef ? !!process.env[preferredProviderDef.envVar] : false;
|
|
35080
35178
|
const preferredHasOpenAIOAuth = preferredProviderDef?.id === "openai" && hasOpenAIOAuthTokens;
|
|
@@ -35104,12 +35202,12 @@ async function ensureConfiguredV2(config) {
|
|
|
35104
35202
|
preferredUnavailableWasLocal = preferredIsLocal;
|
|
35105
35203
|
}
|
|
35106
35204
|
if (!preferredWasConfiguredButUnavailable || !preferredUnavailableWasLocal) {
|
|
35107
|
-
const configuredProviders = providers.filter((
|
|
35108
|
-
if (
|
|
35109
|
-
if (
|
|
35110
|
-
return hasOpenAIOAuthTokens || !!process.env[
|
|
35205
|
+
const configuredProviders = providers.filter((p46) => {
|
|
35206
|
+
if (p46.id === "copilot") return isProviderConfigured();
|
|
35207
|
+
if (p46.id === "openai") {
|
|
35208
|
+
return hasOpenAIOAuthTokens || !!process.env[p46.envVar];
|
|
35111
35209
|
}
|
|
35112
|
-
return
|
|
35210
|
+
return p46.requiresApiKey === false || !!process.env[p46.envVar];
|
|
35113
35211
|
});
|
|
35114
35212
|
for (const prov of configuredProviders) {
|
|
35115
35213
|
try {
|
|
@@ -35182,7 +35280,7 @@ init_auth();
|
|
|
35182
35280
|
init_env();
|
|
35183
35281
|
async function selectProviderInteractively(providers, currentProviderId) {
|
|
35184
35282
|
return new Promise((resolve4) => {
|
|
35185
|
-
let selectedIndex = providers.findIndex((
|
|
35283
|
+
let selectedIndex = providers.findIndex((p46) => p46.id === currentProviderId);
|
|
35186
35284
|
if (selectedIndex === -1) selectedIndex = 0;
|
|
35187
35285
|
let lastTotalLines = 0;
|
|
35188
35286
|
const clearPrevious = () => {
|
|
@@ -35280,12 +35378,12 @@ var providerCommand = {
|
|
|
35280
35378
|
`));
|
|
35281
35379
|
const allProviders2 = getAllProviders();
|
|
35282
35380
|
const configuredProviders = getConfiguredProviders();
|
|
35283
|
-
const providerOptions = allProviders2.map((
|
|
35284
|
-
id:
|
|
35285
|
-
name:
|
|
35286
|
-
emoji:
|
|
35287
|
-
description:
|
|
35288
|
-
isConfigured: configuredProviders.some((cp) => cp.id ===
|
|
35381
|
+
const providerOptions = allProviders2.map((p46) => ({
|
|
35382
|
+
id: p46.id,
|
|
35383
|
+
name: p46.name,
|
|
35384
|
+
emoji: p46.emoji,
|
|
35385
|
+
description: p46.description,
|
|
35386
|
+
isConfigured: configuredProviders.some((cp) => cp.id === p46.id)
|
|
35289
35387
|
}));
|
|
35290
35388
|
const selectedProviderId = await selectProviderInteractively(
|
|
35291
35389
|
providerOptions,
|
|
@@ -35300,15 +35398,15 @@ var providerCommand = {
|
|
|
35300
35398
|
`));
|
|
35301
35399
|
return false;
|
|
35302
35400
|
}
|
|
35303
|
-
const newProvider2 = allProviders2.find((
|
|
35401
|
+
const newProvider2 = allProviders2.find((p46) => p46.id === selectedProviderId);
|
|
35304
35402
|
return await switchProvider(newProvider2, session);
|
|
35305
35403
|
}
|
|
35306
35404
|
const newProviderId = args[0]?.toLowerCase();
|
|
35307
35405
|
const allProviders = getAllProviders();
|
|
35308
|
-
const newProvider = allProviders.find((
|
|
35406
|
+
const newProvider = allProviders.find((p46) => p46.id === newProviderId);
|
|
35309
35407
|
if (!newProvider) {
|
|
35310
35408
|
console.log(chalk.red(`Unknown provider: ${newProviderId}`));
|
|
35311
|
-
console.log(chalk.dim(`Available: ${allProviders.map((
|
|
35409
|
+
console.log(chalk.dim(`Available: ${allProviders.map((p46) => p46.id).join(", ")}
|
|
35312
35410
|
`));
|
|
35313
35411
|
return false;
|
|
35314
35412
|
}
|
|
@@ -36345,7 +36443,7 @@ async function showTrustStatus(session, trustStore) {
|
|
|
36345
36443
|
}
|
|
36346
36444
|
const level = trustStore.getLevel(projectPath);
|
|
36347
36445
|
const list = trustStore.list();
|
|
36348
|
-
const project = list.find((
|
|
36446
|
+
const project = list.find((p46) => p46.path === projectPath);
|
|
36349
36447
|
p26.log.message("");
|
|
36350
36448
|
p26.log.message(`\u{1F510} Project Trust Status`);
|
|
36351
36449
|
p26.log.message(` Path: ${projectPath}`);
|
|
@@ -38312,8 +38410,8 @@ var STARTUP_TIMEOUT_MS = 5500;
|
|
|
38312
38410
|
var CACHE_DIR = path39__default.join(os4__default.homedir(), ".coco");
|
|
38313
38411
|
var CACHE_FILE = path39__default.join(CACHE_DIR, "version-check-cache.json");
|
|
38314
38412
|
function compareVersions(a, b) {
|
|
38315
|
-
const partsA = a.replace(/^v/, "").split(".").map((
|
|
38316
|
-
const partsB = b.replace(/^v/, "").split(".").map((
|
|
38413
|
+
const partsA = a.replace(/^v/, "").split(".").map((p46) => Number(p46.replace(/-.*$/, "")));
|
|
38414
|
+
const partsB = b.replace(/^v/, "").split(".").map((p46) => Number(p46.replace(/-.*$/, "")));
|
|
38317
38415
|
for (let i = 0; i < 3; i++) {
|
|
38318
38416
|
const numA = partsA[i] ?? 0;
|
|
38319
38417
|
const numB = partsB[i] ?? 0;
|
|
@@ -38437,13 +38535,13 @@ async function checkForUpdatesInteractive() {
|
|
|
38437
38535
|
]);
|
|
38438
38536
|
clearTimeout(startupTimerId);
|
|
38439
38537
|
if (!updateInfo) return;
|
|
38440
|
-
const
|
|
38538
|
+
const p46 = await import('@clack/prompts');
|
|
38441
38539
|
printUpdateBanner(updateInfo);
|
|
38442
|
-
const answer = await
|
|
38540
|
+
const answer = await p46.confirm({
|
|
38443
38541
|
message: "Exit now to update?",
|
|
38444
38542
|
initialValue: true
|
|
38445
38543
|
});
|
|
38446
|
-
if (!
|
|
38544
|
+
if (!p46.isCancel(answer) && answer) {
|
|
38447
38545
|
console.log();
|
|
38448
38546
|
console.log(chalk.dim(` Running: ${updateInfo.updateCommand}`));
|
|
38449
38547
|
console.log();
|
|
@@ -38572,7 +38670,7 @@ function getClipboardCommand() {
|
|
|
38572
38670
|
}
|
|
38573
38671
|
return null;
|
|
38574
38672
|
}
|
|
38575
|
-
async function copyToClipboard(
|
|
38673
|
+
async function copyToClipboard(text15) {
|
|
38576
38674
|
const clipboardCmd = getClipboardCommand();
|
|
38577
38675
|
if (!clipboardCmd) {
|
|
38578
38676
|
return false;
|
|
@@ -38593,7 +38691,7 @@ async function copyToClipboard(text14) {
|
|
|
38593
38691
|
});
|
|
38594
38692
|
xselProc.on("error", () => resolve4(false));
|
|
38595
38693
|
xselProc.on("close", (code) => resolve4(code === 0));
|
|
38596
|
-
xselProc.stdin.write(
|
|
38694
|
+
xselProc.stdin.write(text15);
|
|
38597
38695
|
xselProc.stdin.end();
|
|
38598
38696
|
} catch {
|
|
38599
38697
|
resolve4(false);
|
|
@@ -38609,7 +38707,7 @@ async function copyToClipboard(text14) {
|
|
|
38609
38707
|
});
|
|
38610
38708
|
proc.stdin.on("error", () => {
|
|
38611
38709
|
});
|
|
38612
|
-
proc.stdin.write(
|
|
38710
|
+
proc.stdin.write(text15);
|
|
38613
38711
|
proc.stdin.end();
|
|
38614
38712
|
} catch {
|
|
38615
38713
|
resolve4(false);
|
|
@@ -39369,7 +39467,7 @@ async function shouldShowPermissionSuggestion(projectPath = process.cwd()) {
|
|
|
39369
39467
|
}
|
|
39370
39468
|
async function applyRecommendedPermissions(projectPath = process.cwd()) {
|
|
39371
39469
|
for (const tool of [...RECOMMENDED_GLOBAL, ...RECOMMENDED_PROJECT]) {
|
|
39372
|
-
await saveTrustedTool(tool,
|
|
39470
|
+
await saveTrustedTool(tool, projectPath, false);
|
|
39373
39471
|
}
|
|
39374
39472
|
await saveProjectPermissionPreference("recommendedAllowlistAppliedProjects", projectPath, true);
|
|
39375
39473
|
await saveProjectPermissionPreference(
|
|
@@ -39382,7 +39480,7 @@ async function showPermissionSuggestion(projectPath = process.cwd()) {
|
|
|
39382
39480
|
console.log();
|
|
39383
39481
|
console.log(chalk.magenta.bold(" \u{1F4CB} Recommended Permissions"));
|
|
39384
39482
|
console.log();
|
|
39385
|
-
console.log(chalk.dim(" Coco has a curated set of tool permissions for
|
|
39483
|
+
console.log(chalk.dim(" Coco has a curated set of tool permissions for this project:"));
|
|
39386
39484
|
console.log(chalk.dim(" \u2022 Allow: file read/write, search, git staging, build, tests..."));
|
|
39387
39485
|
console.log(
|
|
39388
39486
|
chalk.dim(" \u2022 Ask each time: git commit, curl, rm, git pull, docker exec, cloud...")
|
|
@@ -39391,12 +39489,17 @@ async function showPermissionSuggestion(projectPath = process.cwd()) {
|
|
|
39391
39489
|
console.log();
|
|
39392
39490
|
console.log(chalk.dim(" Stored in ~/.coco/trusted-tools.json \u2014 edit manually or let"));
|
|
39393
39491
|
console.log(chalk.dim(" Coco manage it when you approve actions from the prompt."));
|
|
39492
|
+
console.log(chalk.dim(" Note: applying here affects only the current project."));
|
|
39394
39493
|
console.log();
|
|
39395
39494
|
const action = await p26.select({
|
|
39396
39495
|
message: "Apply recommended permissions?",
|
|
39397
39496
|
options: [
|
|
39398
39497
|
{ value: "view", label: "View details", hint: "See the full list before deciding" },
|
|
39399
|
-
{
|
|
39498
|
+
{
|
|
39499
|
+
value: "apply",
|
|
39500
|
+
label: "Apply",
|
|
39501
|
+
hint: "Apply recommended permissions for this project"
|
|
39502
|
+
},
|
|
39400
39503
|
{ value: "later", label: "Later", hint: "Remind me next time" },
|
|
39401
39504
|
{ value: "dismiss", label: "No thanks", hint: "Don't show again" }
|
|
39402
39505
|
]
|
|
@@ -40208,9 +40311,9 @@ var UserCancelledError = class extends Error {
|
|
|
40208
40311
|
var SPEC_AGENT_SYSTEM = `You are a senior technical product manager specialising in rapid MVP delivery.
|
|
40209
40312
|
Your job is to help a developer plan a software project efficiently and honestly.
|
|
40210
40313
|
Always respond with valid JSON only \u2014 no markdown fences, no prose outside JSON.`;
|
|
40211
|
-
function extractJson2(
|
|
40212
|
-
const match =
|
|
40213
|
-
return match ? (match[1] ??
|
|
40314
|
+
function extractJson2(text15) {
|
|
40315
|
+
const match = text15.match(/```(?:json)?\s*([\s\S]*?)```/) ?? text15.match(/(\{[\s\S]*\})/);
|
|
40316
|
+
return match ? (match[1] ?? text15).trim() : text15.trim();
|
|
40214
40317
|
}
|
|
40215
40318
|
function validateBacklogSpec(raw) {
|
|
40216
40319
|
if (!raw.sprints || raw.sprints.length === 0) {
|
|
@@ -43851,15 +43954,15 @@ ${message}
|
|
|
43851
43954
|
let stdoutBuffer = "";
|
|
43852
43955
|
let stderrBuffer = "";
|
|
43853
43956
|
subprocess.stdout?.on("data", (chunk) => {
|
|
43854
|
-
const
|
|
43855
|
-
stdoutBuffer +=
|
|
43856
|
-
process.stdout.write(
|
|
43957
|
+
const text15 = chunk.toString();
|
|
43958
|
+
stdoutBuffer += text15;
|
|
43959
|
+
process.stdout.write(text15);
|
|
43857
43960
|
heartbeat.activity();
|
|
43858
43961
|
});
|
|
43859
43962
|
subprocess.stderr?.on("data", (chunk) => {
|
|
43860
|
-
const
|
|
43861
|
-
stderrBuffer +=
|
|
43862
|
-
process.stderr.write(
|
|
43963
|
+
const text15 = chunk.toString();
|
|
43964
|
+
stderrBuffer += text15;
|
|
43965
|
+
process.stderr.write(text15);
|
|
43863
43966
|
heartbeat.activity();
|
|
43864
43967
|
});
|
|
43865
43968
|
const result = await subprocess;
|
|
@@ -43976,15 +44079,15 @@ ${message}
|
|
|
43976
44079
|
let stdoutBuffer = "";
|
|
43977
44080
|
let stderrBuffer = "";
|
|
43978
44081
|
subprocess.stdout?.on("data", (chunk) => {
|
|
43979
|
-
const
|
|
43980
|
-
stdoutBuffer +=
|
|
43981
|
-
process.stdout.write(
|
|
44082
|
+
const text15 = chunk.toString();
|
|
44083
|
+
stdoutBuffer += text15;
|
|
44084
|
+
process.stdout.write(text15);
|
|
43982
44085
|
heartbeat.activity();
|
|
43983
44086
|
});
|
|
43984
44087
|
subprocess.stderr?.on("data", (chunk) => {
|
|
43985
|
-
const
|
|
43986
|
-
stderrBuffer +=
|
|
43987
|
-
process.stderr.write(
|
|
44088
|
+
const text15 = chunk.toString();
|
|
44089
|
+
stderrBuffer += text15;
|
|
44090
|
+
process.stderr.write(text15);
|
|
43988
44091
|
heartbeat.activity();
|
|
43989
44092
|
});
|
|
43990
44093
|
const result = await subprocess;
|
|
@@ -44078,15 +44181,15 @@ ${message}
|
|
|
44078
44181
|
let stdoutBuffer = "";
|
|
44079
44182
|
let stderrBuffer = "";
|
|
44080
44183
|
subprocess.stdout?.on("data", (chunk) => {
|
|
44081
|
-
const
|
|
44082
|
-
stdoutBuffer +=
|
|
44083
|
-
process.stdout.write(
|
|
44184
|
+
const text15 = chunk.toString();
|
|
44185
|
+
stdoutBuffer += text15;
|
|
44186
|
+
process.stdout.write(text15);
|
|
44084
44187
|
heartbeat.activity();
|
|
44085
44188
|
});
|
|
44086
44189
|
subprocess.stderr?.on("data", (chunk) => {
|
|
44087
|
-
const
|
|
44088
|
-
stderrBuffer +=
|
|
44089
|
-
process.stderr.write(
|
|
44190
|
+
const text15 = chunk.toString();
|
|
44191
|
+
stderrBuffer += text15;
|
|
44192
|
+
process.stderr.write(text15);
|
|
44090
44193
|
heartbeat.activity();
|
|
44091
44194
|
});
|
|
44092
44195
|
const result = await subprocess;
|
|
@@ -44181,15 +44284,15 @@ ${message}
|
|
|
44181
44284
|
let stdoutBuffer = "";
|
|
44182
44285
|
let stderrBuffer = "";
|
|
44183
44286
|
subprocess.stdout?.on("data", (chunk) => {
|
|
44184
|
-
const
|
|
44185
|
-
stdoutBuffer +=
|
|
44186
|
-
process.stdout.write(
|
|
44287
|
+
const text15 = chunk.toString();
|
|
44288
|
+
stdoutBuffer += text15;
|
|
44289
|
+
process.stdout.write(text15);
|
|
44187
44290
|
heartbeat.activity();
|
|
44188
44291
|
});
|
|
44189
44292
|
subprocess.stderr?.on("data", (chunk) => {
|
|
44190
|
-
const
|
|
44191
|
-
stderrBuffer +=
|
|
44192
|
-
process.stderr.write(
|
|
44293
|
+
const text15 = chunk.toString();
|
|
44294
|
+
stderrBuffer += text15;
|
|
44295
|
+
process.stderr.write(text15);
|
|
44193
44296
|
heartbeat.activity();
|
|
44194
44297
|
});
|
|
44195
44298
|
const result = await subprocess;
|
|
@@ -44285,15 +44388,15 @@ ${message}
|
|
|
44285
44388
|
let stdoutBuffer = "";
|
|
44286
44389
|
let stderrBuffer = "";
|
|
44287
44390
|
subprocess.stdout?.on("data", (chunk) => {
|
|
44288
|
-
const
|
|
44289
|
-
stdoutBuffer +=
|
|
44290
|
-
process.stdout.write(
|
|
44391
|
+
const text15 = chunk.toString();
|
|
44392
|
+
stdoutBuffer += text15;
|
|
44393
|
+
process.stdout.write(text15);
|
|
44291
44394
|
heartbeat.activity();
|
|
44292
44395
|
});
|
|
44293
44396
|
subprocess.stderr?.on("data", (chunk) => {
|
|
44294
|
-
const
|
|
44295
|
-
stderrBuffer +=
|
|
44296
|
-
process.stderr.write(
|
|
44397
|
+
const text15 = chunk.toString();
|
|
44398
|
+
stderrBuffer += text15;
|
|
44399
|
+
process.stderr.write(text15);
|
|
44297
44400
|
heartbeat.activity();
|
|
44298
44401
|
});
|
|
44299
44402
|
const result = await subprocess;
|
|
@@ -44372,15 +44475,15 @@ ${message}
|
|
|
44372
44475
|
let stdoutBuffer = "";
|
|
44373
44476
|
let stderrBuffer = "";
|
|
44374
44477
|
subprocess.stdout?.on("data", (chunk) => {
|
|
44375
|
-
const
|
|
44376
|
-
stdoutBuffer +=
|
|
44377
|
-
process.stdout.write(
|
|
44478
|
+
const text15 = chunk.toString();
|
|
44479
|
+
stdoutBuffer += text15;
|
|
44480
|
+
process.stdout.write(text15);
|
|
44378
44481
|
heartbeat.activity();
|
|
44379
44482
|
});
|
|
44380
44483
|
subprocess.stderr?.on("data", (chunk) => {
|
|
44381
|
-
const
|
|
44382
|
-
stderrBuffer +=
|
|
44383
|
-
process.stderr.write(
|
|
44484
|
+
const text15 = chunk.toString();
|
|
44485
|
+
stderrBuffer += text15;
|
|
44486
|
+
process.stderr.write(text15);
|
|
44384
44487
|
heartbeat.activity();
|
|
44385
44488
|
});
|
|
44386
44489
|
const result = await subprocess;
|
|
@@ -44871,16 +44974,16 @@ function htmlToMarkdown(html) {
|
|
|
44871
44974
|
const prefix = "#".repeat(i);
|
|
44872
44975
|
const regex = new RegExp(`<h${i}[^>]*>([\\s\\S]*?)<\\/h${i}>`, "gi");
|
|
44873
44976
|
md = md.replace(regex, (_, content) => {
|
|
44874
|
-
const
|
|
44875
|
-
return
|
|
44977
|
+
const text15 = content.replace(/<[^>]*>/g, "").trim();
|
|
44978
|
+
return text15 ? `
|
|
44876
44979
|
|
|
44877
|
-
${prefix} ${
|
|
44980
|
+
${prefix} ${text15}
|
|
44878
44981
|
|
|
44879
44982
|
` : "";
|
|
44880
44983
|
});
|
|
44881
44984
|
}
|
|
44882
|
-
md = md.replace(/<a\s+[^>]*href=["']([^"']+)["'][^>]*>([\s\S]*?)<\/a>/gi, (_, href,
|
|
44883
|
-
const cleanText =
|
|
44985
|
+
md = md.replace(/<a\s+[^>]*href=["']([^"']+)["'][^>]*>([\s\S]*?)<\/a>/gi, (_, href, text15) => {
|
|
44986
|
+
const cleanText = text15.replace(/<[^>]*>/g, "").trim();
|
|
44884
44987
|
if (!cleanText) return "";
|
|
44885
44988
|
if (href.startsWith("#") || href.startsWith("javascript:")) return cleanText;
|
|
44886
44989
|
return `[${cleanText}](${href})`;
|
|
@@ -44907,8 +45010,8 @@ ${decoded.trim()}
|
|
|
44907
45010
|
});
|
|
44908
45011
|
md = md.replace(/<ul[^>]*>([\s\S]*?)<\/ul>/gi, (_, items) => {
|
|
44909
45012
|
return "\n" + items.replace(/<li[^>]*>([\s\S]*?)<\/li>/gi, (_2, item) => {
|
|
44910
|
-
const
|
|
44911
|
-
return
|
|
45013
|
+
const text15 = item.replace(/<[^>]*>/g, "").trim();
|
|
45014
|
+
return text15 ? `- ${text15}
|
|
44912
45015
|
` : "";
|
|
44913
45016
|
}) + "\n";
|
|
44914
45017
|
});
|
|
@@ -44916,29 +45019,29 @@ ${decoded.trim()}
|
|
|
44916
45019
|
let counter = 0;
|
|
44917
45020
|
return "\n" + items.replace(/<li[^>]*>([\s\S]*?)<\/li>/gi, (_2, item) => {
|
|
44918
45021
|
counter++;
|
|
44919
|
-
const
|
|
44920
|
-
return
|
|
45022
|
+
const text15 = item.replace(/<[^>]*>/g, "").trim();
|
|
45023
|
+
return text15 ? `${counter}. ${text15}
|
|
44921
45024
|
` : "";
|
|
44922
45025
|
}) + "\n";
|
|
44923
45026
|
});
|
|
44924
45027
|
md = md.replace(/<blockquote[^>]*>([\s\S]*?)<\/blockquote>/gi, (_, content) => {
|
|
44925
|
-
const
|
|
44926
|
-
return
|
|
45028
|
+
const text15 = content.replace(/<[^>]*>/g, "").trim();
|
|
45029
|
+
return text15 ? "\n" + text15.split("\n").map((line) => `> ${line.trim()}`).join("\n") + "\n" : "";
|
|
44927
45030
|
});
|
|
44928
45031
|
md = md.replace(/<p[^>]*>([\s\S]*?)<\/p>/gi, (_, content) => {
|
|
44929
|
-
const
|
|
44930
|
-
return
|
|
45032
|
+
const text15 = content.replace(/<[^>]*>/g, "").trim();
|
|
45033
|
+
return text15 ? `
|
|
44931
45034
|
|
|
44932
|
-
${
|
|
45035
|
+
${text15}
|
|
44933
45036
|
|
|
44934
45037
|
` : "";
|
|
44935
45038
|
});
|
|
44936
45039
|
md = md.replace(/<br\s*\/?>/gi, "\n");
|
|
44937
45040
|
md = md.replace(
|
|
44938
45041
|
/<(?:strong|b)[^>]*>([\s\S]*?)<\/(?:strong|b)>/gi,
|
|
44939
|
-
(_,
|
|
45042
|
+
(_, text15) => `**${text15.trim()}**`
|
|
44940
45043
|
);
|
|
44941
|
-
md = md.replace(/<(?:em|i)[^>]*>([\s\S]*?)<\/(?:em|i)>/gi, (_,
|
|
45044
|
+
md = md.replace(/<(?:em|i)[^>]*>([\s\S]*?)<\/(?:em|i)>/gi, (_, text15) => `*${text15.trim()}*`);
|
|
44942
45045
|
md = md.replace(/<hr\s*\/?>/gi, "\n---\n");
|
|
44943
45046
|
md = md.replace(/<table[^>]*>([\s\S]*?)<\/table>/gi, (_, tableContent) => {
|
|
44944
45047
|
const rows = [];
|
|
@@ -46068,10 +46171,10 @@ function chunkContent(content, chunkSize) {
|
|
|
46068
46171
|
const chunks = [];
|
|
46069
46172
|
for (let i = 0; i < lines.length; i += chunkSize) {
|
|
46070
46173
|
const chunkLines = lines.slice(i, Math.min(i + chunkSize, lines.length));
|
|
46071
|
-
const
|
|
46072
|
-
if (
|
|
46174
|
+
const text15 = chunkLines.join("\n").trim();
|
|
46175
|
+
if (text15.length > 10) {
|
|
46073
46176
|
chunks.push({
|
|
46074
|
-
text:
|
|
46177
|
+
text: text15,
|
|
46075
46178
|
startLine: i + 1,
|
|
46076
46179
|
endLine: Math.min(i + chunkSize, lines.length)
|
|
46077
46180
|
});
|
|
@@ -46079,8 +46182,8 @@ function chunkContent(content, chunkSize) {
|
|
|
46079
46182
|
}
|
|
46080
46183
|
return chunks;
|
|
46081
46184
|
}
|
|
46082
|
-
function simpleEmbedding(
|
|
46083
|
-
const words =
|
|
46185
|
+
function simpleEmbedding(text15) {
|
|
46186
|
+
const words = text15.toLowerCase().replace(/[^\w\s]/g, " ").split(/\s+/).filter((w) => w.length > 1);
|
|
46084
46187
|
const freq = /* @__PURE__ */ new Map();
|
|
46085
46188
|
for (const word of words) {
|
|
46086
46189
|
freq.set(word, (freq.get(word) ?? 0) + 1);
|
|
@@ -46106,7 +46209,7 @@ function simpleEmbedding(text14) {
|
|
|
46106
46209
|
}
|
|
46107
46210
|
var embedFn = null;
|
|
46108
46211
|
var usingFallbackEmbedding = false;
|
|
46109
|
-
async function getEmbedding(
|
|
46212
|
+
async function getEmbedding(text15) {
|
|
46110
46213
|
if (!embedFn) {
|
|
46111
46214
|
try {
|
|
46112
46215
|
const transformers = await import('@xenova/transformers');
|
|
@@ -46123,7 +46226,7 @@ async function getEmbedding(text14) {
|
|
|
46123
46226
|
usingFallbackEmbedding = true;
|
|
46124
46227
|
}
|
|
46125
46228
|
}
|
|
46126
|
-
return embedFn(
|
|
46229
|
+
return embedFn(text15);
|
|
46127
46230
|
}
|
|
46128
46231
|
async function loadIndex2(indexDir) {
|
|
46129
46232
|
try {
|
|
@@ -46676,23 +46779,23 @@ Examples:
|
|
|
46676
46779
|
const pdfData = await pdfParse.default(dataBuffer, {
|
|
46677
46780
|
max: maxPages
|
|
46678
46781
|
});
|
|
46679
|
-
let
|
|
46782
|
+
let text15 = pdfData.text;
|
|
46680
46783
|
let truncated = false;
|
|
46681
46784
|
const totalPages = pdfData.numpages;
|
|
46682
46785
|
if (pages) {
|
|
46683
46786
|
const range = parsePageRange(pages, totalPages);
|
|
46684
|
-
const pageTexts =
|
|
46787
|
+
const pageTexts = text15.split(/\f/);
|
|
46685
46788
|
if (pageTexts.length > 1) {
|
|
46686
46789
|
const selectedPages = pageTexts.slice(range.start - 1, range.end);
|
|
46687
|
-
|
|
46790
|
+
text15 = selectedPages.join("\n\n--- Page Break ---\n\n");
|
|
46688
46791
|
}
|
|
46689
46792
|
}
|
|
46690
|
-
if (
|
|
46691
|
-
|
|
46793
|
+
if (text15.length > 5e5) {
|
|
46794
|
+
text15 = text15.slice(0, 5e5);
|
|
46692
46795
|
truncated = true;
|
|
46693
46796
|
}
|
|
46694
46797
|
return {
|
|
46695
|
-
text:
|
|
46798
|
+
text: text15,
|
|
46696
46799
|
pages: totalPages,
|
|
46697
46800
|
metadata: {
|
|
46698
46801
|
title: pdfData.info?.Title,
|
|
@@ -47706,7 +47809,14 @@ var SuggestImprovementsSchema = z.object({
|
|
|
47706
47809
|
context: z.string().optional().describe("Additional context about the code")
|
|
47707
47810
|
});
|
|
47708
47811
|
async function analyzeAndSuggest(filePath, _context) {
|
|
47709
|
-
|
|
47812
|
+
let rawContent = await fs46.readFile(filePath, "utf-8");
|
|
47813
|
+
if (typeof rawContent !== "string") {
|
|
47814
|
+
const defaultReadFile = fs46.default?.readFile;
|
|
47815
|
+
if (typeof defaultReadFile === "function") {
|
|
47816
|
+
rawContent = await defaultReadFile(filePath, "utf-8");
|
|
47817
|
+
}
|
|
47818
|
+
}
|
|
47819
|
+
const content = typeof rawContent === "string" ? rawContent : String(rawContent ?? "");
|
|
47710
47820
|
const lines = content.split("\n");
|
|
47711
47821
|
const suggestions = [];
|
|
47712
47822
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -48071,11 +48181,11 @@ var getLearnedPatternsTool = defineTool({
|
|
|
48071
48181
|
const patterns = store.getFrequentPatterns(typedInput.limit);
|
|
48072
48182
|
return {
|
|
48073
48183
|
totalPatterns: patterns.length,
|
|
48074
|
-
patterns: patterns.map((
|
|
48075
|
-
pattern:
|
|
48076
|
-
preference:
|
|
48077
|
-
frequency:
|
|
48078
|
-
lastUsed: new Date(
|
|
48184
|
+
patterns: patterns.map((p46) => ({
|
|
48185
|
+
pattern: p46.pattern,
|
|
48186
|
+
preference: p46.userPreference,
|
|
48187
|
+
frequency: p46.frequency,
|
|
48188
|
+
lastUsed: new Date(p46.lastUsed).toISOString()
|
|
48079
48189
|
}))
|
|
48080
48190
|
};
|
|
48081
48191
|
}
|
|
@@ -50119,24 +50229,24 @@ function formatHtmlLine(line) {
|
|
|
50119
50229
|
}
|
|
50120
50230
|
return null;
|
|
50121
50231
|
}
|
|
50122
|
-
function formatInlineMarkdown(
|
|
50123
|
-
|
|
50124
|
-
|
|
50125
|
-
|
|
50126
|
-
|
|
50127
|
-
|
|
50128
|
-
|
|
50129
|
-
|
|
50130
|
-
return
|
|
50131
|
-
}
|
|
50132
|
-
function wrapText(
|
|
50133
|
-
if (maxWidth <= 0) return [
|
|
50134
|
-
const plainText = stripAnsi(
|
|
50232
|
+
function formatInlineMarkdown(text15) {
|
|
50233
|
+
text15 = text15.replace(/\*\*\*(.+?)\*\*\*/g, (_, content) => chalk.bold.italic(content));
|
|
50234
|
+
text15 = text15.replace(/\*\*(.+?)\*\*/g, (_, content) => chalk.bold(content));
|
|
50235
|
+
text15 = text15.replace(/\*([^*]+)\*/g, (_, content) => chalk.italic(content));
|
|
50236
|
+
text15 = text15.replace(/_([^_]+)_/g, (_, content) => chalk.italic(content));
|
|
50237
|
+
text15 = text15.replace(/`([^`]+)`/g, (_, content) => chalk.cyan(content));
|
|
50238
|
+
text15 = text15.replace(/~~(.+?)~~/g, (_, content) => chalk.strikethrough(content));
|
|
50239
|
+
text15 = text15.replace(/\[([^\]]+)\]\([^)]+\)/g, (_, linkText) => chalk.blue.underline(linkText));
|
|
50240
|
+
return text15;
|
|
50241
|
+
}
|
|
50242
|
+
function wrapText(text15, maxWidth) {
|
|
50243
|
+
if (maxWidth <= 0) return [text15];
|
|
50244
|
+
const plainText = stripAnsi(text15);
|
|
50135
50245
|
if (plainText.length <= maxWidth) {
|
|
50136
|
-
return [
|
|
50246
|
+
return [text15];
|
|
50137
50247
|
}
|
|
50138
50248
|
const lines = [];
|
|
50139
|
-
let remaining =
|
|
50249
|
+
let remaining = text15;
|
|
50140
50250
|
while (true) {
|
|
50141
50251
|
const plain = stripAnsi(remaining);
|
|
50142
50252
|
if (plain.length <= maxWidth) break;
|
|
@@ -50174,7 +50284,7 @@ function wrapText(text14, maxWidth) {
|
|
|
50174
50284
|
if (remaining) {
|
|
50175
50285
|
lines.push(remaining);
|
|
50176
50286
|
}
|
|
50177
|
-
return lines.length > 0 ? lines : [
|
|
50287
|
+
return lines.length > 0 ? lines : [text15];
|
|
50178
50288
|
}
|
|
50179
50289
|
function stripAnsi(str) {
|
|
50180
50290
|
return str.replace(/\x1b\[[0-9;]*m/g, "");
|
|
@@ -50326,9 +50436,9 @@ function printEditDiff(oldStr, newStr) {
|
|
|
50326
50436
|
if (lines.length === 0) return;
|
|
50327
50437
|
const truncate4 = (s) => s.length > termWidth - 2 ? s.slice(0, termWidth - 3) + "\u2026" : s;
|
|
50328
50438
|
for (const l of lines) {
|
|
50329
|
-
const
|
|
50330
|
-
const pad = Math.max(0, termWidth - stripAnsi(
|
|
50331
|
-
console.log(" " + diffBgAdd(
|
|
50439
|
+
const text15 = `+ ${truncate4(l)}`;
|
|
50440
|
+
const pad = Math.max(0, termWidth - stripAnsi(text15).length + 2);
|
|
50441
|
+
console.log(" " + diffBgAdd(text15 + " ".repeat(pad)));
|
|
50332
50442
|
}
|
|
50333
50443
|
return;
|
|
50334
50444
|
}
|
|
@@ -50356,9 +50466,9 @@ function printEditDiff(oldStr, newStr) {
|
|
|
50356
50466
|
}
|
|
50357
50467
|
if (diffLineList.length === 0) return;
|
|
50358
50468
|
const pairs = pairAdjacentDiffLines(diffLineList);
|
|
50359
|
-
const pairedDeletes = new Set(pairs.map((
|
|
50360
|
-
const pairedAdds = new Set(pairs.map((
|
|
50361
|
-
const pairByAdd = new Map(pairs.map((
|
|
50469
|
+
const pairedDeletes = new Set(pairs.map((p46) => p46.deleteIdx));
|
|
50470
|
+
const pairedAdds = new Set(pairs.map((p46) => p46.addIdx));
|
|
50471
|
+
const pairByAdd = new Map(pairs.map((p46) => [p46.addIdx, p46.deleteIdx]));
|
|
50362
50472
|
const wordHighlights = /* @__PURE__ */ new Map();
|
|
50363
50473
|
for (const pair of pairs) {
|
|
50364
50474
|
const del = diffLineList[pair.deleteIdx];
|
|
@@ -50784,10 +50894,10 @@ function findNextWordBoundary(line, pos) {
|
|
|
50784
50894
|
while (i < line.length && line[i] === " ") i++;
|
|
50785
50895
|
return i;
|
|
50786
50896
|
}
|
|
50787
|
-
function countVisualRows(
|
|
50897
|
+
function countVisualRows(text15, startCol, termCols) {
|
|
50788
50898
|
let rows = 1;
|
|
50789
50899
|
let col = startCol;
|
|
50790
|
-
for (const char of
|
|
50900
|
+
for (const char of text15) {
|
|
50791
50901
|
if (char === "\n") {
|
|
50792
50902
|
if (col > 0) rows++;
|
|
50793
50903
|
col = 0;
|
|
@@ -50801,11 +50911,11 @@ function countVisualRows(text14, startCol, termCols) {
|
|
|
50801
50911
|
}
|
|
50802
50912
|
return rows;
|
|
50803
50913
|
}
|
|
50804
|
-
function getCursorVisualPos(
|
|
50914
|
+
function getCursorVisualPos(text15, cursorPos, promptLen, termCols) {
|
|
50805
50915
|
let row = 0;
|
|
50806
50916
|
let col = promptLen;
|
|
50807
50917
|
for (let i = 0; i < cursorPos; i++) {
|
|
50808
|
-
if (
|
|
50918
|
+
if (text15[i] === "\n") {
|
|
50809
50919
|
if (col > 0) row++;
|
|
50810
50920
|
col = 0;
|
|
50811
50921
|
} else {
|
|
@@ -50818,14 +50928,14 @@ function getCursorVisualPos(text14, cursorPos, promptLen, termCols) {
|
|
|
50818
50928
|
}
|
|
50819
50929
|
return { row, col };
|
|
50820
50930
|
}
|
|
50821
|
-
function computeWordWrap(
|
|
50931
|
+
function computeWordWrap(text15, startCol, termCols) {
|
|
50822
50932
|
const passthrough = {
|
|
50823
|
-
display:
|
|
50824
|
-
toDisplayPos: (
|
|
50825
|
-
toOrigPos: (
|
|
50933
|
+
display: text15,
|
|
50934
|
+
toDisplayPos: (p46) => p46,
|
|
50935
|
+
toOrigPos: (p46) => p46
|
|
50826
50936
|
};
|
|
50827
|
-
if (!
|
|
50828
|
-
const origToDisp = new Int32Array(
|
|
50937
|
+
if (!text15 || termCols <= 1) return passthrough;
|
|
50938
|
+
const origToDisp = new Int32Array(text15.length + 1);
|
|
50829
50939
|
const dispToOrig = [];
|
|
50830
50940
|
let display = "";
|
|
50831
50941
|
let col = startCol;
|
|
@@ -50841,15 +50951,15 @@ function computeWordWrap(text14, startCol, termCols) {
|
|
|
50841
50951
|
col = 0;
|
|
50842
50952
|
}
|
|
50843
50953
|
let i = 0;
|
|
50844
|
-
while (i <
|
|
50845
|
-
const ch =
|
|
50954
|
+
while (i < text15.length) {
|
|
50955
|
+
const ch = text15[i];
|
|
50846
50956
|
if (ch === "\n") {
|
|
50847
50957
|
emitChar("\n", i++);
|
|
50848
50958
|
continue;
|
|
50849
50959
|
}
|
|
50850
50960
|
if (ch !== " ") {
|
|
50851
50961
|
let wordEnd = i;
|
|
50852
|
-
while (wordEnd <
|
|
50962
|
+
while (wordEnd < text15.length && text15[wordEnd] !== " " && text15[wordEnd] !== "\n") {
|
|
50853
50963
|
wordEnd++;
|
|
50854
50964
|
}
|
|
50855
50965
|
const wordLen = wordEnd - i;
|
|
@@ -50857,7 +50967,7 @@ function computeWordWrap(text14, startCol, termCols) {
|
|
|
50857
50967
|
injectNewline();
|
|
50858
50968
|
}
|
|
50859
50969
|
for (let k = i; k < wordEnd; k++) {
|
|
50860
|
-
emitChar(
|
|
50970
|
+
emitChar(text15[k], k);
|
|
50861
50971
|
if (col >= termCols && k + 1 < wordEnd) {
|
|
50862
50972
|
injectNewline();
|
|
50863
50973
|
}
|
|
@@ -50869,7 +50979,7 @@ function computeWordWrap(text14, startCol, termCols) {
|
|
|
50869
50979
|
col = 0;
|
|
50870
50980
|
} else {
|
|
50871
50981
|
let nextWordEnd = i;
|
|
50872
|
-
while (nextWordEnd <
|
|
50982
|
+
while (nextWordEnd < text15.length && text15[nextWordEnd] !== " " && text15[nextWordEnd] !== "\n") {
|
|
50873
50983
|
nextWordEnd++;
|
|
50874
50984
|
}
|
|
50875
50985
|
const nextWordLen = nextWordEnd - i;
|
|
@@ -50879,10 +50989,10 @@ function computeWordWrap(text14, startCol, termCols) {
|
|
|
50879
50989
|
}
|
|
50880
50990
|
}
|
|
50881
50991
|
}
|
|
50882
|
-
origToDisp[
|
|
50992
|
+
origToDisp[text15.length] = display.length;
|
|
50883
50993
|
return {
|
|
50884
50994
|
display,
|
|
50885
|
-
toDisplayPos: (origPos) => origToDisp[Math.min(origPos,
|
|
50995
|
+
toDisplayPos: (origPos) => origToDisp[Math.min(origPos, text15.length)] ?? display.length,
|
|
50886
50996
|
toOrigPos: (displayPos) => {
|
|
50887
50997
|
const dp = Math.max(0, Math.min(displayPos, dispToOrig.length - 1));
|
|
50888
50998
|
for (let d = dp; d >= 0; d--) {
|
|
@@ -51015,11 +51125,11 @@ function createInputHandler(_session) {
|
|
|
51015
51125
|
const item = visibleItems[itemIndex];
|
|
51016
51126
|
const actualIndex = startIndex + itemIndex;
|
|
51017
51127
|
const isSelected = actualIndex === selectedCompletion;
|
|
51018
|
-
const
|
|
51128
|
+
const text15 = ` ${item.cmd}`.padEnd(ITEM_WIDTH);
|
|
51019
51129
|
if (isSelected) {
|
|
51020
|
-
output += chalk.bgBlue.white(
|
|
51130
|
+
output += chalk.bgBlue.white(text15);
|
|
51021
51131
|
} else {
|
|
51022
|
-
output += chalk.cyan(
|
|
51132
|
+
output += chalk.cyan(text15);
|
|
51023
51133
|
}
|
|
51024
51134
|
}
|
|
51025
51135
|
}
|
|
@@ -51071,8 +51181,8 @@ function createInputHandler(_session) {
|
|
|
51071
51181
|
process.stdout.write("\r" + ansiEscapes.eraseDown);
|
|
51072
51182
|
lastMenuLines = 0;
|
|
51073
51183
|
}
|
|
51074
|
-
function insertTextAtCursor(
|
|
51075
|
-
const cleaned =
|
|
51184
|
+
function insertTextAtCursor(text15) {
|
|
51185
|
+
const cleaned = text15.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
51076
51186
|
const printable = cleaned.replace(/[^\n\x20-\x7E\u00A0-\uFFFF]/g, "");
|
|
51077
51187
|
if (printable.length === 0) return;
|
|
51078
51188
|
currentLine = currentLine.slice(0, cursorPos) + printable + currentLine.slice(cursorPos);
|
|
@@ -51975,10 +52085,10 @@ function formatWriteFilePreview(toolCall, maxLines = 10) {
|
|
|
51975
52085
|
const footer = truncated ? chalk.dim(` \u2514\u2500 ... ${lines.length - maxLines} more lines`) : "";
|
|
51976
52086
|
return formatted + (footer ? "\n" + footer : "");
|
|
51977
52087
|
}
|
|
51978
|
-
function wrapCommandText(
|
|
51979
|
-
if (
|
|
52088
|
+
function wrapCommandText(text15, maxWidth = 70, indent = " ") {
|
|
52089
|
+
if (text15.length <= maxWidth) return text15;
|
|
51980
52090
|
const lines = [];
|
|
51981
|
-
let remaining =
|
|
52091
|
+
let remaining = text15;
|
|
51982
52092
|
while (remaining.length > maxWidth) {
|
|
51983
52093
|
let breakAt = maxWidth;
|
|
51984
52094
|
const spaceIdx = remaining.lastIndexOf(" ", maxWidth);
|
|
@@ -52081,16 +52191,16 @@ function formatToolCallForConfirmation(toolCall, metadata) {
|
|
|
52081
52191
|
const reason = input.reason ? String(input.reason) : void 0;
|
|
52082
52192
|
const actionLabel = action === "allow" ? chalk.green.bold("ALLOW") : chalk.red.bold(action.toUpperCase());
|
|
52083
52193
|
const scopeLabel = scope === "global" ? chalk.blue("Global (all projects)") : chalk.magenta("Project (current only)");
|
|
52084
|
-
const patternList = patterns.map((
|
|
52194
|
+
const patternList = patterns.map((p46) => chalk.cyan(p46)).join(", ");
|
|
52085
52195
|
const lines = [`${actionLabel}: ${patternList}`];
|
|
52086
52196
|
lines.push(`${chalk.dim(" Scope:")} ${scopeLabel}`);
|
|
52087
52197
|
if (reason) {
|
|
52088
52198
|
lines.push(`${chalk.dim(" Reason:")} ${reason}`);
|
|
52089
52199
|
}
|
|
52090
|
-
for (const
|
|
52091
|
-
lines.push(`${chalk.dim(" Risk:")} ${getRiskDescription(
|
|
52200
|
+
for (const p46 of patterns) {
|
|
52201
|
+
lines.push(`${chalk.dim(" Risk:")} ${getRiskDescription(p46)}`);
|
|
52092
52202
|
lines.push(
|
|
52093
|
-
`${chalk.dim(" Effect:")} ${getEffectDescription(action,
|
|
52203
|
+
`${chalk.dim(" Effect:")} ${getEffectDescription(action, p46, scope)}`
|
|
52094
52204
|
);
|
|
52095
52205
|
}
|
|
52096
52206
|
description = lines.join("\n ");
|
|
@@ -52331,6 +52441,46 @@ async function confirmToolExecution(toolCall) {
|
|
|
52331
52441
|
process.stdin.on("data", onData);
|
|
52332
52442
|
});
|
|
52333
52443
|
}
|
|
52444
|
+
async function confirmToolExecutionFallback(toolCall) {
|
|
52445
|
+
const { description } = formatToolCallForConfirmation(toolCall);
|
|
52446
|
+
const isBashExec = toolCall.name === "bash_exec";
|
|
52447
|
+
console.log();
|
|
52448
|
+
console.log(chalk.yellow(" \u26A0 Interactive tool selector unavailable. Using safe fallback."));
|
|
52449
|
+
const options = [
|
|
52450
|
+
{ value: "yes", label: "yes", hint: "Allow once" },
|
|
52451
|
+
{ value: "no", label: "no", hint: "Skip this action" },
|
|
52452
|
+
{ value: "trust_project", label: "trust (project)", hint: "Always allow in this project" },
|
|
52453
|
+
{ value: "trust_global", label: "trust (global)", hint: "Always allow everywhere" }
|
|
52454
|
+
];
|
|
52455
|
+
if (isBashExec) {
|
|
52456
|
+
options.splice(2, 0, { value: "edit", label: "edit command", hint: "Modify before running" });
|
|
52457
|
+
}
|
|
52458
|
+
const choice = await p26.select({
|
|
52459
|
+
message: `Confirm tool action:
|
|
52460
|
+
${description}`,
|
|
52461
|
+
options
|
|
52462
|
+
});
|
|
52463
|
+
if (p26.isCancel(choice)) return "abort";
|
|
52464
|
+
if (choice === "edit") {
|
|
52465
|
+
const currentCommand = String(toolCall.input.command ?? "");
|
|
52466
|
+
const edited = await p26.text({
|
|
52467
|
+
message: "Edit command:",
|
|
52468
|
+
placeholder: currentCommand,
|
|
52469
|
+
initialValue: currentCommand,
|
|
52470
|
+
validate: (value) => !value?.trim() ? "Command is required" : void 0
|
|
52471
|
+
});
|
|
52472
|
+
if (p26.isCancel(edited)) return "abort";
|
|
52473
|
+
return { type: "edit", newCommand: edited.trim() };
|
|
52474
|
+
}
|
|
52475
|
+
return choice;
|
|
52476
|
+
}
|
|
52477
|
+
async function confirmToolExecutionWithFallback(toolCall) {
|
|
52478
|
+
try {
|
|
52479
|
+
return await confirmToolExecution(toolCall);
|
|
52480
|
+
} catch {
|
|
52481
|
+
return await confirmToolExecutionFallback(toolCall);
|
|
52482
|
+
}
|
|
52483
|
+
}
|
|
52334
52484
|
|
|
52335
52485
|
// src/cli/repl/parallel-executor.ts
|
|
52336
52486
|
init_error_resilience();
|
|
@@ -53060,14 +53210,15 @@ ${tail}`;
|
|
|
53060
53210
|
options.onBeforeConfirmation?.();
|
|
53061
53211
|
let confirmResult;
|
|
53062
53212
|
try {
|
|
53063
|
-
confirmResult = await
|
|
53213
|
+
confirmResult = await confirmToolExecutionWithFallback(toolCall);
|
|
53064
53214
|
} catch (confirmError) {
|
|
53065
53215
|
options.onAfterConfirmation?.();
|
|
53066
|
-
declinedTools.set(
|
|
53067
|
-
|
|
53216
|
+
declinedTools.set(toolCall.id, "Confirmation failed");
|
|
53217
|
+
options.onToolSkipped?.(
|
|
53218
|
+
toolCall,
|
|
53068
53219
|
`Confirmation failed: ${confirmError instanceof Error ? confirmError.message : String(confirmError)}`
|
|
53069
53220
|
);
|
|
53070
|
-
|
|
53221
|
+
turnAborted = true;
|
|
53071
53222
|
continue;
|
|
53072
53223
|
}
|
|
53073
53224
|
options.onAfterConfirmation?.();
|
|
@@ -53137,29 +53288,29 @@ ${tail}`;
|
|
|
53137
53288
|
const patterns = executed.input.patterns;
|
|
53138
53289
|
const scope = executed.input.scope || "project";
|
|
53139
53290
|
if (Array.isArray(patterns)) {
|
|
53140
|
-
for (const
|
|
53291
|
+
for (const p46 of patterns) {
|
|
53141
53292
|
if (action === "allow") {
|
|
53142
|
-
session.trustedTools.add(
|
|
53293
|
+
session.trustedTools.add(p46);
|
|
53143
53294
|
if (scope === "global") {
|
|
53144
|
-
saveTrustedTool(
|
|
53295
|
+
saveTrustedTool(p46, null, true).catch(() => {
|
|
53145
53296
|
});
|
|
53146
53297
|
} else {
|
|
53147
|
-
saveTrustedTool(
|
|
53298
|
+
saveTrustedTool(p46, session.projectPath, false).catch(() => {
|
|
53148
53299
|
});
|
|
53149
53300
|
}
|
|
53150
|
-
removeDeniedTool(
|
|
53301
|
+
removeDeniedTool(p46, session.projectPath).catch(() => {
|
|
53151
53302
|
});
|
|
53152
53303
|
} else if (action === "deny") {
|
|
53153
|
-
session.trustedTools.delete(
|
|
53304
|
+
session.trustedTools.delete(p46);
|
|
53154
53305
|
if (scope === "global") {
|
|
53155
|
-
removeTrustedTool(
|
|
53306
|
+
removeTrustedTool(p46, session.projectPath, true).catch(() => {
|
|
53156
53307
|
});
|
|
53157
53308
|
} else {
|
|
53158
|
-
saveDeniedTool(
|
|
53309
|
+
saveDeniedTool(p46, session.projectPath).catch(() => {
|
|
53159
53310
|
});
|
|
53160
53311
|
}
|
|
53161
53312
|
} else {
|
|
53162
|
-
session.trustedTools.delete(
|
|
53313
|
+
session.trustedTools.delete(p46);
|
|
53163
53314
|
}
|
|
53164
53315
|
}
|
|
53165
53316
|
}
|
|
@@ -54207,14 +54358,14 @@ async function startRepl(options = {}) {
|
|
|
54207
54358
|
imageCount++;
|
|
54208
54359
|
}
|
|
54209
54360
|
}
|
|
54210
|
-
const
|
|
54211
|
-
if (
|
|
54361
|
+
const text15 = textParts.join("\n\n").trim();
|
|
54362
|
+
if (text15.length > 0) {
|
|
54212
54363
|
if (imageCount > 0) {
|
|
54213
|
-
return `${
|
|
54364
|
+
return `${text15}
|
|
54214
54365
|
|
|
54215
54366
|
[System: The original request included ${imageCount} image(s). Use the image context already provided in this conversation.]`;
|
|
54216
54367
|
}
|
|
54217
|
-
return
|
|
54368
|
+
return text15;
|
|
54218
54369
|
}
|
|
54219
54370
|
if (imageCount > 0) {
|
|
54220
54371
|
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 +54384,8 @@ async function startRepl(options = {}) {
|
|
|
54233
54384
|
};
|
|
54234
54385
|
const getAutoSwitchCandidates = (current) => {
|
|
54235
54386
|
const ordered = [];
|
|
54236
|
-
const push = (
|
|
54237
|
-
if (
|
|
54387
|
+
const push = (p46) => {
|
|
54388
|
+
if (p46 !== current && !ordered.includes(p46)) ordered.push(p46);
|
|
54238
54389
|
};
|
|
54239
54390
|
if (current === "openai") {
|
|
54240
54391
|
push("codex");
|
|
@@ -54272,7 +54423,7 @@ async function startRepl(options = {}) {
|
|
|
54272
54423
|
"lmstudio",
|
|
54273
54424
|
"ollama"
|
|
54274
54425
|
];
|
|
54275
|
-
for (const
|
|
54426
|
+
for (const p46 of genericOrder) push(p46);
|
|
54276
54427
|
return ordered;
|
|
54277
54428
|
};
|
|
54278
54429
|
const attemptAutoProviderSwitch = async (reason, originalMessage) => {
|