@corbat-tech/coco 2.27.4 → 2.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +728 -384
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +158 -77
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -963,6 +963,8 @@ interface ToolUseContent {
|
|
|
963
963
|
id: string;
|
|
964
964
|
name: string;
|
|
965
965
|
input: Record<string, unknown>;
|
|
966
|
+
/** Gemini-specific: preserve function-call thought signature across tool turns */
|
|
967
|
+
geminiThoughtSignature?: string;
|
|
966
968
|
}
|
|
967
969
|
/**
|
|
968
970
|
* Tool result content block
|
|
@@ -999,6 +1001,8 @@ interface ToolCall {
|
|
|
999
1001
|
id: string;
|
|
1000
1002
|
name: string;
|
|
1001
1003
|
input: Record<string, unknown>;
|
|
1004
|
+
/** Gemini-specific: preserve function-call thought signature across tool turns */
|
|
1005
|
+
geminiThoughtSignature?: string;
|
|
1002
1006
|
}
|
|
1003
1007
|
/**
|
|
1004
1008
|
* Chat options
|
package/dist/index.js
CHANGED
|
@@ -8,11 +8,11 @@ import fs16__default, { access, readFile, readdir, writeFile, mkdir } from 'fs/p
|
|
|
8
8
|
import { randomUUID, randomBytes, createHash } from 'crypto';
|
|
9
9
|
import * as http from 'http';
|
|
10
10
|
import { fileURLToPath, URL as URL$1 } from 'url';
|
|
11
|
+
import { exec, execFile, execSync, spawn } from 'child_process';
|
|
12
|
+
import { promisify } from 'util';
|
|
11
13
|
import { z } from 'zod';
|
|
12
14
|
import * as p4 from '@clack/prompts';
|
|
13
15
|
import chalk5 from 'chalk';
|
|
14
|
-
import { exec, execFile, execSync, spawn } from 'child_process';
|
|
15
|
-
import { promisify } from 'util';
|
|
16
16
|
import { homedir } from 'os';
|
|
17
17
|
import JSON5 from 'json5';
|
|
18
18
|
import { execa } from 'execa';
|
|
@@ -676,6 +676,15 @@ async function exchangeForCopilotToken(githubToken) {
|
|
|
676
676
|
}
|
|
677
677
|
return await response.json();
|
|
678
678
|
}
|
|
679
|
+
async function getGitHubCliToken() {
|
|
680
|
+
try {
|
|
681
|
+
const { stdout } = await execFileAsync("gh", ["auth", "token"], { timeout: 5e3 });
|
|
682
|
+
const token = stdout.trim();
|
|
683
|
+
return token.length > 0 ? token : null;
|
|
684
|
+
} catch {
|
|
685
|
+
return null;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
679
688
|
function getCopilotBaseUrl(accountType) {
|
|
680
689
|
if (accountType && accountType in COPILOT_BASE_URLS) {
|
|
681
690
|
return COPILOT_BASE_URLS[accountType];
|
|
@@ -713,10 +722,11 @@ function isCopilotTokenExpired(creds) {
|
|
|
713
722
|
}
|
|
714
723
|
async function getValidCopilotToken() {
|
|
715
724
|
const creds = await loadCopilotCredentials();
|
|
716
|
-
|
|
717
|
-
const
|
|
718
|
-
const githubToken = envToken || creds
|
|
719
|
-
if (!
|
|
725
|
+
const envToken = process.env["COPILOT_GITHUB_TOKEN"] || process.env["GH_TOKEN"] || process.env["GITHUB_TOKEN"];
|
|
726
|
+
const fallbackGhToken = await getGitHubCliToken();
|
|
727
|
+
const githubToken = envToken || creds?.githubToken || fallbackGhToken;
|
|
728
|
+
if (!githubToken) return null;
|
|
729
|
+
if (creds && !isCopilotTokenExpired(creds) && creds.copilotToken) {
|
|
720
730
|
return {
|
|
721
731
|
token: creds.copilotToken,
|
|
722
732
|
baseUrl: getCopilotBaseUrl(creds.accountType),
|
|
@@ -726,11 +736,11 @@ async function getValidCopilotToken() {
|
|
|
726
736
|
try {
|
|
727
737
|
const copilotToken = await exchangeForCopilotToken(githubToken);
|
|
728
738
|
const updatedCreds = {
|
|
729
|
-
...creds,
|
|
730
|
-
githubToken: creds
|
|
739
|
+
...creds ?? { githubToken },
|
|
740
|
+
githubToken: creds?.githubToken ?? githubToken,
|
|
731
741
|
copilotToken: copilotToken.token,
|
|
732
742
|
copilotTokenExpiresAt: copilotToken.expires_at * 1e3,
|
|
733
|
-
accountType: copilotToken.annotations?.copilot_plan ?? creds
|
|
743
|
+
accountType: copilotToken.annotations?.copilot_plan ?? creds?.accountType
|
|
734
744
|
};
|
|
735
745
|
await saveCopilotCredentials(updatedCreds);
|
|
736
746
|
return {
|
|
@@ -746,7 +756,7 @@ async function getValidCopilotToken() {
|
|
|
746
756
|
throw error;
|
|
747
757
|
}
|
|
748
758
|
}
|
|
749
|
-
var COPILOT_TOKEN_URL, COPILOT_BASE_URLS, DEFAULT_COPILOT_BASE_URL, REFRESH_BUFFER_MS, CopilotAuthError, CopilotCredentialsSchema;
|
|
759
|
+
var COPILOT_TOKEN_URL, COPILOT_BASE_URLS, DEFAULT_COPILOT_BASE_URL, REFRESH_BUFFER_MS, execFileAsync, CopilotAuthError, CopilotCredentialsSchema;
|
|
750
760
|
var init_copilot = __esm({
|
|
751
761
|
"src/auth/copilot.ts"() {
|
|
752
762
|
COPILOT_TOKEN_URL = "https://api.github.com/copilot_internal/v2/token";
|
|
@@ -757,6 +767,7 @@ var init_copilot = __esm({
|
|
|
757
767
|
};
|
|
758
768
|
DEFAULT_COPILOT_BASE_URL = "https://api.githubcopilot.com";
|
|
759
769
|
REFRESH_BUFFER_MS = 6e4;
|
|
770
|
+
execFileAsync = promisify(execFile);
|
|
760
771
|
CopilotAuthError = class extends Error {
|
|
761
772
|
constructor(message, permanent) {
|
|
762
773
|
super(message);
|
|
@@ -1482,7 +1493,7 @@ function getDefaultModel(provider) {
|
|
|
1482
1493
|
case "anthropic":
|
|
1483
1494
|
return process.env["ANTHROPIC_MODEL"] ?? "claude-opus-4-6";
|
|
1484
1495
|
case "openai":
|
|
1485
|
-
return process.env["OPENAI_MODEL"] ?? "gpt-5.
|
|
1496
|
+
return process.env["OPENAI_MODEL"] ?? "gpt-5.3-codex";
|
|
1486
1497
|
case "gemini":
|
|
1487
1498
|
return process.env["GEMINI_MODEL"] ?? "gemini-3.1-pro-preview";
|
|
1488
1499
|
case "vertex":
|
|
@@ -14107,7 +14118,7 @@ var ResponsesToolCallAssembler = class {
|
|
|
14107
14118
|
};
|
|
14108
14119
|
|
|
14109
14120
|
// src/providers/openai.ts
|
|
14110
|
-
var DEFAULT_MODEL2 = "gpt-5.
|
|
14121
|
+
var DEFAULT_MODEL2 = "gpt-5.3-codex";
|
|
14111
14122
|
var CONTEXT_WINDOWS2 = {
|
|
14112
14123
|
// OpenAI models
|
|
14113
14124
|
"gpt-4o": 128e3,
|
|
@@ -15313,7 +15324,7 @@ function createKimiProvider(config) {
|
|
|
15313
15324
|
init_errors();
|
|
15314
15325
|
init_auth();
|
|
15315
15326
|
var CODEX_API_ENDPOINT = "https://chatgpt.com/backend-api/codex/responses";
|
|
15316
|
-
var DEFAULT_MODEL3 = "gpt-5.
|
|
15327
|
+
var DEFAULT_MODEL3 = "gpt-5.3-codex";
|
|
15317
15328
|
var CONTEXT_WINDOWS3 = {
|
|
15318
15329
|
"gpt-5.4-codex": 2e5,
|
|
15319
15330
|
"gpt-5.3-codex": 2e5,
|
|
@@ -16089,6 +16100,7 @@ var CopilotProvider = class extends OpenAIProvider {
|
|
|
16089
16100
|
// src/providers/gemini.ts
|
|
16090
16101
|
init_errors();
|
|
16091
16102
|
var DEFAULT_MODEL5 = "gemini-3.1-pro-preview";
|
|
16103
|
+
var SKIP_THOUGHT_SIGNATURE_VALIDATOR = "skip_thought_signature_validator";
|
|
16092
16104
|
var CONTEXT_WINDOWS5 = {
|
|
16093
16105
|
"gemini-3.1-pro-preview": 1e6,
|
|
16094
16106
|
"gemini-3.1-flash-lite-preview": 1e6,
|
|
@@ -16181,30 +16193,29 @@ var GeminiProvider = class {
|
|
|
16181
16193
|
if (text) {
|
|
16182
16194
|
yield { type: "text", text };
|
|
16183
16195
|
}
|
|
16184
|
-
const
|
|
16185
|
-
for (const
|
|
16186
|
-
const toolCallId =
|
|
16196
|
+
const toolCalls = this.extractToolCalls(chunk, { includeLegacyFunctionCalls: true });
|
|
16197
|
+
for (const toolCall of toolCalls) {
|
|
16198
|
+
const toolCallId = toolCall.id ?? `gemini_call_${++fallbackToolCounter}`;
|
|
16187
16199
|
if (emittedToolIds.has(toolCallId)) continue;
|
|
16188
16200
|
emittedToolIds.add(toolCallId);
|
|
16189
|
-
const
|
|
16190
|
-
|
|
16191
|
-
|
|
16192
|
-
input: functionCall.args ?? {}
|
|
16201
|
+
const normalizedToolCall = {
|
|
16202
|
+
...toolCall,
|
|
16203
|
+
id: toolCallId
|
|
16193
16204
|
};
|
|
16194
16205
|
yield {
|
|
16195
16206
|
type: "tool_use_start",
|
|
16196
16207
|
toolCall: {
|
|
16197
|
-
id:
|
|
16198
|
-
name:
|
|
16208
|
+
id: normalizedToolCall.id,
|
|
16209
|
+
name: normalizedToolCall.name
|
|
16199
16210
|
}
|
|
16200
16211
|
};
|
|
16201
16212
|
yield {
|
|
16202
16213
|
type: "tool_use_end",
|
|
16203
|
-
toolCall
|
|
16214
|
+
toolCall: normalizedToolCall
|
|
16204
16215
|
};
|
|
16205
16216
|
}
|
|
16206
16217
|
const finishReason = chunk.candidates?.[0]?.finishReason;
|
|
16207
|
-
if (
|
|
16218
|
+
if (toolCalls.length > 0) {
|
|
16208
16219
|
streamStopReason = "tool_use";
|
|
16209
16220
|
} else if (finishReason) {
|
|
16210
16221
|
streamStopReason = this.mapFinishReason(finishReason);
|
|
@@ -16328,13 +16339,18 @@ var GeminiProvider = class {
|
|
|
16328
16339
|
});
|
|
16329
16340
|
} else if (block.type === "tool_use") {
|
|
16330
16341
|
const toolUse = block;
|
|
16331
|
-
|
|
16332
|
-
|
|
16333
|
-
|
|
16334
|
-
|
|
16335
|
-
|
|
16336
|
-
|
|
16337
|
-
|
|
16342
|
+
const thoughtSignature = toolUse.geminiThoughtSignature ?? SKIP_THOUGHT_SIGNATURE_VALIDATOR;
|
|
16343
|
+
const functionCall = {
|
|
16344
|
+
id: toolUse.id,
|
|
16345
|
+
name: toolUse.name,
|
|
16346
|
+
args: toolUse.input
|
|
16347
|
+
};
|
|
16348
|
+
const part = {
|
|
16349
|
+
functionCall,
|
|
16350
|
+
thoughtSignature,
|
|
16351
|
+
thought_signature: thoughtSignature
|
|
16352
|
+
};
|
|
16353
|
+
parts.push(part);
|
|
16338
16354
|
}
|
|
16339
16355
|
}
|
|
16340
16356
|
return parts.length > 0 ? parts : [{ text: "" }];
|
|
@@ -16358,13 +16374,31 @@ var GeminiProvider = class {
|
|
|
16358
16374
|
allowedFunctionNames: [choice.name]
|
|
16359
16375
|
};
|
|
16360
16376
|
}
|
|
16361
|
-
|
|
16362
|
-
|
|
16363
|
-
|
|
16377
|
+
extractThoughtSignatureFromPart(part) {
|
|
16378
|
+
const withSignature = part;
|
|
16379
|
+
return withSignature.thoughtSignature ?? withSignature.thought_signature ?? withSignature.functionCall?.thoughtSignature ?? withSignature.functionCall?.thought_signature;
|
|
16380
|
+
}
|
|
16381
|
+
extractToolCalls(response, options) {
|
|
16382
|
+
const toolCallsFromParts = (response.candidates?.[0]?.content?.parts ?? []).filter((part) => !!part.functionCall).map((part, index) => ({
|
|
16383
|
+
id: part.functionCall.id ?? `gemini_call_${index + 1}`,
|
|
16384
|
+
name: part.functionCall.name ?? "unknown_function",
|
|
16385
|
+
input: part.functionCall.args ?? {},
|
|
16386
|
+
geminiThoughtSignature: this.extractThoughtSignatureFromPart(part)
|
|
16387
|
+
}));
|
|
16388
|
+
if (toolCallsFromParts.length > 0) {
|
|
16389
|
+
return toolCallsFromParts;
|
|
16364
16390
|
}
|
|
16365
|
-
|
|
16366
|
-
|
|
16367
|
-
|
|
16391
|
+
if (!options?.includeLegacyFunctionCalls || !response.functionCalls?.length) {
|
|
16392
|
+
return [];
|
|
16393
|
+
}
|
|
16394
|
+
return response.functionCalls.map((functionCall, index) => ({
|
|
16395
|
+
id: functionCall.id ?? `gemini_call_${index + 1}`,
|
|
16396
|
+
name: functionCall.name ?? "unknown_function",
|
|
16397
|
+
input: functionCall.args ?? {},
|
|
16398
|
+
geminiThoughtSignature: this.extractThoughtSignatureFromPart({
|
|
16399
|
+
functionCall
|
|
16400
|
+
})
|
|
16401
|
+
}));
|
|
16368
16402
|
}
|
|
16369
16403
|
parseResponse(response, model) {
|
|
16370
16404
|
const usage = response.usageMetadata;
|
|
@@ -16381,11 +16415,7 @@ var GeminiProvider = class {
|
|
|
16381
16415
|
}
|
|
16382
16416
|
parseResponseWithTools(response, model) {
|
|
16383
16417
|
const usage = response.usageMetadata;
|
|
16384
|
-
const toolCalls = this.
|
|
16385
|
-
id: functionCall.id ?? `gemini_call_${index + 1}`,
|
|
16386
|
-
name: functionCall.name ?? "unknown_function",
|
|
16387
|
-
input: functionCall.args ?? {}
|
|
16388
|
-
}));
|
|
16418
|
+
const toolCalls = this.extractToolCalls(response, { includeLegacyFunctionCalls: true });
|
|
16389
16419
|
return {
|
|
16390
16420
|
id: `gemini-${Date.now()}`,
|
|
16391
16421
|
content: response.text ?? "",
|
|
@@ -16437,12 +16467,33 @@ var DEFAULT_MODEL6 = "gemini-2.5-pro";
|
|
|
16437
16467
|
var DEFAULT_BASE_URL = "https://aiplatform.googleapis.com/v1";
|
|
16438
16468
|
var DEFAULT_LOCATION = "global";
|
|
16439
16469
|
var CONTEXT_WINDOWS6 = {
|
|
16470
|
+
"gemini-3-pro-preview": 1048576,
|
|
16471
|
+
"gemini-3-flash-preview": 1048576,
|
|
16440
16472
|
"gemini-2.5-pro": 1048576,
|
|
16441
16473
|
"gemini-2.5-flash": 1048576,
|
|
16442
16474
|
"gemini-2.5-flash-lite": 1048576,
|
|
16443
16475
|
"gemini-2.0-flash-001": 1048576,
|
|
16444
16476
|
"gemini-2.0-flash-lite-001": 1048576
|
|
16445
16477
|
};
|
|
16478
|
+
var SKIP_THOUGHT_SIGNATURE_VALIDATOR2 = "skip_thought_signature_validator";
|
|
16479
|
+
function extractSseEventData(rawEvent) {
|
|
16480
|
+
const dataLines = rawEvent.split(/\r?\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trim()).filter(Boolean);
|
|
16481
|
+
if (dataLines.length === 0) {
|
|
16482
|
+
return null;
|
|
16483
|
+
}
|
|
16484
|
+
return dataLines.join("\n");
|
|
16485
|
+
}
|
|
16486
|
+
function getToolCallFingerprint(part) {
|
|
16487
|
+
const name = part.functionCall?.name ?? "unknown_function";
|
|
16488
|
+
let argsSerialized = "{}";
|
|
16489
|
+
try {
|
|
16490
|
+
argsSerialized = JSON.stringify(part.functionCall?.args ?? {});
|
|
16491
|
+
} catch {
|
|
16492
|
+
argsSerialized = "{}";
|
|
16493
|
+
}
|
|
16494
|
+
const thoughtSignature = part.thoughtSignature ?? part.thought_signature ?? part.functionCall?.thoughtSignature ?? part.functionCall?.thought_signature ?? "";
|
|
16495
|
+
return `${name}:${argsSerialized}:${thoughtSignature}`;
|
|
16496
|
+
}
|
|
16446
16497
|
var VertexProvider = class {
|
|
16447
16498
|
id = "vertex";
|
|
16448
16499
|
name = "Google Vertex AI Gemini";
|
|
@@ -16518,6 +16569,7 @@ var VertexProvider = class {
|
|
|
16518
16569
|
);
|
|
16519
16570
|
let stopReason = "end_turn";
|
|
16520
16571
|
let streamToolCallCounter = 0;
|
|
16572
|
+
const emittedToolFingerprints = /* @__PURE__ */ new Set();
|
|
16521
16573
|
for await (const chunk of stream) {
|
|
16522
16574
|
const candidate = chunk.candidates?.[0];
|
|
16523
16575
|
const parts = candidate?.content?.parts ?? [];
|
|
@@ -16526,13 +16578,20 @@ var VertexProvider = class {
|
|
|
16526
16578
|
yield { type: "text", text: part.text };
|
|
16527
16579
|
}
|
|
16528
16580
|
if (part.functionCall) {
|
|
16581
|
+
const fingerprint = getToolCallFingerprint(part);
|
|
16582
|
+
if (emittedToolFingerprints.has(fingerprint)) {
|
|
16583
|
+
continue;
|
|
16584
|
+
}
|
|
16585
|
+
emittedToolFingerprints.add(fingerprint);
|
|
16529
16586
|
streamToolCallCounter++;
|
|
16587
|
+
const geminiThoughtSignature = part.thoughtSignature ?? part.thought_signature ?? part.functionCall.thoughtSignature ?? part.functionCall.thought_signature;
|
|
16530
16588
|
yield {
|
|
16531
16589
|
type: "tool_use_start",
|
|
16532
16590
|
toolCall: {
|
|
16533
16591
|
id: `vertex_call_${streamToolCallCounter}`,
|
|
16534
16592
|
name: part.functionCall.name,
|
|
16535
|
-
input: part.functionCall.args ?? {}
|
|
16593
|
+
input: part.functionCall.args ?? {},
|
|
16594
|
+
geminiThoughtSignature
|
|
16536
16595
|
}
|
|
16537
16596
|
};
|
|
16538
16597
|
yield {
|
|
@@ -16540,7 +16599,8 @@ var VertexProvider = class {
|
|
|
16540
16599
|
toolCall: {
|
|
16541
16600
|
id: `vertex_call_${streamToolCallCounter}`,
|
|
16542
16601
|
name: part.functionCall.name,
|
|
16543
|
-
input: part.functionCall.args ?? {}
|
|
16602
|
+
input: part.functionCall.args ?? {},
|
|
16603
|
+
geminiThoughtSignature
|
|
16544
16604
|
}
|
|
16545
16605
|
};
|
|
16546
16606
|
}
|
|
@@ -16673,11 +16733,14 @@ var VertexProvider = class {
|
|
|
16673
16733
|
});
|
|
16674
16734
|
} else if (block.type === "tool_use") {
|
|
16675
16735
|
const toolUse = block;
|
|
16736
|
+
const thoughtSignature = toolUse.geminiThoughtSignature ?? SKIP_THOUGHT_SIGNATURE_VALIDATOR2;
|
|
16676
16737
|
parts.push({
|
|
16677
16738
|
functionCall: {
|
|
16678
16739
|
name: toolUse.name,
|
|
16679
16740
|
args: toolUse.input
|
|
16680
|
-
}
|
|
16741
|
+
},
|
|
16742
|
+
thoughtSignature,
|
|
16743
|
+
thought_signature: thoughtSignature
|
|
16681
16744
|
});
|
|
16682
16745
|
}
|
|
16683
16746
|
}
|
|
@@ -16769,22 +16832,27 @@ var VertexProvider = class {
|
|
|
16769
16832
|
if (done) break;
|
|
16770
16833
|
buffer += decoder.decode(value, { stream: true });
|
|
16771
16834
|
while (true) {
|
|
16772
|
-
const
|
|
16773
|
-
if (
|
|
16774
|
-
const rawEvent = buffer.slice(0,
|
|
16775
|
-
buffer = buffer.slice(
|
|
16776
|
-
const
|
|
16777
|
-
|
|
16778
|
-
if (
|
|
16779
|
-
|
|
16835
|
+
const boundaryMatch = /\r?\n\r?\n/.exec(buffer);
|
|
16836
|
+
if (!boundaryMatch || boundaryMatch.index === void 0) break;
|
|
16837
|
+
const rawEvent = buffer.slice(0, boundaryMatch.index);
|
|
16838
|
+
buffer = buffer.slice(boundaryMatch.index + boundaryMatch[0].length);
|
|
16839
|
+
const data = extractSseEventData(rawEvent);
|
|
16840
|
+
if (!data || data === "[DONE]") {
|
|
16841
|
+
if (data === "[DONE]") return;
|
|
16842
|
+
continue;
|
|
16843
|
+
}
|
|
16844
|
+
try {
|
|
16845
|
+
yield JSON.parse(data);
|
|
16846
|
+
} catch {
|
|
16847
|
+
continue;
|
|
16780
16848
|
}
|
|
16781
16849
|
}
|
|
16782
16850
|
}
|
|
16783
|
-
const
|
|
16784
|
-
if (
|
|
16785
|
-
|
|
16786
|
-
|
|
16787
|
-
|
|
16851
|
+
const trailingData = extractSseEventData(buffer.trim());
|
|
16852
|
+
if (trailingData && trailingData !== "[DONE]") {
|
|
16853
|
+
try {
|
|
16854
|
+
yield JSON.parse(trailingData);
|
|
16855
|
+
} catch {
|
|
16788
16856
|
}
|
|
16789
16857
|
}
|
|
16790
16858
|
}
|
|
@@ -16817,7 +16885,8 @@ var VertexProvider = class {
|
|
|
16817
16885
|
toolCalls.push({
|
|
16818
16886
|
id: `vertex_call_${toolIndex}`,
|
|
16819
16887
|
name: part.functionCall.name,
|
|
16820
|
-
input: part.functionCall.args ?? {}
|
|
16888
|
+
input: part.functionCall.args ?? {},
|
|
16889
|
+
geminiThoughtSignature: part.thoughtSignature ?? part.thought_signature ?? part.functionCall.thoughtSignature ?? part.functionCall.thought_signature
|
|
16821
16890
|
});
|
|
16822
16891
|
}
|
|
16823
16892
|
}
|
|
@@ -21448,9 +21517,6 @@ var buildTools = [
|
|
|
21448
21517
|
runGradleTool
|
|
21449
21518
|
];
|
|
21450
21519
|
|
|
21451
|
-
// src/cli/repl/recommended-permissions.ts
|
|
21452
|
-
init_paths();
|
|
21453
|
-
|
|
21454
21520
|
// src/cli/repl/session.ts
|
|
21455
21521
|
init_env();
|
|
21456
21522
|
init_paths();
|
|
@@ -21485,6 +21551,7 @@ z.object({
|
|
|
21485
21551
|
// src/cli/repl/session.ts
|
|
21486
21552
|
path17__default.dirname(CONFIG_PATHS.trustedTools);
|
|
21487
21553
|
CONFIG_PATHS.trustedTools;
|
|
21554
|
+
path17__default.join(".coco", "trusted-tools.json");
|
|
21488
21555
|
|
|
21489
21556
|
// src/cli/repl/recommended-permissions.ts
|
|
21490
21557
|
var RECOMMENDED_GLOBAL = [
|
|
@@ -27503,7 +27570,7 @@ init_errors2();
|
|
|
27503
27570
|
init_callback_server();
|
|
27504
27571
|
init_paths();
|
|
27505
27572
|
init_logger();
|
|
27506
|
-
var
|
|
27573
|
+
var execFileAsync3 = promisify(execFile);
|
|
27507
27574
|
var TOKEN_STORE_PATH = path17__default.join(CONFIG_PATHS.tokens, "mcp-oauth.json");
|
|
27508
27575
|
var OAUTH_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
27509
27576
|
var logger = getLogger();
|
|
@@ -27600,7 +27667,7 @@ async function openBrowser(url) {
|
|
|
27600
27667
|
}
|
|
27601
27668
|
for (const { cmd, args } of commands) {
|
|
27602
27669
|
try {
|
|
27603
|
-
await
|
|
27670
|
+
await execFileAsync3(cmd, args);
|
|
27604
27671
|
return true;
|
|
27605
27672
|
} catch {
|
|
27606
27673
|
continue;
|
|
@@ -28476,6 +28543,25 @@ var MCPServerManager = class _MCPServerManager {
|
|
|
28476
28543
|
connections = /* @__PURE__ */ new Map();
|
|
28477
28544
|
logger = getLogger();
|
|
28478
28545
|
static STOP_TIMEOUT_MS = 5e3;
|
|
28546
|
+
/**
|
|
28547
|
+
* Run an async operation with a timeout, always clearing timer resources.
|
|
28548
|
+
*/
|
|
28549
|
+
async runWithTimeout(operation, timeoutMs, timeoutMessage) {
|
|
28550
|
+
let timeoutId;
|
|
28551
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
28552
|
+
timeoutId = setTimeout(() => reject(new Error(timeoutMessage)), timeoutMs);
|
|
28553
|
+
if (typeof timeoutId.unref === "function") {
|
|
28554
|
+
timeoutId.unref();
|
|
28555
|
+
}
|
|
28556
|
+
});
|
|
28557
|
+
try {
|
|
28558
|
+
return await Promise.race([operation, timeoutPromise]);
|
|
28559
|
+
} finally {
|
|
28560
|
+
if (timeoutId) {
|
|
28561
|
+
clearTimeout(timeoutId);
|
|
28562
|
+
}
|
|
28563
|
+
}
|
|
28564
|
+
}
|
|
28479
28565
|
/**
|
|
28480
28566
|
* Create transport for a server config
|
|
28481
28567
|
*/
|
|
@@ -28562,15 +28648,11 @@ var MCPServerManager = class _MCPServerManager {
|
|
|
28562
28648
|
}
|
|
28563
28649
|
this.logger.info(`Stopping MCP server: ${name}`);
|
|
28564
28650
|
try {
|
|
28565
|
-
await
|
|
28651
|
+
await this.runWithTimeout(
|
|
28566
28652
|
connection.transport.disconnect(),
|
|
28567
|
-
|
|
28568
|
-
|
|
28569
|
-
|
|
28570
|
-
_MCPServerManager.STOP_TIMEOUT_MS
|
|
28571
|
-
)
|
|
28572
|
-
)
|
|
28573
|
-
]);
|
|
28653
|
+
_MCPServerManager.STOP_TIMEOUT_MS,
|
|
28654
|
+
"MCP disconnect timeout"
|
|
28655
|
+
);
|
|
28574
28656
|
} catch (error) {
|
|
28575
28657
|
this.logger.error(
|
|
28576
28658
|
`Error disconnecting server '${name}': ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -28607,12 +28689,11 @@ var MCPServerManager = class _MCPServerManager {
|
|
|
28607
28689
|
}
|
|
28608
28690
|
const startTime = performance.now();
|
|
28609
28691
|
try {
|
|
28610
|
-
const { tools } = await
|
|
28692
|
+
const { tools } = await this.runWithTimeout(
|
|
28611
28693
|
connection.client.listTools(),
|
|
28612
|
-
|
|
28613
|
-
|
|
28614
|
-
|
|
28615
|
-
]);
|
|
28694
|
+
5e3,
|
|
28695
|
+
"Health check timeout"
|
|
28696
|
+
);
|
|
28616
28697
|
const latencyMs = performance.now() - startTime;
|
|
28617
28698
|
connection.healthy = true;
|
|
28618
28699
|
connection.toolCount = tools.length;
|