@corbat-tech/coco 2.33.2 → 2.34.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/index.js CHANGED
@@ -858,6 +858,22 @@ function isCopilotTokenExpired(creds) {
858
858
  if (!creds.copilotToken || !creds.copilotTokenExpiresAt) return true;
859
859
  return Date.now() >= creds.copilotTokenExpiresAt - REFRESH_BUFFER_MS;
860
860
  }
861
+ function exchangeForCopilotTokenViaGhCli() {
862
+ return new Promise((resolve3) => {
863
+ execFile("gh", ["api", "/copilot_internal/v2/token"], { timeout: 1e4 }, (err, stdout) => {
864
+ if (err || !stdout) {
865
+ resolve3(null);
866
+ return;
867
+ }
868
+ try {
869
+ const parsed = JSON.parse(stdout);
870
+ resolve3(parsed.token && parsed.expires_at ? parsed : null);
871
+ } catch {
872
+ resolve3(null);
873
+ }
874
+ });
875
+ });
876
+ }
861
877
  async function getValidCopilotToken() {
862
878
  const creds = await loadCopilotCredentials();
863
879
  const envToken = process.env["COPILOT_GITHUB_TOKEN"] || process.env["GH_TOKEN"] || process.env["GITHUB_TOKEN"];
@@ -871,8 +887,7 @@ async function getValidCopilotToken() {
871
887
  isNew: false
872
888
  };
873
889
  }
874
- try {
875
- const copilotToken = await exchangeForCopilotToken(githubToken);
890
+ const saveAndReturn = async (copilotToken) => {
876
891
  const updatedCreds = {
877
892
  ...creds ?? { githubToken },
878
893
  githubToken: creds?.githubToken ?? githubToken,
@@ -886,11 +901,23 @@ async function getValidCopilotToken() {
886
901
  baseUrl: getCopilotBaseUrl(updatedCreds.accountType),
887
902
  isNew: true
888
903
  };
904
+ };
905
+ try {
906
+ const copilotToken = await exchangeForCopilotToken(githubToken);
907
+ return saveAndReturn(copilotToken);
889
908
  } catch (error) {
890
909
  if (error instanceof CopilotAuthError && error.permanent) {
910
+ const ghCliToken2 = await exchangeForCopilotTokenViaGhCli();
911
+ if (ghCliToken2) {
912
+ return saveAndReturn(ghCliToken2);
913
+ }
891
914
  await deleteCopilotCredentials();
892
915
  return null;
893
916
  }
917
+ const ghCliToken = await exchangeForCopilotTokenViaGhCli();
918
+ if (ghCliToken) {
919
+ return saveAndReturn(ghCliToken);
920
+ }
894
921
  throw error;
895
922
  }
896
923
  }
@@ -1680,6 +1707,18 @@ function getDefaultProvider() {
1680
1707
  }
1681
1708
  return "anthropic";
1682
1709
  }
1710
+ function getEditorModel() {
1711
+ const raw = process.env["COCO_EDITOR_MODEL"]?.trim();
1712
+ if (!raw || raw.length === 0) return void 0;
1713
+ if (["none", "default", "null", "undefined"].includes(raw.toLowerCase())) return void 0;
1714
+ return raw;
1715
+ }
1716
+ function getWeakModel() {
1717
+ const raw = process.env["COCO_WEAK_MODEL"]?.trim();
1718
+ if (!raw || raw.length === 0) return void 0;
1719
+ if (["none", "default", "null", "undefined"].includes(raw.toLowerCase())) return void 0;
1720
+ return raw;
1721
+ }
1683
1722
  var VALID_PROVIDERS;
1684
1723
  var init_env = __esm({
1685
1724
  "src/config/env.ts"() {
@@ -1709,7 +1748,9 @@ var init_env = __esm({
1709
1748
  provider: getDefaultProvider(),
1710
1749
  getApiKey,
1711
1750
  getBaseUrl,
1712
- getDefaultModel
1751
+ getDefaultModel,
1752
+ getWeakModel,
1753
+ getEditorModel
1713
1754
  });
1714
1755
  }
1715
1756
  });
@@ -10316,13 +10357,21 @@ var ToolRegistry = class {
10316
10357
  const field = issue.path.join(".") || "input";
10317
10358
  return `${field} (${issue.message.toLowerCase()})`;
10318
10359
  });
10319
- errorMessage = `Invalid tool input \u2014 ${fields.join(", ")}`;
10360
+ errorMessage = `Invalid tool input for '${name}' \u2014 ${fields.join(", ")}`;
10320
10361
  const allUndefined = error.issues.every(
10321
10362
  (i) => i.message.toLowerCase().includes("received undefined")
10322
10363
  );
10323
10364
  if (allUndefined && error.issues.length > 1) {
10324
10365
  errorMessage += ". All parameters are missing \u2014 this is likely a JSON serialization error on our side. Please retry with the same arguments.";
10325
10366
  }
