@corbat-tech/coco 2.10.0 → 2.11.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/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { homedir } from 'os';
2
- import * as path16 from 'path';
3
- import path16__default, { dirname, join, basename, resolve } from 'path';
2
+ import * as path17 from 'path';
3
+ import path17__default, { dirname, join, basename, resolve } from 'path';
4
4
  import * as fs4 from 'fs';
5
5
  import fs4__default, { readFileSync, constants } from 'fs';
6
- import * as fs15 from 'fs/promises';
7
- import fs15__default, { readFile, access, readdir } from 'fs/promises';
6
+ import * as fs16 from 'fs/promises';
7
+ import fs16__default, { readFile, access, readdir } from 'fs/promises';
8
8
  import chalk4 from 'chalk';
9
9
  import * as p4 from '@clack/prompts';
10
10
  import { fileURLToPath } from 'url';
@@ -92,7 +92,7 @@ function loadGlobalCocoEnv() {
92
92
  try {
93
93
  const home = process.env.HOME || process.env.USERPROFILE || "";
94
94
  if (!home) return;
95
- const globalEnvPath = path16.join(home, ".coco", ".env");
95
+ const globalEnvPath = path17.join(home, ".coco", ".env");
96
96
  const content = fs4.readFileSync(globalEnvPath, "utf-8");
97
97
  for (const line of content.split("\n")) {
98
98
  const trimmed = line.trim();
@@ -128,6 +128,8 @@ function getApiKey(provider) {
128
128
  return process.env["OLLAMA_API_KEY"] ?? "ollama";
129
129
  case "codex":
130
130
  return void 0;
131
+ case "copilot":
132
+ return process.env["GITHUB_TOKEN"] ?? process.env["GH_TOKEN"];
131
133
  case "groq":
132
134
  return process.env["GROQ_API_KEY"];
133
135
  case "openrouter":
@@ -162,6 +164,8 @@ function getBaseUrl(provider) {
162
164
  return process.env["OLLAMA_BASE_URL"] ?? "http://localhost:11434/v1";
163
165
  case "codex":
164
166
  return "https://chatgpt.com/backend-api/codex/responses";
167
+ case "copilot":
168
+ return process.env["COPILOT_BASE_URL"] ?? "https://api.githubcopilot.com";
165
169
  case "groq":
166
170
  return process.env["GROQ_BASE_URL"] ?? "https://api.groq.com/openai/v1";
167
171
  case "openrouter":
@@ -183,11 +187,11 @@ function getBaseUrl(provider) {
183
187
  function getDefaultModel(provider) {
184
188
  switch (provider) {
185
189
  case "anthropic":
186
- return process.env["ANTHROPIC_MODEL"] ?? "claude-opus-4-6-20260115";
190
+ return process.env["ANTHROPIC_MODEL"] ?? "claude-opus-4-6";
187
191
  case "openai":
188
192
  return process.env["OPENAI_MODEL"] ?? "gpt-5.3-codex";
189
193
  case "gemini":
190
- return process.env["GEMINI_MODEL"] ?? "gemini-3-flash-preview";
194
+ return process.env["GEMINI_MODEL"] ?? "gemini-3.1-pro-preview";
191
195
  case "kimi":
192
196
  return process.env["KIMI_MODEL"] ?? "kimi-k2.5";
193
197
  case "kimi-code":
@@ -198,6 +202,8 @@ function getDefaultModel(provider) {
198
202
  return process.env["OLLAMA_MODEL"] ?? "llama3.1";
199
203
  case "codex":
200
204
  return process.env["CODEX_MODEL"] ?? "gpt-5.3-codex";
205
+ case "copilot":
206
+ return process.env["COPILOT_MODEL"] ?? "claude-sonnet-4.6";
201
207
  case "groq":
202
208
  return process.env["GROQ_MODEL"] ?? "llama-3.3-70b-versatile";
203
209
  case "openrouter":
@@ -232,6 +238,7 @@ var init_env = __esm({
232
238
  "anthropic",
233
239
  "openai",
234
240
  "codex",
241
+ "copilot",
235
242
  "gemini",
236
243
  "kimi",
237
244
  "kimi-code",
@@ -257,10 +264,10 @@ function getAllowedPaths() {
257
264
  return [...sessionAllowedPaths];
258
265
  }
259
266
  function isWithinAllowedPath(absolutePath, operation) {
260
- const normalizedTarget = path16__default.normalize(absolutePath);
267
+ const normalizedTarget = path17__default.normalize(absolutePath);
261
268
  for (const entry of sessionAllowedPaths) {
262
- const normalizedAllowed = path16__default.normalize(entry.path);
263
- if (normalizedTarget === normalizedAllowed || normalizedTarget.startsWith(normalizedAllowed + path16__default.sep)) {
269
+ const normalizedAllowed = path17__default.normalize(entry.path);
270
+ if (normalizedTarget === normalizedAllowed || normalizedTarget.startsWith(normalizedAllowed + path17__default.sep)) {
264
271
  if (operation === "read") return true;
265
272
  if (entry.level === "write") return true;
266
273
  }
@@ -268,8 +275,8 @@ function isWithinAllowedPath(absolutePath, operation) {
268
275
  return false;
269
276
  }
270
277
  function addAllowedPathToSession(dirPath, level) {
271
- const absolute = path16__default.resolve(dirPath);
272
- if (sessionAllowedPaths.some((e) => path16__default.normalize(e.path) === path16__default.normalize(absolute))) {
278
+ const absolute = path17__default.resolve(dirPath);
279
+ if (sessionAllowedPaths.some((e) => path17__default.normalize(e.path) === path17__default.normalize(absolute))) {
273
280
  return;
274
281
  }
275
282
  sessionAllowedPaths.push({
@@ -280,14 +287,14 @@ function addAllowedPathToSession(dirPath, level) {
280
287
  }
281
288
  async function persistAllowedPath(dirPath, level) {
282
289
  if (!currentProjectPath) return;
283
- const absolute = path16__default.resolve(dirPath);
290
+ const absolute = path17__default.resolve(dirPath);
284
291
  const store = await loadStore();
285
292
  if (!store.projects[currentProjectPath]) {
286
293
  store.projects[currentProjectPath] = [];
287
294
  }
288
295
  const entries = store.projects[currentProjectPath];
289
- const normalized = path16__default.normalize(absolute);
290
- if (entries.some((e) => path16__default.normalize(e.path) === normalized)) {
296
+ const normalized = path17__default.normalize(absolute);
297
+ if (entries.some((e) => path17__default.normalize(e.path) === normalized)) {
291
298
  return;
292
299
  }
293
300
  entries.push({
@@ -299,7 +306,7 @@ async function persistAllowedPath(dirPath, level) {
299
306
  }
300
307
  async function loadStore() {
301
308
  try {
302
- const content = await fs15__default.readFile(STORE_FILE, "utf-8");
309
+ const content = await fs16__default.readFile(STORE_FILE, "utf-8");
303
310
  return { ...DEFAULT_STORE, ...JSON.parse(content) };
304
311
  } catch {
305
312
  return { ...DEFAULT_STORE };
@@ -307,8 +314,8 @@ async function loadStore() {
307
314
  }
308
315
  async function saveStore(store) {
309
316
  try {
310
- await fs15__default.mkdir(path16__default.dirname(STORE_FILE), { recursive: true });
311
- await fs15__default.writeFile(STORE_FILE, JSON.stringify(store, null, 2), "utf-8");
317
+ await fs16__default.mkdir(path17__default.dirname(STORE_FILE), { recursive: true });
318
+ await fs16__default.writeFile(STORE_FILE, JSON.stringify(store, null, 2), "utf-8");
312
319
  } catch {
313
320
  }
314
321
  }
@@ -316,7 +323,7 @@ var STORE_FILE, DEFAULT_STORE, sessionAllowedPaths, currentProjectPath;
316
323
  var init_allowed_paths = __esm({
317
324
  "src/tools/allowed-paths.ts"() {
318
325
  init_paths();
319
- STORE_FILE = path16__default.join(CONFIG_PATHS.home, "allowed-paths.json");
326
+ STORE_FILE = path17__default.join(CONFIG_PATHS.home, "allowed-paths.json");
320
327
  DEFAULT_STORE = {
321
328
  version: 1,
322
329
  projects: {}
@@ -397,7 +404,7 @@ __export(allow_path_prompt_exports, {
397
404
  promptAllowPath: () => promptAllowPath
398
405
  });
399
406
  async function promptAllowPath(dirPath) {
400
- const absolute = path16__default.resolve(dirPath);
407
+ const absolute = path17__default.resolve(dirPath);
401
408
  console.log();
402
409
  console.log(chalk4.yellow(" \u26A0 Access denied \u2014 path is outside the project directory"));
403
410
  console.log(chalk4.dim(` \u{1F4C1} ${absolute}`));
@@ -1778,13 +1785,13 @@ function createSpecificationGenerator(llm, config) {
1778
1785
  return new SpecificationGenerator(llm, config);
1779
1786
  }
1780
1787
  function getPersistencePaths(projectPath) {
1781
- const baseDir = path16__default.join(projectPath, ".coco", "spec");
1788
+ const baseDir = path17__default.join(projectPath, ".coco", "spec");
1782
1789
  return {
1783
1790
  baseDir,
1784
- sessionFile: path16__default.join(baseDir, "discovery-session.json"),
1785
- specFile: path16__default.join(baseDir, "spec.md"),
1786
- conversationLog: path16__default.join(baseDir, "conversation.jsonl"),
1787
- checkpointFile: path16__default.join(baseDir, "checkpoint.json")
1791
+ sessionFile: path17__default.join(baseDir, "discovery-session.json"),
1792
+ specFile: path17__default.join(baseDir, "spec.md"),
1793
+ conversationLog: path17__default.join(baseDir, "conversation.jsonl"),
1794
+ checkpointFile: path17__default.join(baseDir, "checkpoint.json")
1788
1795
  };
1789
1796
  }
1790
1797
  var SessionPersistence = class {
@@ -1797,7 +1804,7 @@ var SessionPersistence = class {
1797
1804
  */
1798
1805
  async ensureDir() {
1799
1806
  try {
1800
- await fs15__default.mkdir(this.paths.baseDir, { recursive: true });
1807
+ await fs16__default.mkdir(this.paths.baseDir, { recursive: true });
1801
1808
  } catch {
1802
1809
  throw new FileSystemError(`Failed to create persistence directory: ${this.paths.baseDir}`, {
1803
1810
  path: this.paths.baseDir,
@@ -1812,7 +1819,7 @@ var SessionPersistence = class {
1812
1819
  await this.ensureDir();
1813
1820
  try {
1814
1821
  const data = JSON.stringify(session, null, 2);
1815
- await fs15__default.writeFile(this.paths.sessionFile, data, "utf-8");
1822
+ await fs16__default.writeFile(this.paths.sessionFile, data, "utf-8");
1816
1823
  } catch {
1817
1824
  throw new FileSystemError("Failed to save discovery session", {
1818
1825
  path: this.paths.sessionFile,
@@ -1825,7 +1832,7 @@ var SessionPersistence = class {
1825
1832
  */
1826
1833
  async loadSession() {
1827
1834
  try {
1828
- const data = await fs15__default.readFile(this.paths.sessionFile, "utf-8");
1835
+ const data = await fs16__default.readFile(this.paths.sessionFile, "utf-8");
1829
1836
  const parsed = JSON.parse(data);
1830
1837
  parsed.startedAt = new Date(parsed.startedAt);
1831
1838
  parsed.updatedAt = new Date(parsed.updatedAt);
@@ -1851,7 +1858,7 @@ var SessionPersistence = class {
1851
1858
  */
1852
1859
  async hasSession() {
1853
1860
  try {
1854
- await fs15__default.access(this.paths.sessionFile);
1861
+ await fs16__default.access(this.paths.sessionFile);
1855
1862
  return true;
1856
1863
  } catch {
1857
1864
  return false;
@@ -1862,7 +1869,7 @@ var SessionPersistence = class {
1862
1869
  */
1863
1870
  async deleteSession() {
1864
1871
  try {
1865
- await fs15__default.unlink(this.paths.sessionFile);
1872
+ await fs16__default.unlink(this.paths.sessionFile);
1866
1873
  } catch (error) {
1867
1874
  if (error.code !== "ENOENT") {
1868
1875
  throw new FileSystemError("Failed to delete discovery session", {
@@ -1878,7 +1885,7 @@ var SessionPersistence = class {
1878
1885
  async saveSpecification(content) {
1879
1886
  await this.ensureDir();
1880
1887
  try {
1881
- await fs15__default.writeFile(this.paths.specFile, content, "utf-8");
1888
+ await fs16__default.writeFile(this.paths.specFile, content, "utf-8");
1882
1889
  } catch {
1883
1890
  throw new FileSystemError("Failed to save specification", {
1884
1891
  path: this.paths.specFile,
@@ -1891,7 +1898,7 @@ var SessionPersistence = class {
1891
1898
  */
1892
1899
  async loadSpecification() {
1893
1900
  try {
1894
- return await fs15__default.readFile(this.paths.specFile, "utf-8");
1901
+ return await fs16__default.readFile(this.paths.specFile, "utf-8");
1895
1902
  } catch {
1896
1903
  return null;
1897
1904
  }
@@ -1907,7 +1914,7 @@ var SessionPersistence = class {
1907
1914
  content
1908
1915
  };
1909
1916
  try {
1910
- await fs15__default.appendFile(this.paths.conversationLog, JSON.stringify(entry) + "\n", "utf-8");
1917
+ await fs16__default.appendFile(this.paths.conversationLog, JSON.stringify(entry) + "\n", "utf-8");
1911
1918
  } catch {
1912
1919
  throw new FileSystemError("Failed to append to conversation log", {
1913
1920
  path: this.paths.conversationLog,
@@ -1920,7 +1927,7 @@ var SessionPersistence = class {
1920
1927
  */
1921
1928
  async loadConversationLog() {
1922
1929
  try {
1923
- const data = await fs15__default.readFile(this.paths.conversationLog, "utf-8");
1930
+ const data = await fs16__default.readFile(this.paths.conversationLog, "utf-8");
1924
1931
  const lines = data.trim().split("\n");
1925
1932
  return lines.filter((line) => line.trim()).map((line) => JSON.parse(line));
1926
1933
  } catch {
@@ -1934,7 +1941,7 @@ var SessionPersistence = class {
1934
1941
  await this.ensureDir();
1935
1942
  try {
1936
1943
  const data = JSON.stringify(checkpoint, null, 2);
1937
- await fs15__default.writeFile(this.paths.checkpointFile, data, "utf-8");
1944
+ await fs16__default.writeFile(this.paths.checkpointFile, data, "utf-8");
1938
1945
  } catch {
1939
1946
  throw new FileSystemError("Failed to save checkpoint", {
1940
1947
  path: this.paths.checkpointFile,
@@ -1947,7 +1954,7 @@ var SessionPersistence = class {
1947
1954
  */
1948
1955
  async loadCheckpoint() {
1949
1956
  try {
1950
- const data = await fs15__default.readFile(this.paths.checkpointFile, "utf-8");
1957
+ const data = await fs16__default.readFile(this.paths.checkpointFile, "utf-8");
1951
1958
  const parsed = JSON.parse(data);
1952
1959
  parsed.timestamp = new Date(parsed.timestamp);
1953
1960
  return parsed;
@@ -1960,7 +1967,7 @@ var SessionPersistence = class {
1960
1967
  */
1961
1968
  async clearAll() {
1962
1969
  try {
1963
- await fs15__default.rm(this.paths.baseDir, { recursive: true, force: true });
1970
+ await fs16__default.rm(this.paths.baseDir, { recursive: true, force: true });
1964
1971
  } catch (error) {
1965
1972
  if (error.code !== "ENOENT") {
1966
1973
  throw new FileSystemError("Failed to clear persistence data", {
@@ -3814,8 +3821,8 @@ var OrchestrateExecutor = class {
3814
3821
  }
3815
3822
  async loadSpecification(projectPath) {
3816
3823
  try {
3817
- const jsonPath = path16__default.join(projectPath, ".coco", "spec", "spec.json");
3818
- const jsonContent = await fs15__default.readFile(jsonPath, "utf-8");
3824
+ const jsonPath = path17__default.join(projectPath, ".coco", "spec", "spec.json");
3825
+ const jsonContent = await fs16__default.readFile(jsonPath, "utf-8");
3819
3826
  return JSON.parse(jsonContent);
3820
3827
  } catch {
3821
3828
  return this.createMinimalSpec(projectPath);
@@ -3826,7 +3833,7 @@ var OrchestrateExecutor = class {
3826
3833
  version: "1.0.0",
3827
3834
  generatedAt: /* @__PURE__ */ new Date(),
3828
3835
  overview: {
3829
- name: path16__default.basename(projectPath),
3836
+ name: path17__default.basename(projectPath),
3830
3837
  description: "Project specification",
3831
3838
  goals: [],
3832
3839
  targetUsers: ["developers"],
@@ -3853,53 +3860,53 @@ var OrchestrateExecutor = class {
3853
3860
  };
3854
3861
  }
3855
3862
  async saveArchitecture(projectPath, architecture) {
3856
- const dir = path16__default.join(projectPath, ".coco", "architecture");
3857
- await fs15__default.mkdir(dir, { recursive: true });
3858
- const mdPath = path16__default.join(dir, "ARCHITECTURE.md");
3859
- await fs15__default.writeFile(mdPath, generateArchitectureMarkdown(architecture), "utf-8");
3860
- const jsonPath = path16__default.join(dir, "architecture.json");
3861
- await fs15__default.writeFile(jsonPath, JSON.stringify(architecture, null, 2), "utf-8");
3863
+ const dir = path17__default.join(projectPath, ".coco", "architecture");
3864
+ await fs16__default.mkdir(dir, { recursive: true });
3865
+ const mdPath = path17__default.join(dir, "ARCHITECTURE.md");
3866
+ await fs16__default.writeFile(mdPath, generateArchitectureMarkdown(architecture), "utf-8");
3867
+ const jsonPath = path17__default.join(dir, "architecture.json");
3868
+ await fs16__default.writeFile(jsonPath, JSON.stringify(architecture, null, 2), "utf-8");
3862
3869
  return mdPath;
3863
3870
  }
3864
3871
  async saveADRs(projectPath, adrs) {
3865
- const dir = path16__default.join(projectPath, ".coco", "architecture", "adrs");
3866
- await fs15__default.mkdir(dir, { recursive: true });
3872
+ const dir = path17__default.join(projectPath, ".coco", "architecture", "adrs");
3873
+ await fs16__default.mkdir(dir, { recursive: true });
3867
3874
  const paths = [];
3868
- const indexPath = path16__default.join(dir, "README.md");
3869
- await fs15__default.writeFile(indexPath, generateADRIndexMarkdown(adrs), "utf-8");
3875
+ const indexPath = path17__default.join(dir, "README.md");
3876
+ await fs16__default.writeFile(indexPath, generateADRIndexMarkdown(adrs), "utf-8");
3870
3877
  paths.push(indexPath);
3871
3878
  for (const adr of adrs) {
3872
3879
  const filename = getADRFilename(adr);
3873
- const adrPath = path16__default.join(dir, filename);
3874
- await fs15__default.writeFile(adrPath, generateADRMarkdown(adr), "utf-8");
3880
+ const adrPath = path17__default.join(dir, filename);
3881
+ await fs16__default.writeFile(adrPath, generateADRMarkdown(adr), "utf-8");
3875
3882
  paths.push(adrPath);
3876
3883
  }
3877
3884
  return paths;
3878
3885
  }
3879
3886
  async saveBacklog(projectPath, backlogResult) {
3880
- const dir = path16__default.join(projectPath, ".coco", "planning");
3881
- await fs15__default.mkdir(dir, { recursive: true });
3882
- const mdPath = path16__default.join(dir, "BACKLOG.md");
3883
- await fs15__default.writeFile(mdPath, generateBacklogMarkdown(backlogResult.backlog), "utf-8");
3884
- const jsonPath = path16__default.join(dir, "backlog.json");
3885
- await fs15__default.writeFile(jsonPath, JSON.stringify(backlogResult, null, 2), "utf-8");
3887
+ const dir = path17__default.join(projectPath, ".coco", "planning");
3888
+ await fs16__default.mkdir(dir, { recursive: true });
3889
+ const mdPath = path17__default.join(dir, "BACKLOG.md");
3890
+ await fs16__default.writeFile(mdPath, generateBacklogMarkdown(backlogResult.backlog), "utf-8");
3891
+ const jsonPath = path17__default.join(dir, "backlog.json");
3892
+ await fs16__default.writeFile(jsonPath, JSON.stringify(backlogResult, null, 2), "utf-8");
3886
3893
  return mdPath;
3887
3894
  }
3888
3895
  async saveSprint(projectPath, sprint, backlogResult) {
3889
- const dir = path16__default.join(projectPath, ".coco", "planning", "sprints");
3890
- await fs15__default.mkdir(dir, { recursive: true });
3896
+ const dir = path17__default.join(projectPath, ".coco", "planning", "sprints");
3897
+ await fs16__default.mkdir(dir, { recursive: true });
3891
3898
  const filename = `${sprint.id}.md`;
3892
- const sprintPath = path16__default.join(dir, filename);
3893
- await fs15__default.writeFile(sprintPath, generateSprintMarkdown(sprint, backlogResult.backlog), "utf-8");
3894
- const jsonPath = path16__default.join(dir, `${sprint.id}.json`);
3895
- await fs15__default.writeFile(jsonPath, JSON.stringify(sprint, null, 2), "utf-8");
3899
+ const sprintPath = path17__default.join(dir, filename);
3900
+ await fs16__default.writeFile(sprintPath, generateSprintMarkdown(sprint, backlogResult.backlog), "utf-8");
3901
+ const jsonPath = path17__default.join(dir, `${sprint.id}.json`);
3902
+ await fs16__default.writeFile(jsonPath, JSON.stringify(sprint, null, 2), "utf-8");
3896
3903
  return sprintPath;
3897
3904
  }
3898
3905
  async saveDiagram(projectPath, id, mermaid) {
3899
- const dir = path16__default.join(projectPath, ".coco", "architecture", "diagrams");
3900
- await fs15__default.mkdir(dir, { recursive: true });
3901
- const diagramPath = path16__default.join(dir, `${id}.mmd`);
3902
- await fs15__default.writeFile(diagramPath, mermaid, "utf-8");
3906
+ const dir = path17__default.join(projectPath, ".coco", "architecture", "diagrams");
3907
+ await fs16__default.mkdir(dir, { recursive: true });
3908
+ const diagramPath = path17__default.join(dir, `${id}.mmd`);
3909
+ await fs16__default.writeFile(diagramPath, mermaid, "utf-8");
3903
3910
  return diagramPath;
3904
3911
  }
3905
3912
  };
@@ -4054,10 +4061,10 @@ var CoverageAnalyzer = class {
4054
4061
  join(this.projectPath, ".coverage", "coverage-summary.json"),
4055
4062
  join(this.projectPath, "coverage", "lcov-report", "coverage-summary.json")
4056
4063
  ];
4057
- for (const path39 of possiblePaths) {
4064
+ for (const path40 of possiblePaths) {
4058
4065
  try {
4059
- await access(path39, constants.R_OK);
4060
- const content = await readFile(path39, "utf-8");
4066
+ await access(path40, constants.R_OK);
4067
+ const content = await readFile(path40, "utf-8");
4061
4068
  const report = JSON.parse(content);
4062
4069
  return parseCoverageSummary(report);
4063
4070
  } catch {
@@ -4776,7 +4783,7 @@ var BuildVerifier = class {
4776
4783
  async verifyTypes() {
4777
4784
  const startTime = Date.now();
4778
4785
  try {
4779
- const hasTsConfig = await this.fileExists(path16.join(this.projectPath, "tsconfig.json"));
4786
+ const hasTsConfig = await this.fileExists(path17.join(this.projectPath, "tsconfig.json"));
4780
4787
  if (!hasTsConfig) {
4781
4788
  return {
4782
4789
  success: true,
@@ -4826,8 +4833,8 @@ var BuildVerifier = class {
4826
4833
  */
4827
4834
  async detectBuildCommand() {
4828
4835
  try {
4829
- const packageJsonPath = path16.join(this.projectPath, "package.json");
4830
- const content = await fs15.readFile(packageJsonPath, "utf-8");
4836
+ const packageJsonPath = path17.join(this.projectPath, "package.json");
4837
+ const content = await fs16.readFile(packageJsonPath, "utf-8");
4831
4838
  const packageJson = JSON.parse(content);
4832
4839
  if (packageJson.scripts?.build) {
4833
4840
  return "npm run build";
@@ -4903,7 +4910,7 @@ var BuildVerifier = class {
4903
4910
  */
4904
4911
  async fileExists(filePath) {
4905
4912
  try {
4906
- await fs15.access(filePath);
4913
+ await fs16.access(filePath);
4907
4914
  return true;
4908
4915
  } catch {
4909
4916
  return false;
@@ -6449,9 +6456,9 @@ function detectProjectLanguage(files) {
6449
6456
  return { language: dominant, confidence, evidence };
6450
6457
  }
6451
6458
  function getFileExtension(filePath) {
6452
- const base = path16.basename(filePath);
6459
+ const base = path17.basename(filePath);
6453
6460
  if (base.endsWith(".d.ts")) return ".d.ts";
6454
- return path16.extname(filePath).toLowerCase();
6461
+ return path17.extname(filePath).toLowerCase();
6455
6462
  }
6456
6463
  function buildEvidence(dominant, counts, totalSourceFiles, files) {
6457
6464
  const evidence = [];
@@ -6459,7 +6466,7 @@ function buildEvidence(dominant, counts, totalSourceFiles, files) {
6459
6466
  evidence.push(`${dominantCount} of ${totalSourceFiles} source files are ${dominant}`);
6460
6467
  const configFiles = ["tsconfig.json", "pom.xml", "build.gradle", "Cargo.toml", "go.mod"];
6461
6468
  for (const cfg of configFiles) {
6462
- if (files.some((f) => path16.basename(f) === cfg)) {
6469
+ if (files.some((f) => path17.basename(f) === cfg)) {
6463
6470
  evidence.push(`Found ${cfg}`);
6464
6471
  }
6465
6472
  }
@@ -8171,7 +8178,7 @@ function setupFileLogging(logger, logDir, name) {
8171
8178
  if (!fs4__default.existsSync(logDir)) {
8172
8179
  fs4__default.mkdirSync(logDir, { recursive: true });
8173
8180
  }
8174
- const logFile = path16__default.join(logDir, `${name}.log`);
8181
+ const logFile = path17__default.join(logDir, `${name}.log`);
8175
8182
  logger.attachTransport((logObj) => {
8176
8183
  const line = JSON.stringify(logObj) + "\n";
8177
8184
  fs4__default.appendFileSync(logFile, line);
@@ -8234,12 +8241,12 @@ function humanizeError(message, toolName) {
8234
8241
  return msg;
8235
8242
  }
8236
8243
  if (/ENOENT/i.test(msg)) {
8237
- const path39 = extractQuotedPath(msg);
8238
- return path39 ? `File or directory not found: ${path39}` : "File or directory not found";
8244
+ const path40 = extractQuotedPath(msg);
8245
+ return path40 ? `File or directory not found: ${path40}` : "File or directory not found";
8239
8246
  }
8240
8247
  if (/EACCES/i.test(msg)) {
8241
- const path39 = extractQuotedPath(msg);
8242
- return path39 ? `Permission denied: ${path39}` : "Permission denied \u2014 check file permissions";
8248
+ const path40 = extractQuotedPath(msg);
8249
+ return path40 ? `Permission denied: ${path40}` : "Permission denied \u2014 check file permissions";
8243
8250
  }
8244
8251
  if (/EISDIR/i.test(msg)) {
8245
8252
  return "Expected a file but found a directory at the specified path";
@@ -9724,14 +9731,14 @@ var CompleteExecutor = class {
9724
9731
  */
9725
9732
  async checkpoint(context) {
9726
9733
  if (this.checkpointState && this.currentSprint) {
9727
- const checkpointPath = path16__default.join(
9734
+ const checkpointPath = path17__default.join(
9728
9735
  context.projectPath,
9729
9736
  ".coco",
9730
9737
  "checkpoints",
9731
9738
  `complete-${this.currentSprint.id}.json`
9732
9739
  );
9733
- await fs15__default.mkdir(path16__default.dirname(checkpointPath), { recursive: true });
9734
- await fs15__default.writeFile(checkpointPath, JSON.stringify(this.checkpointState, null, 2), "utf-8");
9740
+ await fs16__default.mkdir(path17__default.dirname(checkpointPath), { recursive: true });
9741
+ await fs16__default.writeFile(checkpointPath, JSON.stringify(this.checkpointState, null, 2), "utf-8");
9735
9742
  }
9736
9743
  return {
9737
9744
  phase: "complete",
@@ -9751,13 +9758,13 @@ var CompleteExecutor = class {
9751
9758
  const sprintId = checkpoint.resumePoint;
9752
9759
  if (sprintId === "start") return;
9753
9760
  try {
9754
- const checkpointPath = path16__default.join(
9761
+ const checkpointPath = path17__default.join(
9755
9762
  context.projectPath,
9756
9763
  ".coco",
9757
9764
  "checkpoints",
9758
9765
  `complete-${sprintId}.json`
9759
9766
  );
9760
- const content = await fs15__default.readFile(checkpointPath, "utf-8");
9767
+ const content = await fs16__default.readFile(checkpointPath, "utf-8");
9761
9768
  this.checkpointState = JSON.parse(content);
9762
9769
  this.completedTaskIds = new Set(this.checkpointState.completedTaskIds);
9763
9770
  } catch {
@@ -10004,14 +10011,14 @@ var CompleteExecutor = class {
10004
10011
  };
10005
10012
  const saveFiles = async (files) => {
10006
10013
  for (const file of files) {
10007
- const filePath = path16__default.join(context.projectPath, file.path);
10008
- const dir = path16__default.dirname(filePath);
10009
- await fs15__default.mkdir(dir, { recursive: true });
10014
+ const filePath = path17__default.join(context.projectPath, file.path);
10015
+ const dir = path17__default.dirname(filePath);
10016
+ await fs16__default.mkdir(dir, { recursive: true });
10010
10017
  if (file.action === "delete") {
10011
- await fs15__default.unlink(filePath).catch(() => {
10018
+ await fs16__default.unlink(filePath).catch(() => {
10012
10019
  });
10013
10020
  } else {
10014
- await fs15__default.writeFile(filePath, file.content, "utf-8");
10021
+ await fs16__default.writeFile(filePath, file.content, "utf-8");
10015
10022
  }
10016
10023
  }
10017
10024
  };
@@ -10137,8 +10144,8 @@ var CompleteExecutor = class {
10137
10144
  */
10138
10145
  async loadBacklog(projectPath) {
10139
10146
  try {
10140
- const backlogPath = path16__default.join(projectPath, ".coco", "planning", "backlog.json");
10141
- const content = await fs15__default.readFile(backlogPath, "utf-8");
10147
+ const backlogPath = path17__default.join(projectPath, ".coco", "planning", "backlog.json");
10148
+ const content = await fs16__default.readFile(backlogPath, "utf-8");
10142
10149
  const data = JSON.parse(content);
10143
10150
  return data.backlog;
10144
10151
  } catch {
@@ -10150,12 +10157,12 @@ var CompleteExecutor = class {
10150
10157
  */
10151
10158
  async loadCurrentSprint(projectPath) {
10152
10159
  try {
10153
- const sprintsDir = path16__default.join(projectPath, ".coco", "planning", "sprints");
10154
- const files = await fs15__default.readdir(sprintsDir);
10160
+ const sprintsDir = path17__default.join(projectPath, ".coco", "planning", "sprints");
10161
+ const files = await fs16__default.readdir(sprintsDir);
10155
10162
  const jsonFiles = files.filter((f) => f.endsWith(".json"));
10156
10163
  if (jsonFiles.length === 0) return null;
10157
- const sprintPath = path16__default.join(sprintsDir, jsonFiles[0] || "");
10158
- const content = await fs15__default.readFile(sprintPath, "utf-8");
10164
+ const sprintPath = path17__default.join(sprintsDir, jsonFiles[0] || "");
10165
+ const content = await fs16__default.readFile(sprintPath, "utf-8");
10159
10166
  const sprint = JSON.parse(content);
10160
10167
  sprint.startDate = new Date(sprint.startDate);
10161
10168
  return sprint;
@@ -10167,12 +10174,12 @@ var CompleteExecutor = class {
10167
10174
  * Save sprint results
10168
10175
  */
10169
10176
  async saveSprintResults(projectPath, result) {
10170
- const resultsDir = path16__default.join(projectPath, ".coco", "results");
10171
- await fs15__default.mkdir(resultsDir, { recursive: true });
10172
- const resultsPath = path16__default.join(resultsDir, `${result.sprintId}-results.json`);
10173
- await fs15__default.writeFile(resultsPath, JSON.stringify(result, null, 2), "utf-8");
10174
- const mdPath = path16__default.join(resultsDir, `${result.sprintId}-results.md`);
10175
- await fs15__default.writeFile(mdPath, this.generateResultsMarkdown(result), "utf-8");
10177
+ const resultsDir = path17__default.join(projectPath, ".coco", "results");
10178
+ await fs16__default.mkdir(resultsDir, { recursive: true });
10179
+ const resultsPath = path17__default.join(resultsDir, `${result.sprintId}-results.json`);
10180
+ await fs16__default.writeFile(resultsPath, JSON.stringify(result, null, 2), "utf-8");
10181
+ const mdPath = path17__default.join(resultsDir, `${result.sprintId}-results.md`);
10182
+ await fs16__default.writeFile(mdPath, this.generateResultsMarkdown(result), "utf-8");
10176
10183
  return resultsPath;
10177
10184
  }
10178
10185
  /**
@@ -11396,9 +11403,9 @@ var OutputExecutor = class {
11396
11403
  const cicdGenerator = new CICDGenerator(metadata, cicdConfig);
11397
11404
  const cicdFiles = cicdGenerator.generate();
11398
11405
  for (const file of cicdFiles) {
11399
- const filePath = path16__default.join(context.projectPath, file.path);
11400
- await this.ensureDir(path16__default.dirname(filePath));
11401
- await fs15__default.writeFile(filePath, file.content, "utf-8");
11406
+ const filePath = path17__default.join(context.projectPath, file.path);
11407
+ await this.ensureDir(path17__default.dirname(filePath));
11408
+ await fs16__default.writeFile(filePath, file.content, "utf-8");
11402
11409
  artifacts.push({
11403
11410
  type: "cicd",
11404
11411
  path: filePath,
@@ -11408,16 +11415,16 @@ var OutputExecutor = class {
11408
11415
  if (this.config.docker.enabled) {
11409
11416
  const dockerGenerator = new DockerGenerator(metadata);
11410
11417
  const dockerfile2 = dockerGenerator.generateDockerfile();
11411
- const dockerfilePath = path16__default.join(context.projectPath, "Dockerfile");
11412
- await fs15__default.writeFile(dockerfilePath, dockerfile2, "utf-8");
11418
+ const dockerfilePath = path17__default.join(context.projectPath, "Dockerfile");
11419
+ await fs16__default.writeFile(dockerfilePath, dockerfile2, "utf-8");
11413
11420
  artifacts.push({
11414
11421
  type: "deployment",
11415
11422
  path: dockerfilePath,
11416
11423
  description: "Dockerfile"
11417
11424
  });
11418
11425
  const dockerignore = dockerGenerator.generateDockerignore();
11419
- const dockerignorePath = path16__default.join(context.projectPath, ".dockerignore");
11420
- await fs15__default.writeFile(dockerignorePath, dockerignore, "utf-8");
11426
+ const dockerignorePath = path17__default.join(context.projectPath, ".dockerignore");
11427
+ await fs16__default.writeFile(dockerignorePath, dockerignore, "utf-8");
11421
11428
  artifacts.push({
11422
11429
  type: "deployment",
11423
11430
  path: dockerignorePath,
@@ -11425,8 +11432,8 @@ var OutputExecutor = class {
11425
11432
  });
11426
11433
  if (this.config.docker.compose) {
11427
11434
  const compose = dockerGenerator.generateDockerCompose();
11428
- const composePath = path16__default.join(context.projectPath, "docker-compose.yml");
11429
- await fs15__default.writeFile(composePath, compose, "utf-8");
11435
+ const composePath = path17__default.join(context.projectPath, "docker-compose.yml");
11436
+ await fs16__default.writeFile(composePath, compose, "utf-8");
11430
11437
  artifacts.push({
11431
11438
  type: "deployment",
11432
11439
  path: composePath,
@@ -11437,8 +11444,8 @@ var OutputExecutor = class {
11437
11444
  const docsGenerator = new DocsGenerator(metadata);
11438
11445
  const docs = docsGenerator.generate();
11439
11446
  if (this.config.docs.readme) {
11440
- const readmePath = path16__default.join(context.projectPath, "README.md");
11441
- await fs15__default.writeFile(readmePath, docs.readme, "utf-8");
11447
+ const readmePath = path17__default.join(context.projectPath, "README.md");
11448
+ await fs16__default.writeFile(readmePath, docs.readme, "utf-8");
11442
11449
  artifacts.push({
11443
11450
  type: "documentation",
11444
11451
  path: readmePath,
@@ -11446,8 +11453,8 @@ var OutputExecutor = class {
11446
11453
  });
11447
11454
  }
11448
11455
  if (this.config.docs.contributing) {
11449
- const contributingPath = path16__default.join(context.projectPath, "CONTRIBUTING.md");
11450
- await fs15__default.writeFile(contributingPath, docs.contributing, "utf-8");
11456
+ const contributingPath = path17__default.join(context.projectPath, "CONTRIBUTING.md");
11457
+ await fs16__default.writeFile(contributingPath, docs.contributing, "utf-8");
11451
11458
  artifacts.push({
11452
11459
  type: "documentation",
11453
11460
  path: contributingPath,
@@ -11455,8 +11462,8 @@ var OutputExecutor = class {
11455
11462
  });
11456
11463
  }
11457
11464
  if (this.config.docs.changelog) {
11458
- const changelogPath = path16__default.join(context.projectPath, "CHANGELOG.md");
11459
- await fs15__default.writeFile(changelogPath, docs.changelog, "utf-8");
11465
+ const changelogPath = path17__default.join(context.projectPath, "CHANGELOG.md");
11466
+ await fs16__default.writeFile(changelogPath, docs.changelog, "utf-8");
11460
11467
  artifacts.push({
11461
11468
  type: "documentation",
11462
11469
  path: changelogPath,
@@ -11464,11 +11471,11 @@ var OutputExecutor = class {
11464
11471
  });
11465
11472
  }
11466
11473
  if (this.config.docs.api) {
11467
- const docsDir = path16__default.join(context.projectPath, "docs");
11474
+ const docsDir = path17__default.join(context.projectPath, "docs");
11468
11475
  await this.ensureDir(docsDir);
11469
11476
  if (docs.api) {
11470
- const apiPath = path16__default.join(docsDir, "api.md");
11471
- await fs15__default.writeFile(apiPath, docs.api, "utf-8");
11477
+ const apiPath = path17__default.join(docsDir, "api.md");
11478
+ await fs16__default.writeFile(apiPath, docs.api, "utf-8");
11472
11479
  artifacts.push({
11473
11480
  type: "documentation",
11474
11481
  path: apiPath,
@@ -11476,8 +11483,8 @@ var OutputExecutor = class {
11476
11483
  });
11477
11484
  }
11478
11485
  if (docs.deployment) {
11479
- const deployPath = path16__default.join(docsDir, "deployment.md");
11480
- await fs15__default.writeFile(deployPath, docs.deployment, "utf-8");
11486
+ const deployPath = path17__default.join(docsDir, "deployment.md");
11487
+ await fs16__default.writeFile(deployPath, docs.deployment, "utf-8");
11481
11488
  artifacts.push({
11482
11489
  type: "documentation",
11483
11490
  path: deployPath,
@@ -11485,8 +11492,8 @@ var OutputExecutor = class {
11485
11492
  });
11486
11493
  }
11487
11494
  if (docs.development) {
11488
- const devPath = path16__default.join(docsDir, "development.md");
11489
- await fs15__default.writeFile(devPath, docs.development, "utf-8");
11495
+ const devPath = path17__default.join(docsDir, "development.md");
11496
+ await fs16__default.writeFile(devPath, docs.development, "utf-8");
11490
11497
  artifacts.push({
11491
11498
  type: "documentation",
11492
11499
  path: devPath,
@@ -11551,16 +11558,16 @@ var OutputExecutor = class {
11551
11558
  */
11552
11559
  async loadMetadata(projectPath) {
11553
11560
  try {
11554
- const packagePath = path16__default.join(projectPath, "package.json");
11555
- const content = await fs15__default.readFile(packagePath, "utf-8");
11561
+ const packagePath = path17__default.join(projectPath, "package.json");
11562
+ const content = await fs16__default.readFile(packagePath, "utf-8");
11556
11563
  const pkg = JSON.parse(content);
11557
11564
  let packageManager = "npm";
11558
11565
  try {
11559
- await fs15__default.access(path16__default.join(projectPath, "pnpm-lock.yaml"));
11566
+ await fs16__default.access(path17__default.join(projectPath, "pnpm-lock.yaml"));
11560
11567
  packageManager = "pnpm";
11561
11568
  } catch {
11562
11569
  try {
11563
- await fs15__default.access(path16__default.join(projectPath, "yarn.lock"));
11570
+ await fs16__default.access(path17__default.join(projectPath, "yarn.lock"));
11564
11571
  packageManager = "yarn";
11565
11572
  } catch {
11566
11573
  }
@@ -11572,7 +11579,7 @@ var OutputExecutor = class {
11572
11579
  repository = pkg.repository.url;
11573
11580
  }
11574
11581
  return {
11575
- name: pkg.name || path16__default.basename(projectPath),
11582
+ name: pkg.name || path17__default.basename(projectPath),
11576
11583
  description: pkg.description || "",
11577
11584
  version: pkg.version || "0.1.0",
11578
11585
  language: "typescript",
@@ -11586,7 +11593,7 @@ var OutputExecutor = class {
11586
11593
  };
11587
11594
  } catch {
11588
11595
  return {
11589
- name: path16__default.basename(projectPath),
11596
+ name: path17__default.basename(projectPath),
11590
11597
  description: "",
11591
11598
  version: "0.1.0",
11592
11599
  language: "typescript",
@@ -11602,7 +11609,7 @@ var OutputExecutor = class {
11602
11609
  * Ensure directory exists
11603
11610
  */
11604
11611
  async ensureDir(dir) {
11605
- await fs15__default.mkdir(dir, { recursive: true });
11612
+ await fs16__default.mkdir(dir, { recursive: true });
11606
11613
  }
11607
11614
  };
11608
11615
  function createOutputExecutor(config) {
@@ -11664,18 +11671,19 @@ async function withRetry(fn, config = {}) {
11664
11671
  }
11665
11672
 
11666
11673
  // src/providers/anthropic.ts
11667
- var DEFAULT_MODEL = "claude-opus-4-6-20260115";
11674
+ var DEFAULT_MODEL = "claude-opus-4-6";
11668
11675
  var CONTEXT_WINDOWS = {
11669
11676
  // Kimi Code model (Anthropic-compatible endpoint)
11670
11677
  "kimi-for-coding": 131072,
11671
- // Claude 4.6 (latest, Jan 2026) - 200K-1M context, 128K output
11672
- "claude-opus-4-6-20260115": 2e5,
11673
- // Claude 4.5 models (Nov 2025)
11674
- "claude-opus-4-5-20251124": 2e5,
11678
+ // Claude 4.6 (latest) 200K standard, 1M beta
11679
+ "claude-opus-4-6": 2e5,
11680
+ "claude-sonnet-4-6": 2e5,
11681
+ // Claude 4.5 models
11682
+ "claude-opus-4-5-20251101": 2e5,
11675
11683
  "claude-sonnet-4-5-20250929": 2e5,
11676
11684
  "claude-haiku-4-5-20251001": 2e5,
11677
11685
  // Claude 4.1 models
11678
- "claude-opus-4-1-20250801": 2e5,
11686
+ "claude-opus-4-1-20250805": 2e5,
11679
11687
  // Claude 4 models
11680
11688
  "claude-sonnet-4-20250514": 2e5,
11681
11689
  "claude-opus-4-20250514": 2e5,
@@ -11797,12 +11805,16 @@ var AnthropicProvider = class {
11797
11805
  );
11798
11806
  const streamTimeout = this.config.timeout ?? 12e4;
11799
11807
  let lastActivityTime = Date.now();
11800
- const checkTimeout = () => {
11808
+ const timeoutController = new AbortController();
11809
+ const timeoutInterval = setInterval(() => {
11801
11810
  if (Date.now() - lastActivityTime > streamTimeout) {
11802
- throw new Error(`Stream timeout: No response from LLM for ${streamTimeout / 1e3}s`);
11811
+ clearInterval(timeoutInterval);
11812
+ timeoutController.abort();
11803
11813
  }
11804
- };
11805
- const timeoutInterval = setInterval(checkTimeout, 5e3);
11814
+ }, 5e3);
11815
+ timeoutController.signal.addEventListener("abort", () => stream.controller.abort(), {
11816
+ once: true
11817
+ });
11806
11818
  try {
11807
11819
  let streamStopReason;
11808
11820
  for await (const event of stream) {
@@ -11823,6 +11835,9 @@ var AnthropicProvider = class {
11823
11835
  } finally {
11824
11836
  clearInterval(timeoutInterval);
11825
11837
  }
11838
+ if (timeoutController.signal.aborted) {
11839
+ throw new Error(`Stream timeout: No response from LLM for ${streamTimeout / 1e3}s`);
11840
+ }
11826
11841
  } catch (error) {
11827
11842
  throw this.handleError(error);
11828
11843
  }
@@ -11849,12 +11864,16 @@ var AnthropicProvider = class {
11849
11864
  let currentToolInputJson = "";
11850
11865
  const streamTimeout = this.config.timeout ?? 12e4;
11851
11866
  let lastActivityTime = Date.now();
11852
- const checkTimeout = () => {
11867
+ const timeoutController = new AbortController();
11868
+ const timeoutInterval = setInterval(() => {
11853
11869
  if (Date.now() - lastActivityTime > streamTimeout) {
11854
- throw new Error(`Stream timeout: No response from LLM for ${streamTimeout / 1e3}s`);
11870
+ clearInterval(timeoutInterval);
11871
+ timeoutController.abort();
11855
11872
  }
11856
- };
11857
- const timeoutInterval = setInterval(checkTimeout, 5e3);
11873
+ }, 5e3);
11874
+ timeoutController.signal.addEventListener("abort", () => stream.controller.abort(), {
11875
+ once: true
11876
+ });
11858
11877
  try {
11859
11878
  let streamStopReason;
11860
11879
  for await (const event of stream) {
@@ -11939,6 +11958,9 @@ var AnthropicProvider = class {
11939
11958
  } finally {
11940
11959
  clearInterval(timeoutInterval);
11941
11960
  }
11961
+ if (timeoutController.signal.aborted) {
11962
+ throw new Error(`Stream timeout: No response from LLM for ${streamTimeout / 1e3}s`);
11963
+ }
11942
11964
  } catch (error) {
11943
11965
  throw this.handleError(error);
11944
11966
  }
@@ -12274,6 +12296,9 @@ var LOCAL_MODEL_PATTERNS = [
12274
12296
  "starcoder"
12275
12297
  ];
12276
12298
  var MODELS_WITH_THINKING_MODE = ["kimi-k2.5", "kimi-k2-0324", "kimi-latest"];
12299
+ function needsResponsesApi(model) {
12300
+ return model.includes("codex") || model.startsWith("gpt-5") || model.startsWith("o4-") || model.startsWith("o3-");
12301
+ }
12277
12302
  var OpenAIProvider = class {
12278
12303
  id;
12279
12304
  name;
@@ -12343,9 +12368,12 @@ var OpenAIProvider = class {
12343
12368
  */
12344
12369
  async chat(messages, options) {
12345
12370
  this.ensureInitialized();
12371
+ const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
12372
+ if (needsResponsesApi(model)) {
12373
+ return this.chatViaResponses(messages, options);
12374
+ }
12346
12375
  return withRetry(async () => {
12347
12376
  try {
12348
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
12349
12377
  const supportsTemp = this.supportsTemperature(model);
12350
12378
  const response = await this.client.chat.completions.create({
12351
12379
  model,
@@ -12377,9 +12405,12 @@ var OpenAIProvider = class {
12377
12405
  */
12378
12406
  async chatWithTools(messages, options) {
12379
12407
  this.ensureInitialized();
12408
+ const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
12409
+ if (needsResponsesApi(model)) {
12410
+ return this.chatWithToolsViaResponses(messages, options);
12411
+ }
12380
12412
  return withRetry(async () => {
12381
12413
  try {
12382
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
12383
12414
  const supportsTemp = this.supportsTemperature(model);
12384
12415
  const extraBody = this.getExtraBody(model);
12385
12416
  const requestParams = {
@@ -12421,8 +12452,12 @@ var OpenAIProvider = class {
12421
12452
  */
12422
12453
  async *stream(messages, options) {
12423
12454
  this.ensureInitialized();
12455
+ const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
12456
+ if (needsResponsesApi(model)) {
12457
+ yield* this.streamViaResponses(messages, options);
12458
+ return;
12459
+ }
12424
12460
  try {
12425
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
12426
12461
  const supportsTemp = this.supportsTemperature(model);
12427
12462
  const stream = await this.client.chat.completions.create({
12428
12463
  model,
@@ -12452,8 +12487,12 @@ var OpenAIProvider = class {
12452
12487
  */
12453
12488
  async *streamWithTools(messages, options) {
12454
12489
  this.ensureInitialized();
12490
+ const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
12491
+ if (needsResponsesApi(model)) {
12492
+ yield* this.streamWithToolsViaResponses(messages, options);
12493
+ return;
12494
+ }
12455
12495
  try {
12456
- const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
12457
12496
  const supportsTemp = this.supportsTemperature(model);
12458
12497
  const extraBody = this.getExtraBody(model);
12459
12498
  const requestParams = {
@@ -12476,12 +12515,16 @@ var OpenAIProvider = class {
12476
12515
  const toolCallBuilders = /* @__PURE__ */ new Map();
12477
12516
  const streamTimeout = this.config.timeout ?? 12e4;
12478
12517
  let lastActivityTime = Date.now();
12479
- const checkTimeout = () => {
12518
+ const timeoutController = new AbortController();
12519
+ const timeoutInterval = setInterval(() => {
12480
12520
  if (Date.now() - lastActivityTime > streamTimeout) {
12481
- throw new Error(`Stream timeout: No response from LLM for ${streamTimeout / 1e3}s`);
12521
+ clearInterval(timeoutInterval);
12522
+ timeoutController.abort();
12482
12523
  }
12483
- };
12484
- const timeoutInterval = setInterval(checkTimeout, 5e3);
12524
+ }, 5e3);
12525
+ timeoutController.signal.addEventListener("abort", () => stream.controller.abort(), {
12526
+ once: true
12527
+ });
12485
12528
  const providerName = this.name;
12486
12529
  const parseArguments = (builder) => {
12487
12530
  let input = {};
@@ -12585,6 +12628,9 @@ var OpenAIProvider = class {
12585
12628
  } finally {
12586
12629
  clearInterval(timeoutInterval);
12587
12630
  }
12631
+ if (timeoutController.signal.aborted) {
12632
+ throw new Error(`Stream timeout: No response from LLM for ${streamTimeout / 1e3}s`);
12633
+ }
12588
12634
  } catch (error) {
12589
12635
  throw this.handleError(error);
12590
12636
  }
@@ -12917,6 +12963,375 @@ var OpenAIProvider = class {
12917
12963
  cause: error instanceof Error ? error : void 0
12918
12964
  });
12919
12965
  }
12966
+ // --- Responses API support (GPT-5+, Codex, o3, o4 models) ---
12967
+ /**
12968
+ * Simple chat via Responses API (no tools)
12969
+ */
12970
+ async chatViaResponses(messages, options) {
12971
+ this.ensureInitialized();
12972
+ return withRetry(async () => {
12973
+ try {
12974
+ const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
12975
+ const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
12976
+ const response = await this.client.responses.create({
12977
+ model,
12978
+ input,
12979
+ instructions: instructions ?? void 0,
12980
+ max_output_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
12981
+ temperature: options?.temperature ?? this.config.temperature ?? 0,
12982
+ store: false
12983
+ });
12984
+ return {
12985
+ id: response.id,
12986
+ content: response.output_text ?? "",
12987
+ stopReason: response.status === "completed" ? "end_turn" : "max_tokens",
12988
+ usage: {
12989
+ inputTokens: response.usage?.input_tokens ?? 0,
12990
+ outputTokens: response.usage?.output_tokens ?? 0
12991
+ },
12992
+ model: String(response.model)
12993
+ };
12994
+ } catch (error) {
12995
+ throw this.handleError(error);
12996
+ }
12997
+ }, this.retryConfig);
12998
+ }
12999
+ /**
13000
+ * Chat with tools via Responses API
13001
+ */
13002
+ async chatWithToolsViaResponses(messages, options) {
13003
+ this.ensureInitialized();
13004
+ return withRetry(async () => {
13005
+ try {
13006
+ const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
13007
+ const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
13008
+ const tools = this.convertToolsForResponses(options.tools);
13009
+ const response = await this.client.responses.create({
13010
+ model,
13011
+ input,
13012
+ instructions: instructions ?? void 0,
13013
+ tools,
13014
+ max_output_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
13015
+ temperature: options?.temperature ?? this.config.temperature ?? 0,
13016
+ store: false
13017
+ });
13018
+ let content = "";
13019
+ const toolCalls = [];
13020
+ for (const item of response.output) {
13021
+ if (item.type === "message") {
13022
+ for (const part of item.content) {
13023
+ if (part.type === "output_text") {
13024
+ content += part.text;
13025
+ }
13026
+ }
13027
+ } else if (item.type === "function_call") {
13028
+ toolCalls.push({
13029
+ id: item.call_id,
13030
+ name: item.name,
13031
+ input: this.parseResponsesArguments(item.arguments)
13032
+ });
13033
+ }
13034
+ }
13035
+ return {
13036
+ id: response.id,
13037
+ content,
13038
+ stopReason: toolCalls.length > 0 ? "tool_use" : "end_turn",
13039
+ usage: {
13040
+ inputTokens: response.usage?.input_tokens ?? 0,
13041
+ outputTokens: response.usage?.output_tokens ?? 0
13042
+ },
13043
+ model: String(response.model),
13044
+ toolCalls
13045
+ };
13046
+ } catch (error) {
13047
+ throw this.handleError(error);
13048
+ }
13049
+ }, this.retryConfig);
13050
+ }
13051
+ /**
13052
+ * Stream via Responses API (no tools)
13053
+ */
13054
+ async *streamViaResponses(messages, options) {
13055
+ this.ensureInitialized();
13056
+ try {
13057
+ const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
13058
+ const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
13059
+ const stream = await this.client.responses.create({
13060
+ model,
13061
+ input,
13062
+ instructions: instructions ?? void 0,
13063
+ max_output_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
13064
+ temperature: options?.temperature ?? this.config.temperature ?? 0,
13065
+ store: false,
13066
+ stream: true
13067
+ });
13068
+ const streamTimeout = this.config.timeout ?? 12e4;
13069
+ let lastActivityTime = Date.now();
13070
+ const timeoutController = new AbortController();
13071
+ const timeoutInterval = setInterval(() => {
13072
+ if (Date.now() - lastActivityTime > streamTimeout) {
13073
+ clearInterval(timeoutInterval);
13074
+ timeoutController.abort();
13075
+ }
13076
+ }, 5e3);
13077
+ timeoutController.signal.addEventListener(
13078
+ "abort",
13079
+ () => stream.controller?.abort(),
13080
+ { once: true }
13081
+ );
13082
+ try {
13083
+ for await (const event of stream) {
13084
+ lastActivityTime = Date.now();
13085
+ if (event.type === "response.output_text.delta") {
13086
+ yield { type: "text", text: event.delta };
13087
+ } else if (event.type === "response.completed") {
13088
+ yield { type: "done", stopReason: "end_turn" };
13089
+ }
13090
+ }
13091
+ } finally {
13092
+ clearInterval(timeoutInterval);
13093
+ }
13094
+ if (timeoutController.signal.aborted) {
13095
+ throw new Error(`Stream timeout: No response from LLM for ${streamTimeout / 1e3}s`);
13096
+ }
13097
+ } catch (error) {
13098
+ throw this.handleError(error);
13099
+ }
13100
+ }
13101
+ /**
13102
+ * Stream with tools via Responses API
13103
+ *
13104
+ * IMPORTANT: fnCallBuilders is keyed by output item ID (fc.id), NOT by
13105
+ * call_id. The streaming events (function_call_arguments.delta/done) use
13106
+ * item_id which references the output item's id field, not call_id.
13107
+ */
13108
+ async *streamWithToolsViaResponses(messages, options) {
13109
+ this.ensureInitialized();
13110
+ try {
13111
+ const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
13112
+ const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
13113
+ const tools = options.tools.length > 0 ? this.convertToolsForResponses(options.tools) : void 0;
13114
+ const requestParams = {
13115
+ model,
13116
+ input,
13117
+ instructions: instructions ?? void 0,
13118
+ max_output_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
13119
+ temperature: options?.temperature ?? this.config.temperature ?? 0,
13120
+ store: false,
13121
+ stream: true
13122
+ };
13123
+ if (tools) {
13124
+ requestParams.tools = tools;
13125
+ }
13126
+ const stream = await this.client.responses.create(
13127
+ requestParams
13128
+ );
13129
+ const fnCallBuilders = /* @__PURE__ */ new Map();
13130
+ const streamTimeout = this.config.timeout ?? 12e4;
13131
+ let lastActivityTime = Date.now();
13132
+ const timeoutController = new AbortController();
13133
+ const timeoutInterval = setInterval(() => {
13134
+ if (Date.now() - lastActivityTime > streamTimeout) {
13135
+ clearInterval(timeoutInterval);
13136
+ timeoutController.abort();
13137
+ }
13138
+ }, 5e3);
13139
+ timeoutController.signal.addEventListener(
13140
+ "abort",
13141
+ () => stream.controller?.abort(),
13142
+ { once: true }
13143
+ );
13144
+ try {
13145
+ for await (const event of stream) {
13146
+ lastActivityTime = Date.now();
13147
+ switch (event.type) {
13148
+ case "response.output_text.delta":
13149
+ yield { type: "text", text: event.delta };
13150
+ break;
13151
+ case "response.output_item.added":
13152
+ if (event.item.type === "function_call") {
13153
+ const fc = event.item;
13154
+ const itemKey = fc.id ?? fc.call_id;
13155
+ fnCallBuilders.set(itemKey, {
13156
+ callId: fc.call_id,
13157
+ name: fc.name,
13158
+ arguments: ""
13159
+ });
13160
+ yield {
13161
+ type: "tool_use_start",
13162
+ toolCall: { id: fc.call_id, name: fc.name }
13163
+ };
13164
+ }
13165
+ break;
13166
+ case "response.function_call_arguments.delta":
13167
+ {
13168
+ const builder = fnCallBuilders.get(event.item_id);
13169
+ if (builder) {
13170
+ builder.arguments += event.delta;
13171
+ }
13172
+ }
13173
+ break;
13174
+ case "response.function_call_arguments.done":
13175
+ {
13176
+ const builder = fnCallBuilders.get(event.item_id);
13177
+ if (builder) {
13178
+ yield {
13179
+ type: "tool_use_end",
13180
+ toolCall: {
13181
+ id: builder.callId,
13182
+ name: builder.name,
13183
+ input: this.parseResponsesArguments(event.arguments)
13184
+ }
13185
+ };
13186
+ fnCallBuilders.delete(event.item_id);
13187
+ }
13188
+ }
13189
+ break;
13190
+ case "response.completed":
13191
+ {
13192
+ for (const [, builder] of fnCallBuilders) {
13193
+ yield {
13194
+ type: "tool_use_end",
13195
+ toolCall: {
13196
+ id: builder.callId,
13197
+ name: builder.name,
13198
+ input: this.parseResponsesArguments(builder.arguments)
13199
+ }
13200
+ };
13201
+ }
13202
+ fnCallBuilders.clear();
13203
+ const hasToolCalls = event.response.output.some(
13204
+ (i) => i.type === "function_call"
13205
+ );
13206
+ yield {
13207
+ type: "done",
13208
+ stopReason: hasToolCalls ? "tool_use" : "end_turn"
13209
+ };
13210
+ }
13211
+ break;
13212
+ }
13213
+ }
13214
+ } finally {
13215
+ clearInterval(timeoutInterval);
13216
+ }
13217
+ if (timeoutController.signal.aborted) {
13218
+ throw new Error(`Stream timeout: No response from LLM for ${streamTimeout / 1e3}s`);
13219
+ }
13220
+ } catch (error) {
13221
+ throw this.handleError(error);
13222
+ }
13223
+ }
13224
+ // --- Responses API conversion helpers ---
13225
+ /**
13226
+ * Convert internal messages to Responses API input format.
13227
+ *
13228
+ * The Responses API uses a flat array of input items instead of the
13229
+ * chat completions messages array.
13230
+ */
13231
+ convertToResponsesInput(messages, systemPrompt) {
13232
+ const input = [];
13233
+ let instructions = null;
13234
+ if (systemPrompt) {
13235
+ instructions = systemPrompt;
13236
+ }
13237
+ for (const msg of messages) {
13238
+ if (msg.role === "system") {
13239
+ instructions = (instructions ? instructions + "\n\n" : "") + this.contentToString(msg.content);
13240
+ } else if (msg.role === "user") {
13241
+ if (Array.isArray(msg.content) && msg.content.some((b) => b.type === "tool_result")) {
13242
+ for (const block of msg.content) {
13243
+ if (block.type === "tool_result") {
13244
+ const tr = block;
13245
+ input.push({
13246
+ type: "function_call_output",
13247
+ call_id: tr.tool_use_id,
13248
+ output: tr.content
13249
+ });
13250
+ }
13251
+ }
13252
+ } else if (Array.isArray(msg.content) && msg.content.some((b) => b.type === "image")) {
13253
+ const parts = [];
13254
+ for (const block of msg.content) {
13255
+ if (block.type === "text") {
13256
+ parts.push({ type: "input_text", text: block.text });
13257
+ } else if (block.type === "image") {
13258
+ const imgBlock = block;
13259
+ parts.push({
13260
+ type: "input_image",
13261
+ image_url: `data:${imgBlock.source.media_type};base64,${imgBlock.source.data}`,
13262
+ detail: "auto"
13263
+ });
13264
+ }
13265
+ }
13266
+ input.push({
13267
+ role: "user",
13268
+ content: parts
13269
+ });
13270
+ } else {
13271
+ input.push({
13272
+ role: "user",
13273
+ content: this.contentToString(msg.content)
13274
+ });
13275
+ }
13276
+ } else if (msg.role === "assistant") {
13277
+ if (typeof msg.content === "string") {
13278
+ input.push({ role: "assistant", content: msg.content });
13279
+ } else if (Array.isArray(msg.content)) {
13280
+ const textParts = [];
13281
+ for (const block of msg.content) {
13282
+ if (block.type === "text") {
13283
+ textParts.push(block.text);
13284
+ } else if (block.type === "tool_use") {
13285
+ if (textParts.length > 0) {
13286
+ input.push({ role: "assistant", content: textParts.join("") });
13287
+ textParts.length = 0;
13288
+ }
13289
+ input.push({
13290
+ type: "function_call",
13291
+ call_id: block.id,
13292
+ name: block.name,
13293
+ arguments: JSON.stringify(block.input)
13294
+ });
13295
+ }
13296
+ }
13297
+ if (textParts.length > 0) {
13298
+ input.push({ role: "assistant", content: textParts.join("") });
13299
+ }
13300
+ }
13301
+ }
13302
+ }
13303
+ return { input, instructions };
13304
+ }
13305
+ /**
13306
+ * Convert tool definitions to Responses API FunctionTool format
13307
+ */
13308
+ convertToolsForResponses(tools) {
13309
+ return tools.map((tool) => ({
13310
+ type: "function",
13311
+ name: tool.name,
13312
+ description: tool.description ?? void 0,
13313
+ parameters: tool.input_schema ?? null,
13314
+ strict: false
13315
+ }));
13316
+ }
13317
+ /**
13318
+ * Parse tool call arguments with jsonrepair fallback (Responses API)
13319
+ */
13320
+ parseResponsesArguments(args) {
13321
+ try {
13322
+ return args ? JSON.parse(args) : {};
13323
+ } catch {
13324
+ try {
13325
+ if (args) {
13326
+ const repaired = jsonrepair(args);
13327
+ return JSON.parse(repaired);
13328
+ }
13329
+ } catch {
13330
+ console.error(`[${this.name}] Cannot parse tool arguments: ${args.slice(0, 200)}`);
13331
+ }
13332
+ return {};
13333
+ }
13334
+ }
12920
13335
  };
12921
13336
  function createKimiProvider(config) {
12922
13337
  const provider = new OpenAIProvider("kimi", "Kimi (Moonshot)");
@@ -12985,18 +13400,18 @@ async function refreshAccessToken(provider, refreshToken) {
12985
13400
  }
12986
13401
  function getTokenStoragePath(provider) {
12987
13402
  const home = process.env.HOME || process.env.USERPROFILE || "";
12988
- return path16.join(home, ".coco", "tokens", `${provider}.json`);
13403
+ return path17.join(home, ".coco", "tokens", `${provider}.json`);
12989
13404
  }
12990
13405
  async function saveTokens(provider, tokens) {
12991
13406
  const filePath = getTokenStoragePath(provider);
12992
- const dir = path16.dirname(filePath);
12993
- await fs15.mkdir(dir, { recursive: true, mode: 448 });
12994
- await fs15.writeFile(filePath, JSON.stringify(tokens, null, 2), { mode: 384 });
13407
+ const dir = path17.dirname(filePath);
13408
+ await fs16.mkdir(dir, { recursive: true, mode: 448 });
13409
+ await fs16.writeFile(filePath, JSON.stringify(tokens, null, 2), { mode: 384 });
12995
13410
  }
12996
13411
  async function loadTokens(provider) {
12997
13412
  const filePath = getTokenStoragePath(provider);
12998
13413
  try {
12999
- const content = await fs15.readFile(filePath, "utf-8");
13414
+ const content = await fs16.readFile(filePath, "utf-8");
13000
13415
  return JSON.parse(content);
13001
13416
  } catch {
13002
13417
  return null;
@@ -13005,7 +13420,7 @@ async function loadTokens(provider) {
13005
13420
  async function deleteTokens(provider) {
13006
13421
  const filePath = getTokenStoragePath(provider);
13007
13422
  try {
13008
- await fs15.unlink(filePath);
13423
+ await fs16.unlink(filePath);
13009
13424
  } catch {
13010
13425
  }
13011
13426
  }
@@ -13043,6 +13458,124 @@ function detectWSL() {
13043
13458
  }
13044
13459
  }
13045
13460
  var isWSL = detectWSL();
13461
+ var COPILOT_TOKEN_URL = "https://api.github.com/copilot_internal/v2/token";
13462
+ var COPILOT_BASE_URLS = {
13463
+ individual: "https://api.githubcopilot.com",
13464
+ business: "https://api.business.githubcopilot.com",
13465
+ enterprise: "https://api.enterprise.githubcopilot.com"
13466
+ };
13467
+ var DEFAULT_COPILOT_BASE_URL = "https://api.githubcopilot.com";
13468
+ var REFRESH_BUFFER_MS = 6e4;
13469
+ var CopilotAuthError = class extends Error {
13470
+ constructor(message, permanent) {
13471
+ super(message);
13472
+ this.permanent = permanent;
13473
+ this.name = "CopilotAuthError";
13474
+ }
13475
+ };
13476
+ async function exchangeForCopilotToken(githubToken) {
13477
+ const response = await fetch(COPILOT_TOKEN_URL, {
13478
+ method: "GET",
13479
+ headers: {
13480
+ Authorization: `token ${githubToken}`,
13481
+ Accept: "application/json",
13482
+ "User-Agent": "Corbat-Coco/1.0"
13483
+ }
13484
+ });
13485
+ if (!response.ok) {
13486
+ const error = await response.text();
13487
+ if (response.status === 401) {
13488
+ throw new CopilotAuthError(
13489
+ "GitHub token is invalid or expired. Please re-authenticate with /provider copilot.",
13490
+ true
13491
+ );
13492
+ }
13493
+ if (response.status === 403) {
13494
+ throw new CopilotAuthError(
13495
+ "GitHub Copilot is not enabled for this account.\n Please ensure you have an active Copilot subscription:\n https://github.com/settings/copilot",
13496
+ true
13497
+ );
13498
+ }
13499
+ throw new Error(`Copilot token exchange failed: ${response.status} - ${error}`);
13500
+ }
13501
+ return await response.json();
13502
+ }
13503
+ function getCopilotBaseUrl(accountType) {
13504
+ if (accountType && accountType in COPILOT_BASE_URLS) {
13505
+ return COPILOT_BASE_URLS[accountType];
13506
+ }
13507
+ return DEFAULT_COPILOT_BASE_URL;
13508
+ }
13509
+ function getCopilotCredentialsPath() {
13510
+ const home = process.env.HOME || process.env.USERPROFILE || "";
13511
+ return path17.join(home, ".coco", "tokens", "copilot.json");
13512
+ }
13513
+ async function saveCopilotCredentials(creds) {
13514
+ const filePath = getCopilotCredentialsPath();
13515
+ const dir = path17.dirname(filePath);
13516
+ await fs16.mkdir(dir, { recursive: true, mode: 448 });
13517
+ await fs16.writeFile(filePath, JSON.stringify(creds, null, 2), { mode: 384 });
13518
+ }
13519
+ var CopilotCredentialsSchema = z.object({
13520
+ githubToken: z.string().min(1),
13521
+ copilotToken: z.string().optional(),
13522
+ copilotTokenExpiresAt: z.number().optional(),
13523
+ accountType: z.string().optional()
13524
+ });
13525
+ async function loadCopilotCredentials() {
13526
+ try {
13527
+ const content = await fs16.readFile(getCopilotCredentialsPath(), "utf-8");
13528
+ const parsed = CopilotCredentialsSchema.safeParse(JSON.parse(content));
13529
+ return parsed.success ? parsed.data : null;
13530
+ } catch {
13531
+ return null;
13532
+ }
13533
+ }
13534
+ async function deleteCopilotCredentials() {
13535
+ try {
13536
+ await fs16.unlink(getCopilotCredentialsPath());
13537
+ } catch {
13538
+ }
13539
+ }
13540
+ function isCopilotTokenExpired(creds) {
13541
+ if (!creds.copilotToken || !creds.copilotTokenExpiresAt) return true;
13542
+ return Date.now() >= creds.copilotTokenExpiresAt - REFRESH_BUFFER_MS;
13543
+ }
13544
+ async function getValidCopilotToken() {
13545
+ const creds = await loadCopilotCredentials();
13546
+ if (!creds) return null;
13547
+ const envToken = process.env["GITHUB_TOKEN"] || process.env["GH_TOKEN"];
13548
+ const githubToken = envToken || creds.githubToken;
13549
+ if (!isCopilotTokenExpired(creds) && creds.copilotToken) {
13550
+ return {
13551
+ token: creds.copilotToken,
13552
+ baseUrl: getCopilotBaseUrl(creds.accountType),
13553
+ isNew: false
13554
+ };
13555
+ }
13556
+ try {
13557
+ const copilotToken = await exchangeForCopilotToken(githubToken);
13558
+ const updatedCreds = {
13559
+ ...creds,
13560
+ githubToken: creds.githubToken,
13561
+ copilotToken: copilotToken.token,
13562
+ copilotTokenExpiresAt: copilotToken.expires_at * 1e3,
13563
+ accountType: copilotToken.annotations?.copilot_plan ?? creds.accountType
13564
+ };
13565
+ await saveCopilotCredentials(updatedCreds);
13566
+ return {
13567
+ token: copilotToken.token,
13568
+ baseUrl: getCopilotBaseUrl(updatedCreds.accountType),
13569
+ isNew: true
13570
+ };
13571
+ } catch (error) {
13572
+ if (error instanceof CopilotAuthError && error.permanent) {
13573
+ await deleteCopilotCredentials();
13574
+ return null;
13575
+ }
13576
+ throw error;
13577
+ }
13578
+ }
13046
13579
 
13047
13580
  // src/auth/flow.ts
13048
13581
  promisify(execFile);
@@ -13355,22 +13888,160 @@ var CodexProvider = class {
13355
13888
  yield* this.stream(messages, options);
13356
13889
  }
13357
13890
  };
13358
- var DEFAULT_MODEL4 = "gemini-3-flash-preview";
13359
13891
  var CONTEXT_WINDOWS4 = {
13360
- // Gemini 3 series (latest, Jan 2026 - use -preview suffix)
13892
+ // Claude models
13893
+ "claude-sonnet-4.6": 2e5,
13894
+ "claude-opus-4.6": 2e5,
13895
+ "claude-sonnet-4.5": 2e5,
13896
+ "claude-opus-4.5": 2e5,
13897
+ "claude-haiku-4.5": 2e5,
13898
+ // OpenAI models — chat/completions
13899
+ "gpt-4.1": 1048576,
13900
+ // OpenAI models — /responses API (Codex/GPT-5+)
13901
+ "gpt-5.3-codex": 4e5,
13902
+ "gpt-5.2-codex": 4e5,
13903
+ "gpt-5.1-codex-max": 4e5,
13904
+ "gpt-5.2": 4e5,
13905
+ "gpt-5.1": 4e5,
13906
+ // Google models
13907
+ "gemini-3.1-pro-preview": 1e6,
13908
+ "gemini-3-flash-preview": 1e6,
13909
+ "gemini-2.5-pro": 1048576
13910
+ };
13911
+ var DEFAULT_MODEL4 = "claude-sonnet-4.6";
13912
+ var COPILOT_HEADERS = {
13913
+ "Copilot-Integration-Id": "vscode-chat",
13914
+ "Editor-Version": "vscode/1.99.0",
13915
+ "Editor-Plugin-Version": "copilot-chat/0.26.7",
13916
+ "X-GitHub-Api-Version": "2025-04-01"
13917
+ };
13918
+ var CopilotProvider = class extends OpenAIProvider {
13919
+ baseUrl = "https://api.githubcopilot.com";
13920
+ currentToken = null;
13921
+ /** In-flight refresh promise to prevent concurrent token exchanges */
13922
+ refreshPromise = null;
13923
+ constructor() {
13924
+ super("copilot", "GitHub Copilot");
13925
+ }
13926
+ /**
13927
+ * Initialize the provider with Copilot credentials.
13928
+ *
13929
+ * Gets a valid Copilot API token (from cache or by refreshing),
13930
+ * then creates an OpenAI client configured for the Copilot endpoint.
13931
+ */
13932
+ async initialize(config) {
13933
+ this.config = {
13934
+ ...config,
13935
+ model: config.model ?? DEFAULT_MODEL4
13936
+ };
13937
+ const tokenResult = await getValidCopilotToken();
13938
+ if (tokenResult) {
13939
+ this.currentToken = tokenResult.token;
13940
+ this.baseUrl = tokenResult.baseUrl;
13941
+ } else if (config.apiKey) {
13942
+ this.currentToken = config.apiKey;
13943
+ }
13944
+ if (!this.currentToken) {
13945
+ throw new ProviderError(
13946
+ "No Copilot token found. Please authenticate with: coco --provider copilot",
13947
+ { provider: this.id }
13948
+ );
13949
+ }
13950
+ this.createCopilotClient();
13951
+ }
13952
+ /**
13953
+ * Create the OpenAI client configured for Copilot API
13954
+ */
13955
+ createCopilotClient() {
13956
+ this.client = new OpenAI({
13957
+ apiKey: this.currentToken,
13958
+ baseURL: this.config.baseUrl ?? this.baseUrl,
13959
+ timeout: this.config.timeout ?? 12e4,
13960
+ defaultHeaders: COPILOT_HEADERS
13961
+ });
13962
+ }
13963
+ /**
13964
+ * Refresh the Copilot token if expired.
13965
+ *
13966
+ * Uses a mutex so concurrent callers share a single in-flight token
13967
+ * exchange. The slot is cleared inside the IIFE's finally block,
13968
+ * which runs after all awaiting callers have resumed.
13969
+ */
13970
+ async refreshTokenIfNeeded() {
13971
+ if (!this.refreshPromise) {
13972
+ this.refreshPromise = (async () => {
13973
+ try {
13974
+ const tokenResult = await getValidCopilotToken();
13975
+ if (tokenResult && tokenResult.isNew) {
13976
+ this.currentToken = tokenResult.token;
13977
+ this.baseUrl = tokenResult.baseUrl;
13978
+ this.createCopilotClient();
13979
+ }
13980
+ } finally {
13981
+ this.refreshPromise = null;
13982
+ }
13983
+ })();
13984
+ }
13985
+ await this.refreshPromise;
13986
+ }
13987
+ // --- Override public methods to add token refresh ---
13988
+ async chat(messages, options) {
13989
+ await this.refreshTokenIfNeeded();
13990
+ return super.chat(messages, options);
13991
+ }
13992
+ async chatWithTools(messages, options) {
13993
+ await this.refreshTokenIfNeeded();
13994
+ return super.chatWithTools(messages, options);
13995
+ }
13996
+ async *stream(messages, options) {
13997
+ await this.refreshTokenIfNeeded();
13998
+ yield* super.stream(messages, options);
13999
+ }
14000
+ async *streamWithTools(messages, options) {
14001
+ await this.refreshTokenIfNeeded();
14002
+ yield* super.streamWithTools(messages, options);
14003
+ }
14004
+ // --- Override metadata methods ---
14005
+ /**
14006
+ * Count tokens (approximate — Copilot models vary in tokenizer)
14007
+ */
14008
+ countTokens(text) {
14009
+ if (!text) return 0;
14010
+ return Math.ceil(text.length / 3.5);
14011
+ }
14012
+ /**
14013
+ * Get context window for the current model
14014
+ */
14015
+ getContextWindow() {
14016
+ const model = this.config.model ?? DEFAULT_MODEL4;
14017
+ return CONTEXT_WINDOWS4[model] ?? 128e3;
14018
+ }
14019
+ /**
14020
+ * Check if Copilot credentials are available
14021
+ */
14022
+ async isAvailable() {
14023
+ try {
14024
+ const tokenResult = await getValidCopilotToken();
14025
+ return tokenResult !== null;
14026
+ } catch {
14027
+ return false;
14028
+ }
14029
+ }
14030
+ };
14031
+ var DEFAULT_MODEL5 = "gemini-3.1-pro-preview";
14032
+ var CONTEXT_WINDOWS5 = {
14033
+ // Gemini 3.1 series (latest)
14034
+ "gemini-3.1-pro-preview": 1e6,
14035
+ "gemini-3.1-flash-lite-preview": 1e6,
14036
+ // Gemini 3 series
13361
14037
  "gemini-3-flash-preview": 1e6,
13362
- "gemini-3-pro-preview": 1e6,
13363
14038
  // Gemini 2.5 series (production stable)
13364
- "gemini-2.5-pro-preview-05-06": 1048576,
13365
- "gemini-2.5-flash-preview-05-20": 1048576,
13366
14039
  "gemini-2.5-pro": 1048576,
13367
14040
  "gemini-2.5-flash": 1048576,
13368
- // Gemini 2.0 series (GA stable)
13369
- "gemini-2.0-flash": 1048576,
14041
+ "gemini-2.5-flash-lite": 1048576,
13370
14042
  // Legacy
13371
14043
  "gemini-1.5-flash": 1e6,
13372
- "gemini-1.5-pro": 2e6,
13373
- "gemini-1.0-pro": 32e3
14044
+ "gemini-1.5-pro": 2e6
13374
14045
  };
13375
14046
  var GeminiProvider = class {
13376
14047
  id = "gemini";
@@ -13429,7 +14100,7 @@ var GeminiProvider = class {
13429
14100
  await this.refreshADCIfNeeded();
13430
14101
  try {
13431
14102
  const model = this.client.getGenerativeModel({
13432
- model: options?.model ?? this.config.model ?? DEFAULT_MODEL4,
14103
+ model: options?.model ?? this.config.model ?? DEFAULT_MODEL5,
13433
14104
  generationConfig: {
13434
14105
  maxOutputTokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
13435
14106
  temperature: options?.temperature ?? this.config.temperature ?? 0,
@@ -13458,7 +14129,7 @@ var GeminiProvider = class {
13458
14129
  }
13459
14130
  ];
13460
14131
  const model = this.client.getGenerativeModel({
13461
- model: options?.model ?? this.config.model ?? DEFAULT_MODEL4,
14132
+ model: options?.model ?? this.config.model ?? DEFAULT_MODEL5,
13462
14133
  generationConfig: {
13463
14134
  maxOutputTokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
13464
14135
  temperature: options?.temperature ?? this.config.temperature ?? 0
@@ -13487,7 +14158,7 @@ var GeminiProvider = class {
13487
14158
  await this.refreshADCIfNeeded();
13488
14159
  try {
13489
14160
  const model = this.client.getGenerativeModel({
13490
- model: options?.model ?? this.config.model ?? DEFAULT_MODEL4,
14161
+ model: options?.model ?? this.config.model ?? DEFAULT_MODEL5,
13491
14162
  generationConfig: {
13492
14163
  maxOutputTokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
13493
14164
  temperature: options?.temperature ?? this.config.temperature ?? 0
@@ -13526,7 +14197,7 @@ var GeminiProvider = class {
13526
14197
  }
13527
14198
  ];
13528
14199
  const model = this.client.getGenerativeModel({
13529
- model: options?.model ?? this.config.model ?? DEFAULT_MODEL4,
14200
+ model: options?.model ?? this.config.model ?? DEFAULT_MODEL5,
13530
14201
  generationConfig: {
13531
14202
  maxOutputTokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
13532
14203
  temperature: options?.temperature ?? this.config.temperature ?? 0
@@ -13610,8 +14281,8 @@ var GeminiProvider = class {
13610
14281
  * Get context window size
13611
14282
  */
13612
14283
  getContextWindow() {
13613
- const model = this.config.model ?? DEFAULT_MODEL4;
13614
- return CONTEXT_WINDOWS4[model] ?? 1e6;
14284
+ const model = this.config.model ?? DEFAULT_MODEL5;
14285
+ return CONTEXT_WINDOWS5[model] ?? 1e6;
13615
14286
  }
13616
14287
  /**
13617
14288
  * Check if provider is available
@@ -13619,7 +14290,7 @@ var GeminiProvider = class {
13619
14290
  async isAvailable() {
13620
14291
  if (!this.client) return false;
13621
14292
  try {
13622
- const modelName = this.config.model ?? DEFAULT_MODEL4;
14293
+ const modelName = this.config.model ?? DEFAULT_MODEL5;
13623
14294
  const model = this.client.getGenerativeModel({ model: modelName });
13624
14295
  await model.generateContent("hi");
13625
14296
  return true;
@@ -13751,7 +14422,7 @@ var GeminiProvider = class {
13751
14422
  inputTokens: usage?.promptTokenCount ?? 0,
13752
14423
  outputTokens: usage?.candidatesTokenCount ?? 0
13753
14424
  },
13754
- model: this.config.model ?? DEFAULT_MODEL4
14425
+ model: this.config.model ?? DEFAULT_MODEL5
13755
14426
  };
13756
14427
  }
13757
14428
  /**
@@ -13786,7 +14457,7 @@ var GeminiProvider = class {
13786
14457
  inputTokens: usage?.promptTokenCount ?? 0,
13787
14458
  outputTokens: usage?.candidatesTokenCount ?? 0
13788
14459
  },
13789
- model: this.config.model ?? DEFAULT_MODEL4,
14460
+ model: this.config.model ?? DEFAULT_MODEL5,
13790
14461
  toolCalls
13791
14462
  };
13792
14463
  }
@@ -13820,8 +14491,6 @@ var GeminiProvider = class {
13820
14491
  });
13821
14492
  }
13822
14493
  };
13823
-
13824
- // src/providers/index.ts
13825
14494
  init_env();
13826
14495
  async function createProvider(type, config = {}) {
13827
14496
  let provider;
@@ -13843,6 +14512,9 @@ async function createProvider(type, config = {}) {
13843
14512
  case "codex":
13844
14513
  provider = new CodexProvider();
13845
14514
  break;
14515
+ case "copilot":
14516
+ provider = new CopilotProvider();
14517
+ break;
13846
14518
  case "gemini":
13847
14519
  provider = new GeminiProvider();
13848
14520
  break;
@@ -14013,9 +14685,9 @@ function createInitialState(config) {
14013
14685
  }
14014
14686
  async function loadExistingState(projectPath) {
14015
14687
  try {
14016
- const fs37 = await import('fs/promises');
14688
+ const fs38 = await import('fs/promises');
14017
14689
  const statePath = `${projectPath}/.coco/state/project.json`;
14018
- const content = await fs37.readFile(statePath, "utf-8");
14690
+ const content = await fs38.readFile(statePath, "utf-8");
14019
14691
  const data = JSON.parse(content);
14020
14692
  data.createdAt = new Date(data.createdAt);
14021
14693
  data.updatedAt = new Date(data.updatedAt);
@@ -14025,13 +14697,13 @@ async function loadExistingState(projectPath) {
14025
14697
  }
14026
14698
  }
14027
14699
  async function saveState(state) {
14028
- const fs37 = await import('fs/promises');
14700
+ const fs38 = await import('fs/promises');
14029
14701
  const statePath = `${state.path}/.coco/state`;
14030
- await fs37.mkdir(statePath, { recursive: true });
14702
+ await fs38.mkdir(statePath, { recursive: true });
14031
14703
  const filePath = `${statePath}/project.json`;
14032
14704
  const tmpPath = `${filePath}.tmp.${Date.now()}`;
14033
- await fs37.writeFile(tmpPath, JSON.stringify(state, null, 2), "utf-8");
14034
- await fs37.rename(tmpPath, filePath);
14705
+ await fs38.writeFile(tmpPath, JSON.stringify(state, null, 2), "utf-8");
14706
+ await fs38.rename(tmpPath, filePath);
14035
14707
  }
14036
14708
  function getPhaseExecutor(phase) {
14037
14709
  switch (phase) {
@@ -14090,20 +14762,20 @@ async function createPhaseContext(config, state) {
14090
14762
  };
14091
14763
  const tools = {
14092
14764
  file: {
14093
- async read(path39) {
14094
- const fs37 = await import('fs/promises');
14095
- return fs37.readFile(path39, "utf-8");
14765
+ async read(path40) {
14766
+ const fs38 = await import('fs/promises');
14767
+ return fs38.readFile(path40, "utf-8");
14096
14768
  },
14097
- async write(path39, content) {
14098
- const fs37 = await import('fs/promises');
14769
+ async write(path40, content) {
14770
+ const fs38 = await import('fs/promises');
14099
14771
  const nodePath = await import('path');
14100
- await fs37.mkdir(nodePath.dirname(path39), { recursive: true });
14101
- await fs37.writeFile(path39, content, "utf-8");
14772
+ await fs38.mkdir(nodePath.dirname(path40), { recursive: true });
14773
+ await fs38.writeFile(path40, content, "utf-8");
14102
14774
  },
14103
- async exists(path39) {
14104
- const fs37 = await import('fs/promises');
14775
+ async exists(path40) {
14776
+ const fs38 = await import('fs/promises');
14105
14777
  try {
14106
- await fs37.access(path39);
14778
+ await fs38.access(path40);
14107
14779
  return true;
14108
14780
  } catch {
14109
14781
  return false;
@@ -14252,9 +14924,9 @@ async function createSnapshot(state) {
14252
14924
  var MAX_CHECKPOINT_VERSIONS = 5;
14253
14925
  async function getCheckpointFiles(state, phase) {
14254
14926
  try {
14255
- const fs37 = await import('fs/promises');
14927
+ const fs38 = await import('fs/promises');
14256
14928
  const checkpointDir = `${state.path}/.coco/checkpoints`;
14257
- const files = await fs37.readdir(checkpointDir);
14929
+ const files = await fs38.readdir(checkpointDir);
14258
14930
  const phaseFiles = files.filter((f) => f.startsWith(`snapshot-pre-${phase}-`) && f.endsWith(".json")).sort((a, b) => {
14259
14931
  const tsA = parseInt(a.split("-").pop()?.replace(".json", "") ?? "0", 10);
14260
14932
  const tsB = parseInt(b.split("-").pop()?.replace(".json", "") ?? "0", 10);
@@ -14267,11 +14939,11 @@ async function getCheckpointFiles(state, phase) {
14267
14939
  }
14268
14940
  async function cleanupOldCheckpoints(state, phase) {
14269
14941
  try {
14270
- const fs37 = await import('fs/promises');
14942
+ const fs38 = await import('fs/promises');
14271
14943
  const files = await getCheckpointFiles(state, phase);
14272
14944
  if (files.length > MAX_CHECKPOINT_VERSIONS) {
14273
14945
  const filesToDelete = files.slice(MAX_CHECKPOINT_VERSIONS);
14274
- await Promise.all(filesToDelete.map((f) => fs37.unlink(f).catch(() => {
14946
+ await Promise.all(filesToDelete.map((f) => fs38.unlink(f).catch(() => {
14275
14947
  })));
14276
14948
  }
14277
14949
  } catch {
@@ -14279,13 +14951,13 @@ async function cleanupOldCheckpoints(state, phase) {
14279
14951
  }
14280
14952
  async function saveSnapshot(state, snapshotId) {
14281
14953
  try {
14282
- const fs37 = await import('fs/promises');
14954
+ const fs38 = await import('fs/promises');
14283
14955
  const snapshotPath = `${state.path}/.coco/checkpoints/snapshot-${snapshotId}.json`;
14284
14956
  const snapshotDir = `${state.path}/.coco/checkpoints`;
14285
- await fs37.mkdir(snapshotDir, { recursive: true });
14957
+ await fs38.mkdir(snapshotDir, { recursive: true });
14286
14958
  const createdAt = state.createdAt instanceof Date ? state.createdAt.toISOString() : String(state.createdAt);
14287
14959
  const updatedAt = state.updatedAt instanceof Date ? state.updatedAt.toISOString() : String(state.updatedAt);
14288
- await fs37.writeFile(
14960
+ await fs38.writeFile(
14289
14961
  snapshotPath,
14290
14962
  JSON.stringify(
14291
14963
  {
@@ -14597,7 +15269,7 @@ async function loadConfig(configPath) {
14597
15269
  async function loadConfigFile(configPath, options = {}) {
14598
15270
  const { strict = true } = options;
14599
15271
  try {
14600
- const content = await fs15__default.readFile(configPath, "utf-8");
15272
+ const content = await fs16__default.readFile(configPath, "utf-8");
14601
15273
  const parsed = JSON5.parse(content);
14602
15274
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
14603
15275
  if (!strict) {
@@ -14653,7 +15325,7 @@ function deepMergeConfig(base, override) {
14653
15325
  };
14654
15326
  }
14655
15327
  function getProjectConfigPath2() {
14656
- return path16__default.join(process.cwd(), ".coco", "config.json");
15328
+ return path17__default.join(process.cwd(), ".coco", "config.json");
14657
15329
  }
14658
15330
  async function saveConfig(config, configPath, global = false) {
14659
15331
  const result = CocoConfigSchema.safeParse(config);
@@ -14668,10 +15340,10 @@ async function saveConfig(config, configPath, global = false) {
14668
15340
  });
14669
15341
  }
14670
15342
  const resolvedPath = configPath || (global ? CONFIG_PATHS.config : getProjectConfigPath2());
14671
- const dir = path16__default.dirname(resolvedPath);
14672
- await fs15__default.mkdir(dir, { recursive: true });
15343
+ const dir = path17__default.dirname(resolvedPath);
15344
+ await fs16__default.mkdir(dir, { recursive: true });
14673
15345
  const content = JSON.stringify(result.data, null, 2);
14674
- await fs15__default.writeFile(resolvedPath, content, "utf-8");
15346
+ await fs16__default.writeFile(resolvedPath, content, "utf-8");
14675
15347
  }
14676
15348
  function createDefaultConfig(projectName, language = "typescript") {
14677
15349
  return createDefaultConfigObject(projectName, language);
@@ -14679,7 +15351,7 @@ function createDefaultConfig(projectName, language = "typescript") {
14679
15351
  async function configExists(configPath, scope = "any") {
14680
15352
  if (configPath) {
14681
15353
  try {
14682
- await fs15__default.access(configPath);
15354
+ await fs16__default.access(configPath);
14683
15355
  return true;
14684
15356
  } catch {
14685
15357
  return false;
@@ -14687,7 +15359,7 @@ async function configExists(configPath, scope = "any") {
14687
15359
  }
14688
15360
  if (scope === "project" || scope === "any") {
14689
15361
  try {
14690
- await fs15__default.access(getProjectConfigPath2());
15362
+ await fs16__default.access(getProjectConfigPath2());
14691
15363
  return true;
14692
15364
  } catch {
14693
15365
  if (scope === "project") return false;
@@ -14695,7 +15367,7 @@ async function configExists(configPath, scope = "any") {
14695
15367
  }
14696
15368
  if (scope === "global" || scope === "any") {
14697
15369
  try {
14698
- await fs15__default.access(CONFIG_PATHS.config);
15370
+ await fs16__default.access(CONFIG_PATHS.config);
14699
15371
  return true;
14700
15372
  } catch {
14701
15373
  return false;
@@ -14737,15 +15409,15 @@ function levenshtein(a, b) {
14737
15409
  var MAX_DIR_ENTRIES = 200;
14738
15410
  var MAX_SUGGESTIONS = 5;
14739
15411
  async function suggestSimilarFiles(missingPath, options) {
14740
- const absPath = path16__default.resolve(missingPath);
14741
- const dir = path16__default.dirname(absPath);
14742
- const target = path16__default.basename(absPath);
15412
+ const absPath = path17__default.resolve(missingPath);
15413
+ const dir = path17__default.dirname(absPath);
15414
+ const target = path17__default.basename(absPath);
14743
15415
  const maxResults = MAX_SUGGESTIONS;
14744
15416
  try {
14745
- const entries = await fs15__default.readdir(dir);
15417
+ const entries = await fs16__default.readdir(dir);
14746
15418
  const limited = entries.slice(0, MAX_DIR_ENTRIES);
14747
15419
  const scored = limited.map((name) => ({
14748
- path: path16__default.join(dir, name),
15420
+ path: path17__default.join(dir, name),
14749
15421
  distance: levenshtein(target.toLowerCase(), name.toLowerCase())
14750
15422
  })).filter((s) => s.distance <= Math.max(target.length * 0.6, 3)).sort((a, b) => a.distance - b.distance);
14751
15423
  return scored.slice(0, maxResults);
@@ -14756,15 +15428,15 @@ async function suggestSimilarFiles(missingPath, options) {
14756
15428
  async function suggestSimilarPaths(missingPath, options) {
14757
15429
  const fileSuggestions = await suggestSimilarFiles(missingPath);
14758
15430
  if (fileSuggestions.length > 0) return fileSuggestions;
14759
- const absPath = path16__default.resolve(missingPath);
14760
- const grandparent = path16__default.dirname(path16__default.dirname(absPath));
14761
- const parentBasename = path16__default.basename(path16__default.dirname(absPath));
15431
+ const absPath = path17__default.resolve(missingPath);
15432
+ const grandparent = path17__default.dirname(path17__default.dirname(absPath));
15433
+ const parentBasename = path17__default.basename(path17__default.dirname(absPath));
14762
15434
  const maxResults = MAX_SUGGESTIONS;
14763
15435
  try {
14764
- const entries = await fs15__default.readdir(grandparent, { withFileTypes: true });
15436
+ const entries = await fs16__default.readdir(grandparent, { withFileTypes: true });
14765
15437
  const dirs = entries.filter((e) => e.isDirectory()).slice(0, MAX_DIR_ENTRIES);
14766
15438
  const scored = dirs.map((d) => ({
14767
- path: path16__default.join(grandparent, d.name),
15439
+ path: path17__default.join(grandparent, d.name),
14768
15440
  distance: levenshtein(parentBasename.toLowerCase(), d.name.toLowerCase())
14769
15441
  })).filter((s) => s.distance <= Math.max(parentBasename.length * 0.6, 3)).sort((a, b) => a.distance - b.distance);
14770
15442
  return scored.slice(0, maxResults);
@@ -14776,7 +15448,7 @@ function formatSuggestions(suggestions, baseDir) {
14776
15448
  if (suggestions.length === 0) return "";
14777
15449
  const base = baseDir ?? process.cwd();
14778
15450
  const lines = suggestions.map((s) => {
14779
- const rel = path16__default.relative(base, s.path);
15451
+ const rel = path17__default.relative(base, s.path);
14780
15452
  return ` - ${rel}`;
14781
15453
  });
14782
15454
  return `
@@ -14809,7 +15481,7 @@ function hasNullByte(str) {
14809
15481
  }
14810
15482
  function normalizePath(filePath) {
14811
15483
  let normalized = filePath.replace(/\0/g, "");
14812
- normalized = path16__default.normalize(normalized);
15484
+ normalized = path17__default.normalize(normalized);
14813
15485
  return normalized;
14814
15486
  }
14815
15487
  function isPathAllowed(filePath, operation) {
@@ -14817,31 +15489,31 @@ function isPathAllowed(filePath, operation) {
14817
15489
  return { allowed: false, reason: "Path contains invalid characters" };
14818
15490
  }
14819
15491
  const normalized = normalizePath(filePath);
14820
- const absolute = path16__default.resolve(normalized);
15492
+ const absolute = path17__default.resolve(normalized);
14821
15493
  const cwd = process.cwd();
14822
15494
  for (const blocked of BLOCKED_PATHS) {
14823
- const normalizedBlocked = path16__default.normalize(blocked);
14824
- if (absolute === normalizedBlocked || absolute.startsWith(normalizedBlocked + path16__default.sep)) {
15495
+ const normalizedBlocked = path17__default.normalize(blocked);
15496
+ if (absolute === normalizedBlocked || absolute.startsWith(normalizedBlocked + path17__default.sep)) {
14825
15497
  return { allowed: false, reason: `Access to system path '${blocked}' is not allowed` };
14826
15498
  }
14827
15499
  }
14828
15500
  const home = process.env.HOME;
14829
15501
  if (home) {
14830
- const normalizedHome = path16__default.normalize(home);
14831
- const normalizedCwd = path16__default.normalize(cwd);
15502
+ const normalizedHome = path17__default.normalize(home);
15503
+ const normalizedCwd = path17__default.normalize(cwd);
14832
15504
  if (absolute.startsWith(normalizedHome) && !absolute.startsWith(normalizedCwd)) {
14833
15505
  if (isWithinAllowedPath(absolute, operation)) ; else if (operation === "read") {
14834
15506
  const allowedHomeReads = [".gitconfig", ".zshrc", ".bashrc"];
14835
- const basename5 = path16__default.basename(absolute);
15507
+ const basename5 = path17__default.basename(absolute);
14836
15508
  if (!allowedHomeReads.includes(basename5)) {
14837
- const targetDir = path16__default.dirname(absolute);
15509
+ const targetDir = path17__default.dirname(absolute);
14838
15510
  return {
14839
15511
  allowed: false,
14840
15512
  reason: `Reading files outside project directory is not allowed. Use /allow-path ${targetDir} to grant access.`
14841
15513
  };
14842
15514
  }
14843
15515
  } else {
14844
- const targetDir = path16__default.dirname(absolute);
15516
+ const targetDir = path17__default.dirname(absolute);
14845
15517
  return {
14846
15518
  allowed: false,
14847
15519
  reason: `${operation} operations outside project directory are not allowed. Use /allow-path ${targetDir} to grant access.`
@@ -14850,7 +15522,7 @@ function isPathAllowed(filePath, operation) {
14850
15522
  }
14851
15523
  }
14852
15524
  if (operation === "write" || operation === "delete") {
14853
- const basename5 = path16__default.basename(absolute);
15525
+ const basename5 = path17__default.basename(absolute);
14854
15526
  for (const pattern of SENSITIVE_PATTERNS) {
14855
15527
  if (pattern.test(basename5)) {
14856
15528
  return {
@@ -14873,17 +15545,17 @@ function isENOENT(error) {
14873
15545
  return error.code === "ENOENT";
14874
15546
  }
14875
15547
  async function enrichENOENT(filePath, operation) {
14876
- const absPath = path16__default.resolve(filePath);
15548
+ const absPath = path17__default.resolve(filePath);
14877
15549
  const suggestions = await suggestSimilarFiles(absPath);
14878
- const hint = formatSuggestions(suggestions, path16__default.dirname(absPath));
15550
+ const hint = formatSuggestions(suggestions, path17__default.dirname(absPath));
14879
15551
  const action = operation === "read" ? "Use glob or list_dir to find the correct path." : "Check that the parent directory exists.";
14880
15552
  return `File not found: ${filePath}${hint}
14881
15553
  ${action}`;
14882
15554
  }
14883
15555
  async function enrichDirENOENT(dirPath) {
14884
- const absPath = path16__default.resolve(dirPath);
15556
+ const absPath = path17__default.resolve(dirPath);
14885
15557
  const suggestions = await suggestSimilarPaths(absPath);
14886
- const hint = formatSuggestions(suggestions, path16__default.dirname(absPath));
15558
+ const hint = formatSuggestions(suggestions, path17__default.dirname(absPath));
14887
15559
  return `Directory not found: ${dirPath}${hint}
14888
15560
  Use list_dir or glob to find the correct path.`;
14889
15561
  }
@@ -14904,13 +15576,13 @@ Examples:
14904
15576
  async execute({ path: filePath, encoding, maxSize }) {
14905
15577
  validatePath(filePath, "read");
14906
15578
  try {
14907
- const absolutePath = path16__default.resolve(filePath);
14908
- const stats = await fs15__default.stat(absolutePath);
15579
+ const absolutePath = path17__default.resolve(filePath);
15580
+ const stats = await fs16__default.stat(absolutePath);
14909
15581
  const maxBytes = maxSize ?? DEFAULT_MAX_FILE_SIZE;
14910
15582
  let truncated = false;
14911
15583
  let content;
14912
15584
  if (stats.size > maxBytes) {
14913
- const handle = await fs15__default.open(absolutePath, "r");
15585
+ const handle = await fs16__default.open(absolutePath, "r");
14914
15586
  try {
14915
15587
  const buffer = Buffer.alloc(maxBytes);
14916
15588
  await handle.read(buffer, 0, maxBytes, 0);
@@ -14920,7 +15592,7 @@ Examples:
14920
15592
  await handle.close();
14921
15593
  }
14922
15594
  } else {
14923
- content = await fs15__default.readFile(absolutePath, encoding);
15595
+ content = await fs16__default.readFile(absolutePath, encoding);
14924
15596
  }
14925
15597
  return {
14926
15598
  content,
@@ -14963,10 +15635,10 @@ Examples:
14963
15635
  async execute({ path: filePath, content, createDirs, dryRun }) {
14964
15636
  validatePath(filePath, "write");
14965
15637
  try {
14966
- const absolutePath = path16__default.resolve(filePath);
15638
+ const absolutePath = path17__default.resolve(filePath);
14967
15639
  let wouldCreate = false;
14968
15640
  try {
14969
- await fs15__default.access(absolutePath);
15641
+ await fs16__default.access(absolutePath);
14970
15642
  } catch {
14971
15643
  wouldCreate = true;
14972
15644
  }
@@ -14979,10 +15651,10 @@ Examples:
14979
15651
  };
14980
15652
  }
14981
15653
  if (createDirs) {
14982
- await fs15__default.mkdir(path16__default.dirname(absolutePath), { recursive: true });
15654
+ await fs16__default.mkdir(path17__default.dirname(absolutePath), { recursive: true });
14983
15655
  }
14984
- await fs15__default.writeFile(absolutePath, content, "utf-8");
14985
- const stats = await fs15__default.stat(absolutePath);
15656
+ await fs16__default.writeFile(absolutePath, content, "utf-8");
15657
+ const stats = await fs16__default.stat(absolutePath);
14986
15658
  return {
14987
15659
  path: absolutePath,
14988
15660
  size: stats.size,
@@ -15025,8 +15697,8 @@ Examples:
15025
15697
  async execute({ path: filePath, oldText, newText, all, dryRun }) {
15026
15698
  validatePath(filePath, "write");
15027
15699
  try {
15028
- const absolutePath = path16__default.resolve(filePath);
15029
- let content = await fs15__default.readFile(absolutePath, "utf-8");
15700
+ const absolutePath = path17__default.resolve(filePath);
15701
+ let content = await fs16__default.readFile(absolutePath, "utf-8");
15030
15702
  let replacements = 0;
15031
15703
  if (all) {
15032
15704
  const regex = new RegExp(escapeRegex(oldText), "g");
@@ -15075,7 +15747,7 @@ Hint: Use read_file first to verify the exact content.`
15075
15747
  preview
15076
15748
  };
15077
15749
  }
15078
- await fs15__default.writeFile(absolutePath, content, "utf-8");
15750
+ await fs16__default.writeFile(absolutePath, content, "utf-8");
15079
15751
  return {
15080
15752
  path: absolutePath,
15081
15753
  replacements,
@@ -15146,8 +15818,8 @@ Examples:
15146
15818
  }),
15147
15819
  async execute({ path: filePath }) {
15148
15820
  try {
15149
- const absolutePath = path16__default.resolve(filePath);
15150
- const stats = await fs15__default.stat(absolutePath);
15821
+ const absolutePath = path17__default.resolve(filePath);
15822
+ const stats = await fs16__default.stat(absolutePath);
15151
15823
  return {
15152
15824
  exists: true,
15153
15825
  isFile: stats.isFile(),
@@ -15177,12 +15849,12 @@ Examples:
15177
15849
  }),
15178
15850
  async execute({ path: dirPath, recursive }) {
15179
15851
  try {
15180
- const absolutePath = path16__default.resolve(dirPath);
15852
+ const absolutePath = path17__default.resolve(dirPath);
15181
15853
  const entries = [];
15182
15854
  async function listDir(dir, prefix = "") {
15183
- const items = await fs15__default.readdir(dir, { withFileTypes: true });
15855
+ const items = await fs16__default.readdir(dir, { withFileTypes: true });
15184
15856
  for (const item of items) {
15185
- const fullPath = path16__default.join(dir, item.name);
15857
+ const fullPath = path17__default.join(dir, item.name);
15186
15858
  const relativePath = prefix ? `${prefix}/${item.name}` : item.name;
15187
15859
  if (item.isDirectory()) {
15188
15860
  entries.push({ name: relativePath, type: "directory" });
@@ -15190,7 +15862,7 @@ Examples:
15190
15862
  await listDir(fullPath, relativePath);
15191
15863
  }
15192
15864
  } else if (item.isFile()) {
15193
- const stats = await fs15__default.stat(fullPath);
15865
+ const stats = await fs16__default.stat(fullPath);
15194
15866
  entries.push({ name: relativePath, type: "file", size: stats.size });
15195
15867
  }
15196
15868
  }
@@ -15237,23 +15909,23 @@ Examples:
15237
15909
  }
15238
15910
  validatePath(filePath, "delete");
15239
15911
  try {
15240
- const absolutePath = path16__default.resolve(filePath);
15241
- const stats = await fs15__default.stat(absolutePath);
15912
+ const absolutePath = path17__default.resolve(filePath);
15913
+ const stats = await fs16__default.stat(absolutePath);
15242
15914
  if (stats.isDirectory()) {
15243
15915
  if (!recursive) {
15244
15916
  throw new ToolError("Cannot delete directory without recursive: true", {
15245
15917
  tool: "delete_file"
15246
15918
  });
15247
15919
  }
15248
- await fs15__default.rm(absolutePath, { recursive: true });
15920
+ await fs16__default.rm(absolutePath, { recursive: true });
15249
15921
  } else {
15250
- await fs15__default.unlink(absolutePath);
15922
+ await fs16__default.unlink(absolutePath);
15251
15923
  }
15252
15924
  return { deleted: true, path: absolutePath };
15253
15925
  } catch (error) {
15254
15926
  if (error instanceof ToolError) throw error;
15255
15927
  if (error.code === "ENOENT") {
15256
- return { deleted: false, path: path16__default.resolve(filePath) };
15928
+ return { deleted: false, path: path17__default.resolve(filePath) };
15257
15929
  }
15258
15930
  throw new FileSystemError(`Failed to delete: ${filePath}`, {
15259
15931
  path: filePath,
@@ -15281,11 +15953,11 @@ Examples:
15281
15953
  validatePath(source, "read");
15282
15954
  validatePath(destination, "write");
15283
15955
  try {
15284
- const srcPath = path16__default.resolve(source);
15285
- const destPath = path16__default.resolve(destination);
15956
+ const srcPath = path17__default.resolve(source);
15957
+ const destPath = path17__default.resolve(destination);
15286
15958
  if (!overwrite) {
15287
15959
  try {
15288
- await fs15__default.access(destPath);
15960
+ await fs16__default.access(destPath);
15289
15961
  throw new ToolError(
15290
15962
  `Destination already exists: ${destination}. Use overwrite: true to replace.`,
15291
15963
  {
@@ -15298,9 +15970,9 @@ Examples:
15298
15970
  }
15299
15971
  }
15300
15972
  }
15301
- await fs15__default.mkdir(path16__default.dirname(destPath), { recursive: true });
15302
- await fs15__default.copyFile(srcPath, destPath);
15303
- const stats = await fs15__default.stat(destPath);
15973
+ await fs16__default.mkdir(path17__default.dirname(destPath), { recursive: true });
15974
+ await fs16__default.copyFile(srcPath, destPath);
15975
+ const stats = await fs16__default.stat(destPath);
15304
15976
  return {
15305
15977
  source: srcPath,
15306
15978
  destination: destPath,
@@ -15342,11 +16014,11 @@ Examples:
15342
16014
  validatePath(source, "delete");
15343
16015
  validatePath(destination, "write");
15344
16016
  try {
15345
- const srcPath = path16__default.resolve(source);
15346
- const destPath = path16__default.resolve(destination);
16017
+ const srcPath = path17__default.resolve(source);
16018
+ const destPath = path17__default.resolve(destination);
15347
16019
  if (!overwrite) {
15348
16020
  try {
15349
- await fs15__default.access(destPath);
16021
+ await fs16__default.access(destPath);
15350
16022
  throw new ToolError(
15351
16023
  `Destination already exists: ${destination}. Use overwrite: true to replace.`,
15352
16024
  {
@@ -15359,8 +16031,8 @@ Examples:
15359
16031
  }
15360
16032
  }
15361
16033
  }
15362
- await fs15__default.mkdir(path16__default.dirname(destPath), { recursive: true });
15363
- await fs15__default.rename(srcPath, destPath);
16034
+ await fs16__default.mkdir(path17__default.dirname(destPath), { recursive: true });
16035
+ await fs16__default.rename(srcPath, destPath);
15364
16036
  return {
15365
16037
  source: srcPath,
15366
16038
  destination: destPath
@@ -15402,13 +16074,13 @@ Examples:
15402
16074
  }),
15403
16075
  async execute({ path: dirPath, depth, showHidden, dirsOnly }) {
15404
16076
  try {
15405
- const absolutePath = path16__default.resolve(dirPath ?? ".");
16077
+ const absolutePath = path17__default.resolve(dirPath ?? ".");
15406
16078
  let totalFiles = 0;
15407
16079
  let totalDirs = 0;
15408
- const lines = [path16__default.basename(absolutePath) + "/"];
16080
+ const lines = [path17__default.basename(absolutePath) + "/"];
15409
16081
  async function buildTree(dir, prefix, currentDepth) {
15410
16082
  if (currentDepth > (depth ?? 4)) return;
15411
- let items = await fs15__default.readdir(dir, { withFileTypes: true });
16083
+ let items = await fs16__default.readdir(dir, { withFileTypes: true });
15412
16084
  if (!showHidden) {
15413
16085
  items = items.filter((item) => !item.name.startsWith("."));
15414
16086
  }
@@ -15428,7 +16100,7 @@ Examples:
15428
16100
  if (item.isDirectory()) {
15429
16101
  totalDirs++;
15430
16102
  lines.push(`${prefix}${connector}${item.name}/`);
15431
- await buildTree(path16__default.join(dir, item.name), prefix + childPrefix, currentDepth + 1);
16103
+ await buildTree(path17__default.join(dir, item.name), prefix + childPrefix, currentDepth + 1);
15432
16104
  } else {
15433
16105
  totalFiles++;
15434
16106
  lines.push(`${prefix}${connector}${item.name}`);
@@ -16469,8 +17141,8 @@ var checkAgentCapabilityTool = defineTool({
16469
17141
  var simpleAgentTools = [spawnSimpleAgentTool, checkAgentCapabilityTool];
16470
17142
  async function detectTestFramework2(cwd) {
16471
17143
  try {
16472
- const pkgPath = path16__default.join(cwd, "package.json");
16473
- const pkgContent = await fs15__default.readFile(pkgPath, "utf-8");
17144
+ const pkgPath = path17__default.join(cwd, "package.json");
17145
+ const pkgContent = await fs16__default.readFile(pkgPath, "utf-8");
16474
17146
  const pkg = JSON.parse(pkgContent);
16475
17147
  const deps = {
16476
17148
  ...pkg.dependencies,
@@ -16651,13 +17323,13 @@ Examples:
16651
17323
  const projectDir = cwd ?? process.cwd();
16652
17324
  try {
16653
17325
  const coverageLocations = [
16654
- path16__default.join(projectDir, "coverage", "coverage-summary.json"),
16655
- path16__default.join(projectDir, "coverage", "coverage-final.json"),
16656
- path16__default.join(projectDir, ".nyc_output", "coverage-summary.json")
17326
+ path17__default.join(projectDir, "coverage", "coverage-summary.json"),
17327
+ path17__default.join(projectDir, "coverage", "coverage-final.json"),
17328
+ path17__default.join(projectDir, ".nyc_output", "coverage-summary.json")
16657
17329
  ];
16658
17330
  for (const location of coverageLocations) {
16659
17331
  try {
16660
- const content = await fs15__default.readFile(location, "utf-8");
17332
+ const content = await fs16__default.readFile(location, "utf-8");
16661
17333
  const coverage = JSON.parse(content);
16662
17334
  if (coverage.total) {
16663
17335
  return {
@@ -16710,8 +17382,8 @@ Examples:
16710
17382
  var testTools = [runTestsTool, getCoverageTool, runTestFileTool];
16711
17383
  async function detectLinter2(cwd) {
16712
17384
  try {
16713
- const pkgPath = path16__default.join(cwd, "package.json");
16714
- const pkgContent = await fs15__default.readFile(pkgPath, "utf-8");
17385
+ const pkgPath = path17__default.join(cwd, "package.json");
17386
+ const pkgContent = await fs16__default.readFile(pkgPath, "utf-8");
16715
17387
  const pkg = JSON.parse(pkgContent);
16716
17388
  const deps = {
16717
17389
  ...pkg.dependencies,
@@ -16869,7 +17541,7 @@ Examples:
16869
17541
  let totalFunctions = 0;
16870
17542
  let complexFunctions = 0;
16871
17543
  for (const file of targetFiles) {
16872
- const content = await fs15__default.readFile(file, "utf-8");
17544
+ const content = await fs16__default.readFile(file, "utf-8");
16873
17545
  const fileComplexity = analyzeFileComplexity(content, file);
16874
17546
  fileResults.push(fileComplexity);
16875
17547
  totalComplexity += fileComplexity.complexity;
@@ -17020,7 +17692,7 @@ Examples:
17020
17692
  caseSensitive,
17021
17693
  wholeWord
17022
17694
  }) {
17023
- const targetPath = searchPath ? path16__default.resolve(searchPath) : process.cwd();
17695
+ const targetPath = searchPath ? path17__default.resolve(searchPath) : process.cwd();
17024
17696
  const matches = [];
17025
17697
  let filesSearched = 0;
17026
17698
  const filesWithMatches = /* @__PURE__ */ new Set();
@@ -17042,7 +17714,7 @@ Examples:
17042
17714
  tool: "grep"
17043
17715
  });
17044
17716
  }
17045
- const stats = await fs15__default.stat(targetPath);
17717
+ const stats = await fs16__default.stat(targetPath);
17046
17718
  let filesToSearch;
17047
17719
  if (stats.isFile()) {
17048
17720
  filesToSearch = [targetPath];
@@ -17064,7 +17736,7 @@ Examples:
17064
17736
  }
17065
17737
  filesSearched++;
17066
17738
  try {
17067
- const content = await fs15__default.readFile(file, "utf-8");
17739
+ const content = await fs16__default.readFile(file, "utf-8");
17068
17740
  const lines = content.split("\n");
17069
17741
  let fileHasMatch = false;
17070
17742
  for (let i = 0; i < lines.length; i++) {
@@ -17087,7 +17759,7 @@ Examples:
17087
17759
  contextAfter.push(lines[j] ?? "");
17088
17760
  }
17089
17761
  matches.push({
17090
- file: path16__default.relative(process.cwd(), file),
17762
+ file: path17__default.relative(process.cwd(), file),
17091
17763
  line: i + 1,
17092
17764
  column: match.index + 1,
17093
17765
  content: line,
@@ -17138,8 +17810,8 @@ Examples:
17138
17810
  }),
17139
17811
  async execute({ file, pattern, caseSensitive }) {
17140
17812
  try {
17141
- const absolutePath = path16__default.resolve(file);
17142
- const content = await fs15__default.readFile(absolutePath, "utf-8");
17813
+ const absolutePath = path17__default.resolve(file);
17814
+ const content = await fs16__default.readFile(absolutePath, "utf-8");
17143
17815
  const lines = content.split("\n");
17144
17816
  const matches = [];
17145
17817
  const flags = caseSensitive ? "" : "i";
@@ -17336,7 +18008,7 @@ async function detectPackageManager(cwd) {
17336
18008
  ];
17337
18009
  for (const { file, pm } of lockfiles) {
17338
18010
  try {
17339
- await fs15__default.access(path16__default.join(cwd, file));
18011
+ await fs16__default.access(path17__default.join(cwd, file));
17340
18012
  return pm;
17341
18013
  } catch {
17342
18014
  }
@@ -17609,7 +18281,7 @@ ${message}
17609
18281
  });
17610
18282
  try {
17611
18283
  try {
17612
- await fs15__default.access(path16__default.join(projectDir, "Makefile"));
18284
+ await fs16__default.access(path17__default.join(projectDir, "Makefile"));
17613
18285
  } catch {
17614
18286
  throw new ToolError("No Makefile found in directory", { tool: "make" });
17615
18287
  }
@@ -17814,7 +18486,7 @@ z.object({
17814
18486
  });
17815
18487
 
17816
18488
  // src/cli/repl/session.ts
17817
- path16__default.dirname(CONFIG_PATHS.trustedTools);
18489
+ path17__default.dirname(CONFIG_PATHS.trustedTools);
17818
18490
  CONFIG_PATHS.trustedTools;
17819
18491
 
17820
18492
  // src/cli/repl/recommended-permissions.ts
@@ -19349,15 +20021,15 @@ Examples:
19349
20021
  var diffTools = [showDiffTool];
19350
20022
  async function fileExists(filePath) {
19351
20023
  try {
19352
- await fs15__default.access(filePath);
20024
+ await fs16__default.access(filePath);
19353
20025
  return true;
19354
20026
  } catch {
19355
20027
  return false;
19356
20028
  }
19357
20029
  }
19358
- async function fileExists2(path39) {
20030
+ async function fileExists2(path40) {
19359
20031
  try {
19360
- await access(path39);
20032
+ await access(path40);
19361
20033
  return true;
19362
20034
  } catch {
19363
20035
  return false;
@@ -19447,7 +20119,7 @@ async function detectMaturity(cwd) {
19447
20119
  if (!hasLintConfig && hasPackageJson) {
19448
20120
  try {
19449
20121
  const pkgRaw = await import('fs/promises').then(
19450
- (fs37) => fs37.readFile(join(cwd, "package.json"), "utf-8")
20122
+ (fs38) => fs38.readFile(join(cwd, "package.json"), "utf-8")
19451
20123
  );
19452
20124
  const pkg = JSON.parse(pkgRaw);
19453
20125
  if (pkg.scripts?.lint || pkg.scripts?.["lint:fix"]) {
@@ -19616,7 +20288,7 @@ async function checkTestCoverage(diff, cwd) {
19616
20288
  );
19617
20289
  if (!hasTestChange) {
19618
20290
  const ext = src.path.match(/\.(ts|tsx|js|jsx)$/)?.[0] ?? ".ts";
19619
- const testExists = await fileExists(path16__default.join(cwd, `${baseName}.test${ext}`)) || await fileExists(path16__default.join(cwd, `${baseName}.spec${ext}`));
20291
+ const testExists = await fileExists(path17__default.join(cwd, `${baseName}.test${ext}`)) || await fileExists(path17__default.join(cwd, `${baseName}.spec${ext}`));
19620
20292
  if (testExists) {
19621
20293
  if (src.additions >= TEST_COVERAGE_LARGE_CHANGE_THRESHOLD) {
19622
20294
  findings.push({
@@ -19847,8 +20519,8 @@ Examples:
19847
20519
  }
19848
20520
  });
19849
20521
  var reviewTools = [reviewCodeTool];
19850
- var fs24 = await import('fs/promises');
19851
- var path26 = await import('path');
20522
+ var fs25 = await import('fs/promises');
20523
+ var path27 = await import('path');
19852
20524
  var { glob: glob14 } = await import('glob');
19853
20525
  var DEFAULT_MAX_FILES = 200;
19854
20526
  var LANGUAGE_EXTENSIONS = {
@@ -19874,7 +20546,7 @@ var DEFAULT_EXCLUDES = [
19874
20546
  "**/*.d.ts"
19875
20547
  ];
19876
20548
  function detectLanguage3(filePath) {
19877
- const ext = path26.extname(filePath).toLowerCase();
20549
+ const ext = path27.extname(filePath).toLowerCase();
19878
20550
  for (const [lang, extensions] of Object.entries(LANGUAGE_EXTENSIONS)) {
19879
20551
  if (extensions.includes(ext)) return lang;
19880
20552
  }
@@ -20283,9 +20955,9 @@ Examples:
20283
20955
  }),
20284
20956
  async execute({ path: rootPath, include, exclude, languages, maxFiles, depth }) {
20285
20957
  const startTime = performance.now();
20286
- const absPath = path26.resolve(rootPath);
20958
+ const absPath = path27.resolve(rootPath);
20287
20959
  try {
20288
- const stat2 = await fs24.stat(absPath);
20960
+ const stat2 = await fs25.stat(absPath);
20289
20961
  if (!stat2.isDirectory()) {
20290
20962
  throw new ToolError(`Path is not a directory: ${absPath}`, {
20291
20963
  tool: "codebase_map"
@@ -20322,14 +20994,14 @@ Examples:
20322
20994
  let totalDefinitions = 0;
20323
20995
  let exportedSymbols = 0;
20324
20996
  for (const file of limitedFiles) {
20325
- const fullPath = path26.join(absPath, file);
20997
+ const fullPath = path27.join(absPath, file);
20326
20998
  const language = detectLanguage3(file);
20327
20999
  if (!language) continue;
20328
21000
  if (languages && !languages.includes(language)) {
20329
21001
  continue;
20330
21002
  }
20331
21003
  try {
20332
- const content = await fs24.readFile(fullPath, "utf-8");
21004
+ const content = await fs25.readFile(fullPath, "utf-8");
20333
21005
  const lineCount = content.split("\n").length;
20334
21006
  const parsed = parseFile(content, language);
20335
21007
  const definitions = depth === "overview" ? parsed.definitions.filter((d) => d.exported) : parsed.definitions;
@@ -20362,23 +21034,23 @@ Examples:
20362
21034
  });
20363
21035
  var codebaseMapTools = [codebaseMapTool];
20364
21036
  init_paths();
20365
- var fs25 = await import('fs/promises');
20366
- var path27 = await import('path');
21037
+ var fs26 = await import('fs/promises');
21038
+ var path28 = await import('path');
20367
21039
  var crypto2 = await import('crypto');
20368
- var GLOBAL_MEMORIES_DIR = path27.join(COCO_HOME, "memories");
21040
+ var GLOBAL_MEMORIES_DIR = path28.join(COCO_HOME, "memories");
20369
21041
  var PROJECT_MEMORIES_DIR = ".coco/memories";
20370
21042
  var DEFAULT_MAX_MEMORIES = 1e3;
20371
21043
  async function ensureDir(dirPath) {
20372
- await fs25.mkdir(dirPath, { recursive: true });
21044
+ await fs26.mkdir(dirPath, { recursive: true });
20373
21045
  }
20374
21046
  function getMemoriesDir(scope) {
20375
21047
  return scope === "global" ? GLOBAL_MEMORIES_DIR : PROJECT_MEMORIES_DIR;
20376
21048
  }
20377
21049
  async function loadIndex(scope) {
20378
21050
  const dir = getMemoriesDir(scope);
20379
- const indexPath = path27.join(dir, "index.json");
21051
+ const indexPath = path28.join(dir, "index.json");
20380
21052
  try {
20381
- const content = await fs25.readFile(indexPath, "utf-8");
21053
+ const content = await fs26.readFile(indexPath, "utf-8");
20382
21054
  return JSON.parse(content);
20383
21055
  } catch {
20384
21056
  return [];
@@ -20387,14 +21059,14 @@ async function loadIndex(scope) {
20387
21059
  async function saveIndex(scope, index) {
20388
21060
  const dir = getMemoriesDir(scope);
20389
21061
  await ensureDir(dir);
20390
- const indexPath = path27.join(dir, "index.json");
20391
- await fs25.writeFile(indexPath, JSON.stringify(index, null, 2), "utf-8");
21062
+ const indexPath = path28.join(dir, "index.json");
21063
+ await fs26.writeFile(indexPath, JSON.stringify(index, null, 2), "utf-8");
20392
21064
  }
20393
21065
  async function loadMemory(scope, id) {
20394
21066
  const dir = getMemoriesDir(scope);
20395
- const memPath = path27.join(dir, `${id}.json`);
21067
+ const memPath = path28.join(dir, `${id}.json`);
20396
21068
  try {
20397
- const content = await fs25.readFile(memPath, "utf-8");
21069
+ const content = await fs26.readFile(memPath, "utf-8");
20398
21070
  return JSON.parse(content);
20399
21071
  } catch {
20400
21072
  return null;
@@ -20403,8 +21075,8 @@ async function loadMemory(scope, id) {
20403
21075
  async function saveMemory(scope, memory) {
20404
21076
  const dir = getMemoriesDir(scope);
20405
21077
  await ensureDir(dir);
20406
- const memPath = path27.join(dir, `${memory.id}.json`);
20407
- await fs25.writeFile(memPath, JSON.stringify(memory, null, 2), "utf-8");
21078
+ const memPath = path28.join(dir, `${memory.id}.json`);
21079
+ await fs26.writeFile(memPath, JSON.stringify(memory, null, 2), "utf-8");
20408
21080
  }
20409
21081
  var createMemoryTool = defineTool({
20410
21082
  name: "create_memory",
@@ -20556,17 +21228,17 @@ Examples:
20556
21228
  }
20557
21229
  });
20558
21230
  var memoryTools = [createMemoryTool, recallMemoryTool, listMemoriesTool];
20559
- var fs26 = await import('fs/promises');
21231
+ var fs27 = await import('fs/promises');
20560
21232
  var crypto3 = await import('crypto');
20561
21233
  var CHECKPOINT_FILE = ".coco/checkpoints.json";
20562
21234
  var DEFAULT_MAX_CHECKPOINTS = 50;
20563
21235
  var STASH_PREFIX = "coco-cp";
20564
21236
  async function ensureCocoDir() {
20565
- await fs26.mkdir(".coco", { recursive: true });
21237
+ await fs27.mkdir(".coco", { recursive: true });
20566
21238
  }
20567
21239
  async function loadCheckpoints() {
20568
21240
  try {
20569
- const content = await fs26.readFile(CHECKPOINT_FILE, "utf-8");
21241
+ const content = await fs27.readFile(CHECKPOINT_FILE, "utf-8");
20570
21242
  return JSON.parse(content);
20571
21243
  } catch {
20572
21244
  return [];
@@ -20574,7 +21246,7 @@ async function loadCheckpoints() {
20574
21246
  }
20575
21247
  async function saveCheckpoints(checkpoints) {
20576
21248
  await ensureCocoDir();
20577
- await fs26.writeFile(CHECKPOINT_FILE, JSON.stringify(checkpoints, null, 2), "utf-8");
21249
+ await fs27.writeFile(CHECKPOINT_FILE, JSON.stringify(checkpoints, null, 2), "utf-8");
20578
21250
  }
20579
21251
  async function execGit(args) {
20580
21252
  const { execaCommand } = await import('execa');
@@ -20736,8 +21408,8 @@ Examples:
20736
21408
  }
20737
21409
  });
20738
21410
  var checkpointTools = [createCheckpointTool, restoreCheckpointTool, listCheckpointsTool];
20739
- var fs27 = await import('fs/promises');
20740
- var path28 = await import('path');
21411
+ var fs28 = await import('fs/promises');
21412
+ var path29 = await import('path');
20741
21413
  var { glob: glob15 } = await import('glob');
20742
21414
  var INDEX_DIR = ".coco/search-index";
20743
21415
  var DEFAULT_CHUNK_SIZE = 20;
@@ -20865,20 +21537,20 @@ async function getEmbedding(text) {
20865
21537
  }
20866
21538
  async function loadIndex2(indexDir) {
20867
21539
  try {
20868
- const indexPath = path28.join(indexDir, "index.json");
20869
- const content = await fs27.readFile(indexPath, "utf-8");
21540
+ const indexPath = path29.join(indexDir, "index.json");
21541
+ const content = await fs28.readFile(indexPath, "utf-8");
20870
21542
  return JSON.parse(content);
20871
21543
  } catch {
20872
21544
  return null;
20873
21545
  }
20874
21546
  }
20875
21547
  async function saveIndex2(indexDir, index) {
20876
- await fs27.mkdir(indexDir, { recursive: true });
20877
- const indexPath = path28.join(indexDir, "index.json");
20878
- await fs27.writeFile(indexPath, JSON.stringify(index), "utf-8");
21548
+ await fs28.mkdir(indexDir, { recursive: true });
21549
+ const indexPath = path29.join(indexDir, "index.json");
21550
+ await fs28.writeFile(indexPath, JSON.stringify(index), "utf-8");
20879
21551
  }
20880
21552
  function isBinary(filePath) {
20881
- return BINARY_EXTENSIONS.has(path28.extname(filePath).toLowerCase());
21553
+ return BINARY_EXTENSIONS.has(path29.extname(filePath).toLowerCase());
20882
21554
  }
20883
21555
  var semanticSearchTool = defineTool({
20884
21556
  name: "semantic_search",
@@ -20903,8 +21575,8 @@ Examples:
20903
21575
  const effectivePath = rootPath ?? ".";
20904
21576
  const effectiveMaxResults = maxResults ?? 10;
20905
21577
  const effectiveThreshold = threshold ?? 0.3;
20906
- const absPath = path28.resolve(effectivePath);
20907
- const indexDir = path28.join(absPath, INDEX_DIR);
21578
+ const absPath = path29.resolve(effectivePath);
21579
+ const indexDir = path29.join(absPath, INDEX_DIR);
20908
21580
  let index = reindex ? null : await loadIndex2(indexDir);
20909
21581
  let warnings = [];
20910
21582
  if (!index) {
@@ -20920,10 +21592,10 @@ Examples:
20920
21592
  let indexSaveWarning = "";
20921
21593
  for (const file of files) {
20922
21594
  if (isBinary(file)) continue;
20923
- const fullPath = path28.join(absPath, file);
21595
+ const fullPath = path29.join(absPath, file);
20924
21596
  try {
20925
- const stat2 = await fs27.stat(fullPath);
20926
- const content = await fs27.readFile(fullPath, "utf-8");
21597
+ const stat2 = await fs28.stat(fullPath);
21598
+ const content = await fs28.readFile(fullPath, "utf-8");
20927
21599
  if (content.length > 1e5) continue;
20928
21600
  const fileChunks = chunkContent(content, DEFAULT_CHUNK_SIZE);
20929
21601
  for (const chunk of fileChunks) {
@@ -20999,8 +21671,8 @@ Examples:
20999
21671
  }
21000
21672
  });
21001
21673
  var semanticSearchTools = [semanticSearchTool];
21002
- var fs28 = await import('fs/promises');
21003
- var path29 = await import('path');
21674
+ var fs29 = await import('fs/promises');
21675
+ var path30 = await import('path');
21004
21676
  var { glob: glob16 } = await import('glob');
21005
21677
  async function parseClassRelationships(rootPath, include) {
21006
21678
  const pattern = include ?? "**/*.{ts,tsx,js,jsx}";
@@ -21013,7 +21685,7 @@ async function parseClassRelationships(rootPath, include) {
21013
21685
  const interfaces = [];
21014
21686
  for (const file of files.slice(0, 100)) {
21015
21687
  try {
21016
- const content = await fs28.readFile(path29.join(rootPath, file), "utf-8");
21688
+ const content = await fs29.readFile(path30.join(rootPath, file), "utf-8");
21017
21689
  const lines = content.split("\n");
21018
21690
  for (let i = 0; i < lines.length; i++) {
21019
21691
  const line = lines[i];
@@ -21132,14 +21804,14 @@ async function generateClassDiagram(rootPath, include) {
21132
21804
  };
21133
21805
  }
21134
21806
  async function generateArchitectureDiagram(rootPath) {
21135
- const entries = await fs28.readdir(rootPath, { withFileTypes: true });
21807
+ const entries = await fs29.readdir(rootPath, { withFileTypes: true });
21136
21808
  const dirs = entries.filter(
21137
21809
  (e) => e.isDirectory() && !e.name.startsWith(".") && !["node_modules", "dist", "build", "coverage", "__pycache__", "target"].includes(e.name)
21138
21810
  );
21139
21811
  const lines = ["graph TD"];
21140
21812
  let nodeCount = 0;
21141
21813
  let edgeCount = 0;
21142
- const rootName = path29.basename(rootPath);
21814
+ const rootName = path30.basename(rootPath);
21143
21815
  lines.push(` ROOT["${rootName}"]`);
21144
21816
  nodeCount++;
21145
21817
  for (const dir of dirs) {
@@ -21149,7 +21821,7 @@ async function generateArchitectureDiagram(rootPath) {
21149
21821
  nodeCount++;
21150
21822
  edgeCount++;
21151
21823
  try {
21152
- const subEntries = await fs28.readdir(path29.join(rootPath, dir.name), {
21824
+ const subEntries = await fs29.readdir(path30.join(rootPath, dir.name), {
21153
21825
  withFileTypes: true
21154
21826
  });
21155
21827
  const subDirs = subEntries.filter(
@@ -21272,7 +21944,7 @@ Examples:
21272
21944
  tool: "generate_diagram"
21273
21945
  });
21274
21946
  }
21275
- const absPath = rootPath ? path29.resolve(rootPath) : process.cwd();
21947
+ const absPath = rootPath ? path30.resolve(rootPath) : process.cwd();
21276
21948
  switch (type) {
21277
21949
  case "class":
21278
21950
  return generateClassDiagram(absPath, include);
@@ -21333,8 +22005,8 @@ Examples:
21333
22005
  }
21334
22006
  });
21335
22007
  var diagramTools = [generateDiagramTool];
21336
- var fs29 = await import('fs/promises');
21337
- var path30 = await import('path');
22008
+ var fs30 = await import('fs/promises');
22009
+ var path31 = await import('path');
21338
22010
  var DEFAULT_MAX_PAGES = 20;
21339
22011
  var MAX_FILE_SIZE = 50 * 1024 * 1024;
21340
22012
  function parsePageRange(rangeStr, totalPages) {
@@ -21369,9 +22041,9 @@ Examples:
21369
22041
  }),
21370
22042
  async execute({ path: filePath, pages, maxPages }) {
21371
22043
  const startTime = performance.now();
21372
- const absPath = path30.resolve(filePath);
22044
+ const absPath = path31.resolve(filePath);
21373
22045
  try {
21374
- const stat2 = await fs29.stat(absPath);
22046
+ const stat2 = await fs30.stat(absPath);
21375
22047
  if (!stat2.isFile()) {
21376
22048
  throw new ToolError(`Path is not a file: ${absPath}`, {
21377
22049
  tool: "read_pdf"
@@ -21402,7 +22074,7 @@ Examples:
21402
22074
  }
21403
22075
  try {
21404
22076
  const pdfParse = await import('pdf-parse');
21405
- const dataBuffer = await fs29.readFile(absPath);
22077
+ const dataBuffer = await fs30.readFile(absPath);
21406
22078
  const pdfData = await pdfParse.default(dataBuffer, {
21407
22079
  max: maxPages
21408
22080
  });
@@ -21449,8 +22121,8 @@ Examples:
21449
22121
  }
21450
22122
  });
21451
22123
  var pdfTools = [readPdfTool];
21452
- var fs30 = await import('fs/promises');
21453
- var path31 = await import('path');
22124
+ var fs31 = await import('fs/promises');
22125
+ var path32 = await import('path');
21454
22126
  var SUPPORTED_FORMATS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".webp", ".bmp"]);
21455
22127
  var MAX_IMAGE_SIZE = 20 * 1024 * 1024;
21456
22128
  var MIME_TYPES = {
@@ -21478,15 +22150,15 @@ Examples:
21478
22150
  async execute({ path: filePath, prompt, provider }) {
21479
22151
  const startTime = performance.now();
21480
22152
  const effectivePrompt = prompt ?? "Describe this image in detail. If it's code or a UI, identify the key elements.";
21481
- const absPath = path31.resolve(filePath);
22153
+ const absPath = path32.resolve(filePath);
21482
22154
  const cwd = process.cwd();
21483
- if (!absPath.startsWith(cwd + path31.sep) && absPath !== cwd) {
22155
+ if (!absPath.startsWith(cwd + path32.sep) && absPath !== cwd) {
21484
22156
  throw new ToolError(
21485
22157
  `Path traversal denied: '${filePath}' resolves outside the project directory`,
21486
22158
  { tool: "read_image" }
21487
22159
  );
21488
22160
  }
21489
- const ext = path31.extname(absPath).toLowerCase();
22161
+ const ext = path32.extname(absPath).toLowerCase();
21490
22162
  if (!SUPPORTED_FORMATS.has(ext)) {
21491
22163
  throw new ToolError(
21492
22164
  `Unsupported image format '${ext}'. Supported: ${Array.from(SUPPORTED_FORMATS).join(", ")}`,
@@ -21494,7 +22166,7 @@ Examples:
21494
22166
  );
21495
22167
  }
21496
22168
  try {
21497
- const stat2 = await fs30.stat(absPath);
22169
+ const stat2 = await fs31.stat(absPath);
21498
22170
  if (!stat2.isFile()) {
21499
22171
  throw new ToolError(`Path is not a file: ${absPath}`, {
21500
22172
  tool: "read_image"
@@ -21515,7 +22187,7 @@ Examples:
21515
22187
  if (error instanceof ToolError) throw error;
21516
22188
  throw error;
21517
22189
  }
21518
- const imageBuffer = await fs30.readFile(absPath);
22190
+ const imageBuffer = await fs31.readFile(absPath);
21519
22191
  const base64 = imageBuffer.toString("base64");
21520
22192
  const mimeType = MIME_TYPES[ext] ?? "image/png";
21521
22193
  const selectedProvider = provider ?? "anthropic";
@@ -21552,8 +22224,8 @@ Examples:
21552
22224
  description = response.content.filter((block) => block.type === "text").map((block) => block.text).join("\n") || "No description generated";
21553
22225
  } else if (selectedProvider === "openai") {
21554
22226
  model = "gpt-4o";
21555
- const { default: OpenAI2 } = await import('openai');
21556
- const client = new OpenAI2();
22227
+ const { default: OpenAI3 } = await import('openai');
22228
+ const client = new OpenAI3();
21557
22229
  const openaiMessages = [
21558
22230
  {
21559
22231
  role: "user",
@@ -21633,7 +22305,7 @@ Examples:
21633
22305
  }
21634
22306
  });
21635
22307
  var imageTools = [readImageTool];
21636
- var path32 = await import('path');
22308
+ var path33 = await import('path');
21637
22309
  var DANGEROUS_PATTERNS = [
21638
22310
  /\bDROP\s+(?:TABLE|DATABASE|INDEX|VIEW)\b/i,
21639
22311
  /\bTRUNCATE\b/i,
@@ -21664,7 +22336,7 @@ Examples:
21664
22336
  async execute({ database, query, params, readonly: isReadonlyParam }) {
21665
22337
  const isReadonly = isReadonlyParam ?? true;
21666
22338
  const startTime = performance.now();
21667
- const absPath = path32.resolve(database);
22339
+ const absPath = path33.resolve(database);
21668
22340
  if (isReadonly && isDangerousSql(query)) {
21669
22341
  throw new ToolError(
21670
22342
  "Write operations (INSERT, UPDATE, DELETE, DROP, ALTER, TRUNCATE, CREATE) are blocked in readonly mode. Set readonly: false to allow writes.",
@@ -21747,7 +22419,7 @@ Examples:
21747
22419
  }),
21748
22420
  async execute({ database, table }) {
21749
22421
  const startTime = performance.now();
21750
- const absPath = path32.resolve(database);
22422
+ const absPath = path33.resolve(database);
21751
22423
  try {
21752
22424
  const { default: Database } = await import('better-sqlite3');
21753
22425
  const db = new Database(absPath, { readonly: true, fileMustExist: true });
@@ -21806,14 +22478,14 @@ Examples:
21806
22478
  }
21807
22479
  });
21808
22480
  var databaseTools = [sqlQueryTool, inspectSchemaTool];
21809
- var fs31 = await import('fs/promises');
21810
- var path33 = await import('path');
22481
+ var fs32 = await import('fs/promises');
22482
+ var path34 = await import('path');
21811
22483
  var AnalyzeFileSchema = z.object({
21812
22484
  filePath: z.string().describe("Path to file to analyze"),
21813
22485
  includeAst: z.boolean().default(false).describe("Include AST in result")
21814
22486
  });
21815
22487
  async function analyzeFile(filePath, includeAst = false) {
21816
- const content = await fs31.readFile(filePath, "utf-8");
22488
+ const content = await fs32.readFile(filePath, "utf-8");
21817
22489
  const lines = content.split("\n").length;
21818
22490
  const functions = [];
21819
22491
  const classes = [];
@@ -21917,10 +22589,10 @@ async function analyzeDirectory(dirPath) {
21917
22589
  try {
21918
22590
  const analysis = await analyzeFile(file, false);
21919
22591
  totalLines += analysis.lines;
21920
- const ext = path33.extname(file);
22592
+ const ext = path34.extname(file);
21921
22593
  filesByType[ext] = (filesByType[ext] || 0) + 1;
21922
22594
  fileStats.push({
21923
- file: path33.relative(dirPath, file),
22595
+ file: path34.relative(dirPath, file),
21924
22596
  lines: analysis.lines,
21925
22597
  complexity: analysis.complexity.cyclomatic
21926
22598
  });
@@ -22285,13 +22957,13 @@ ${completed.map((r) => `- ${r.agentId}: Success`).join("\n")}`;
22285
22957
  }
22286
22958
  });
22287
22959
  var agentCoordinatorTools = [createAgentPlanTool, delegateTaskTool, aggregateResultsTool];
22288
- var fs32 = await import('fs/promises');
22960
+ var fs33 = await import('fs/promises');
22289
22961
  var SuggestImprovementsSchema = z.object({
22290
22962
  filePath: z.string().describe("File to analyze for improvement suggestions"),
22291
22963
  context: z.string().optional().describe("Additional context about the code")
22292
22964
  });
22293
22965
  async function analyzeAndSuggest(filePath, _context) {
22294
- const content = await fs32.readFile(filePath, "utf-8");
22966
+ const content = await fs33.readFile(filePath, "utf-8");
22295
22967
  const lines = content.split("\n");
22296
22968
  const suggestions = [];
22297
22969
  for (let i = 0; i < lines.length; i++) {
@@ -22383,7 +23055,7 @@ async function analyzeAndSuggest(filePath, _context) {
22383
23055
  if (filePath.endsWith(".ts") && !filePath.includes("test") && !filePath.includes(".d.ts") && line.includes("export ")) {
22384
23056
  const testPath = filePath.replace(".ts", ".test.ts");
22385
23057
  try {
22386
- await fs32.access(testPath);
23058
+ await fs33.access(testPath);
22387
23059
  } catch {
22388
23060
  suggestions.push({
22389
23061
  type: "testing",
@@ -22440,7 +23112,7 @@ var calculateCodeScoreTool = defineTool({
22440
23112
  async execute(input) {
22441
23113
  const { filePath } = input;
22442
23114
  const suggestions = await analyzeAndSuggest(filePath);
22443
- const content = await fs32.readFile(filePath, "utf-8");
23115
+ const content = await fs33.readFile(filePath, "utf-8");
22444
23116
  const lines = content.split("\n");
22445
23117
  const nonEmptyLines = lines.filter((l) => l.trim()).length;
22446
23118
  let score = 100;
@@ -22474,8 +23146,8 @@ var calculateCodeScoreTool = defineTool({
22474
23146
  }
22475
23147
  });
22476
23148
  var smartSuggestionsTools = [suggestImprovementsTool, calculateCodeScoreTool];
22477
- var fs33 = await import('fs/promises');
22478
- var path34 = await import('path');
23149
+ var fs34 = await import('fs/promises');
23150
+ var path35 = await import('path');
22479
23151
  var ContextMemoryStore = class {
22480
23152
  items = /* @__PURE__ */ new Map();
22481
23153
  learnings = /* @__PURE__ */ new Map();
@@ -22487,7 +23159,7 @@ var ContextMemoryStore = class {
22487
23159
  }
22488
23160
  async load() {
22489
23161
  try {
22490
- const content = await fs33.readFile(this.storePath, "utf-8");
23162
+ const content = await fs34.readFile(this.storePath, "utf-8");
22491
23163
  const data = JSON.parse(content);
22492
23164
  this.items = new Map(Object.entries(data.items || {}));
22493
23165
  this.learnings = new Map(Object.entries(data.learnings || {}));
@@ -22495,15 +23167,15 @@ var ContextMemoryStore = class {
22495
23167
  }
22496
23168
  }
22497
23169
  async save() {
22498
- const dir = path34.dirname(this.storePath);
22499
- await fs33.mkdir(dir, { recursive: true });
23170
+ const dir = path35.dirname(this.storePath);
23171
+ await fs34.mkdir(dir, { recursive: true });
22500
23172
  const data = {
22501
23173
  sessionId: this.sessionId,
22502
23174
  items: Object.fromEntries(this.items),
22503
23175
  learnings: Object.fromEntries(this.learnings),
22504
23176
  savedAt: Date.now()
22505
23177
  };
22506
- await fs33.writeFile(this.storePath, JSON.stringify(data, null, 2));
23178
+ await fs34.writeFile(this.storePath, JSON.stringify(data, null, 2));
22507
23179
  }
22508
23180
  addContext(id, item) {
22509
23181
  this.items.set(id, item);
@@ -22668,11 +23340,11 @@ var contextEnhancerTools = [
22668
23340
  recordLearningTool,
22669
23341
  getLearnedPatternsTool
22670
23342
  ];
22671
- var fs34 = await import('fs/promises');
22672
- var path35 = await import('path');
23343
+ var fs35 = await import('fs/promises');
23344
+ var path36 = await import('path');
22673
23345
  async function discoverSkills(skillsDir) {
22674
23346
  try {
22675
- const files = await fs34.readdir(skillsDir);
23347
+ const files = await fs35.readdir(skillsDir);
22676
23348
  return files.filter((f) => f.endsWith(".ts") || f.endsWith(".js"));
22677
23349
  } catch {
22678
23350
  return [];
@@ -22680,12 +23352,12 @@ async function discoverSkills(skillsDir) {
22680
23352
  }
22681
23353
  async function loadSkillMetadata(skillPath) {
22682
23354
  try {
22683
- const content = await fs34.readFile(skillPath, "utf-8");
23355
+ const content = await fs35.readFile(skillPath, "utf-8");
22684
23356
  const nameMatch = content.match(/@name\s+(\S+)/);
22685
23357
  const descMatch = content.match(/@description\s+(.+)/);
22686
23358
  const versionMatch = content.match(/@version\s+(\S+)/);
22687
23359
  return {
22688
- name: nameMatch?.[1] || path35.basename(skillPath, path35.extname(skillPath)),
23360
+ name: nameMatch?.[1] || path36.basename(skillPath, path36.extname(skillPath)),
22689
23361
  description: descMatch?.[1] || "No description",
22690
23362
  version: versionMatch?.[1] || "1.0.0",
22691
23363
  dependencies: []
@@ -22729,7 +23401,7 @@ var discoverSkillsTool = defineTool({
22729
23401
  const { skillsDir } = input;
22730
23402
  const skills = await discoverSkills(skillsDir);
22731
23403
  const metadata = await Promise.all(
22732
- skills.map((s) => loadSkillMetadata(path35.join(skillsDir, s)))
23404
+ skills.map((s) => loadSkillMetadata(path36.join(skillsDir, s)))
22733
23405
  );
22734
23406
  return {
22735
23407
  skillsDir,
@@ -23230,8 +23902,8 @@ function hasNullByte2(str) {
23230
23902
  }
23231
23903
  function isBlockedPath(absolute) {
23232
23904
  for (const blocked of BLOCKED_PATHS2) {
23233
- const normalizedBlocked = path16__default.normalize(blocked);
23234
- if (absolute === normalizedBlocked || absolute.startsWith(normalizedBlocked + path16__default.sep)) {
23905
+ const normalizedBlocked = path17__default.normalize(blocked);
23906
+ if (absolute === normalizedBlocked || absolute.startsWith(normalizedBlocked + path17__default.sep)) {
23235
23907
  return blocked;
23236
23908
  }
23237
23909
  }
@@ -23249,7 +23921,7 @@ function getInterpreter(ext) {
23249
23921
  }
23250
23922
  async function isExecutable(filePath) {
23251
23923
  try {
23252
- await fs15__default.access(filePath, fs15__default.constants.X_OK);
23924
+ await fs16__default.access(filePath, fs16__default.constants.X_OK);
23253
23925
  return true;
23254
23926
  } catch {
23255
23927
  return false;
@@ -23289,7 +23961,7 @@ Examples:
23289
23961
  throw new ToolError("Invalid file path", { tool: "open_file" });
23290
23962
  }
23291
23963
  const workDir = cwd ?? process.cwd();
23292
- const absolute = path16__default.isAbsolute(filePath) ? path16__default.normalize(filePath) : path16__default.resolve(workDir, filePath);
23964
+ const absolute = path17__default.isAbsolute(filePath) ? path17__default.normalize(filePath) : path17__default.resolve(workDir, filePath);
23293
23965
  const blockedBy = isBlockedPath(absolute);
23294
23966
  if (blockedBy) {
23295
23967
  throw new ToolError(`Access to system path '${blockedBy}' is not allowed`, {
@@ -23297,7 +23969,7 @@ Examples:
23297
23969
  });
23298
23970
  }
23299
23971
  try {
23300
- await fs15__default.access(absolute);
23972
+ await fs16__default.access(absolute);
23301
23973
  } catch {
23302
23974
  throw new ToolError(`File not found: ${absolute}`, { tool: "open_file" });
23303
23975
  }
@@ -23312,14 +23984,14 @@ Examples:
23312
23984
  };
23313
23985
  }
23314
23986
  if (isBlockedExecFile(absolute)) {
23315
- throw new ToolError(`Execution of sensitive file is blocked: ${path16__default.basename(absolute)}`, {
23987
+ throw new ToolError(`Execution of sensitive file is blocked: ${path17__default.basename(absolute)}`, {
23316
23988
  tool: "open_file"
23317
23989
  });
23318
23990
  }
23319
23991
  if (args.length > 0 && hasDangerousArgs(args)) {
23320
23992
  throw new ToolError("Arguments contain dangerous patterns", { tool: "open_file" });
23321
23993
  }
23322
- const ext = path16__default.extname(absolute);
23994
+ const ext = path17__default.extname(absolute);
23323
23995
  const interpreter = getInterpreter(ext);
23324
23996
  const executable = await isExecutable(absolute);
23325
23997
  let command;
@@ -23332,7 +24004,7 @@ Examples:
23332
24004
  cmdArgs = [...args];
23333
24005
  } else {
23334
24006
  throw new ToolError(
23335
- `Cannot execute '${path16__default.basename(absolute)}': no known interpreter for '${ext || "(no extension)"}' and file is not executable`,
24007
+ `Cannot execute '${path17__default.basename(absolute)}': no known interpreter for '${ext || "(no extension)"}' and file is not executable`,
23336
24008
  { tool: "open_file" }
23337
24009
  );
23338
24010
  }
@@ -23384,7 +24056,7 @@ Examples:
23384
24056
  reason: z.string().optional().describe("Why access is needed (shown to user for context)")
23385
24057
  }),
23386
24058
  async execute({ path: dirPath, reason }) {
23387
- const absolute = path16__default.resolve(dirPath);
24059
+ const absolute = path17__default.resolve(dirPath);
23388
24060
  if (isWithinAllowedPath(absolute, "read")) {
23389
24061
  return {
23390
24062
  authorized: true,
@@ -23393,8 +24065,8 @@ Examples:
23393
24065
  };
23394
24066
  }
23395
24067
  for (const blocked of BLOCKED_SYSTEM_PATHS) {
23396
- const normalizedBlocked = path16__default.normalize(blocked);
23397
- if (absolute === normalizedBlocked || absolute.startsWith(normalizedBlocked + path16__default.sep)) {
24068
+ const normalizedBlocked = path17__default.normalize(blocked);
24069
+ if (absolute === normalizedBlocked || absolute.startsWith(normalizedBlocked + path17__default.sep)) {
23398
24070
  return {
23399
24071
  authorized: false,
23400
24072
  path: absolute,
@@ -23403,7 +24075,7 @@ Examples:
23403
24075
  }
23404
24076
  }
23405
24077
  const cwd = process.cwd();
23406
- if (absolute === path16__default.normalize(cwd) || absolute.startsWith(path16__default.normalize(cwd) + path16__default.sep)) {
24078
+ if (absolute === path17__default.normalize(cwd) || absolute.startsWith(path17__default.normalize(cwd) + path17__default.sep)) {
23407
24079
  return {
23408
24080
  authorized: true,
23409
24081
  path: absolute,
@@ -23411,7 +24083,7 @@ Examples:
23411
24083
  };
23412
24084
  }
23413
24085
  try {
23414
- const stat2 = await fs15__default.stat(absolute);
24086
+ const stat2 = await fs16__default.stat(absolute);
23415
24087
  if (!stat2.isDirectory()) {
23416
24088
  return {
23417
24089
  authorized: false,
@@ -23427,7 +24099,7 @@ Examples:
23427
24099
  };
23428
24100
  }
23429
24101
  const existing = getAllowedPaths();
23430
- if (existing.some((e) => path16__default.normalize(e.path) === path16__default.normalize(absolute))) {
24102
+ if (existing.some((e) => path17__default.normalize(e.path) === path17__default.normalize(absolute))) {
23431
24103
  return {
23432
24104
  authorized: true,
23433
24105
  path: absolute,