@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 +351 -303
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +2 -1
- 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)
|
|
@@ -5712,9 +5712,9 @@ var init_copilot2 = __esm({
|
|
|
5712
5712
|
/**
|
|
5713
5713
|
* Count tokens (approximate — Copilot models vary in tokenizer)
|
|
5714
5714
|
*/
|
|
5715
|
-
countTokens(
|
|
5716
|
-
if (!
|
|
5717
|
-
return Math.ceil(
|
|
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
|
|
5816
|
-
if (
|
|
5817
|
-
yield { type: "text", text:
|
|
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
|
|
5842
|
-
if (
|
|
5843
|
-
yield { type: "text", text:
|
|
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(
|
|
5880
|
-
if (!
|
|
5881
|
-
return Math.ceil(
|
|
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
|
|
5930
|
-
return
|
|
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(
|
|
6228
|
-
return Math.ceil(
|
|
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
|
|
6291
|
-
return
|
|
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
|
|
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:
|
|
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((
|
|
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(
|
|
6954
|
+
countTokens(text15) {
|
|
6955
6955
|
const provider = this.getCurrentProvider();
|
|
6956
|
-
return provider.provider.countTokens(
|
|
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 (
|
|
6980
|
-
if (
|
|
6979
|
+
this.providers.map(async (p46) => {
|
|
6980
|
+
if (p46.breaker.isOpen()) {
|
|
6981
6981
|
return false;
|
|
6982
6982
|
}
|
|
6983
|
-
return
|
|
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((
|
|
7015
|
-
providerId:
|
|
7016
|
-
state:
|
|
7017
|
-
failureCount:
|
|
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
|
|
7028
|
-
|
|
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(
|
|
7173
|
-
return this.provider.countTokens(
|
|
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(
|
|
8487
|
-
return
|
|
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
|
|
9585
|
-
total += provider.countTokens(
|
|
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((
|
|
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((
|
|
12381
|
-
const pairedAddIndices = new Set(pairs.map((
|
|
12382
|
-
const pairByAdd = new Map(pairs.map((
|
|
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
|
|
12838
|
+
for (const p46 of possiblePaths) {
|
|
12839
12839
|
try {
|
|
12840
|
-
await access(
|
|
12841
|
-
const content = await readFile(
|
|
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
|
|
18676
|
-
stdoutBuffer +=
|
|
18677
|
-
process.stdout.write(
|
|
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
|
|
18682
|
-
stderrBuffer +=
|
|
18683
|
-
process.stderr.write(
|
|
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((
|
|
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((
|
|
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(
|
|
23149
|
+
function matchPatterns(text15, patterns) {
|
|
23150
23150
|
for (let i = 0; i < patterns.length; i++) {
|
|
23151
|
-
if (patterns[i].test(
|
|
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
|
|
23159
|
-
const abortConf = matchPatterns(
|
|
23160
|
-
const modifyConf = matchPatterns(
|
|
23161
|
-
const correctConf = matchPatterns(
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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(
|
|
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
|
|
25712
|
-
if (
|
|
25713
|
-
if (
|
|
25714
|
-
if (
|
|
25715
|
-
if (
|
|
25716
|
-
if (
|
|
25717
|
-
if (
|
|
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((
|
|
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((
|
|
30120
|
-
if (
|
|
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 (
|
|
30124
|
-
return !!process.env[
|
|
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 (
|
|
30127
|
-
return hasLocalProviderConfig(
|
|
30126
|
+
if (p46.id === "lmstudio" || p46.id === "ollama") {
|
|
30127
|
+
return hasLocalProviderConfig(p46.id);
|
|
30128
30128
|
}
|
|
30129
|
-
if (
|
|
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[
|
|
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(
|
|
31268
|
-
return
|
|
31267
|
+
htmlEscape(text15) {
|
|
31268
|
+
return text15.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
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(
|
|
31790
|
+
function extractJsonScore(text15) {
|
|
31791
31791
|
try {
|
|
31792
|
-
const stripped =
|
|
31792
|
+
const stripped = text15.replace(/^```(?:json)?\s*\n?/, "").replace(/\n?```\s*$/, "").trim();
|
|
31793
31793
|
return JSON.parse(stripped);
|
|
31794
31794
|
} catch {
|
|
31795
|
-
const match =
|
|
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
|
|
32019
|
+
const p46 = await import('@clack/prompts');
|
|
32020
32020
|
if (q.options && q.options.length > 0) {
|
|
32021
|
-
const result = await
|
|
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 (
|
|
32028
|
+
if (p46.isCancel(result)) {
|
|
32029
32029
|
return q.assumedAnswer;
|
|
32030
32030
|
}
|
|
32031
32031
|
return result;
|
|
32032
32032
|
} else {
|
|
32033
|
-
const result = await
|
|
32033
|
+
const result = await p46.text({
|
|
32034
32034
|
message: q.question,
|
|
32035
32035
|
placeholder: q.assumedAnswer
|
|
32036
32036
|
});
|
|
32037
|
-
if (
|
|
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(
|
|
33008
|
+
function extractJson(text15) {
|
|
33009
33009
|
try {
|
|
33010
|
-
const stripped =
|
|
33010
|
+
const stripped = text15.replace(/^```(?:json)?\s*\n?/, "").replace(/\n?```\s*$/, "").trim();
|
|
33011
33011
|
return JSON.parse(stripped);
|
|
33012
33012
|
} catch {
|
|
33013
|
-
const match =
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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}
|
|
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((
|
|
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((
|
|
34684
|
-
value:
|
|
34685
|
-
label: `${
|
|
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((
|
|
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((
|
|
35108
|
-
if (
|
|
35109
|
-
if (
|
|
35110
|
-
return hasOpenAIOAuthTokens || !!process.env[
|
|
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
|
|
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((
|
|
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((
|
|
35284
|
-
id:
|
|
35285
|
-
name:
|
|
35286
|
-
emoji:
|
|
35287
|
-
description:
|
|
35288
|
-
isConfigured: configuredProviders.some((cp) => cp.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((
|
|
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((
|
|
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((
|
|
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((
|
|
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((
|
|
38316
|
-
const partsB = b.replace(/^v/, "").split(".").map((
|
|
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
|
|
38441
|
+
const p46 = await import('@clack/prompts');
|
|
38441
38442
|
printUpdateBanner(updateInfo);
|
|
38442
|
-
const answer = await
|
|
38443
|
+
const answer = await p46.confirm({
|
|
38443
38444
|
message: "Exit now to update?",
|
|
38444
38445
|
initialValue: true
|
|
38445
38446
|
});
|
|
38446
|
-
if (!
|
|
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(
|
|
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(
|
|
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(
|
|
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,
|
|
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
|
|
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
|
-
{
|
|
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(
|
|
40212
|
-
const match =
|
|
40213
|
-
return match ? (match[1] ??
|
|
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
|
|
43855
|
-
stdoutBuffer +=
|
|
43856
|
-
process.stdout.write(
|
|
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
|
|
43861
|
-
stderrBuffer +=
|
|
43862
|
-
process.stderr.write(
|
|
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
|
|
43980
|
-
stdoutBuffer +=
|
|
43981
|
-
process.stdout.write(
|
|
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
|
|
43986
|
-
stderrBuffer +=
|
|
43987
|
-
process.stderr.write(
|
|
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
|
|
44082
|
-
stdoutBuffer +=
|
|
44083
|
-
process.stdout.write(
|
|
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
|
|
44088
|
-
stderrBuffer +=
|
|
44089
|
-
process.stderr.write(
|
|
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
|
|
44185
|
-
stdoutBuffer +=
|
|
44186
|
-
process.stdout.write(
|
|
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
|
|
44191
|
-
stderrBuffer +=
|
|
44192
|
-
process.stderr.write(
|
|
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
|
|
44289
|
-
stdoutBuffer +=
|
|
44290
|
-
process.stdout.write(
|
|
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
|
|
44295
|
-
stderrBuffer +=
|
|
44296
|
-
process.stderr.write(
|
|
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
|
|
44376
|
-
stdoutBuffer +=
|
|
44377
|
-
process.stdout.write(
|
|
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
|
|
44382
|
-
stderrBuffer +=
|
|
44383
|
-
process.stderr.write(
|
|
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
|
|
44875
|
-
return
|
|
44880
|
+
const text15 = content.replace(/<[^>]*>/g, "").trim();
|
|
44881
|
+
return text15 ? `
|
|
44876
44882
|
|
|
44877
|
-
${prefix} ${
|
|
44883
|
+
${prefix} ${text15}
|
|
44878
44884
|
|
|
44879
44885
|
` : "";
|
|
44880
44886
|
});
|
|
44881
44887
|
}
|
|
44882
|
-
md = md.replace(/<a\s+[^>]*href=["']([^"']+)["'][^>]*>([\s\S]*?)<\/a>/gi, (_, href,
|
|
44883
|
-
const cleanText =
|
|
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
|
|
44911
|
-
return
|
|
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
|
|
44920
|
-
return
|
|
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
|
|
44926
|
-
return
|
|
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
|
|
44930
|
-
return
|
|
44935
|
+
const text15 = content.replace(/<[^>]*>/g, "").trim();
|
|
44936
|
+
return text15 ? `
|
|
44931
44937
|
|
|
44932
|
-
${
|
|
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
|
-
(_,
|
|
44945
|
+
(_, text15) => `**${text15.trim()}**`
|
|
44940
44946
|
);
|
|
44941
|
-
md = md.replace(/<(?:em|i)[^>]*>([\s\S]*?)<\/(?:em|i)>/gi, (_,
|
|
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
|
|
46072
|
-
if (
|
|
46077
|
+
const text15 = chunkLines.join("\n").trim();
|
|
46078
|
+
if (text15.length > 10) {
|
|
46073
46079
|
chunks.push({
|
|
46074
|
-
text:
|
|
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(
|
|
46083
|
-
const words =
|
|
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(
|
|
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(
|
|
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
|
|
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 =
|
|
46690
|
+
const pageTexts = text15.split(/\f/);
|
|
46685
46691
|
if (pageTexts.length > 1) {
|
|
46686
46692
|
const selectedPages = pageTexts.slice(range.start - 1, range.end);
|
|
46687
|
-
|
|
46693
|
+
text15 = selectedPages.join("\n\n--- Page Break ---\n\n");
|
|
46688
46694
|
}
|
|
46689
46695
|
}
|
|
46690
|
-
if (
|
|
46691
|
-
|
|
46696
|
+
if (text15.length > 5e5) {
|
|
46697
|
+
text15 = text15.slice(0, 5e5);
|
|
46692
46698
|
truncated = true;
|
|
46693
46699
|
}
|
|
46694
46700
|
return {
|
|
46695
|
-
text:
|
|
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
|
|
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((
|
|
48075
|
-
pattern:
|
|
48076
|
-
preference:
|
|
48077
|
-
frequency:
|
|
48078
|
-
lastUsed: new Date(
|
|
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(
|
|
50123
|
-
|
|
50124
|
-
|
|
50125
|
-
|
|
50126
|
-
|
|
50127
|
-
|
|
50128
|
-
|
|
50129
|
-
|
|
50130
|
-
return
|
|
50131
|
-
}
|
|
50132
|
-
function wrapText(
|
|
50133
|
-
if (maxWidth <= 0) return [
|
|
50134
|
-
const plainText = stripAnsi(
|
|
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 [
|
|
50143
|
+
return [text15];
|
|
50137
50144
|
}
|
|
50138
50145
|
const lines = [];
|
|
50139
|
-
let remaining =
|
|
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 : [
|
|
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
|
|
50330
|
-
const pad = Math.max(0, termWidth - stripAnsi(
|
|
50331
|
-
console.log(" " + diffBgAdd(
|
|
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((
|
|
50360
|
-
const pairedAdds = new Set(pairs.map((
|
|
50361
|
-
const pairByAdd = new Map(pairs.map((
|
|
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(
|
|
50794
|
+
function countVisualRows(text15, startCol, termCols) {
|
|
50788
50795
|
let rows = 1;
|
|
50789
50796
|
let col = startCol;
|
|
50790
|
-
for (const char of
|
|
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(
|
|
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 (
|
|
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(
|
|
50828
|
+
function computeWordWrap(text15, startCol, termCols) {
|
|
50822
50829
|
const passthrough = {
|
|
50823
|
-
display:
|
|
50824
|
-
toDisplayPos: (
|
|
50825
|
-
toOrigPos: (
|
|
50830
|
+
display: text15,
|
|
50831
|
+
toDisplayPos: (p46) => p46,
|
|
50832
|
+
toOrigPos: (p46) => p46
|
|
50826
50833
|
};
|
|
50827
|
-
if (!
|
|
50828
|
-
const origToDisp = new Int32Array(
|
|
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 <
|
|
50845
|
-
const ch =
|
|
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 <
|
|
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(
|
|
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 <
|
|
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[
|
|
50889
|
+
origToDisp[text15.length] = display.length;
|
|
50883
50890
|
return {
|
|
50884
50891
|
display,
|
|
50885
|
-
toDisplayPos: (origPos) => origToDisp[Math.min(origPos,
|
|
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
|
|
51025
|
+
const text15 = ` ${item.cmd}`.padEnd(ITEM_WIDTH);
|
|
51019
51026
|
if (isSelected) {
|
|
51020
|
-
output += chalk.bgBlue.white(
|
|
51027
|
+
output += chalk.bgBlue.white(text15);
|
|
51021
51028
|
} else {
|
|
51022
|
-
output += chalk.cyan(
|
|
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(
|
|
51075
|
-
const cleaned =
|
|
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(
|
|
51979
|
-
if (
|
|
51985
|
+
function wrapCommandText(text15, maxWidth = 70, indent = " ") {
|
|
51986
|
+
if (text15.length <= maxWidth) return text15;
|
|
51980
51987
|
const lines = [];
|
|
51981
|
-
let remaining =
|
|
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((
|
|
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
|
|
52091
|
-
lines.push(`${chalk.dim(" Risk:")} ${getRiskDescription(
|
|
52097
|
+
for (const p46 of patterns) {
|
|
52098
|
+
lines.push(`${chalk.dim(" Risk:")} ${getRiskDescription(p46)}`);
|
|
52092
52099
|
lines.push(
|
|
52093
|
-
`${chalk.dim(" Effect:")} ${getEffectDescription(action,
|
|
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
|
|
53110
|
+
confirmResult = await confirmToolExecutionWithFallback(toolCall);
|
|
53064
53111
|
} catch (confirmError) {
|
|
53065
53112
|
options.onAfterConfirmation?.();
|
|
53066
|
-
declinedTools.set(
|
|
53067
|
-
|
|
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
|
-
|
|
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
|
|
53188
|
+
for (const p46 of patterns) {
|
|
53141
53189
|
if (action === "allow") {
|
|
53142
|
-
session.trustedTools.add(
|
|
53190
|
+
session.trustedTools.add(p46);
|
|
53143
53191
|
if (scope === "global") {
|
|
53144
|
-
saveTrustedTool(
|
|
53192
|
+
saveTrustedTool(p46, null, true).catch(() => {
|
|
53145
53193
|
});
|
|
53146
53194
|
} else {
|
|
53147
|
-
saveTrustedTool(
|
|
53195
|
+
saveTrustedTool(p46, session.projectPath, false).catch(() => {
|
|
53148
53196
|
});
|
|
53149
53197
|
}
|
|
53150
|
-
removeDeniedTool(
|
|
53198
|
+
removeDeniedTool(p46, session.projectPath).catch(() => {
|
|
53151
53199
|
});
|
|
53152
53200
|
} else if (action === "deny") {
|
|
53153
|
-
session.trustedTools.delete(
|
|
53201
|
+
session.trustedTools.delete(p46);
|
|
53154
53202
|
if (scope === "global") {
|
|
53155
|
-
removeTrustedTool(
|
|
53203
|
+
removeTrustedTool(p46, session.projectPath, true).catch(() => {
|
|
53156
53204
|
});
|
|
53157
53205
|
} else {
|
|
53158
|
-
saveDeniedTool(
|
|
53206
|
+
saveDeniedTool(p46, session.projectPath).catch(() => {
|
|
53159
53207
|
});
|
|
53160
53208
|
}
|
|
53161
53209
|
} else {
|
|
53162
|
-
session.trustedTools.delete(
|
|
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
|
|
54211
|
-
if (
|
|
54258
|
+
const text15 = textParts.join("\n\n").trim();
|
|
54259
|
+
if (text15.length > 0) {
|
|
54212
54260
|
if (imageCount > 0) {
|
|
54213
|
-
return `${
|
|
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
|
|
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 = (
|
|
54237
|
-
if (
|
|
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
|
|
54323
|
+
for (const p46 of genericOrder) push(p46);
|
|
54276
54324
|
return ordered;
|
|
54277
54325
|
};
|
|
54278
54326
|
const attemptAutoProviderSwitch = async (reason, originalMessage) => {
|