10367
+ try {
10368
+ const schema = zodToJsonSchema(tool.parameters);
10369
+ errorMessage += `
10370
+
10371
+ Expected schema for '${name}':
10372
+ ${JSON.stringify(schema, null, 2)}`;
10373
+ } catch {
10374
+ }
10326
10375
  } else if (isCocoError(error)) {
10327
10376
  const causeMsg = error.cause instanceof Error ? error.cause.message : "";
10328
10377
  const isRawEnoent = causeMsg.startsWith("ENOENT:");
@@ -14368,6 +14417,129 @@ var ResponsesToolCallAssembler = class {
14368
14417
  }
14369
14418
  };
14370
14419
 
14420
+ // src/providers/model-tier.ts
14421
+ var TIER_CONFIGS = {
14422
+ mini: {
14423
+ maxTools: 12,
14424
+ parallelToolCalls: false,
14425
+ compactionThreshold: 0.5,
14426
+ supportsCoT: false
14427
+ },
14428
+ standard: {
14429
+ maxTools: 40,
14430
+ parallelToolCalls: true,
14431
+ compactionThreshold: 0.75,
14432
+ supportsCoT: true
14433
+ },
14434
+ advanced: {
14435
+ maxTools: 128,
14436
+ parallelToolCalls: true,
14437
+ compactionThreshold: 0.8,
14438
+ supportsCoT: true
14439
+ }
14440
+ };
14441
+ var ANTHROPIC_TIERS = [
14442
+ // Haiku — mini tier
14443
+ { prefix: "claude-haiku", tier: "mini" },
14444
+ { prefix: "claude-3-haiku", tier: "mini" },
14445
+ // Sonnet / Claude 3.5 — standard tier
14446
+ { prefix: "claude-3-5-sonnet", tier: "standard" },
14447
+ { prefix: "claude-3-7-sonnet", tier: "standard" },
14448
+ { prefix: "claude-sonnet", tier: "standard" },
14449
+ // Opus — advanced tier
14450
+ { prefix: "claude-opus", tier: "advanced" },
14451
+ { prefix: "claude-3-opus", tier: "advanced" }
14452
+ // claude-4+ (future) — default to standard unless matched above
14453
+ ];
14454
+ var OPENAI_TIERS = [
14455
+ // Mini models
14456
+ { prefix: "gpt-4o-mini", tier: "mini" },
14457
+ { prefix: "gpt-5-mini", tier: "mini" },
14458
+ { prefix: "gpt-5.4-mini", tier: "mini" },
14459
+ { prefix: "gpt-5.3-mini", tier: "mini" },
14460
+ { prefix: "o1-mini", tier: "mini" },
14461
+ { prefix: "o3-mini", tier: "mini" },
14462
+ // Advanced / reasoning models
14463
+ { prefix: "o1", tier: "advanced" },
14464
+ { prefix: "o3", tier: "advanced" },
14465
+ { prefix: "o4", tier: "advanced" },
14466
+ { prefix: "gpt-4.1", tier: "advanced" },
14467
+ { prefix: "gpt-5.4-codex", tier: "advanced" },
14468
+ { prefix: "gpt-5.3-codex", tier: "advanced" },
14469
+ { prefix: "gpt-5.2-codex", tier: "advanced" },
14470
+ { prefix: "gpt-5.1-codex", tier: "advanced" },
14471
+ { prefix: "gpt-5.4", tier: "advanced" },
14472
+ { prefix: "gpt-5.3", tier: "advanced" },
14473
+ { prefix: "gpt-5.2", tier: "advanced" },
14474
+ { prefix: "gpt-5.1", tier: "advanced" },
14475
+ // GPT-5 catch-all (non-mini/codex) — advanced
14476
+ { prefix: "gpt-5", tier: "advanced" },
14477
+ // GPT-4o — standard
14478
+ { prefix: "gpt-4o", tier: "standard" },
14479
+ // GPT-4 — standard
14480
+ { prefix: "gpt-4", tier: "standard" }
14481
+ ];
14482
+ var GEMINI_TIERS = [
14483
+ // Flash — mini tier
14484
+ { prefix: "gemini-3-flash", tier: "mini" },
14485
+ { prefix: "gemini-2.5-flash", tier: "mini" },
14486
+ { prefix: "gemini-2.0-flash", tier: "mini" },
14487
+ { prefix: "gemini-1.5-flash", tier: "mini" },
14488
+ // Pro — standard/advanced
14489
+ { prefix: "gemini-3.1-pro", tier: "advanced" },
14490
+ { prefix: "gemini-3-pro", tier: "advanced" },
14491
+ { prefix: "gemini-2.5-pro", tier: "standard" },
14492
+ { prefix: "gemini-2.0-pro", tier: "standard" },
14493
+ { prefix: "gemini-1.5-pro", tier: "standard" }
14494
+ ];
14495
+ var KIMI_TIERS = [
14496
+ { prefix: "kimi-for-coding", tier: "advanced" },
14497
+ { prefix: "kimi-k2", tier: "advanced" },
14498
+ { prefix: "kimi-latest", tier: "standard" },
14499
+ { prefix: "kimi", tier: "standard" }
14500
+ ];
14501
+ var EVAL_TIERS = [
14502
+ { prefix: "grok-code", tier: "standard" },
14503
+ { prefix: "raptor", tier: "mini" },
14504
+ { prefix: "goldeneye", tier: "standard" }
14505
+ ];
14506
+ function matchTier(model, table) {
14507
+ const lower = model.toLowerCase();
14508
+ const sorted = [...table].sort((a, b) => b.prefix.length - a.prefix.length);
14509
+ for (const { prefix, tier } of sorted) {
14510
+ if (lower.startsWith(prefix.toLowerCase())) return tier;
14511
+ }
14512
+ return null;
14513
+ }
14514
+ function getModelTier(provider, model) {
14515
+ if (!model) return "standard";
14516
+ const p5 = provider.toLowerCase();
14517
+ if (p5 === "anthropic") {
14518
+ return matchTier(model, ANTHROPIC_TIERS) ?? "standard";
14519
+ }
14520
+ if (p5 === "kimi-code") {
14521
+ return matchTier(model, KIMI_TIERS) ?? matchTier(model, ANTHROPIC_TIERS) ?? "standard";
14522
+ }
14523
+ if (p5 === "openai" || p5 === "copilot" || p5 === "codex") {
14524
+ if (model.startsWith("claude-")) {
14525
+ return matchTier(model, ANTHROPIC_TIERS) ?? "standard";
14526
+ }
14527
+ const evalMatch = matchTier(model, EVAL_TIERS);
14528
+ if (evalMatch) return evalMatch;
14529
+ return matchTier(model, OPENAI_TIERS) ?? "standard";
14530
+ }
14531
+ if (p5 === "gemini" || p5 === "vertex") {
14532
+ return matchTier(model, GEMINI_TIERS) ?? "standard";
14533
+ }
14534
+ if (p5 === "kimi" || p5 === "moonshot") {
14535
+ return matchTier(model, KIMI_TIERS) ?? "standard";
14536
+ }
14537
+ return "standard";
14538
+ }
14539
+ function getTierConfig(provider, model) {
14540
+ return TIER_CONFIGS[getModelTier(provider, model)];
14541
+ }
14542
+
14371
14543
  // src/providers/openai.ts
