@corbat-tech/coco 2.4.2 → 2.5.1
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 +402 -144
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +136 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8180,6 +8180,129 @@ function getLogger() {
|
|
|
8180
8180
|
return globalLogger;
|
|
8181
8181
|
}
|
|
8182
8182
|
|
|
8183
|
+
// src/utils/error-humanizer.ts
|
|
8184
|
+
function extractQuotedPath(msg) {
|
|
8185
|
+
const single = msg.match(/'([^']+)'/);
|
|
8186
|
+
if (single?.[1]) return single[1];
|
|
8187
|
+
const double = msg.match(/"([^"]+)"/);
|
|
8188
|
+
return double?.[1] ?? null;
|
|
8189
|
+
}
|
|
8190
|
+
function humanizeError(message, toolName) {
|
|
8191
|
+
const msg = message.trim();
|
|
8192
|
+
if (!msg) return msg;
|
|
8193
|
+
if (/ECONNREFUSED/i.test(msg)) {
|
|
8194
|
+
return "Connection refused \u2014 the server may not be running";
|
|
8195
|
+
}
|
|
8196
|
+
if (/ENOTFOUND/i.test(msg)) {
|
|
8197
|
+
return "Host not found \u2014 check the URL or your internet connection";
|
|
8198
|
+
}
|
|
8199
|
+
if (/EHOSTUNREACH/i.test(msg)) {
|
|
8200
|
+
return "Host unreachable \u2014 check your network connection";
|
|
8201
|
+
}
|
|
8202
|
+
if (/ECONNRESET/i.test(msg)) {
|
|
8203
|
+
return "Connection reset \u2014 the server closed the connection unexpectedly";
|
|
8204
|
+
}
|
|
8205
|
+
if (/ERR_INVALID_URL/i.test(msg)) {
|
|
8206
|
+
return "Invalid URL format \u2014 check the URL syntax";
|
|
8207
|
+
}
|
|
8208
|
+
if (/CERT_|ERR_CERT_|SSL_ERROR|UNABLE_TO_VERIFY_LEAF_SIGNATURE/i.test(msg)) {
|
|
8209
|
+
return "SSL/TLS certificate error \u2014 the server certificate may be untrusted";
|
|
8210
|
+
}
|
|
8211
|
+
if (/fetch failed|network error|Failed to fetch/i.test(msg)) {
|
|
8212
|
+
return "Network request failed \u2014 check your internet connection";
|
|
8213
|
+
}
|
|
8214
|
+
if (/ENOENT/i.test(msg)) {
|
|
8215
|
+
const path38 = extractQuotedPath(msg);
|
|
8216
|
+
return path38 ? `File or directory not found: ${path38}` : "File or directory not found";
|
|
8217
|
+
}
|
|
8218
|
+
if (/EACCES/i.test(msg)) {
|
|
8219
|
+
const path38 = extractQuotedPath(msg);
|
|
8220
|
+
return path38 ? `Permission denied: ${path38}` : "Permission denied \u2014 check file permissions";
|
|
8221
|
+
}
|
|
8222
|
+
if (/EISDIR/i.test(msg)) {
|
|
8223
|
+
return "Expected a file but found a directory at the specified path";
|
|
8224
|
+
}
|
|
8225
|
+
if (/ENOTDIR/i.test(msg)) {
|
|
8226
|
+
return "Expected a directory but found a file in the path";
|
|
8227
|
+
}
|
|
8228
|
+
if (/EEXIST/i.test(msg)) {
|
|
8229
|
+
return "File or directory already exists";
|
|
8230
|
+
}
|
|
8231
|
+
if (/ENOSPC/i.test(msg)) {
|
|
8232
|
+
return "No disk space left \u2014 free up some space and try again";
|
|
8233
|
+
}
|
|
8234
|
+
if (/EROFS/i.test(msg)) {
|
|
8235
|
+
return "Write failed \u2014 the file system is read-only";
|
|
8236
|
+
}
|
|
8237
|
+
if (/EMFILE|ENFILE/i.test(msg)) {
|
|
8238
|
+
return "Too many open files \u2014 try restarting and running again";
|
|
8239
|
+
}
|
|
8240
|
+
if (/not a git repository/i.test(msg)) {
|
|
8241
|
+
return "Not a git repository \u2014 run 'git init' to initialize one";
|
|
8242
|
+
}
|
|
8243
|
+
if (/nothing to commit/i.test(msg)) {
|
|
8244
|
+
return "Nothing to commit \u2014 the working tree is clean";
|
|
8245
|
+
}
|
|
8246
|
+
if (/merge conflict|CONFLICT/i.test(msg)) {
|
|
8247
|
+
return "Merge conflict detected \u2014 resolve the conflicts before continuing";
|
|
8248
|
+
}
|
|
8249
|
+
if (/non-fast-forward|rejected.*push/i.test(msg)) {
|
|
8250
|
+
return "Push rejected \u2014 pull the latest changes first (git pull)";
|
|
8251
|
+
}
|
|
8252
|
+
if (/authentication failed/i.test(msg) && /git/i.test(msg)) {
|
|
8253
|
+
return "Git authentication failed \u2014 check your credentials or SSH key";
|
|
8254
|
+
}
|
|
8255
|
+
if (/branch.*already exists/i.test(msg)) {
|
|
8256
|
+
return "Branch already exists \u2014 choose a different name or use the existing branch";
|
|
8257
|
+
}
|
|
8258
|
+
if (/detached HEAD/i.test(msg)) {
|
|
8259
|
+
return "Detached HEAD \u2014 checkout a branch to start committing";
|
|
8260
|
+
}
|
|
8261
|
+
if (/(bad revision|does not exist on|unknown revision)/i.test(msg)) {
|
|
8262
|
+
return "Git reference not found \u2014 the branch or commit may not exist";
|
|
8263
|
+
}
|
|
8264
|
+
if (/Unexpected token.*JSON|JSON\.parse|Unexpected end of JSON/i.test(msg)) {
|
|
8265
|
+
return "Failed to parse JSON \u2014 the data may be malformed";
|
|
8266
|
+
}
|
|
8267
|
+
if (/SyntaxError.*Unexpected token/i.test(msg)) {
|
|
8268
|
+
return "Syntax error in the data \u2014 check for formatting issues";
|
|
8269
|
+
}
|
|
8270
|
+
const moduleMatch = msg.match(/Cannot find module ['"]([^'"]+)['"]/i);
|
|
8271
|
+
if (moduleMatch) {
|
|
8272
|
+
return `Module not found: '${moduleMatch[1]}' \u2014 run the install command to add it`;
|
|
8273
|
+
}
|
|
8274
|
+
if (/ERR_MODULE_NOT_FOUND|MODULE_NOT_FOUND/i.test(msg)) {
|
|
8275
|
+
return "Required module not found \u2014 run the install command first";
|
|
8276
|
+
}
|
|
8277
|
+
if (/ERR_REQUIRE_ESM/i.test(msg)) {
|
|
8278
|
+
return "Module format mismatch \u2014 this package requires ESM (type: module)";
|
|
8279
|
+
}
|
|
8280
|
+
if (/command not found/i.test(msg) || /spawn.*ENOENT/i.test(msg) && toolName === "bash_exec") {
|
|
8281
|
+
const cmdMatch = msg.match(/Command '([^']+)' not found|spawn ([^\s]+) ENOENT/);
|
|
8282
|
+
const cmd = cmdMatch?.[1] ?? cmdMatch?.[2];
|
|
8283
|
+
return cmd ? `Command '${cmd}' not found \u2014 is it installed and in your PATH?` : "Command not found \u2014 check it is installed and available in PATH";
|
|
8284
|
+
}
|
|
8285
|
+
if (/permission denied/i.test(msg) && /spawn|exec/i.test(msg)) {
|
|
8286
|
+
return "Permission denied \u2014 the script may not be executable (try: chmod +x)";
|
|
8287
|
+
}
|
|
8288
|
+
if (/\b401\b|Unauthorized/i.test(msg)) {
|
|
8289
|
+
return "Authentication failed (401) \u2014 check your API key or credentials";
|
|
8290
|
+
}
|
|
8291
|
+
if (/\b403\b|Forbidden/i.test(msg)) {
|
|
8292
|
+
return "Access denied (403) \u2014 you don't have permission for this action";
|
|
8293
|
+
}
|
|
8294
|
+
if (/\b429\b|rate.?limit/i.test(msg)) {
|
|
8295
|
+
return "Rate limit exceeded (429) \u2014 too many requests, wait a moment and retry";
|
|
8296
|
+
}
|
|
8297
|
+
if (/\b503\b|Service Unavailable/i.test(msg)) {
|
|
8298
|
+
return "Service temporarily unavailable (503) \u2014 try again in a few minutes";
|
|
8299
|
+
}
|
|
8300
|
+
if (/invalid.*api.?key|api.?key.*invalid|api.?key.*not.*found/i.test(msg)) {
|
|
8301
|
+
return "Invalid or missing API key \u2014 check your provider credentials";
|
|
8302
|
+
}
|
|
8303
|
+
return msg;
|
|
8304
|
+
}
|
|
8305
|
+
|
|
8183
8306
|
// src/tools/registry.ts
|
|
8184
8307
|
var ToolRegistry = class {
|
|
8185
8308
|
tools = /* @__PURE__ */ new Map();
|
|
@@ -8271,7 +8394,17 @@ var ToolRegistry = class {
|
|
|
8271
8394
|
};
|
|
8272
8395
|
} catch (error) {
|
|
8273
8396
|
const duration = performance.now() - startTime;
|
|
8274
|
-
|
|
8397
|
+
let errorMessage;
|
|
8398
|
+
if (error instanceof z.ZodError) {
|
|
8399
|
+
const fields = error.issues.map((issue) => {
|
|
8400
|
+
const field = issue.path.join(".") || "input";
|
|
8401
|
+
return `${field} (${issue.message.toLowerCase()})`;
|
|
8402
|
+
});
|
|
8403
|
+
errorMessage = `Invalid tool input \u2014 ${fields.join(", ")}`;
|
|
8404
|
+
} else {
|
|
8405
|
+
const rawMessage = error instanceof Error ? error.message : String(error);
|
|
8406
|
+
errorMessage = humanizeError(rawMessage, name);
|
|
8407
|
+
}
|
|
8275
8408
|
this.logger.error(`Tool '${name}' failed`, { error: errorMessage, duration });
|
|
8276
8409
|
options?.onProgress?.({
|
|
8277
8410
|
phase: "failed",
|
|
@@ -11680,8 +11813,8 @@ var AnthropicProvider = class {
|
|
|
11680
11813
|
try {
|
|
11681
11814
|
currentToolCall.input = currentToolInputJson ? JSON.parse(currentToolInputJson) : {};
|
|
11682
11815
|
} catch {
|
|
11683
|
-
|
|
11684
|
-
`
|
|
11816
|
+
getLogger().warn(
|
|
11817
|
+
`Failed to parse tool call arguments: ${currentToolInputJson?.slice(0, 100)}`
|
|
11685
11818
|
);
|
|
11686
11819
|
currentToolCall.input = {};
|
|
11687
11820
|
}
|