14372
14544
  var DEFAULT_MODEL2 = "gpt-5.3-codex";
14373
14545
  var CONTEXT_WINDOWS2 = {
@@ -14602,18 +14774,21 @@ var OpenAIProvider = class {
14602
14774
  if (this.modelNeedsResponsesApi(model)) {
14603
14775
  return this.chatWithToolsViaResponses(messages, options);
14604
14776
  }
14777
+ const tierCfg = getTierConfig(this.id, model);
14605
14778
  return withRetry(async () => {
14606
14779
  try {
14607
14780
  const supportsTemp = this.supportsTemperature(model);
14608
14781
  const extraBody = this.getExtraBody(model, options?.thinking);
14609
14782
  const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
14610
14783
  const maxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
14784
+ const tools = this.limitTools(options.tools, tierCfg.maxTools);
14611
14785
  const requestParams = {
14612
14786
  model,
14613
14787
  ...buildMaxTokensParam(model, maxTokens),
14614
14788
  messages: this.convertMessages(messages, options?.system),
14615
- tools: this.convertTools(options.tools),
14616
- tool_choice: this.convertToolChoice(options.toolChoice)
14789
+ tools: this.convertTools(tools),
14790
+ tool_choice: this.convertToolChoice(options.toolChoice),
14791
+ parallel_tool_calls: tierCfg.parallelToolCalls
14617
14792
  };
14618
14793
  if (supportsTemp) {
14619
14794
  requestParams.temperature = options?.temperature ?? this.config.temperature ?? 0;
@@ -14693,18 +14868,21 @@ var OpenAIProvider = class {
14693
14868
  yield* this.streamWithToolsViaResponses(messages, options);
14694
14869
  return;
14695
14870
  }
14871
+ const tierCfg = getTierConfig(this.id, model);
14696
14872
  let timeoutTriggered = false;
14697
14873
  try {
14698
14874
  const supportsTemp = this.supportsTemperature(model);
14699
14875
  const extraBody = this.getExtraBody(model, options?.thinking);
14700
14876
  const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
14701
14877
  const maxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
14878
+ const tools = this.limitTools(options.tools, tierCfg.maxTools);
14702
14879
  const requestParams = {
14703
14880
  model,
14704
14881
  ...buildMaxTokensParam(model, maxTokens),
14705
14882
  messages: this.convertMessages(messages, options?.system),
14706
- tools: this.convertTools(options.tools),
14883
+ tools: this.convertTools(tools),
14707
14884
  tool_choice: this.convertToolChoice(options.toolChoice),
14885
+ parallel_tool_calls: tierCfg.parallelToolCalls,
14708
14886
  stream: true
14709
14887
  };
14710
14888
  if (supportsTemp) {
@@ -15074,6 +15252,17 @@ var OpenAIProvider = class {
15074
15252
  }
15075
15253
  return content.filter((block) => block.type === "text").map((block) => block.text).join("");
15076
15254
  }
15255
+ /**
15256
+ * Limit the tool list to at most `max` entries.
15257
+ * Built-in tools (those without an `mcp_server` tag) are prioritised over
15258
+ * MCP tools so core capabilities are never dropped.
15259
+ */
15260
+ limitTools(tools, max) {
15261
+ if (tools.length <= max) return tools;
15262
+ const builtin = tools.filter((t) => !("serverName" in t && t.serverName));
15263
+ const mcp = tools.filter((t) => "serverName" in t && t.serverName);
15264
+ return [...builtin, ...mcp].slice(0, max);
15265
+ }
15077
15266
  /**
15078
15267
  * Convert tools to OpenAI format
15079
15268
  */
@@ -15083,7 +15272,8 @@ var OpenAIProvider = class {
15083
15272
  function: {
15084
15273
  name: tool.name,
15085
15274
  description: truncateToolDescription(tool.description),
15086
- parameters: tool.input_schema
15275
+ parameters: tool.input_schema,
15276
+ strict: true
15087
15277
  }
15088
15278
  }));
15089
15279
  }
@@ -15216,8 +15406,11 @@ var OpenAIProvider = class {
15216
15406
  return withRetry(async () => {
15217
15407
  try {
15218
15408
  const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
15409
+ const tierCfg = getTierConfig(this.id, model);
15219
15410
  const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
15220
- const tools = this.convertToolsForResponses(options.tools);
15411
+ const tools = this.convertToolsForResponses(
15412
+ this.limitTools(options.tools, tierCfg.maxTools)
15413
+ );
15221
15414
  const supportsTemp = this.supportsTemperature(model);
15222
15415
  const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
15223
15416
  const response = await this.client.responses.create({
@@ -15337,8 +15530,10 @@ var OpenAIProvider = class {
15337
15530
  let timeoutTriggered = false;
15338
15531
  try {
15339
15532
  const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
15533
+ const tierCfg = getTierConfig(this.id, model);
15340
15534
  const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
15341
- const tools = options.tools.length > 0 ? this.convertToolsForResponses(options.tools) : void 0;
15535
+ const limitedTools = this.limitTools(options.tools, tierCfg.maxTools);
15536
+ const tools = limitedTools.length > 0 ? this.convertToolsForResponses(limitedTools) : void 0;
15342
15537
  const supportsTemp = this.supportsTemperature(model);
15343
15538
  const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
15344
15539
  const requestParams = {
@@ -15570,7 +15765,7 @@ var OpenAIProvider = class {
15570
15765
  name: tool.name,
15571
15766
  description: tool.description ? truncateToolDescription(tool.description) : void 0,
15572
15767
  parameters: tool.input_schema ?? null,
15573
- strict: false
15768
+ strict: true
15574
15769
  }));
15575
15770
  }
15576
15771
  };
@@ -18422,7 +18617,7 @@ Use list_dir or glob to find the correct path.`;
18422
18617
  }
18423
18618
  var readFileTool = defineTool({
18424
18619
  name: "read_file",
18425
- description: `Read the contents of a file.
18620
+ description: `Read the full text content of a file at the given path and return it as a string. Use this when you need the actual source code, configuration values, or text content of a specific file you already know the path to. Do NOT use this to list files in a directory (use list_directory), to check if a file exists (use file_exists), or to search for files by name pattern (use find_files). Returns an error if the path does not exist or is not a readable text file.
18426
18621
 
18427
18622
  Examples:
18428
18623
  - Read config: { "path": "package.json" }
@@ -18480,7 +18675,7 @@ Examples:
18480
18675
  });
18481
18676
  var writeFileTool = defineTool({
18482
18677
  name: "write_file",
18483
- description: `Write content to a file, creating it if it doesn't exist.
18678
+ description: `Write text content to a file, replacing it entirely if it already exists or creating it if it does not. Use this when you want to create a new file or fully replace an existing file's content. Do NOT use this to make a small change to an existing file (use edit_file instead, which performs a targeted find-and-replace without rewriting the whole file). Set createDirs: true to automatically create missing parent directories; otherwise the parent directory must already exist.
18484
18679
 
18485
18680
  Examples:
18486
18681
  - Create file: { "path": "src/utils.ts", "content": "export const foo = 1;" }
@@ -18541,7 +18736,7 @@ Examples:
18541
18736
  });
18542
18737
  var editFileTool = defineTool({
18543
18738
  name: "edit_file",
18544
- description: `Edit a file by replacing text (find and replace).
18739
+ description: `Make a targeted text replacement inside an existing file by finding oldText and replacing it with newText. Use this for surgical edits to source code, configuration files, or documentation \u2014 it is much safer than rewriting the whole file with write_file because it only touches the exact bytes you specify. The oldText must match exactly (including whitespace and indentation); if it appears more than once in the file, use all: true to replace every occurrence or make oldText longer to be unique. Do NOT use this to create new files (use write_file) or to rename/move files (use move_path).
18545
18740
 
18546
18741
  Examples:
18547
18742
  - Single replace: { "path": "src/app.ts", "oldText": "TODO:", "newText": "DONE:" }
@@ -18625,7 +18820,7 @@ Hint: Use read_file first to verify the exact content.`
18625
18820
  });
18626
18821
  var globTool = defineTool({
18627
18822
  name: "glob",
18628
- description: `Find files matching a glob pattern.
18823
+ description: `Find files whose paths match a glob pattern and return their relative paths as a list. Use this when you know the file extension or naming convention but not the exact path (e.g. find all TypeScript test files, all JSON configs). Do NOT use this to search inside file contents \u2014 use grep or search for that. Returns an empty list when nothing matches; does not throw an error for zero results. node_modules, .git, and dist directories are excluded by default.
18629
18824
 
18630
18825
  Examples:
18631
18826
  - All TypeScript: { "pattern": "**/*.ts" }
@@ -18667,7 +18862,7 @@ Examples:
18667
18862
  });
18668
18863
  var fileExistsTool = defineTool({
18669
18864
  name: "file_exists",
18670
- description: `Check if a file or directory exists.
18865
+ description: `Check whether a path exists on disk and whether it is a file or directory. Use this before attempting to read or write a path when you are unsure it exists \u2014 it never throws, always returning { exists: false } for missing paths. Do NOT use this to read file contents (use read_file) or to list directory contents (use list_directory). Returns isFile and isDirectory flags so you can distinguish files from directories in a single call.
18671
18866
 
18672
18867
  Examples:
18673
18868
  - Check file: { "path": "package.json" } \u2192 { "exists": true, "isFile": true, "isDirectory": false }
@@ -18697,7 +18892,7 @@ Examples:
18697
18892
  });
18698
18893
  var listDirTool = defineTool({
18699
18894
  name: "list_dir",
18700
- description: `List contents of a directory.
18895
+ description: `List the immediate entries (files and subdirectories) inside a directory and return their names, types, and sizes. Use this to understand what's in a folder before deciding which files to read. Do NOT use this to find files matching a pattern across the whole project (use glob) or to read file contents (use read_file). Returns an error if the path does not exist or is not a directory.
18701
18896
 
18702
18897
  Examples:
18703
18898
  - List src: { "path": "src" }
@@ -19130,16 +19325,11 @@ var SENSITIVE_ENV_PATTERNS = [
19130
19325
  ];
19131
19326
  var bashExecTool = defineTool({
19132
19327
  name: "bash_exec",
19133
- description: `Execute a bash/shell command in the user's shell environment.
19328
+ description: `Execute a shell command and return its stdout, stderr, and exit code. Use this for running build scripts, test runners, linters, package managers, CLI tools, git commands, or any other shell operation. Runs in the user's shell environment with their full PATH and locally-configured credentials (kubeconfig, gcloud auth, AWS profiles, SSH keys) so never claim you cannot run a command due to missing credentials \u2014 always attempt and report the actual exit code. Do NOT use this to read or write files (use read_file / write_file / edit_file which are safer); prefer specific file tools for file operations.
19134
19329
 
19135
19330
  Runs with the user's full PATH and inherited environment \u2014 any tool installed
19136
19331
  on the user's machine is available: kubectl, gcloud, aws, docker, git, node,
19137
- pnpm, and others. Credentials configured locally are inherited automatically:
19138
- kubeconfig contexts, gcloud auth, AWS profiles, SSH keys, etc.
19139
-
19140
- IMPORTANT: never claim you cannot run a command because you lack credentials
19141
- or access \u2014 the environment is the user's own shell. Always attempt; report
19142
- failure only if the command actually returns a non-zero exit code.
19332
+ pnpm, and others.
19143
19333
 
19144
19334
  Examples:
19145
19335
  - List files: { "command": "ls -la" }
@@ -19408,7 +19598,7 @@ function getGit(cwd) {
19408
19598
  }
19409
19599
  var gitStatusTool = defineTool({
19410
19600
  name: "git_status",
19411
- description: `Get the current git repository status including branch, staged, modified, and untracked files.
19601
+ description: `Return the current git repository state: branch name, staged files, modified files, and untracked files. Use this before committing to see what has changed, or to check which branch is active. Do NOT use this to see the content of changes (use git_diff), or to view history (use git_log). Returns isClean: true when the working tree is clean with nothing to commit.
19412
19602
 
19413
19603
  Examples:
19414
19604
  - Current dir: {} \u2192 { "branch": "main", "isClean": false, "modified": ["src/app.ts"] }
@@ -19442,7 +19632,7 @@ Examples:
19442
19632
  });
19443
19633
  var gitDiffTool = defineTool({
19444
19634
  name: "git_diff",
19445
- description: `Get git diff showing file changes.
19635
+ description: `Show the unified diff of changes in the working tree or staging area. Use this to see exactly what lines changed in files before committing, or to review changes the user just made. Use staged: true to see only what has been staged (git add), or omit it to see all unstaged changes. Do NOT use this to see commit history (use git_log) or file status summary (use git_status).
19446
19636
 
19447
19637
  Examples:
19448
19638
  - All changes: {} \u2192 { "diff": "...", "filesChanged": 3, "insertions": 42, "deletions": 10 }
@@ -19479,7 +19669,7 @@ Examples:
19479
19669
  });
19480
19670
  var gitAddTool = defineTool({
19481
19671
  name: "git_add",
19482
- description: `Stage files for commit.
19672
+ description: `Stage one or more files (or patterns) so they are included in the next git commit. Use this after making file edits to mark them ready for commit. Pass ["."] to stage all changes, or list specific file paths to stage selectively. Do NOT use this to commit (use git_commit after staging) or to view what is staged (use git_status or git_diff with staged: true).
19483
19673
 
19484
19674
  Examples:
19485
19675
  - Stage all: { "files": ["."] }
@@ -19505,7 +19695,7 @@ Examples:
19505
19695
  });
19506
19696
  var gitCommitTool = defineTool({
19507
19697
  name: "git_commit",
19508
- description: `Create a git commit with the staged changes.
19698
+ description: `Create a git commit from whatever is currently staged (git add must run first). Use conventional commit format (feat/fix/docs/chore). Do NOT use this when nothing is staged \u2014 check git_status first; do NOT use this to stage files (use git_add) or to see what will be committed (use git_diff with staged: true).
19509
19699
 
19510
19700
  Examples:
19511
19701
  - Simple commit: { "message": "fix: resolve auth bug" }
@@ -19538,7 +19728,7 @@ Examples:
19538
19728
  });
19539
19729
  var gitLogTool = defineTool({
19540
19730
  name: "git_log",
19541
- description: `Get git commit history.
19731
+ description: `Show git commit history with hashes, messages, authors, and dates. Use this to understand what changed recently, find the commit that introduced a bug, or check whether a feature was already merged. Do NOT use this to see the content of changes \u2014 use git_diff; do NOT use this to check current file state \u2014 use git_status.
19542
19732
 
19543
19733
  Examples:
19544
19734
  - Last 10 commits: {} (default)
@@ -19578,7 +19768,7 @@ Examples:
19578
19768
  });
19579
19769
  var gitBranchTool = defineTool({
19580
19770
  name: "git_branch",
19581
- description: `Manage git branches (list, create, delete).
19771
+ description: `List all local branches, create a new branch from the current HEAD, or delete a branch. Use this to see available branches before checking out, or to create a feature branch. Do NOT use this to switch the active branch \u2014 use git_checkout; do NOT delete branches that have unmerged work.
19582
19772
 
19583
19773
  Examples:
19584
19774
  - List branches: {} \u2192 { "branches": ["main", "feature/x"], "current": "main" }
@@ -19622,7 +19812,7 @@ Examples:
19622
19812
  });
19623
19813
  var gitCheckoutTool = defineTool({
19624
19814
  name: "git_checkout",
19625
- description: `Switch branches or create and switch to a new branch.
19815
+ description: `Switch the working directory to an existing branch, or create a new branch and switch to it in one step. Use this to move between branches or start a new feature branch. Do NOT use this with unsaved file edits (stage or stash first); do NOT use this to just list branches \u2014 use git_branch.
19626
19816
 
19627
19817
  Examples:
19628
19818
  - Switch branch: { "branch": "main" }
@@ -19652,7 +19842,7 @@ Examples:
19652
19842
  });
19653
19843
  var gitPushTool = defineTool({
19654
19844
  name: "git_push",
19655
- description: `Push commits to remote repository.
19845
+ description: `Upload local commits to a remote repository. Use setUpstream: true the first time you push a new branch to create the tracking relationship. Do NOT use this on main/master without explicit user confirmation \u2014 it modifies shared history; do NOT push without first checking git_status to confirm all commits are clean.
19656
19846
 
19657
19847
  Examples:
19658
19848
  - Push current: {} \u2192 pushes to origin
@@ -19690,7 +19880,7 @@ Examples:
19690
19880
  });
19691
19881
  var gitPullTool = defineTool({
19692
19882
  name: "git_pull",
19693
- description: `Pull changes from remote repository.
19883
+ description: `Fetch and integrate remote commits into the current branch. Use rebase: true to keep a linear history (preferred for feature branches). Do NOT use this when you have uncommitted local changes \u2014 stage or stash them first; if a merge conflict is reported, use read_file / edit_file to resolve then git_add and git_commit.
19694
19884
 
19695
19885
  Examples:
19696
19886
  - Pull current: {} \u2192 pulls from origin
@@ -20813,7 +21003,7 @@ var qualityTools = [runLinterTool, analyzeComplexityTool, calculateQualityTool];
20813
21003
  init_errors();
20814
21004
  var grepTool = defineTool({
20815
21005
  name: "grep",
20816
- description: `Search for text patterns in files using regex.
21006
+ description: `Search for a regex pattern across all files in a directory and return matching lines with file paths and line numbers. Use this when you know a symbol name, string literal, or pattern and want to find where it appears in the codebase (function definitions, imports, error messages, config keys). Do NOT use this to find files by name \u2014 use glob for that. Do NOT use this when you already know the file path \u2014 use read_file directly. Searches are recursive by default; narrow with the include glob to restrict to specific file types.
20817
21007
 
20818
21008
  Examples:
20819
21009
  - Simple search: { "pattern": "TODO" }
@@ -20946,7 +21136,7 @@ Examples:
20946
21136
  });
20947
21137
  var findInFileTool = defineTool({
20948
21138
  name: "find_in_file",
20949
- description: `Search for a pattern in a single file.
21139
+ description: `Search for a text or regex pattern inside a single known file and return matching line numbers and content. Use this when you already have the file path and want to quickly find which lines match (e.g. locate a function signature, find an import, or confirm a value exists). Do NOT use this to search across the whole project \u2014 use grep for that. Returns line numbers so you can navigate directly to the match.
20950
21140
 
20951
21141
  Examples:
20952
21142
  - Find text: { "file": "src/app.ts", "pattern": "export" }
@@ -22447,7 +22637,7 @@ async function searchSerpApi(query, maxResults, timeout) {
22447
22637
  }
22448
22638
  var webSearchTool = defineTool({
22449
22639
  name: "web_search",
22450
- description: `Search the web for information, documentation, error solutions, and API references.
22640
+ description: `Search the web using a natural-language query and return a list of result titles, URLs, and short excerpts. Use this when you need to find documentation, research an error message, discover API references, or learn about a library before you have a specific URL. Do NOT use this when you already have the URL \u2014 use web_fetch to read a known page directly. Returns result titles and URLs you can then fetch with web_fetch for full content.
22451
22641
 
22452
22642
  Examples:
22453
22643
  - Basic search: { "query": "typescript zod validation examples" }
@@ -22728,7 +22918,7 @@ ${rows.join("\n")}
22728
22918
  }
22729
22919
  var webFetchTool = defineTool({
22730
22920
  name: "web_fetch",
22731
- description: `Fetch a URL and convert its content to clean markdown. Extracts main content, strips navigation/ads, and returns readable text.
22921
+ description: `Fetch the content of a specific URL and return it as clean, readable markdown text. Use this when you already have the exact URL \u2014 for example a documentation page, a GitHub file, or an API response \u2014 and want to read its content. Do NOT use this to find information without a URL; use web_search instead to discover relevant URLs first. By default strips navigation menus, headers, and ads to return only the main content; set extractContent: false to get the raw HTML/text.
22732
22922
 
22733
22923
  Examples:
22734
22924
  - Fetch documentation: { "url": "https://docs.example.com/api" }
@@ -24439,8 +24629,7 @@ async function saveMemory(scope, memory) {
24439
24629
  }
24440
24630
  var createMemoryTool = defineTool({
24441
24631
  name: "create_memory",
24442
- description: `Save a memory (key-value pair) that persists between sessions.
24443
- Use for storing project conventions, patterns, preferences, and learnings.
24632
+ description: `Persist a named key-value fact that survives across sessions \u2014 use this for project conventions, patterns, user preferences, or discovered constraints you'll need later. If the key already exists the value is overwritten. Do NOT use this for temporary scratch data within a single session; do NOT use this to store file contents \u2014 use write_file for that.
24444
24633
 
24445
24634
  Examples:
24446
24635
  - Save convention: { "key": "naming-convention", "value": "Use camelCase for variables", "tags": ["style"] }
@@ -24497,7 +24686,7 @@ Examples:
24497
24686
  });
24498
24687
  var recallMemoryTool = defineTool({
24499
24688
  name: "recall_memory",
24500
- description: `Search and recall stored memories by key, tags, or free text query.
24689
+ description: `Search previously saved memories by key substring, tags, or free-text value match. Use this at the start of a task to check if relevant conventions or patterns were already learned. Returns full memory content. Do NOT use this to list all memories (use list_memories) or to search file content (use grep).
24501
24690
 
24502
24691
  Examples:
24503
24692
  - By key substring: { "query": "naming" }
@@ -24552,7 +24741,7 @@ Examples:
24552
24741
  });
24553
24742
  var listMemoriesTool = defineTool({
24554
24743
  name: "list_memories",
24555
- description: `List all stored memories with optional filtering. Returns lightweight index entries.
24744
+ description: `List stored memory keys and tags without loading full values \u2014 useful for browsing what has been saved before recalling specific entries. Do NOT use this to get memory content (use recall_memory for that).
24556
24745
 
24557
24746
  Examples:
24558
24747
  - List all: { "scope": "all" }
@@ -27074,7 +27263,7 @@ async function ghExec(args, cwd) {
27074
27263
  }
27075
27264
  var ghCheckAuthTool = defineTool({
27076
27265
  name: "gh_check_auth",
27077
- description: "Check if the GitHub CLI is installed and authenticated.",
27266
+ description: "Verify the gh CLI is installed and the user is logged into GitHub. Call this before any other gh_ tool to confirm authentication is working. Returns the logged-in username if authenticated.",
27078
27267
  category: "git",
27079
27268
  parameters: z.object({
27080
27269
  cwd: z.string().optional()
@@ -27094,7 +27283,7 @@ var ghCheckAuthTool = defineTool({
27094
27283
  });
27095
27284
  var ghRepoInfoTool = defineTool({
27096
27285
  name: "gh_repo_info",
27097
- description: "Get GitHub repository information (name, default branch, URL).",
27286
+ description: "Get the remote GitHub repository's name, owner, default branch, and URL from within the current git working directory. Use before creating PRs to confirm the target repo. Requires gh_check_auth to pass first.",
27098
27287
  category: "git",
27099
27288
  parameters: z.object({
27100
27289
  cwd: z.string().optional()
@@ -27116,7 +27305,7 @@ var ghRepoInfoTool = defineTool({
27116
27305
  });
27117
27306
  var ghPrCreateTool = defineTool({
27118
27307
  name: "gh_pr_create",
27119
- description: "Create a GitHub pull request.",
27308
+ description: "Open a pull request on GitHub from the current branch. Requires commits to be pushed first (use git_push with setUpstream: true). Do NOT use this if a PR for this branch already exists \u2014 use gh_pr_list to check first. Use draft: true for work in progress.",
27120
27309
  category: "git",
27121
27310
  parameters: z.object({
27122
27311
  title: z.string().describe("PR title"),
@@ -27140,7 +27329,7 @@ var ghPrCreateTool = defineTool({
27140
27329
  });
27141
27330
  var ghPrMergeTool = defineTool({
27142
27331
  name: "gh_pr_merge",
27143
- description: "Merge a GitHub pull request.",
27332
+ description: "Merge a pull request into its base branch. Use squash (default) for feature branches to keep history clean. Always confirm with gh_pr_checks first to ensure CI passed. Do NOT merge if anyFailed is true.",
27144
27333
  category: "git",
27145
27334
  parameters: z.object({
27146
27335
  number: z.number().describe("PR number"),
@@ -27161,7 +27350,7 @@ var ghPrMergeTool = defineTool({
27161
27350
  });
27162
27351
  var ghPrChecksTool = defineTool({
27163
27352
  name: "gh_pr_checks",
27164
- description: "Get CI check statuses for a pull request.",
27353
+ description: "Poll the CI check results for a pull request \u2014 returns pass/fail/pending per check and convenience flags (allPassed, anyFailed). Call this after pushing to confirm CI is green before merging. Check anyPending to know if results are still arriving.",
27165
27354
  category: "git",
27166
27355
  parameters: z.object({
27167
27356
  number: z.number().describe("PR number"),
@@ -27195,7 +27384,7 @@ var ghPrChecksTool = defineTool({
27195
27384
  });
27196
27385
  var ghPrListTool = defineTool({
27197
27386
  name: "gh_pr_list",
27198
- description: "List pull requests, optionally filtered by head branch.",
27387
+ description: "List open (or all) pull requests for this repository, optionally filtered to a specific branch. Use before gh_pr_create to ensure a PR for the current branch doesn't already exist. Returns PR number, title, URL, and state.",
27199
27388
  category: "git",
27200
27389
  parameters: z.object({
27201
27390
  head: z.string().optional().describe("Filter by head branch name"),
@@ -27212,7 +27401,7 @@ var ghPrListTool = defineTool({
27212
27401
  });
27213
27402
  var ghReleaseCreateTool = defineTool({
27214
27403
  name: "gh_release_create",
27215
- description: "Create a GitHub release with notes.",
27404
+ description: "Publish a versioned GitHub release attached to a tag. The tag must already exist in the repo (push it with git_push first). Provide markdown release notes. Use prerelease: true for release candidates or beta builds.",
27216
27405
  category: "git",
27217
27406
  parameters: z.object({
27218
27407
  tag: z.string().describe("Tag name (e.g., v1.2.3)"),