@corbat-tech/coco 2.25.0 → 2.25.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import * as fs5 from 'fs';
3
3
  import fs5__default, { accessSync, readFileSync, constants } from 'fs';
4
- import * as path37 from 'path';
5
- import path37__default, { join, dirname, resolve, basename } from 'path';
4
+ import * as path38 from 'path';
5
+ import path38__default, { join, dirname, resolve, basename } from 'path';
6
6
  import { URL as URL$1, fileURLToPath } from 'url';
7
7
  import { z } from 'zod';
8
8
  import * as os4 from 'os';
9
9
  import os4__default, { homedir } from 'os';
10
- import * as fs34 from 'fs/promises';
11
- import fs34__default, { mkdir, writeFile, readFile, access, readdir, rm } from 'fs/promises';
10
+ import * as fs35 from 'fs/promises';
11
+ import fs35__default, { mkdir, writeFile, readFile, access, readdir, rm } from 'fs/promises';
12
12
  import JSON5 from 'json5';
13
13
  import * as crypto from 'crypto';
14
- import { randomUUID } from 'crypto';
14
+ import { randomUUID, randomBytes, createHash } from 'crypto';
15
15
  import * as http from 'http';
16
16
  import * as p26 from '@clack/prompts';
17
17
  import chalk from 'chalk';
@@ -556,7 +556,7 @@ async function loadConfig(configPath) {
556
556
  async function loadConfigFile(configPath, options = {}) {
557
557
  const { strict = true } = options;
558
558
  try {
559
- const content = await fs34__default.readFile(configPath, "utf-8");
559
+ const content = await fs35__default.readFile(configPath, "utf-8");
560
560
  const parsed = JSON5.parse(content);
561
561
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
562
562
  if (!strict) {
@@ -612,7 +612,7 @@ function deepMergeConfig(base, override) {
612
612
  };
613
613
  }
614
614
  function getProjectConfigPath() {
615
- return path37__default.join(process.cwd(), ".coco", "config.json");
615
+ return path38__default.join(process.cwd(), ".coco", "config.json");
616
616
  }
617
617
  async function saveConfig(config, configPath, global = false) {
618
618
  const result = CocoConfigSchema.safeParse(config);
@@ -627,10 +627,10 @@ async function saveConfig(config, configPath, global = false) {
627
627
  });
628
628
  }
629
629
  const resolvedPath = configPath || (global ? CONFIG_PATHS.config : getProjectConfigPath());
630
- const dir = path37__default.dirname(resolvedPath);
631
- await fs34__default.mkdir(dir, { recursive: true });
630
+ const dir = path38__default.dirname(resolvedPath);
631
+ await fs35__default.mkdir(dir, { recursive: true });
632
632
  const content = JSON.stringify(result.data, null, 2);
633
- await fs34__default.writeFile(resolvedPath, content, "utf-8");
633
+ await fs35__default.writeFile(resolvedPath, content, "utf-8");
634
634
  }
635
635
  function createDefaultConfig(projectName, language = "typescript") {
636
636
  return createDefaultConfigObject(projectName, language);
@@ -639,20 +639,20 @@ async function findConfigPath(cwd) {
639
639
  const envPath = process.env["COCO_CONFIG_PATH"];
640
640
  if (envPath) {
641
641
  try {
642
- await fs34__default.access(envPath);
642
+ await fs35__default.access(envPath);
643
643
  return envPath;
644
644
  } catch {
645
645
  }
646
646
  }
647
647
  const basePath = cwd || process.cwd();
648
- const projectConfigPath = path37__default.join(basePath, ".coco", "config.json");
648
+ const projectConfigPath = path38__default.join(basePath, ".coco", "config.json");
649
649
  try {
650
- await fs34__default.access(projectConfigPath);
650
+ await fs35__default.access(projectConfigPath);
651
651
  return projectConfigPath;
652
652
  } catch {
653
653
  }
654
654
  try {
655
- await fs34__default.access(CONFIG_PATHS.config);
655
+ await fs35__default.access(CONFIG_PATHS.config);
656
656
  return CONFIG_PATHS.config;
657
657
  } catch {
658
658
  return void 0;
@@ -661,14 +661,14 @@ async function findConfigPath(cwd) {
661
661
  async function findAllConfigPaths(cwd) {
662
662
  const result = {};
663
663
  try {
664
- await fs34__default.access(CONFIG_PATHS.config);
664
+ await fs35__default.access(CONFIG_PATHS.config);
665
665
  result.global = CONFIG_PATHS.config;
666
666
  } catch {
667
667
  }
668
668
  const basePath = cwd || process.cwd();
669
- const projectConfigPath = path37__default.join(basePath, ".coco", "config.json");
669
+ const projectConfigPath = path38__default.join(basePath, ".coco", "config.json");
670
670
  try {
671
- await fs34__default.access(projectConfigPath);
671
+ await fs35__default.access(projectConfigPath);
672
672
  result.project = projectConfigPath;
673
673
  } catch {
674
674
  }
@@ -677,7 +677,7 @@ async function findAllConfigPaths(cwd) {
677
677
  async function configExists(configPath, scope = "any") {
678
678
  if (configPath) {
679
679
  try {
680
- await fs34__default.access(configPath);
680
+ await fs35__default.access(configPath);
681
681
  return true;
682
682
  } catch {
683
683
  return false;
@@ -685,7 +685,7 @@ async function configExists(configPath, scope = "any") {
685
685
  }
686
686
  if (scope === "project" || scope === "any") {
687
687
  try {
688
- await fs34__default.access(getProjectConfigPath());
688
+ await fs35__default.access(getProjectConfigPath());
689
689
  return true;
690
690
  } catch {
691
691
  if (scope === "project") return false;
@@ -693,7 +693,7 @@ async function configExists(configPath, scope = "any") {
693
693
  }
694
694
  if (scope === "global" || scope === "any") {
695
695
  try {
696
- await fs34__default.access(CONFIG_PATHS.config);
696
+ await fs35__default.access(CONFIG_PATHS.config);
697
697
  return true;
698
698
  } catch {
699
699
  return false;
@@ -701,8 +701,8 @@ async function configExists(configPath, scope = "any") {
701
701
  }
702
702
  return false;
703
703
  }
704
- function getConfigValue(config, path59) {
705
- const keys = path59.split(".");
704
+ function getConfigValue(config, path60) {
705
+ const keys = path60.split(".");
706
706
  let current = config;
707
707
  for (const key of keys) {
708
708
  if (current === null || current === void 0 || typeof current !== "object") {
@@ -879,18 +879,18 @@ async function refreshAccessToken(provider, refreshToken) {
879
879
  }
880
880
  function getTokenStoragePath(provider) {
881
881
  const home = process.env.HOME || process.env.USERPROFILE || "";
882
- return path37.join(home, ".coco", "tokens", `${provider}.json`);
882
+ return path38.join(home, ".coco", "tokens", `${provider}.json`);
883
883
  }
884
884
  async function saveTokens(provider, tokens) {
885
885
  const filePath = getTokenStoragePath(provider);
886
- const dir = path37.dirname(filePath);
887
- await fs34.mkdir(dir, { recursive: true, mode: 448 });
888
- await fs34.writeFile(filePath, JSON.stringify(tokens, null, 2), { mode: 384 });
886
+ const dir = path38.dirname(filePath);
887
+ await fs35.mkdir(dir, { recursive: true, mode: 448 });
888
+ await fs35.writeFile(filePath, JSON.stringify(tokens, null, 2), { mode: 384 });
889
889
  }
890
890
  async function loadTokens(provider) {
891
891
  const filePath = getTokenStoragePath(provider);
892
892
  try {
893
- const content = await fs34.readFile(filePath, "utf-8");
893
+ const content = await fs35.readFile(filePath, "utf-8");
894
894
  return JSON.parse(content);
895
895
  } catch {
896
896
  return null;
@@ -899,7 +899,7 @@ async function loadTokens(provider) {
899
899
  async function deleteTokens(provider) {
900
900
  const filePath = getTokenStoragePath(provider);
901
901
  try {
902
- await fs34.unlink(filePath);
902
+ await fs35.unlink(filePath);
903
903
  } catch {
904
904
  }
905
905
  }
@@ -1009,16 +1009,16 @@ var init_oauth = __esm({
1009
1009
  }
1010
1010
  });
1011
1011
  function generateCodeVerifier(length = 64) {
1012
- const randomBytes2 = crypto.randomBytes(length);
1013
- return base64UrlEncode(randomBytes2);
1012
+ const randomBytes3 = crypto.randomBytes(length);
1013
+ return base64UrlEncode(randomBytes3);
1014
1014
  }
1015
1015
  function generateCodeChallenge(codeVerifier) {
1016
1016
  const hash = crypto.createHash("sha256").update(codeVerifier).digest();
1017
1017
  return base64UrlEncode(hash);
1018
1018
  }
1019
1019
  function generateState(length = 32) {
1020
- const randomBytes2 = crypto.randomBytes(length);
1021
- return base64UrlEncode(randomBytes2);
1020
+ const randomBytes3 = crypto.randomBytes(length);
1021
+ return base64UrlEncode(randomBytes3);
1022
1022
  }
1023
1023
  function base64UrlEncode(buffer) {
1024
1024
  return buffer.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
@@ -1479,17 +1479,17 @@ function getCopilotBaseUrl(accountType) {
1479
1479
  }
1480
1480
  function getCopilotCredentialsPath() {
1481
1481
  const home = process.env.HOME || process.env.USERPROFILE || "";
1482
- return path37.join(home, ".coco", "tokens", "copilot.json");
1482
+ return path38.join(home, ".coco", "tokens", "copilot.json");
1483
1483
  }
1484
1484
  async function saveCopilotCredentials(creds) {
1485
1485
  const filePath = getCopilotCredentialsPath();
1486
- const dir = path37.dirname(filePath);
1487
- await fs34.mkdir(dir, { recursive: true, mode: 448 });
1488
- await fs34.writeFile(filePath, JSON.stringify(creds, null, 2), { mode: 384 });
1486
+ const dir = path38.dirname(filePath);
1487
+ await fs35.mkdir(dir, { recursive: true, mode: 448 });
1488
+ await fs35.writeFile(filePath, JSON.stringify(creds, null, 2), { mode: 384 });
1489
1489
  }
1490
1490
  async function loadCopilotCredentials() {
1491
1491
  try {
1492
- const content = await fs34.readFile(getCopilotCredentialsPath(), "utf-8");
1492
+ const content = await fs35.readFile(getCopilotCredentialsPath(), "utf-8");
1493
1493
  const parsed = CopilotCredentialsSchema.safeParse(JSON.parse(content));
1494
1494
  return parsed.success ? parsed.data : null;
1495
1495
  } catch {
@@ -1498,7 +1498,7 @@ async function loadCopilotCredentials() {
1498
1498
  }
1499
1499
  async function deleteCopilotCredentials() {
1500
1500
  try {
1501
- await fs34.unlink(getCopilotCredentialsPath());
1501
+ await fs35.unlink(getCopilotCredentialsPath());
1502
1502
  } catch {
1503
1503
  }
1504
1504
  }
@@ -2239,7 +2239,7 @@ function getADCPath() {
2239
2239
  if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
2240
2240
  return process.env.GOOGLE_APPLICATION_CREDENTIALS;
2241
2241
  }
2242
- return path37.join(home, ".config", "gcloud", "application_default_credentials.json");
2242
+ return path38.join(home, ".config", "gcloud", "application_default_credentials.json");
2243
2243
  }
2244
2244
  async function isGcloudInstalled() {
2245
2245
  try {
@@ -2252,7 +2252,7 @@ async function isGcloudInstalled() {
2252
2252
  async function hasADCCredentials() {
2253
2253
  const adcPath = getADCPath();
2254
2254
  try {
2255
- await fs34.access(adcPath);
2255
+ await fs35.access(adcPath);
2256
2256
  return true;
2257
2257
  } catch {
2258
2258
  return false;
@@ -2395,7 +2395,7 @@ function loadGlobalCocoEnv() {
2395
2395
  try {
2396
2396
  const home = process.env.HOME || process.env.USERPROFILE || "";
2397
2397
  if (!home) return;
2398
- const globalEnvPath = path37.join(home, ".coco", ".env");
2398
+ const globalEnvPath = path38.join(home, ".coco", ".env");
2399
2399
  const content = fs5.readFileSync(globalEnvPath, "utf-8");
2400
2400
  for (const line of content.split("\n")) {
2401
2401
  const trimmed = line.trim();
@@ -2633,7 +2633,7 @@ async function updateEnvProvider(provider) {
2633
2633
  try {
2634
2634
  const home = process.env.HOME || process.env.USERPROFILE || "";
2635
2635
  if (!home) return;
2636
- const envPath = path37.join(home, ".coco", ".env");
2636
+ const envPath = path38.join(home, ".coco", ".env");
2637
2637
  let content;
2638
2638
  try {
2639
2639
  content = await fs5.promises.readFile(envPath, "utf-8");
@@ -2660,7 +2660,7 @@ async function removeEnvProvider() {
2660
2660
  try {
2661
2661
  const home = process.env.HOME || process.env.USERPROFILE || "";
2662
2662
  if (!home) return;
2663
- const envPath = path37.join(home, ".coco", ".env");
2663
+ const envPath = path38.join(home, ".coco", ".env");
2664
2664
  let content;
2665
2665
  try {
2666
2666
  content = await fs5.promises.readFile(envPath, "utf-8");
@@ -2679,7 +2679,7 @@ async function migrateOldPreferences() {
2679
2679
  try {
2680
2680
  const home = process.env.HOME || process.env.USERPROFILE || "";
2681
2681
  if (!home) return;
2682
- const oldPrefsPath = path37.join(home, ".coco", "preferences.json");
2682
+ const oldPrefsPath = path38.join(home, ".coco", "preferences.json");
2683
2683
  let oldPrefs = null;
2684
2684
  try {
2685
2685
  const content = await fs5.promises.readFile(oldPrefsPath, "utf-8");
@@ -2855,7 +2855,7 @@ function levelToNumber(level) {
2855
2855
  }
2856
2856
  function createLogger(config = {}) {
2857
2857
  const finalConfig = { ...DEFAULT_CONFIG, ...config };
2858
- const logger = new Logger({
2858
+ const logger2 = new Logger({
2859
2859
  name: finalConfig.name,
2860
2860
  minLevel: levelToNumber(finalConfig.level),
2861
2861
  prettyLogTemplate: finalConfig.prettyPrint ? "{{yyyy}}-{{mm}}-{{dd}} {{hh}}:{{MM}}:{{ss}} {{logLevelName}} [{{name}}] " : void 0,
@@ -2863,16 +2863,16 @@ function createLogger(config = {}) {
2863
2863
  stylePrettyLogs: finalConfig.prettyPrint
2864
2864
  });
2865
2865
  if (finalConfig.logToFile && finalConfig.logDir) {
2866
- setupFileLogging(logger, finalConfig.logDir, finalConfig.name);
2866
+ setupFileLogging(logger2, finalConfig.logDir, finalConfig.name);
2867
2867
  }
2868
- return logger;
2868
+ return logger2;
2869
2869
  }
2870
- function setupFileLogging(logger, logDir, name) {
2870
+ function setupFileLogging(logger2, logDir, name) {
2871
2871
  if (!fs5__default.existsSync(logDir)) {
2872
2872
  fs5__default.mkdirSync(logDir, { recursive: true });
2873
2873
  }
2874
- const logFile = path37__default.join(logDir, `${name}.log`);
2875
- logger.attachTransport((logObj) => {
2874
+ const logFile = path38__default.join(logDir, `${name}.log`);
2875
+ logger2.attachTransport((logObj) => {
2876
2876
  const line = JSON.stringify(logObj) + "\n";
2877
2877
  fs5__default.appendFileSync(logFile, line);
2878
2878
  });
@@ -2886,34 +2886,34 @@ function getLogger() {
2886
2886
  }
2887
2887
  return globalLogger;
2888
2888
  }
2889
- function setLogger(logger) {
2890
- globalLogger = logger;
2889
+ function setLogger(logger2) {
2890
+ globalLogger = logger2;
2891
2891
  }
2892
2892
  function initializeLogging(projectPath, level = "info") {
2893
- const logDir = path37__default.join(projectPath, ".coco", "logs");
2894
- const logger = createLogger({
2893
+ const logDir = path38__default.join(projectPath, ".coco", "logs");
2894
+ const logger2 = createLogger({
2895
2895
  name: "coco",
2896
2896
  level,
2897
2897
  prettyPrint: process.stdout.isTTY ?? true,
2898
2898
  logToFile: true,
2899
2899
  logDir
2900
2900
  });
2901
- setLogger(logger);
2902
- return logger;
2901
+ setLogger(logger2);
2902
+ return logger2;
2903
2903
  }
2904
- function logEvent(logger, event, data = {}) {
2905
- logger.info({ event, ...data });
2904
+ function logEvent(logger2, event, data = {}) {
2905
+ logger2.info({ event, ...data });
2906
2906
  }
2907
- async function logTiming(logger, operation, fn) {
2907
+ async function logTiming(logger2, operation, fn) {
2908
2908
  const start = performance.now();
2909
2909
  try {
2910
2910
  const result = await fn();
2911
2911
  const duration = performance.now() - start;
2912
- logger.debug({ operation, durationMs: duration.toFixed(2), status: "success" });
2912
+ logger2.debug({ operation, durationMs: duration.toFixed(2), status: "success" });
2913
2913
  return result;
2914
2914
  } catch (error) {
2915
2915
  const duration = performance.now() - start;
2916
- logger.error({ operation, durationMs: duration.toFixed(2), status: "error", error });
2916
+ logger2.error({ operation, durationMs: duration.toFixed(2), status: "error", error });
2917
2917
  throw error;
2918
2918
  }
2919
2919
  }
@@ -7164,9 +7164,9 @@ async function migrateGlobalConfig(oldDir, newConfigPath) {
7164
7164
  );
7165
7165
  }
7166
7166
  }
7167
- async function fileExists(path59) {
7167
+ async function fileExists(path60) {
7168
7168
  try {
7169
- await access(path59);
7169
+ await access(path60);
7170
7170
  return true;
7171
7171
  } catch {
7172
7172
  return false;
@@ -7297,8 +7297,8 @@ var init_registry = __esm({
7297
7297
  /**
7298
7298
  * Ensure directory exists
7299
7299
  */
7300
- async ensureDir(path59) {
7301
- await mkdir(dirname(path59), { recursive: true });
7300
+ async ensureDir(path60) {
7301
+ await mkdir(dirname(path60), { recursive: true });
7302
7302
  }
7303
7303
  };
7304
7304
  }
@@ -7373,7 +7373,7 @@ __export(markdown_loader_exports, {
7373
7373
  });
7374
7374
  async function isMarkdownSkill(skillDir) {
7375
7375
  try {
7376
- await fs34__default.access(path37__default.join(skillDir, SKILL_FILENAME));
7376
+ await fs35__default.access(path38__default.join(skillDir, SKILL_FILENAME));
7377
7377
  return true;
7378
7378
  } catch {
7379
7379
  return false;
@@ -7381,16 +7381,16 @@ async function isMarkdownSkill(skillDir) {
7381
7381
  }
7382
7382
  async function loadMarkdownMetadata(skillDir, scope) {
7383
7383
  try {
7384
- const skillPath = path37__default.join(skillDir, SKILL_FILENAME);
7385
- const raw = await fs34__default.readFile(skillPath, "utf-8");
7384
+ const skillPath = path38__default.join(skillDir, SKILL_FILENAME);
7385
+ const raw = await fs35__default.readFile(skillPath, "utf-8");
7386
7386
  const { data } = matter(raw);
7387
7387
  const parsed = SkillFrontmatterSchema.safeParse(data);
7388
7388
  if (!parsed.success) {
7389
7389
  return null;
7390
7390
  }
7391
7391
  const fm = parsed.data;
7392
- const dirName = path37__default.basename(skillDir);
7393
- const parentDir = path37__default.basename(path37__default.dirname(skillDir));
7392
+ const dirName = path38__default.basename(skillDir);
7393
+ const parentDir = path38__default.basename(path38__default.dirname(skillDir));
7394
7394
  const namespace = isNamespaceDirectory(parentDir) ? parentDir : void 0;
7395
7395
  const baseId = toKebabCase(fm.name || dirName);
7396
7396
  const fullId = namespace ? `${namespace}/${baseId}` : baseId;
@@ -7420,8 +7420,8 @@ async function loadMarkdownMetadata(skillDir, scope) {
7420
7420
  context: fm.context
7421
7421
  };
7422
7422
  } catch (error) {
7423
- const logger = getLogger();
7424
- logger.warn(
7423
+ const logger2 = getLogger();
7424
+ logger2.warn(
7425
7425
  `[Skills] Failed to load metadata from ${skillDir}:`,
7426
7426
  error instanceof Error ? error.message : error
7427
7427
  );
@@ -7430,8 +7430,8 @@ async function loadMarkdownMetadata(skillDir, scope) {
7430
7430
  }
7431
7431
  async function loadMarkdownContent(skillDir) {
7432
7432
  try {
7433
- const skillPath = path37__default.join(skillDir, SKILL_FILENAME);
7434
- const raw = await fs34__default.readFile(skillPath, "utf-8");
7433
+ const skillPath = path38__default.join(skillDir, SKILL_FILENAME);
7434
+ const raw = await fs35__default.readFile(skillPath, "utf-8");
7435
7435
  const { content } = matter(raw);
7436
7436
  const references = await listSubdirectory(skillDir, "references");
7437
7437
  const scripts = await listSubdirectory(skillDir, "scripts");
@@ -7443,8 +7443,8 @@ async function loadMarkdownContent(skillDir) {
7443
7443
  templates
7444
7444
  };
7445
7445
  } catch (error) {
7446
- const logger = getLogger();
7447
- logger.warn(
7446
+ const logger2 = getLogger();
7447
+ logger2.warn(
7448
7448
  `[Skills] Failed to load content from ${skillDir}:`,
7449
7449
  error instanceof Error ? error.message : error
7450
7450
  );
@@ -7453,9 +7453,9 @@ async function loadMarkdownContent(skillDir) {
7453
7453
  }
7454
7454
  async function listSubdirectory(skillDir, subdir) {
7455
7455
  try {
7456
- const dir = path37__default.join(skillDir, subdir);
7457
- const entries = await fs34__default.readdir(dir, { withFileTypes: true });
7458
- return entries.filter((e) => e.isFile()).map((e) => path37__default.join(dir, e.name));
7456
+ const dir = path38__default.join(skillDir, subdir);
7457
+ const entries = await fs35__default.readdir(dir, { withFileTypes: true });
7458
+ return entries.filter((e) => e.isFile()).map((e) => path38__default.join(dir, e.name));
7459
7459
  } catch {
7460
7460
  return [];
7461
7461
  }
@@ -7532,8 +7532,8 @@ async function loadSkillFromDirectory(skillDir, scope) {
7532
7532
  if (await isMarkdownSkill(skillDir)) {
7533
7533
  return loadMarkdownMetadata(skillDir, scope);
7534
7534
  }
7535
- const hasTs = await fileExists2(path37__default.join(skillDir, "index.ts"));
7536
- const hasJs = await fileExists2(path37__default.join(skillDir, "index.js"));
7535
+ const hasTs = await fileExists2(path38__default.join(skillDir, "index.ts"));
7536
+ const hasJs = await fileExists2(path38__default.join(skillDir, "index.js"));
7537
7537
  if (hasTs || hasJs) {
7538
7538
  return null;
7539
7539
  }
@@ -7553,7 +7553,7 @@ async function loadFullSkill(metadata) {
7553
7553
  }
7554
7554
  async function fileExists2(filePath) {
7555
7555
  try {
7556
- await fs34__default.access(filePath);
7556
+ await fs35__default.access(filePath);
7557
7557
  return true;
7558
7558
  } catch {
7559
7559
  return false;
@@ -7576,8 +7576,8 @@ function normalizeDirectories(dirs, relativeBaseDir) {
7576
7576
  for (const dir of dirs) {
7577
7577
  const trimmed = dir.trim();
7578
7578
  if (!trimmed) continue;
7579
- const expanded = trimmed === "~" ? home : trimmed.startsWith("~/") ? path37__default.join(home, trimmed.slice(2)) : trimmed;
7580
- const resolved = path37__default.isAbsolute(expanded) ? path37__default.resolve(expanded) : path37__default.resolve(relativeBaseDir ?? process.cwd(), expanded);
7579
+ const expanded = trimmed === "~" ? home : trimmed.startsWith("~/") ? path38__default.join(home, trimmed.slice(2)) : trimmed;
7580
+ const resolved = path38__default.isAbsolute(expanded) ? path38__default.resolve(expanded) : path38__default.resolve(relativeBaseDir ?? process.cwd(), expanded);
7581
7581
  if (seen.has(resolved)) continue;
7582
7582
  seen.add(resolved);
7583
7583
  normalized.push(resolved);
@@ -7590,7 +7590,7 @@ function resolveDiscoveryDirs(projectPath, options) {
7590
7590
  opts.globalDirs && opts.globalDirs.length > 0 ? opts.globalDirs : opts.globalDir ? [opts.globalDir] : GLOBAL_SKILLS_DIRS
7591
7591
  );
7592
7592
  const projectDirs = normalizeDirectories(
7593
- opts.projectDirs && opts.projectDirs.length > 0 ? opts.projectDirs : opts.projectDir ? [opts.projectDir] : PROJECT_SKILLS_DIRNAMES.map((d) => path37__default.join(projectPath, d)),
7593
+ opts.projectDirs && opts.projectDirs.length > 0 ? opts.projectDirs : opts.projectDir ? [opts.projectDir] : PROJECT_SKILLS_DIRNAMES.map((d) => path38__default.join(projectPath, d)),
7594
7594
  projectPath
7595
7595
  );
7596
7596
  return { globalDirs, projectDirs };
@@ -7618,13 +7618,13 @@ async function discoverAllSkills(projectPath, builtinSkills = [], options) {
7618
7618
  }
7619
7619
  async function scanSkillsDirectory(dir, scope) {
7620
7620
  try {
7621
- const entries = await fs34__default.readdir(dir, { withFileTypes: true });
7621
+ const entries = await fs35__default.readdir(dir, { withFileTypes: true });
7622
7622
  const skillDirs = entries.filter((e) => e.isDirectory() && !e.isSymbolicLink());
7623
7623
  const results = [];
7624
7624
  for (const entry of skillDirs) {
7625
- const entryPath = path37__default.join(dir, entry.name);
7625
+ const entryPath = path38__default.join(dir, entry.name);
7626
7626
  try {
7627
- const stat2 = await fs34__default.lstat(entryPath);
7627
+ const stat2 = await fs35__default.lstat(entryPath);
7628
7628
  if (stat2.isSymbolicLink()) continue;
7629
7629
  } catch {
7630
7630
  continue;
@@ -7640,8 +7640,8 @@ async function scanSkillsDirectory(dir, scope) {
7640
7640
  return results.filter((meta) => meta !== null);
7641
7641
  } catch (error) {
7642
7642
  if (error.code !== "ENOENT") {
7643
- const logger = getLogger();
7644
- logger.warn(
7643
+ const logger2 = getLogger();
7644
+ logger2.warn(
7645
7645
  `[Skills] Failed to scan directory ${dir}:`,
7646
7646
  error instanceof Error ? error.message : error
7647
7647
  );
@@ -7652,13 +7652,13 @@ async function scanSkillsDirectory(dir, scope) {
7652
7652
  async function scanNestedSkills(dir, scope, depth) {
7653
7653
  if (depth >= MAX_NESTING_DEPTH) return [];
7654
7654
  try {
7655
- const subEntries = await fs34__default.readdir(dir, { withFileTypes: true });
7655
+ const subEntries = await fs35__default.readdir(dir, { withFileTypes: true });
7656
7656
  const subDirs = subEntries.filter((e) => e.isDirectory() && !e.isSymbolicLink());
7657
7657
  const results = await Promise.all(
7658
7658
  subDirs.map(async (sub) => {
7659
- const subPath = path37__default.join(dir, sub.name);
7659
+ const subPath = path38__default.join(dir, sub.name);
7660
7660
  try {
7661
- const stat2 = await fs34__default.lstat(subPath);
7661
+ const stat2 = await fs35__default.lstat(subPath);
7662
7662
  if (stat2.isSymbolicLink()) return null;
7663
7663
  } catch {
7664
7664
  return null;
@@ -7686,17 +7686,17 @@ var init_discovery = __esm({
7686
7686
  init_paths();
7687
7687
  init_logger();
7688
7688
  GLOBAL_SKILLS_DIRS = [
7689
- path37__default.join(homedir(), ".codex", "skills"),
7689
+ path38__default.join(homedir(), ".codex", "skills"),
7690
7690
  // Codex CLI legacy compat
7691
- path37__default.join(homedir(), ".gemini", "skills"),
7691
+ path38__default.join(homedir(), ".gemini", "skills"),
7692
7692
  // Gemini CLI compat
7693
- path37__default.join(homedir(), ".opencode", "skills"),
7693
+ path38__default.join(homedir(), ".opencode", "skills"),
7694
7694
  // OpenCode compat
7695
- path37__default.join(homedir(), ".claude", "skills"),
7695
+ path38__default.join(homedir(), ".claude", "skills"),
7696
7696
  // Claude Code compat
7697
- path37__default.join(homedir(), ".agents", "skills"),
7697
+ path38__default.join(homedir(), ".agents", "skills"),
7698
7698
  // shared cross-agent standard
7699
- path37__default.join(COCO_HOME, "skills")
7699
+ path38__default.join(COCO_HOME, "skills")
7700
7700
  // Coco native global directory (authoritative for Coco)
7701
7701
  ];
7702
7702
  PROJECT_SKILLS_DIRNAMES = [
@@ -8935,9 +8935,9 @@ function createEmptyMemoryContext() {
8935
8935
  errors: []
8936
8936
  };
8937
8937
  }
8938
- function createMissingMemoryFile(path59, level) {
8938
+ function createMissingMemoryFile(path60, level) {
8939
8939
  return {
8940
- path: path59,
8940
+ path: path60,
8941
8941
  level,
8942
8942
  content: "",
8943
8943
  sections: [],
@@ -9080,11 +9080,11 @@ var init_loader3 = __esm({
9080
9080
  async loadFile(filePath, level) {
9081
9081
  const resolvedPath = this.resolvePath(filePath);
9082
9082
  try {
9083
- const stat2 = await fs34.stat(resolvedPath);
9084
- const rawContent = await fs34.readFile(resolvedPath, "utf-8");
9083
+ const stat2 = await fs35.stat(resolvedPath);
9084
+ const rawContent = await fs35.readFile(resolvedPath, "utf-8");
9085
9085
  const { content, imports } = await this.resolveImports(
9086
9086
  rawContent,
9087
- path37.dirname(resolvedPath),
9087
+ path38.dirname(resolvedPath),
9088
9088
  0
9089
9089
  );
9090
9090
  const sections = this.parseSections(content);
@@ -9111,16 +9111,16 @@ var init_loader3 = __esm({
9111
9111
  if (this.config.includeUserLevel) {
9112
9112
  const userDir = this.resolvePath(USER_CONFIG_DIR);
9113
9113
  for (const pattern of this.config.filePatterns) {
9114
- const userPath = path37.join(userDir, pattern);
9114
+ const userPath = path38.join(userDir, pattern);
9115
9115
  if (await this.fileExists(userPath)) {
9116
9116
  result.user = userPath;
9117
9117
  break;
9118
9118
  }
9119
9119
  }
9120
9120
  }
9121
- const absoluteProjectPath = path37.resolve(projectPath);
9121
+ const absoluteProjectPath = path38.resolve(projectPath);
9122
9122
  for (const pattern of this.config.filePatterns) {
9123
- const projectFilePath = path37.join(absoluteProjectPath, pattern);
9123
+ const projectFilePath = path38.join(absoluteProjectPath, pattern);
9124
9124
  if (await this.fileExists(projectFilePath)) {
9125
9125
  result.project = projectFilePath;
9126
9126
  break;
@@ -9128,14 +9128,14 @@ var init_loader3 = __esm({
9128
9128
  }
9129
9129
  const cwd = currentDir ?? process.cwd();
9130
9130
  if (cwd.startsWith(absoluteProjectPath) && cwd !== absoluteProjectPath) {
9131
- const relativePath = path37.relative(absoluteProjectPath, cwd);
9132
- const parts = relativePath.split(path37.sep);
9131
+ const relativePath = path38.relative(absoluteProjectPath, cwd);
9132
+ const parts = relativePath.split(path38.sep);
9133
9133
  const dirFiles = [];
9134
9134
  let currentDir2 = absoluteProjectPath;
9135
9135
  for (const part of parts) {
9136
- currentDir2 = path37.join(currentDir2, part);
9136
+ currentDir2 = path38.join(currentDir2, part);
9137
9137
  for (const pattern of this.config.filePatterns) {
9138
- const dirFilePath = path37.join(currentDir2, pattern);
9138
+ const dirFilePath = path38.join(currentDir2, pattern);
9139
9139
  if (await this.fileExists(dirFilePath)) {
9140
9140
  dirFiles.push(dirFilePath);
9141
9141
  break;
@@ -9149,7 +9149,7 @@ var init_loader3 = __esm({
9149
9149
  for (const pattern of this.config.filePatterns) {
9150
9150
  const baseName = pattern.replace(/\.md$/, "");
9151
9151
  const localFileName = `${baseName}${LOCAL_SUFFIX}`;
9152
- const localPath = path37.join(absoluteProjectPath, localFileName);
9152
+ const localPath = path38.join(absoluteProjectPath, localFileName);
9153
9153
  if (await this.fileExists(localPath)) {
9154
9154
  result.local = localPath;
9155
9155
  break;
@@ -9200,10 +9200,10 @@ var init_loader3 = __esm({
9200
9200
  };
9201
9201
  try {
9202
9202
  if (await this.fileExists(resolvedPath)) {
9203
- const importedContent = await fs34.readFile(resolvedPath, "utf-8");
9203
+ const importedContent = await fs35.readFile(resolvedPath, "utf-8");
9204
9204
  const nestedResult = await this.resolveImports(
9205
9205
  importedContent,
9206
- path37.dirname(resolvedPath),
9206
+ path38.dirname(resolvedPath),
9207
9207
  depth + 1
9208
9208
  );
9209
9209
  processedLines.push(`<!-- Imported from: ${importPath} -->`);
@@ -9244,7 +9244,7 @@ var init_loader3 = __esm({
9244
9244
  const parts = [];
9245
9245
  for (const file of files) {
9246
9246
  if (file.exists && file.content.trim()) {
9247
- const label = file.level === "directory" ? `directory level (${path37.dirname(file.path)}/${path37.basename(file.path)})` : `${file.level} level (${path37.basename(file.path)})`;
9247
+ const label = file.level === "directory" ? `directory level (${path38.dirname(file.path)}/${path38.basename(file.path)})` : `${file.level} level (${path38.basename(file.path)})`;
9248
9248
  parts.push(`<!-- Memory: ${label} -->`);
9249
9249
  parts.push(file.content);
9250
9250
  parts.push("");
@@ -9307,9 +9307,9 @@ var init_loader3 = __esm({
9307
9307
  */
9308
9308
  resolvePath(filePath) {
9309
9309
  if (filePath.startsWith("~")) {
9310
- return path37.join(os4.homedir(), filePath.slice(1));
9310
+ return path38.join(os4.homedir(), filePath.slice(1));
9311
9311
  }
9312
- return path37.resolve(filePath);
9312
+ return path38.resolve(filePath);
9313
9313
  }
9314
9314
  /**
9315
9315
  * Resolve an import path relative to a base directory.
@@ -9324,22 +9324,22 @@ var init_loader3 = __esm({
9324
9324
  resolveImportPath(importPath, basePath) {
9325
9325
  let resolved;
9326
9326
  if (importPath.startsWith("~")) {
9327
- resolved = path37.join(os4.homedir(), importPath.slice(1));
9327
+ resolved = path38.join(os4.homedir(), importPath.slice(1));
9328
9328
  const userConfigDir = this.resolvePath(USER_CONFIG_DIR);
9329
- if (!resolved.startsWith(userConfigDir + path37.sep) && resolved !== userConfigDir) {
9329
+ if (!resolved.startsWith(userConfigDir + path38.sep) && resolved !== userConfigDir) {
9330
9330
  throw new Error(`Import path escapes user config directory: @${importPath}`);
9331
9331
  }
9332
9332
  return resolved;
9333
9333
  }
9334
- if (path37.isAbsolute(importPath)) {
9335
- resolved = path37.resolve(importPath);
9336
- if (!resolved.startsWith(basePath + path37.sep) && resolved !== basePath) {
9334
+ if (path38.isAbsolute(importPath)) {
9335
+ resolved = path38.resolve(importPath);
9336
+ if (!resolved.startsWith(basePath + path38.sep) && resolved !== basePath) {
9337
9337
  throw new Error(`Import path escapes project directory: @${importPath}`);
9338
9338
  }
9339
9339
  return resolved;
9340
9340
  }
9341
- resolved = path37.resolve(basePath, importPath);
9342
- if (!resolved.startsWith(basePath + path37.sep) && resolved !== basePath) {
9341
+ resolved = path38.resolve(basePath, importPath);
9342
+ if (!resolved.startsWith(basePath + path38.sep) && resolved !== basePath) {
9343
9343
  throw new Error(`Import path escapes project directory: @${importPath}`);
9344
9344
  }
9345
9345
  return resolved;
@@ -9351,7 +9351,7 @@ var init_loader3 = __esm({
9351
9351
  */
9352
9352
  async fileExists(filePath) {
9353
9353
  try {
9354
- await fs34.access(filePath);
9354
+ await fs35.access(filePath);
9355
9355
  return true;
9356
9356
  } catch {
9357
9357
  return false;
@@ -9719,7 +9719,7 @@ function clearSession(session) {
9719
9719
  }
9720
9720
  async function loadTrustSettings() {
9721
9721
  try {
9722
- const content = await fs34__default.readFile(TRUST_SETTINGS_FILE, "utf-8");
9722
+ const content = await fs35__default.readFile(TRUST_SETTINGS_FILE, "utf-8");
9723
9723
  const raw = JSON.parse(content);
9724
9724
  return {
9725
9725
  globalTrusted: raw.globalTrusted ?? [],
@@ -9738,9 +9738,9 @@ async function loadTrustSettings() {
9738
9738
  }
9739
9739
  async function saveTrustSettings(settings) {
9740
9740
  try {
9741
- await fs34__default.mkdir(TRUST_SETTINGS_DIR, { recursive: true });
9741
+ await fs35__default.mkdir(TRUST_SETTINGS_DIR, { recursive: true });
9742
9742
  settings.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
9743
- await fs34__default.writeFile(TRUST_SETTINGS_FILE, JSON.stringify(settings, null, 2), "utf-8");
9743
+ await fs35__default.writeFile(TRUST_SETTINGS_FILE, JSON.stringify(settings, null, 2), "utf-8");
9744
9744
  } catch (error) {
9745
9745
  const msg = error instanceof Error ? error.message : String(error);
9746
9746
  console.warn(`[Trust] Failed to save trust settings: ${msg}`);
@@ -9927,7 +9927,7 @@ var init_session = __esm({
9927
9927
  init_manager();
9928
9928
  init_compactor();
9929
9929
  MAX_SKILL_INSTRUCTIONS_CHARS = 16e3;
9930
- TRUST_SETTINGS_DIR = path37__default.dirname(CONFIG_PATHS.trustedTools);
9930
+ TRUST_SETTINGS_DIR = path38__default.dirname(CONFIG_PATHS.trustedTools);
9931
9931
  TRUST_SETTINGS_FILE = CONFIG_PATHS.trustedTools;
9932
9932
  CATEGORY_LABELS = {
9933
9933
  file: "File Operations",
@@ -10210,13 +10210,13 @@ var init_types4 = __esm({
10210
10210
  }
10211
10211
  });
10212
10212
  function getStatePath(projectPath) {
10213
- return path37.join(projectPath, ".coco", "state.json");
10213
+ return path38.join(projectPath, ".coco", "state.json");
10214
10214
  }
10215
10215
  function createStateManager() {
10216
10216
  async function load(projectPath) {
10217
10217
  const statePath = getStatePath(projectPath);
10218
10218
  try {
10219
- const content = await fs34.readFile(statePath, "utf-8");
10219
+ const content = await fs35.readFile(statePath, "utf-8");
10220
10220
  const file = JSON.parse(content);
10221
10221
  if (file.version !== STATE_VERSION) {
10222
10222
  console.warn(`State version mismatch: ${file.version} vs ${STATE_VERSION}`);
@@ -10235,7 +10235,7 @@ function createStateManager() {
10235
10235
  }
10236
10236
  async function save(state) {
10237
10237
  const statePath = getStatePath(state.path);
10238
- await fs34.mkdir(path37.dirname(statePath), { recursive: true });
10238
+ await fs35.mkdir(path38.dirname(statePath), { recursive: true });
10239
10239
  const file = {
10240
10240
  version: STATE_VERSION,
10241
10241
  state: {
@@ -10243,19 +10243,19 @@ function createStateManager() {
10243
10243
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
10244
10244
  }
10245
10245
  };
10246
- await fs34.writeFile(statePath, JSON.stringify(file, null, 2), "utf-8");
10246
+ await fs35.writeFile(statePath, JSON.stringify(file, null, 2), "utf-8");
10247
10247
  }
10248
10248
  async function clear(projectPath) {
10249
10249
  const statePath = getStatePath(projectPath);
10250
10250
  try {
10251
- await fs34.unlink(statePath);
10251
+ await fs35.unlink(statePath);
10252
10252
  } catch {
10253
10253
  }
10254
10254
  }
10255
10255
  async function exists(projectPath) {
10256
10256
  const statePath = getStatePath(projectPath);
10257
10257
  try {
10258
- await fs34.access(statePath);
10258
+ await fs35.access(statePath);
10259
10259
  return true;
10260
10260
  } catch {
10261
10261
  return false;
@@ -10383,8 +10383,8 @@ __export(trust_store_exports, {
10383
10383
  saveTrustStore: () => saveTrustStore,
10384
10384
  updateLastAccessed: () => updateLastAccessed
10385
10385
  });
10386
- async function ensureDir(path59) {
10387
- await mkdir(dirname(path59), { recursive: true });
10386
+ async function ensureDir(path60) {
10387
+ await mkdir(dirname(path60), { recursive: true });
10388
10388
  }
10389
10389
  async function loadTrustStore(storePath = TRUST_STORE_PATH) {
10390
10390
  try {
@@ -10408,8 +10408,8 @@ async function saveTrustStore(store, storePath = TRUST_STORE_PATH) {
10408
10408
  await ensureDir(storePath);
10409
10409
  await writeFile(storePath, JSON.stringify(store, null, 2), "utf-8");
10410
10410
  } catch (error) {
10411
- const logger = (await Promise.resolve().then(() => (init_logger(), logger_exports))).getLogger();
10412
- logger.warn(
10411
+ const logger2 = (await Promise.resolve().then(() => (init_logger(), logger_exports))).getLogger();
10412
+ logger2.warn(
10413
10413
  `[TrustStore] Failed to save: ${error instanceof Error ? error.message : String(error)}`
10414
10414
  );
10415
10415
  }
@@ -10469,8 +10469,8 @@ function canPerformOperation(store, projectPath, operation) {
10469
10469
  };
10470
10470
  return permissions[level]?.includes(operation) ?? false;
10471
10471
  }
10472
- function normalizePath(path59) {
10473
- return join(path59);
10472
+ function normalizePath(path60) {
10473
+ return join(path60);
10474
10474
  }
10475
10475
  function createTrustStore(storePath = TRUST_STORE_PATH) {
10476
10476
  let store = null;
@@ -10826,12 +10826,12 @@ function humanizeError(message, toolName) {
10826
10826
  return msg;
10827
10827
  }
10828
10828
  if (/ENOENT/i.test(msg)) {
10829
- const path59 = extractQuotedPath(msg);
10830
- return path59 ? `File or directory not found: ${path59}` : "File or directory not found";
10829
+ const path60 = extractQuotedPath(msg);
10830
+ return path60 ? `File or directory not found: ${path60}` : "File or directory not found";
10831
10831
  }
10832
10832
  if (/EACCES/i.test(msg)) {
10833
- const path59 = extractQuotedPath(msg);
10834
- return path59 ? `Permission denied: ${path59}` : "Permission denied \u2014 check file permissions";
10833
+ const path60 = extractQuotedPath(msg);
10834
+ return path60 ? `Permission denied: ${path60}` : "Permission denied \u2014 check file permissions";
10835
10835
  }
10836
10836
  if (/EISDIR/i.test(msg)) {
10837
10837
  return "Expected a file but found a directory at the specified path";
@@ -11306,7 +11306,7 @@ Suggestion: ${error.suggestion}`;
11306
11306
  });
11307
11307
  async function fileExists3(filePath) {
11308
11308
  try {
11309
- await fs34__default.access(filePath);
11309
+ await fs35__default.access(filePath);
11310
11310
  return true;
11311
11311
  } catch {
11312
11312
  return false;
@@ -11765,9 +11765,9 @@ var init_diff_renderer = __esm({
11765
11765
  getTerminalWidth = () => process.stdout.columns || 80;
11766
11766
  }
11767
11767
  });
11768
- async function fileExists4(path59) {
11768
+ async function fileExists4(path60) {
11769
11769
  try {
11770
- await access(path59);
11770
+ await access(path60);
11771
11771
  return true;
11772
11772
  } catch {
11773
11773
  return false;
@@ -11857,7 +11857,7 @@ async function detectMaturity(cwd) {
11857
11857
  if (!hasLintConfig && hasPackageJson) {
11858
11858
  try {
11859
11859
  const pkgRaw = await import('fs/promises').then(
11860
- (fs55) => fs55.readFile(join(cwd, "package.json"), "utf-8")
11860
+ (fs56) => fs56.readFile(join(cwd, "package.json"), "utf-8")
11861
11861
  );
11862
11862
  const pkg = JSON.parse(pkgRaw);
11863
11863
  if (pkg.scripts?.lint || pkg.scripts?.["lint:fix"]) {
@@ -12879,7 +12879,7 @@ var init_build_verifier = __esm({
12879
12879
  async verifyTypes() {
12880
12880
  const startTime = Date.now();
12881
12881
  try {
12882
- const hasTsConfig = await this.fileExists(path37.join(this.projectPath, "tsconfig.json"));
12882
+ const hasTsConfig = await this.fileExists(path38.join(this.projectPath, "tsconfig.json"));
12883
12883
  if (!hasTsConfig) {
12884
12884
  return {
12885
12885
  success: true,
@@ -12929,19 +12929,19 @@ var init_build_verifier = __esm({
12929
12929
  * Checks Maven, Gradle, and Node.js in that order.
12930
12930
  */
12931
12931
  async detectBuildCommand() {
12932
- if (await this.fileExists(path37.join(this.projectPath, "pom.xml"))) {
12933
- const wrapper = path37.join(this.projectPath, "mvnw");
12932
+ if (await this.fileExists(path38.join(this.projectPath, "pom.xml"))) {
12933
+ const wrapper = path38.join(this.projectPath, "mvnw");
12934
12934
  return await this.fileExists(wrapper) ? "./mvnw compile -B -q" : "mvn compile -B -q";
12935
12935
  }
12936
12936
  for (const f of ["build.gradle", "build.gradle.kts"]) {
12937
- if (await this.fileExists(path37.join(this.projectPath, f))) {
12938
- const wrapper = path37.join(this.projectPath, "gradlew");
12937
+ if (await this.fileExists(path38.join(this.projectPath, f))) {
12938
+ const wrapper = path38.join(this.projectPath, "gradlew");
12939
12939
  return await this.fileExists(wrapper) ? "./gradlew classes -q" : "gradle classes -q";
12940
12940
  }
12941
12941
  }
12942
12942
  try {
12943
- const packageJsonPath = path37.join(this.projectPath, "package.json");
12944
- const content = await fs34.readFile(packageJsonPath, "utf-8");
12943
+ const packageJsonPath = path38.join(this.projectPath, "package.json");
12944
+ const content = await fs35.readFile(packageJsonPath, "utf-8");
12945
12945
  const packageJson = JSON.parse(content);
12946
12946
  if (packageJson.scripts?.build) {
12947
12947
  return "npm run build";
@@ -13016,7 +13016,7 @@ var init_build_verifier = __esm({
13016
13016
  */
13017
13017
  async fileExists(filePath) {
13018
13018
  try {
13019
- await fs34.access(filePath);
13019
+ await fs35.access(filePath);
13020
13020
  return true;
13021
13021
  } catch {
13022
13022
  return false;
@@ -14675,9 +14675,9 @@ function detectProjectLanguage(files) {
14675
14675
  return { language: dominant, confidence, evidence };
14676
14676
  }
14677
14677
  function getFileExtension(filePath) {
14678
- const base = path37.basename(filePath);
14678
+ const base = path38.basename(filePath);
14679
14679
  if (base.endsWith(".d.ts")) return ".d.ts";
14680
- return path37.extname(filePath).toLowerCase();
14680
+ return path38.extname(filePath).toLowerCase();
14681
14681
  }
14682
14682
  function buildEvidence(dominant, counts, totalSourceFiles, files) {
14683
14683
  const evidence = [];
@@ -14685,7 +14685,7 @@ function buildEvidence(dominant, counts, totalSourceFiles, files) {
14685
14685
  evidence.push(`${dominantCount} of ${totalSourceFiles} source files are ${dominant}`);
14686
14686
  const configFiles = ["tsconfig.json", "pom.xml", "build.gradle", "Cargo.toml", "go.mod"];
14687
14687
  for (const cfg of configFiles) {
14688
- if (files.some((f) => path37.basename(f) === cfg)) {
14688
+ if (files.some((f) => path38.basename(f) === cfg)) {
14689
14689
  evidence.push(`Found ${cfg}`);
14690
14690
  }
14691
14691
  }
@@ -16180,20 +16180,20 @@ var init_evaluator = __esm({
16180
16180
  });
16181
16181
  async function detectLinter2(cwd) {
16182
16182
  try {
16183
- await fs34__default.access(path37__default.join(cwd, "pom.xml"));
16183
+ await fs35__default.access(path38__default.join(cwd, "pom.xml"));
16184
16184
  return "maven-checkstyle";
16185
16185
  } catch {
16186
16186
  }
16187
16187
  for (const f of ["build.gradle", "build.gradle.kts"]) {
16188
16188
  try {
16189
- await fs34__default.access(path37__default.join(cwd, f));
16189
+ await fs35__default.access(path38__default.join(cwd, f));
16190
16190
  return "gradle-checkstyle";
16191
16191
  } catch {
16192
16192
  }
16193
16193
  }
16194
16194
  try {
16195
- const pkgPath = path37__default.join(cwd, "package.json");
16196
- const pkgContent = await fs34__default.readFile(pkgPath, "utf-8");
16195
+ const pkgPath = path38__default.join(cwd, "package.json");
16196
+ const pkgContent = await fs35__default.readFile(pkgPath, "utf-8");
16197
16197
  const pkg = JSON.parse(pkgContent);
16198
16198
  const deps = {
16199
16199
  ...pkg.dependencies,
@@ -16209,7 +16209,7 @@ async function detectLinter2(cwd) {
16209
16209
  }
16210
16210
  async function mavenExec(cwd) {
16211
16211
  try {
16212
- await fs34__default.access(path37__default.join(cwd, "mvnw"));
16212
+ await fs35__default.access(path38__default.join(cwd, "mvnw"));
16213
16213
  return "./mvnw";
16214
16214
  } catch {
16215
16215
  return "mvn";
@@ -16217,7 +16217,7 @@ async function mavenExec(cwd) {
16217
16217
  }
16218
16218
  async function gradleExec(cwd) {
16219
16219
  try {
16220
- await fs34__default.access(path37__default.join(cwd, "gradlew"));
16220
+ await fs35__default.access(path38__default.join(cwd, "gradlew"));
16221
16221
  return "./gradlew";
16222
16222
  } catch {
16223
16223
  return "gradle";
@@ -16286,14 +16286,14 @@ async function findSourceFiles(cwd) {
16286
16286
  const { glob: glob17 } = await import('glob');
16287
16287
  let isJava = false;
16288
16288
  try {
16289
- await fs34__default.access(path37__default.join(cwd, "pom.xml"));
16289
+ await fs35__default.access(path38__default.join(cwd, "pom.xml"));
16290
16290
  isJava = true;
16291
16291
  } catch {
16292
16292
  }
16293
16293
  if (!isJava) {
16294
16294
  for (const f of ["build.gradle", "build.gradle.kts"]) {
16295
16295
  try {
16296
- await fs34__default.access(path37__default.join(cwd, f));
16296
+ await fs35__default.access(path38__default.join(cwd, f));
16297
16297
  isJava = true;
16298
16298
  break;
16299
16299
  } catch {
@@ -16501,7 +16501,7 @@ Examples:
16501
16501
  let totalFunctions = 0;
16502
16502
  let complexFunctions = 0;
16503
16503
  for (const file of targetFiles) {
16504
- const content = await fs34__default.readFile(file, "utf-8");
16504
+ const content = await fs35__default.readFile(file, "utf-8");
16505
16505
  const fileComplexity = analyzeFileComplexity(content, file);
16506
16506
  fileResults.push(fileComplexity);
16507
16507
  totalComplexity += fileComplexity.complexity;
@@ -16648,7 +16648,7 @@ async function checkTestCoverage(diff, cwd) {
16648
16648
  );
16649
16649
  if (!hasTestChange) {
16650
16650
  const ext = src.path.match(/\.(ts|tsx|js|jsx)$/)?.[0] ?? ".ts";
16651
- const testExists = await fileExists3(path37__default.join(cwd, `${baseName}.test${ext}`)) || await fileExists3(path37__default.join(cwd, `${baseName}.spec${ext}`));
16651
+ const testExists = await fileExists3(path38__default.join(cwd, `${baseName}.test${ext}`)) || await fileExists3(path38__default.join(cwd, `${baseName}.spec${ext}`));
16652
16652
  if (testExists) {
16653
16653
  if (src.additions >= TEST_COVERAGE_LARGE_CHANGE_THRESHOLD) {
16654
16654
  findings.push({
@@ -18329,7 +18329,7 @@ var init_github = __esm({
18329
18329
  });
18330
18330
  async function detectVersionFile(cwd) {
18331
18331
  for (const { file, stack, field } of VERSION_FILES) {
18332
- const fullPath = path37__default.join(cwd, file);
18332
+ const fullPath = path38__default.join(cwd, file);
18333
18333
  if (await fileExists3(fullPath)) {
18334
18334
  const version = await readVersionFromFile(fullPath, stack, field);
18335
18335
  if (version) {
@@ -18375,7 +18375,7 @@ function bumpVersion(current, bump) {
18375
18375
  }
18376
18376
  }
18377
18377
  async function writeVersion(cwd, versionFile, newVersion) {
18378
- const fullPath = path37__default.join(cwd, versionFile.path);
18378
+ const fullPath = path38__default.join(cwd, versionFile.path);
18379
18379
  const content = await readFile(fullPath, "utf-8");
18380
18380
  let updated;
18381
18381
  switch (versionFile.stack) {
@@ -18434,7 +18434,7 @@ var init_version_detector = __esm({
18434
18434
  });
18435
18435
  async function detectChangelog(cwd) {
18436
18436
  for (const name of CHANGELOG_NAMES) {
18437
- const fullPath = path37__default.join(cwd, name);
18437
+ const fullPath = path38__default.join(cwd, name);
18438
18438
  if (await fileExists3(fullPath)) {
18439
18439
  const content = await readFile(fullPath, "utf-8");
18440
18440
  const format = detectFormat(content);
@@ -18456,7 +18456,7 @@ function detectFormat(content) {
18456
18456
  return "custom";
18457
18457
  }
18458
18458
  async function insertChangelogEntry(cwd, changelog, version, entries, date) {
18459
- const fullPath = path37__default.join(cwd, changelog.path);
18459
+ const fullPath = path38__default.join(cwd, changelog.path);
18460
18460
  const content = await readFile(fullPath, "utf-8");
18461
18461
  const dateStr = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
18462
18462
  const entry = buildEntry(changelog.format, version, entries, dateStr);
@@ -18517,11 +18517,11 @@ var init_changelog = __esm({
18517
18517
  }
18518
18518
  });
18519
18519
  async function detectStack(cwd) {
18520
- if (await fileExists3(path37__default.join(cwd, "package.json"))) return "node";
18521
- if (await fileExists3(path37__default.join(cwd, "Cargo.toml"))) return "rust";
18522
- if (await fileExists3(path37__default.join(cwd, "pyproject.toml"))) return "python";
18523
- if (await fileExists3(path37__default.join(cwd, "go.mod"))) return "go";
18524
- if (await fileExists3(path37__default.join(cwd, "pom.xml"))) return "java";
18520
+ if (await fileExists3(path38__default.join(cwd, "package.json"))) return "node";
18521
+ if (await fileExists3(path38__default.join(cwd, "Cargo.toml"))) return "rust";
18522
+ if (await fileExists3(path38__default.join(cwd, "pyproject.toml"))) return "python";
18523
+ if (await fileExists3(path38__default.join(cwd, "go.mod"))) return "go";
18524
+ if (await fileExists3(path38__default.join(cwd, "pom.xml"))) return "java";
18525
18525
  return "unknown";
18526
18526
  }
18527
18527
  async function detectPackageManager(cwd, stack) {
@@ -18529,15 +18529,15 @@ async function detectPackageManager(cwd, stack) {
18529
18529
  if (stack === "python") return "pip";
18530
18530
  if (stack === "go") return "go";
18531
18531
  if (stack === "node") {
18532
- if (await fileExists3(path37__default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
18533
- if (await fileExists3(path37__default.join(cwd, "yarn.lock"))) return "yarn";
18534
- if (await fileExists3(path37__default.join(cwd, "bun.lockb"))) return "bun";
18532
+ if (await fileExists3(path38__default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
18533
+ if (await fileExists3(path38__default.join(cwd, "yarn.lock"))) return "yarn";
18534
+ if (await fileExists3(path38__default.join(cwd, "bun.lockb"))) return "bun";
18535
18535
  return "npm";
18536
18536
  }
18537
18537
  return null;
18538
18538
  }
18539
18539
  async function detectCI(cwd) {
18540
- const ghDir = path37__default.join(cwd, ".github", "workflows");
18540
+ const ghDir = path38__default.join(cwd, ".github", "workflows");
18541
18541
  if (await fileExists3(ghDir)) {
18542
18542
  let workflowFiles = [];
18543
18543
  let hasCodeQL = false;
@@ -18561,7 +18561,7 @@ async function detectCI(cwd) {
18561
18561
  }
18562
18562
  return { type: "github-actions", workflowFiles, hasCodeQL, hasLinting };
18563
18563
  }
18564
- if (await fileExists3(path37__default.join(cwd, ".gitlab-ci.yml"))) {
18564
+ if (await fileExists3(path38__default.join(cwd, ".gitlab-ci.yml"))) {
18565
18565
  return {
18566
18566
  type: "gitlab-ci",
18567
18567
  workflowFiles: [".gitlab-ci.yml"],
@@ -18569,7 +18569,7 @@ async function detectCI(cwd) {
18569
18569
  hasLinting: false
18570
18570
  };
18571
18571
  }
18572
- if (await fileExists3(path37__default.join(cwd, ".circleci"))) {
18572
+ if (await fileExists3(path38__default.join(cwd, ".circleci"))) {
18573
18573
  return { type: "circle-ci", workflowFiles: [], hasCodeQL: false, hasLinting: false };
18574
18574
  }
18575
18575
  return { type: "none", workflowFiles: [], hasCodeQL: false, hasLinting: false };
@@ -19940,8 +19940,8 @@ function hasNullByte(str) {
19940
19940
  }
19941
19941
  function isBlockedPath(absolute) {
19942
19942
  for (const blocked of BLOCKED_PATHS) {
19943
- const normalizedBlocked = path37__default.normalize(blocked);
19944
- if (absolute === normalizedBlocked || absolute.startsWith(normalizedBlocked + path37__default.sep)) {
19943
+ const normalizedBlocked = path38__default.normalize(blocked);
19944
+ if (absolute === normalizedBlocked || absolute.startsWith(normalizedBlocked + path38__default.sep)) {
19945
19945
  return blocked;
19946
19946
  }
19947
19947
  }
@@ -19959,7 +19959,7 @@ function getInterpreter(ext) {
19959
19959
  }
19960
19960
  async function isExecutable(filePath) {
19961
19961
  try {
19962
- await fs34__default.access(filePath, fs34__default.constants.X_OK);
19962
+ await fs35__default.access(filePath, fs35__default.constants.X_OK);
19963
19963
  return true;
19964
19964
  } catch {
19965
19965
  return false;
@@ -20035,7 +20035,7 @@ Examples:
20035
20035
  throw new ToolError("Invalid file path", { tool: "open_file" });
20036
20036
  }
20037
20037
  const workDir = cwd ?? process.cwd();
20038
- const absolute = path37__default.isAbsolute(filePath) ? path37__default.normalize(filePath) : path37__default.resolve(workDir, filePath);
20038
+ const absolute = path38__default.isAbsolute(filePath) ? path38__default.normalize(filePath) : path38__default.resolve(workDir, filePath);
20039
20039
  const blockedBy = isBlockedPath(absolute);
20040
20040
  if (blockedBy) {
20041
20041
  throw new ToolError(`Access to system path '${blockedBy}' is not allowed`, {
@@ -20043,7 +20043,7 @@ Examples:
20043
20043
  });
20044
20044
  }
20045
20045
  try {
20046
- await fs34__default.access(absolute);
20046
+ await fs35__default.access(absolute);
20047
20047
  } catch {
20048
20048
  throw new ToolError(`File not found: ${absolute}`, { tool: "open_file" });
20049
20049
  }
@@ -20058,14 +20058,14 @@ Examples:
20058
20058
  };
20059
20059
  }
20060
20060
  if (isBlockedExecFile(absolute)) {
20061
- throw new ToolError(`Execution of sensitive file is blocked: ${path37__default.basename(absolute)}`, {
20061
+ throw new ToolError(`Execution of sensitive file is blocked: ${path38__default.basename(absolute)}`, {
20062
20062
  tool: "open_file"
20063
20063
  });
20064
20064
  }
20065
20065
  if (args.length > 0 && hasDangerousArgs(args)) {
20066
20066
  throw new ToolError("Arguments contain dangerous patterns", { tool: "open_file" });
20067
20067
  }
20068
- const ext = path37__default.extname(absolute);
20068
+ const ext = path38__default.extname(absolute);
20069
20069
  const interpreter = getInterpreter(ext);
20070
20070
  const executable = await isExecutable(absolute);
20071
20071
  let command;
@@ -20078,7 +20078,7 @@ Examples:
20078
20078
  cmdArgs = [...args];
20079
20079
  } else {
20080
20080
  throw new ToolError(
20081
- `Cannot execute '${path37__default.basename(absolute)}': no known interpreter for '${ext || "(no extension)"}' and file is not executable`,
20081
+ `Cannot execute '${path38__default.basename(absolute)}': no known interpreter for '${ext || "(no extension)"}' and file is not executable`,
20082
20082
  { tool: "open_file" }
20083
20083
  );
20084
20084
  }
@@ -20250,10 +20250,10 @@ function getAllowedPaths() {
20250
20250
  return [...sessionAllowedPaths];
20251
20251
  }
20252
20252
  function isWithinAllowedPath(absolutePath, operation) {
20253
- const normalizedTarget = path37__default.normalize(absolutePath);
20253
+ const normalizedTarget = path38__default.normalize(absolutePath);
20254
20254
  for (const entry of sessionAllowedPaths) {
20255
- const normalizedAllowed = path37__default.normalize(entry.path);
20256
- if (normalizedTarget === normalizedAllowed || normalizedTarget.startsWith(normalizedAllowed + path37__default.sep)) {
20255
+ const normalizedAllowed = path38__default.normalize(entry.path);
20256
+ if (normalizedTarget === normalizedAllowed || normalizedTarget.startsWith(normalizedAllowed + path38__default.sep)) {
20257
20257
  if (operation === "read") return true;
20258
20258
  if (entry.level === "write") return true;
20259
20259
  }
@@ -20261,8 +20261,8 @@ function isWithinAllowedPath(absolutePath, operation) {
20261
20261
  return false;
20262
20262
  }
20263
20263
  function addAllowedPathToSession(dirPath, level) {
20264
- const absolute = path37__default.resolve(dirPath);
20265
- if (sessionAllowedPaths.some((e) => path37__default.normalize(e.path) === path37__default.normalize(absolute))) {
20264
+ const absolute = path38__default.resolve(dirPath);
20265
+ if (sessionAllowedPaths.some((e) => path38__default.normalize(e.path) === path38__default.normalize(absolute))) {
20266
20266
  return;
20267
20267
  }
20268
20268
  sessionAllowedPaths.push({
@@ -20272,14 +20272,14 @@ function addAllowedPathToSession(dirPath, level) {
20272
20272
  });
20273
20273
  }
20274
20274
  function removeAllowedPathFromSession(dirPath) {
20275
- const absolute = path37__default.resolve(dirPath);
20276
- const normalized = path37__default.normalize(absolute);
20275
+ const absolute = path38__default.resolve(dirPath);
20276
+ const normalized = path38__default.normalize(absolute);
20277
20277
  const before = sessionAllowedPaths.length;
20278
- sessionAllowedPaths = sessionAllowedPaths.filter((e) => path37__default.normalize(e.path) !== normalized);
20278
+ sessionAllowedPaths = sessionAllowedPaths.filter((e) => path38__default.normalize(e.path) !== normalized);
20279
20279
  return sessionAllowedPaths.length < before;
20280
20280
  }
20281
20281
  async function loadAllowedPaths(projectPath) {
20282
- currentProjectPath = path37__default.resolve(projectPath);
20282
+ currentProjectPath = path38__default.resolve(projectPath);
20283
20283
  const store = await loadStore();
20284
20284
  const entries = store.projects[currentProjectPath] ?? [];
20285
20285
  for (const entry of entries) {
@@ -20288,14 +20288,14 @@ async function loadAllowedPaths(projectPath) {
20288
20288
  }
20289
20289
  async function persistAllowedPath(dirPath, level) {
20290
20290
  if (!currentProjectPath) return;
20291
- const absolute = path37__default.resolve(dirPath);
20291
+ const absolute = path38__default.resolve(dirPath);
20292
20292
  const store = await loadStore();
20293
20293
  if (!store.projects[currentProjectPath]) {
20294
20294
  store.projects[currentProjectPath] = [];
20295
20295
  }
20296
20296
  const entries = store.projects[currentProjectPath];
20297
- const normalized = path37__default.normalize(absolute);
20298
- if (entries.some((e) => path37__default.normalize(e.path) === normalized)) {
20297
+ const normalized = path38__default.normalize(absolute);
20298
+ if (entries.some((e) => path38__default.normalize(e.path) === normalized)) {
20299
20299
  return;
20300
20300
  }
20301
20301
  entries.push({
@@ -20307,13 +20307,13 @@ async function persistAllowedPath(dirPath, level) {
20307
20307
  }
20308
20308
  async function removePersistedAllowedPath(dirPath) {
20309
20309
  if (!currentProjectPath) return false;
20310
- const absolute = path37__default.resolve(dirPath);
20311
- const normalized = path37__default.normalize(absolute);
20310
+ const absolute = path38__default.resolve(dirPath);
20311
+ const normalized = path38__default.normalize(absolute);
20312
20312
  const store = await loadStore();
20313
20313
  const entries = store.projects[currentProjectPath];
20314
20314
  if (!entries) return false;
20315
20315
  const before = entries.length;
20316
- store.projects[currentProjectPath] = entries.filter((e) => path37__default.normalize(e.path) !== normalized);
20316
+ store.projects[currentProjectPath] = entries.filter((e) => path38__default.normalize(e.path) !== normalized);
20317
20317
  if (store.projects[currentProjectPath].length < before) {
20318
20318
  await saveStore(store);
20319
20319
  return true;
@@ -20322,7 +20322,7 @@ async function removePersistedAllowedPath(dirPath) {
20322
20322
  }
20323
20323
  async function loadStore() {
20324
20324
  try {
20325
- const content = await fs34__default.readFile(STORE_FILE, "utf-8");
20325
+ const content = await fs35__default.readFile(STORE_FILE, "utf-8");
20326
20326
  return { ...DEFAULT_STORE, ...JSON.parse(content) };
20327
20327
  } catch {
20328
20328
  return { ...DEFAULT_STORE };
@@ -20330,8 +20330,8 @@ async function loadStore() {
20330
20330
  }
20331
20331
  async function saveStore(store) {
20332
20332
  try {
20333
- await fs34__default.mkdir(path37__default.dirname(STORE_FILE), { recursive: true });
20334
- await fs34__default.writeFile(STORE_FILE, JSON.stringify(store, null, 2), "utf-8");
20333
+ await fs35__default.mkdir(path38__default.dirname(STORE_FILE), { recursive: true });
20334
+ await fs35__default.writeFile(STORE_FILE, JSON.stringify(store, null, 2), "utf-8");
20335
20335
  } catch {
20336
20336
  }
20337
20337
  }
@@ -20339,7 +20339,7 @@ var STORE_FILE, DEFAULT_STORE, sessionAllowedPaths, currentProjectPath;
20339
20339
  var init_allowed_paths = __esm({
20340
20340
  "src/tools/allowed-paths.ts"() {
20341
20341
  init_paths();
20342
- STORE_FILE = path37__default.join(CONFIG_PATHS.home, "allowed-paths.json");
20342
+ STORE_FILE = path38__default.join(CONFIG_PATHS.home, "allowed-paths.json");
20343
20343
  DEFAULT_STORE = {
20344
20344
  version: 1,
20345
20345
  projects: {}
@@ -20395,7 +20395,7 @@ function shouldAutoApprove(command, cwd) {
20395
20395
  }
20396
20396
  async function loadFullAccessPreference() {
20397
20397
  try {
20398
- const content = await fs34__default.readFile(CONFIG_PATHS.config, "utf-8");
20398
+ const content = await fs35__default.readFile(CONFIG_PATHS.config, "utf-8");
20399
20399
  const config = JSON.parse(content);
20400
20400
  if (typeof config.fullAccessMode === "boolean") {
20401
20401
  fullAccessEnabled = config.fullAccessMode;
@@ -20409,12 +20409,12 @@ async function saveFullAccessPreference(enabled) {
20409
20409
  try {
20410
20410
  let config = {};
20411
20411
  try {
20412
- const content = await fs34__default.readFile(CONFIG_PATHS.config, "utf-8");
20412
+ const content = await fs35__default.readFile(CONFIG_PATHS.config, "utf-8");
20413
20413
  config = JSON.parse(content);
20414
20414
  } catch {
20415
20415
  }
20416
20416
  config.fullAccessMode = enabled;
20417
- await fs34__default.writeFile(CONFIG_PATHS.config, JSON.stringify(config, null, 2) + "\n");
20417
+ await fs35__default.writeFile(CONFIG_PATHS.config, JSON.stringify(config, null, 2) + "\n");
20418
20418
  } catch {
20419
20419
  }
20420
20420
  }
@@ -20822,12 +20822,384 @@ var init_stdio = __esm({
20822
20822
  };
20823
20823
  }
20824
20824
  });
20825
+ function getResourceKey(resourceUrl) {
20826
+ const resource = canonicalizeResourceUrl(resourceUrl);
20827
+ return resource.toLowerCase();
20828
+ }
20829
+ function canonicalizeResourceUrl(resourceUrl) {
20830
+ const parsed = new URL(resourceUrl);
20831
+ parsed.search = "";
20832
+ parsed.hash = "";
20833
+ if (parsed.pathname === "/") {
20834
+ return `${parsed.protocol}//${parsed.host}`;
20835
+ }
20836
+ parsed.pathname = parsed.pathname.replace(/\/+$/, "");
20837
+ return parsed.toString();
20838
+ }
20839
+ async function loadStore2() {
20840
+ try {
20841
+ const content = await fs35__default.readFile(TOKEN_STORE_PATH, "utf-8");
20842
+ const parsed = JSON.parse(content);
20843
+ return {
20844
+ tokens: parsed.tokens ?? {},
20845
+ clients: parsed.clients ?? {}
20846
+ };
20847
+ } catch {
20848
+ return { tokens: {}, clients: {} };
20849
+ }
20850
+ }
20851
+ async function saveStore2(store) {
20852
+ await fs35__default.mkdir(path38__default.dirname(TOKEN_STORE_PATH), { recursive: true });
20853
+ await fs35__default.writeFile(TOKEN_STORE_PATH, JSON.stringify(store, null, 2), {
20854
+ encoding: "utf-8",
20855
+ mode: 384
20856
+ });
20857
+ }
20858
+ function isTokenExpired2(token) {
20859
+ if (!token.expiresAt) return false;
20860
+ return Date.now() >= token.expiresAt - 3e4;
20861
+ }
20862
+ async function getStoredMcpOAuthToken(resourceUrl) {
20863
+ const store = await loadStore2();
20864
+ const token = store.tokens[getResourceKey(resourceUrl)];
20865
+ if (!token) return void 0;
20866
+ if (isTokenExpired2(token)) return void 0;
20867
+ return token.accessToken;
20868
+ }
20869
+ function createCodeVerifier() {
20870
+ return randomBytes(32).toString("base64url");
20871
+ }
20872
+ function createCodeChallenge(verifier) {
20873
+ return createHash("sha256").update(verifier).digest("base64url");
20874
+ }
20875
+ function createState() {
20876
+ return randomBytes(16).toString("hex");
20877
+ }
20878
+ async function openBrowser2(url) {
20879
+ let safeUrl;
20880
+ try {
20881
+ const parsed = new URL(url);
20882
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
20883
+ return false;
20884
+ }
20885
+ safeUrl = parsed.toString();
20886
+ } catch {
20887
+ return false;
20888
+ }
20889
+ const isWSL2 = process.platform === "linux" && (process.env["WSL_DISTRO_NAME"] !== void 0 || process.env["WSL_INTEROP"] !== void 0 || process.env["TERM_PROGRAM"]?.toLowerCase().includes("wsl") === true);
20890
+ const commands2 = [];
20891
+ if (process.platform === "darwin") {
20892
+ commands2.push(
20893
+ { cmd: "open", args: [safeUrl] },
20894
+ { cmd: "open", args: ["-a", "Safari", safeUrl] },
20895
+ { cmd: "open", args: ["-a", "Google Chrome", safeUrl] }
20896
+ );
20897
+ } else if (process.platform === "win32") {
20898
+ commands2.push({ cmd: "rundll32", args: ["url.dll,FileProtocolHandler", safeUrl] });
20899
+ } else if (isWSL2) {
20900
+ commands2.push(
20901
+ { cmd: "cmd.exe", args: ["/c", "start", "", safeUrl] },
20902
+ { cmd: "powershell.exe", args: ["-Command", `Start-Process '${safeUrl}'`] },
20903
+ { cmd: "wslview", args: [safeUrl] }
20904
+ );
20905
+ } else {
20906
+ commands2.push(
20907
+ { cmd: "xdg-open", args: [safeUrl] },
20908
+ { cmd: "sensible-browser", args: [safeUrl] },
20909
+ { cmd: "x-www-browser", args: [safeUrl] },
20910
+ { cmd: "gnome-open", args: [safeUrl] },
20911
+ { cmd: "firefox", args: [safeUrl] },
20912
+ { cmd: "chromium-browser", args: [safeUrl] },
20913
+ { cmd: "google-chrome", args: [safeUrl] }
20914
+ );
20915
+ }
20916
+ for (const { cmd, args } of commands2) {
20917
+ try {
20918
+ await execFileAsync2(cmd, args);
20919
+ return true;
20920
+ } catch {
20921
+ continue;
20922
+ }
20923
+ }
20924
+ return false;
20925
+ }
20926
+ function maskUrlForLogs(rawUrl) {
20927
+ try {
20928
+ const url = new URL(rawUrl);
20929
+ url.search = "";
20930
+ url.hash = "";
20931
+ return url.toString();
20932
+ } catch {
20933
+ return "[invalid-url]";
20934
+ }
20935
+ }
20936
+ function parseResourceMetadataUrl(wwwAuthenticateHeader) {
20937
+ if (!wwwAuthenticateHeader) return void 0;
20938
+ const match = wwwAuthenticateHeader.match(/resource_metadata="([^"]+)"/i);
20939
+ return match?.[1];
20940
+ }
20941
+ function createProtectedMetadataCandidates(resourceUrl, headerUrl) {
20942
+ const candidates = [];
20943
+ if (headerUrl) {
20944
+ candidates.push(headerUrl);
20945
+ }
20946
+ const resource = new URL(resourceUrl);
20947
+ const origin = `${resource.protocol}//${resource.host}`;
20948
+ const pathPart = resource.pathname.replace(/\/+$/, "");
20949
+ candidates.push(`${origin}/.well-known/oauth-protected-resource`);
20950
+ if (pathPart && pathPart !== "/") {
20951
+ candidates.push(`${origin}/.well-known/oauth-protected-resource${pathPart}`);
20952
+ candidates.push(`${origin}/.well-known/oauth-protected-resource/${pathPart.replace(/^\//, "")}`);
20953
+ }
20954
+ return Array.from(new Set(candidates));
20955
+ }
20956
+ async function fetchJson(url) {
20957
+ const res = await fetch(url, { method: "GET", headers: { Accept: "application/json" } });
20958
+ if (!res.ok) {
20959
+ throw new Error(`HTTP ${res.status} while fetching ${url}`);
20960
+ }
20961
+ return await res.json();
20962
+ }
20963
+ function buildAuthorizationMetadataCandidates(issuer) {
20964
+ const parsed = new URL(issuer);
20965
+ const base = `${parsed.protocol}//${parsed.host}`;
20966
+ const issuerPath = parsed.pathname === "/" ? "" : parsed.pathname.replace(/\/+$/, "");
20967
+ const candidates = [
20968
+ `${base}/.well-known/oauth-authorization-server${issuerPath}`,
20969
+ `${base}/.well-known/oauth-authorization-server`,
20970
+ `${base}/.well-known/openid-configuration${issuerPath}`,
20971
+ `${base}/.well-known/openid-configuration`
20972
+ ];
20973
+ return Array.from(new Set(candidates));
20974
+ }
20975
+ async function discoverProtectedResourceMetadata(resourceUrl, wwwAuthenticateHeader) {
20976
+ const headerUrl = parseResourceMetadataUrl(wwwAuthenticateHeader);
20977
+ const candidates = createProtectedMetadataCandidates(resourceUrl, headerUrl);
20978
+ for (const candidate of candidates) {
20979
+ try {
20980
+ const metadata = await fetchJson(candidate);
20981
+ if (Array.isArray(metadata.authorization_servers) && metadata.authorization_servers.length > 0) {
20982
+ return metadata;
20983
+ }
20984
+ } catch {
20985
+ }
20986
+ }
20987
+ throw new Error("Could not discover OAuth protected resource metadata for MCP server");
20988
+ }
20989
+ async function discoverAuthorizationServerMetadata(authorizationServer) {
20990
+ const candidates = buildAuthorizationMetadataCandidates(authorizationServer);
20991
+ for (const candidate of candidates) {
20992
+ try {
20993
+ const metadata = await fetchJson(candidate);
20994
+ if (metadata.authorization_endpoint && metadata.token_endpoint) {
20995
+ return metadata;
20996
+ }
20997
+ } catch {
20998
+ }
20999
+ }
21000
+ throw new Error("Could not discover OAuth authorization server metadata");
21001
+ }
21002
+ async function ensureClientId(authorizationMetadata, authorizationServer, redirectUri) {
21003
+ const store = await loadStore2();
21004
+ const clientKey = `${authorizationServer}|${redirectUri}`;
21005
+ const existing = store.clients[clientKey]?.clientId;
21006
+ if (existing) return existing;
21007
+ const registrationEndpoint = authorizationMetadata.registration_endpoint;
21008
+ if (!registrationEndpoint) {
21009
+ throw new Error(
21010
+ "Authorization server does not expose dynamic client registration; configure a static OAuth client ID for this MCP server."
21011
+ );
21012
+ }
21013
+ const registrationPayload = {
21014
+ client_name: "corbat-coco-mcp",
21015
+ redirect_uris: [redirectUri],
21016
+ grant_types: ["authorization_code", "refresh_token"],
21017
+ response_types: ["code"],
21018
+ token_endpoint_auth_method: "none"
21019
+ };
21020
+ const response = await fetch(registrationEndpoint, {
21021
+ method: "POST",
21022
+ headers: {
21023
+ "Content-Type": "application/json",
21024
+ Accept: "application/json"
21025
+ },
21026
+ body: JSON.stringify(registrationPayload)
21027
+ });
21028
+ if (!response.ok) {
21029
+ throw new Error(`Dynamic client registration failed: HTTP ${response.status}`);
21030
+ }
21031
+ const data = await response.json();
21032
+ const clientId = data.client_id;
21033
+ if (!clientId) {
21034
+ throw new Error("Dynamic client registration did not return client_id");
21035
+ }
21036
+ store.clients[clientKey] = { clientId };
21037
+ await saveStore2(store);
21038
+ return clientId;
21039
+ }
21040
+ async function refreshAccessToken2(params) {
21041
+ const body = new URLSearchParams({
21042
+ grant_type: "refresh_token",
21043
+ client_id: params.clientId,
21044
+ refresh_token: params.refreshToken,
21045
+ resource: params.resource
21046
+ });
21047
+ const response = await fetch(params.tokenEndpoint, {
21048
+ method: "POST",
21049
+ headers: {
21050
+ "Content-Type": "application/x-www-form-urlencoded",
21051
+ Accept: "application/json"
21052
+ },
21053
+ body: body.toString()
21054
+ });
21055
+ if (!response.ok) {
21056
+ throw new Error(`Refresh token exchange failed: HTTP ${response.status}`);
21057
+ }
21058
+ const tokenResponse = await response.json();
21059
+ if (!tokenResponse.access_token) {
21060
+ throw new Error("Refresh token response missing access_token");
21061
+ }
21062
+ return tokenResponse;
21063
+ }
21064
+ async function exchangeCodeForToken(tokenEndpoint, clientId, code, codeVerifier, redirectUri, resource) {
21065
+ const body = new URLSearchParams({
21066
+ grant_type: "authorization_code",
21067
+ code,
21068
+ client_id: clientId,
21069
+ redirect_uri: redirectUri,
21070
+ code_verifier: codeVerifier,
21071
+ resource
21072
+ });
21073
+ const response = await fetch(tokenEndpoint, {
21074
+ method: "POST",
21075
+ headers: {
21076
+ "Content-Type": "application/x-www-form-urlencoded",
21077
+ Accept: "application/json"
21078
+ },
21079
+ body: body.toString()
21080
+ });
21081
+ if (!response.ok) {
21082
+ throw new Error(`Token exchange failed: HTTP ${response.status}`);
21083
+ }
21084
+ const tokenResponse = await response.json();
21085
+ if (!tokenResponse.access_token) {
21086
+ throw new Error("Token exchange response missing access_token");
21087
+ }
21088
+ return tokenResponse;
21089
+ }
21090
+ async function persistToken(resourceUrl, token, metadata) {
21091
+ const store = await loadStore2();
21092
+ const expiresAt = typeof token.expires_in === "number" ? Date.now() + Math.max(0, token.expires_in) * 1e3 : void 0;
21093
+ store.tokens[getResourceKey(resourceUrl)] = {
21094
+ accessToken: token.access_token,
21095
+ tokenType: token.token_type,
21096
+ refreshToken: token.refresh_token,
21097
+ authorizationServer: metadata?.authorizationServer,
21098
+ clientId: metadata?.clientId,
21099
+ resource: canonicalizeResourceUrl(resourceUrl),
21100
+ ...expiresAt ? { expiresAt } : {}
21101
+ };
21102
+ await saveStore2(store);
21103
+ }
21104
+ async function authenticateMcpOAuth(params) {
21105
+ const resource = canonicalizeResourceUrl(params.resourceUrl);
21106
+ const store = await loadStore2();
21107
+ const stored = store.tokens[getResourceKey(resource)];
21108
+ if (stored && !isTokenExpired2(stored)) {
21109
+ return stored.accessToken;
21110
+ }
21111
+ if (!process.stdout.isTTY) {
21112
+ throw new Error(
21113
+ `MCP server '${params.serverName}' requires interactive OAuth in a TTY session. Run Coco in a terminal, or use mcp-remote (e.g. npx -y mcp-remote@latest ${resource}) for IDE bridge workflows.`
21114
+ );
21115
+ }
21116
+ const protectedMetadata = await discoverProtectedResourceMetadata(
21117
+ resource,
21118
+ params.wwwAuthenticateHeader
21119
+ );
21120
+ const authorizationServer = protectedMetadata.authorization_servers?.[0];
21121
+ if (!authorizationServer) {
21122
+ throw new Error("Protected resource metadata does not include authorization_servers");
21123
+ }
21124
+ const authorizationMetadata = await discoverAuthorizationServerMetadata(authorizationServer);
21125
+ if (stored && isTokenExpired2(stored) && stored.refreshToken && stored.clientId) {
21126
+ try {
21127
+ const refreshed = await refreshAccessToken2({
21128
+ tokenEndpoint: authorizationMetadata.token_endpoint,
21129
+ clientId: stored.clientId,
21130
+ refreshToken: stored.refreshToken,
21131
+ resource
21132
+ });
21133
+ await persistToken(resource, refreshed, {
21134
+ authorizationServer,
21135
+ clientId: stored.clientId
21136
+ });
21137
+ return refreshed.access_token;
21138
+ } catch {
21139
+ }
21140
+ }
21141
+ const codeVerifier = createCodeVerifier();
21142
+ const codeChallenge = createCodeChallenge(codeVerifier);
21143
+ const state = createState();
21144
+ const { port, resultPromise } = await createCallbackServer(
21145
+ state,
21146
+ OAUTH_TIMEOUT_MS,
21147
+ OAUTH_CALLBACK_PORT
21148
+ );
21149
+ const redirectUri = `http://localhost:${port}/auth/callback`;
21150
+ const clientId = await ensureClientId(authorizationMetadata, authorizationServer, redirectUri);
21151
+ const authUrl = new URL(authorizationMetadata.authorization_endpoint);
21152
+ authUrl.searchParams.set("response_type", "code");
21153
+ authUrl.searchParams.set("client_id", clientId);
21154
+ authUrl.searchParams.set("redirect_uri", redirectUri);
21155
+ authUrl.searchParams.set("state", state);
21156
+ authUrl.searchParams.set("code_challenge", codeChallenge);
21157
+ authUrl.searchParams.set("code_challenge_method", "S256");
21158
+ authUrl.searchParams.set("resource", resource);
21159
+ if (authorizationMetadata.scopes_supported?.includes("offline_access")) {
21160
+ authUrl.searchParams.set("scope", "offline_access");
21161
+ }
21162
+ const opened = await openBrowser2(authUrl.toString());
21163
+ if (!opened) {
21164
+ logger.warn(`[MCP OAuth] Could not open browser automatically for '${params.serverName}'`);
21165
+ logger.warn(`[MCP OAuth] Manual auth URL base: ${maskUrlForLogs(authUrl.toString())}`);
21166
+ console.log(`[MCP OAuth] Open this URL manually: ${authUrl.toString()}`);
21167
+ } else {
21168
+ logger.info(
21169
+ `[MCP OAuth] Opened browser for '${params.serverName}'. Complete login to continue.`
21170
+ );
21171
+ }
21172
+ const callback = await resultPromise;
21173
+ const token = await exchangeCodeForToken(
21174
+ authorizationMetadata.token_endpoint,
21175
+ clientId,
21176
+ callback.code,
21177
+ codeVerifier,
21178
+ redirectUri,
21179
+ resource
21180
+ );
21181
+ await persistToken(resource, token, { authorizationServer, clientId });
21182
+ return token.access_token;
21183
+ }
21184
+ var execFileAsync2, TOKEN_STORE_PATH, OAUTH_TIMEOUT_MS, logger;
21185
+ var init_oauth2 = __esm({
21186
+ "src/mcp/oauth.ts"() {
21187
+ init_callback_server();
21188
+ init_paths();
21189
+ init_logger();
21190
+ execFileAsync2 = promisify(execFile);
21191
+ TOKEN_STORE_PATH = path38__default.join(CONFIG_PATHS.tokens, "mcp-oauth.json");
21192
+ OAUTH_TIMEOUT_MS = 5 * 60 * 1e3;
21193
+ logger = getLogger();
21194
+ }
21195
+ });
20825
21196
 
20826
21197
  // src/mcp/transport/http.ts
20827
21198
  var HTTPTransport;
20828
21199
  var init_http = __esm({
20829
21200
  "src/mcp/transport/http.ts"() {
20830
21201
  init_errors2();
21202
+ init_oauth2();
20831
21203
  init_errors2();
20832
21204
  HTTPTransport = class {
20833
21205
  constructor(config) {
@@ -20845,10 +21217,15 @@ var init_http = __esm({
20845
21217
  connected = false;
20846
21218
  abortController = null;
20847
21219
  pendingRequests = /* @__PURE__ */ new Map();
21220
+ oauthToken;
21221
+ oauthInFlight = null;
20848
21222
  /**
20849
21223
  * Get authentication token
20850
21224
  */
20851
21225
  getAuthToken() {
21226
+ if (this.oauthToken) {
21227
+ return this.oauthToken;
21228
+ }
20852
21229
  if (!this.config.auth) return void 0;
20853
21230
  if (this.config.auth.token) {
20854
21231
  return this.config.auth.token;
@@ -20867,22 +21244,64 @@ var init_http = __esm({
20867
21244
  Accept: "application/json",
20868
21245
  ...this.config.headers
20869
21246
  };
21247
+ if (this.oauthToken) {
21248
+ headers["Authorization"] = `Bearer ${this.oauthToken}`;
21249
+ return headers;
21250
+ }
20870
21251
  const token = this.getAuthToken();
20871
21252
  if (token && this.config.auth) {
20872
- switch (this.config.auth.type) {
20873
- case "bearer":
20874
- headers["Authorization"] = `Bearer ${token}`;
20875
- break;
20876
- case "apikey":
20877
- headers[this.config.auth.headerName || "X-API-Key"] = token;
20878
- break;
20879
- case "oauth":
20880
- headers["Authorization"] = `Bearer ${token}`;
20881
- break;
21253
+ if (this.config.auth.type === "apikey") {
21254
+ headers[this.config.auth.headerName || "X-API-Key"] = token;
21255
+ } else {
21256
+ headers["Authorization"] = `Bearer ${token}`;
20882
21257
  }
20883
21258
  }
20884
21259
  return headers;
20885
21260
  }
21261
+ shouldAttemptOAuth() {
21262
+ if (this.config.auth?.type === "apikey") {
21263
+ return false;
21264
+ }
21265
+ if (this.config.auth?.type === "bearer") {
21266
+ return !this.getAuthToken();
21267
+ }
21268
+ return true;
21269
+ }
21270
+ async ensureOAuthToken(wwwAuthenticateHeader) {
21271
+ if (this.oauthToken) {
21272
+ return this.oauthToken;
21273
+ }
21274
+ if (this.oauthInFlight) {
21275
+ return this.oauthInFlight;
21276
+ }
21277
+ const serverName = this.config.name ?? this.config.url;
21278
+ this.oauthInFlight = authenticateMcpOAuth({
21279
+ serverName,
21280
+ resourceUrl: this.config.url,
21281
+ wwwAuthenticateHeader
21282
+ }).then((token) => {
21283
+ this.oauthToken = token;
21284
+ return token;
21285
+ }).finally(() => {
21286
+ this.oauthInFlight = null;
21287
+ });
21288
+ return this.oauthInFlight;
21289
+ }
21290
+ async sendRequestWithOAuthRetry(method, body, signal) {
21291
+ const doFetch = async () => fetch(this.config.url, {
21292
+ method,
21293
+ headers: this.buildHeaders(),
21294
+ ...body ? { body } : {},
21295
+ signal
21296
+ });
21297
+ let response = await doFetch();
21298
+ if (response.status !== 401 || !this.shouldAttemptOAuth()) {
21299
+ return response;
21300
+ }
21301
+ await this.ensureOAuthToken(response.headers.get("www-authenticate"));
21302
+ response = await doFetch();
21303
+ return response;
21304
+ }
20886
21305
  /**
20887
21306
  * Connect to the HTTP transport
20888
21307
  */
@@ -20897,11 +21316,14 @@ var init_http = __esm({
20897
21316
  }
20898
21317
  try {
20899
21318
  this.abortController = new AbortController();
20900
- const response = await fetch(this.config.url, {
20901
- method: "GET",
20902
- headers: this.buildHeaders(),
20903
- signal: this.abortController.signal
20904
- });
21319
+ if (this.shouldAttemptOAuth()) {
21320
+ this.oauthToken = await getStoredMcpOAuthToken(this.config.url);
21321
+ }
21322
+ const response = await this.sendRequestWithOAuthRetry(
21323
+ "GET",
21324
+ void 0,
21325
+ this.abortController.signal
21326
+ );
20905
21327
  if (!response.ok && response.status !== 404) {
20906
21328
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
20907
21329
  }
@@ -20933,12 +21355,11 @@ var init_http = __esm({
20933
21355
  const timeoutId = setTimeout(() => {
20934
21356
  abortController.abort();
20935
21357
  }, this.config.timeout);
20936
- const response = await fetch(this.config.url, {
20937
- method: "POST",
20938
- headers: this.buildHeaders(),
20939
- body: JSON.stringify(message),
20940
- signal: abortController.signal
20941
- });
21358
+ const response = await this.sendRequestWithOAuthRetry(
21359
+ "POST",
21360
+ JSON.stringify(message),
21361
+ abortController.signal
21362
+ );
20942
21363
  clearTimeout(timeoutId);
20943
21364
  if (!response.ok) {
20944
21365
  throw new MCPTransportError(`HTTP error ${response.status}: ${response.statusText}`);
@@ -21314,6 +21735,7 @@ var init_lifecycle = __esm({
21314
21735
  throw new MCPConnectionError(`Server '${config.name}' requires http.url`);
21315
21736
  }
21316
21737
  return new HTTPTransport({
21738
+ name: config.name,
21317
21739
  url: config.http.url,
21318
21740
  headers: config.http.headers,
21319
21741
  auth: config.http.auth
@@ -21530,7 +21952,7 @@ function shouldFullPowerApprove(command) {
21530
21952
  }
21531
21953
  async function loadFullPowerRiskPreference() {
21532
21954
  try {
21533
- const content = await fs34__default.readFile(CONFIG_PATHS.config, "utf-8");
21955
+ const content = await fs35__default.readFile(CONFIG_PATHS.config, "utf-8");
21534
21956
  const config = JSON.parse(content);
21535
21957
  if (typeof config.fullPowerRiskMode === "boolean") {
21536
21958
  fullPowerRiskEnabled = config.fullPowerRiskMode;
@@ -21544,12 +21966,12 @@ async function saveFullPowerRiskPreference(enabled) {
21544
21966
  try {
21545
21967
  let config = {};
21546
21968
  try {
21547
- const content = await fs34__default.readFile(CONFIG_PATHS.config, "utf-8");
21969
+ const content = await fs35__default.readFile(CONFIG_PATHS.config, "utf-8");
21548
21970
  config = JSON.parse(content);
21549
21971
  } catch {
21550
21972
  }
21551
21973
  config.fullPowerRiskMode = enabled;
21552
- await fs34__default.writeFile(CONFIG_PATHS.config, JSON.stringify(config, null, 2) + "\n");
21974
+ await fs35__default.writeFile(CONFIG_PATHS.config, JSON.stringify(config, null, 2) + "\n");
21553
21975
  } catch {
21554
21976
  }
21555
21977
  }
@@ -21601,7 +22023,7 @@ __export(allow_path_prompt_exports, {
21601
22023
  promptAllowPath: () => promptAllowPath
21602
22024
  });
21603
22025
  async function promptAllowPath(dirPath) {
21604
- const absolute = path37__default.resolve(dirPath);
22026
+ const absolute = path38__default.resolve(dirPath);
21605
22027
  console.log();
21606
22028
  console.log(chalk.yellow(" \u26A0 Access denied \u2014 path is outside the project directory"));
21607
22029
  console.log(chalk.dim(` \u{1F4C1} ${absolute}`));
@@ -21843,13 +22265,13 @@ __export(stack_detector_exports, {
21843
22265
  detectProjectStack: () => detectProjectStack
21844
22266
  });
21845
22267
  async function detectStack2(cwd) {
21846
- if (await fileExists3(path37__default.join(cwd, "package.json"))) return "node";
21847
- if (await fileExists3(path37__default.join(cwd, "Cargo.toml"))) return "rust";
21848
- if (await fileExists3(path37__default.join(cwd, "pyproject.toml"))) return "python";
21849
- if (await fileExists3(path37__default.join(cwd, "go.mod"))) return "go";
21850
- if (await fileExists3(path37__default.join(cwd, "pom.xml"))) return "java";
21851
- if (await fileExists3(path37__default.join(cwd, "build.gradle"))) return "java";
21852
- if (await fileExists3(path37__default.join(cwd, "build.gradle.kts"))) return "java";
22268
+ if (await fileExists3(path38__default.join(cwd, "package.json"))) return "node";
22269
+ if (await fileExists3(path38__default.join(cwd, "Cargo.toml"))) return "rust";
22270
+ if (await fileExists3(path38__default.join(cwd, "pyproject.toml"))) return "python";
22271
+ if (await fileExists3(path38__default.join(cwd, "go.mod"))) return "go";
22272
+ if (await fileExists3(path38__default.join(cwd, "pom.xml"))) return "java";
22273
+ if (await fileExists3(path38__default.join(cwd, "build.gradle"))) return "java";
22274
+ if (await fileExists3(path38__default.join(cwd, "build.gradle.kts"))) return "java";
21853
22275
  return "unknown";
21854
22276
  }
21855
22277
  async function detectPackageManager3(cwd, stack) {
@@ -21857,25 +22279,25 @@ async function detectPackageManager3(cwd, stack) {
21857
22279
  if (stack === "python") return "pip";
21858
22280
  if (stack === "go") return "go";
21859
22281
  if (stack === "java") {
21860
- if (await fileExists3(path37__default.join(cwd, "build.gradle")) || await fileExists3(path37__default.join(cwd, "build.gradle.kts"))) {
22282
+ if (await fileExists3(path38__default.join(cwd, "build.gradle")) || await fileExists3(path38__default.join(cwd, "build.gradle.kts"))) {
21861
22283
  return "gradle";
21862
22284
  }
21863
- if (await fileExists3(path37__default.join(cwd, "pom.xml"))) {
22285
+ if (await fileExists3(path38__default.join(cwd, "pom.xml"))) {
21864
22286
  return "maven";
21865
22287
  }
21866
22288
  }
21867
22289
  if (stack === "node") {
21868
- if (await fileExists3(path37__default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
21869
- if (await fileExists3(path37__default.join(cwd, "yarn.lock"))) return "yarn";
21870
- if (await fileExists3(path37__default.join(cwd, "bun.lockb"))) return "bun";
22290
+ if (await fileExists3(path38__default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
22291
+ if (await fileExists3(path38__default.join(cwd, "yarn.lock"))) return "yarn";
22292
+ if (await fileExists3(path38__default.join(cwd, "bun.lockb"))) return "bun";
21871
22293
  return "npm";
21872
22294
  }
21873
22295
  return null;
21874
22296
  }
21875
22297
  async function parsePackageJson(cwd) {
21876
- const packageJsonPath = path37__default.join(cwd, "package.json");
22298
+ const packageJsonPath = path38__default.join(cwd, "package.json");
21877
22299
  try {
21878
- const content = await fs34__default.readFile(packageJsonPath, "utf-8");
22300
+ const content = await fs35__default.readFile(packageJsonPath, "utf-8");
21879
22301
  const pkg = JSON.parse(content);
21880
22302
  const allDeps = {
21881
22303
  ...pkg.dependencies,
@@ -21905,7 +22327,7 @@ async function parsePackageJson(cwd) {
21905
22327
  if (allDeps["@playwright/test"]) testingFrameworks.push("playwright");
21906
22328
  if (allDeps.cypress) testingFrameworks.push("cypress");
21907
22329
  const languages = ["JavaScript"];
21908
- if (allDeps.typescript || await fileExists3(path37__default.join(cwd, "tsconfig.json"))) {
22330
+ if (allDeps.typescript || await fileExists3(path38__default.join(cwd, "tsconfig.json"))) {
21909
22331
  languages.push("TypeScript");
21910
22332
  }
21911
22333
  return {
@@ -21926,9 +22348,9 @@ async function parsePackageJson(cwd) {
21926
22348
  }
21927
22349
  }
21928
22350
  async function parsePomXml(cwd) {
21929
- const pomPath = path37__default.join(cwd, "pom.xml");
22351
+ const pomPath = path38__default.join(cwd, "pom.xml");
21930
22352
  try {
21931
- const content = await fs34__default.readFile(pomPath, "utf-8");
22353
+ const content = await fs35__default.readFile(pomPath, "utf-8");
21932
22354
  const dependencies = {};
21933
22355
  const frameworks = [];
21934
22356
  const buildTools2 = ["maven"];
@@ -21963,9 +22385,9 @@ async function parsePomXml(cwd) {
21963
22385
  }
21964
22386
  }
21965
22387
  async function parsePyprojectToml(cwd) {
21966
- const pyprojectPath = path37__default.join(cwd, "pyproject.toml");
22388
+ const pyprojectPath = path38__default.join(cwd, "pyproject.toml");
21967
22389
  try {
21968
- const content = await fs34__default.readFile(pyprojectPath, "utf-8");
22390
+ const content = await fs35__default.readFile(pyprojectPath, "utf-8");
21969
22391
  const dependencies = {};
21970
22392
  const frameworks = [];
21971
22393
  const buildTools2 = ["pip"];
@@ -22006,7 +22428,7 @@ async function detectProjectStack(cwd) {
22006
22428
  testingFrameworks = parsed.testingFrameworks;
22007
22429
  languages = parsed.languages;
22008
22430
  } else if (stack === "java") {
22009
- const isGradle = await fileExists3(path37__default.join(cwd, "build.gradle")) || await fileExists3(path37__default.join(cwd, "build.gradle.kts"));
22431
+ const isGradle = await fileExists3(path38__default.join(cwd, "build.gradle")) || await fileExists3(path38__default.join(cwd, "build.gradle.kts"));
22010
22432
  const parsed = isGradle ? { dependencies: {}, frameworks: [], buildTools: ["gradle"], testingFrameworks: ["JUnit"] } : await parsePomXml(cwd);
22011
22433
  dependencies = parsed.dependencies;
22012
22434
  frameworks = parsed.frameworks;
@@ -22407,7 +22829,7 @@ function loadStandardFormat(config, configPath) {
22407
22829
  return validServers;
22408
22830
  }
22409
22831
  async function loadProjectMCPFile(projectPath) {
22410
- const mcpJsonPath = path37__default.join(projectPath, ".mcp.json");
22832
+ const mcpJsonPath = path38__default.join(projectPath, ".mcp.json");
22411
22833
  try {
22412
22834
  await access(mcpJsonPath);
22413
22835
  } catch {
@@ -23719,26 +24141,26 @@ init_version();
23719
24141
  // src/orchestrator/project.ts
23720
24142
  init_env();
23721
24143
  async function createProjectStructure(projectPath, info) {
23722
- const cocoPath = path37__default.join(projectPath, ".coco");
24144
+ const cocoPath = path38__default.join(projectPath, ".coco");
23723
24145
  const directories = [
23724
24146
  cocoPath,
23725
- path37__default.join(cocoPath, "state"),
23726
- path37__default.join(cocoPath, "checkpoints"),
23727
- path37__default.join(cocoPath, "logs"),
23728
- path37__default.join(cocoPath, "discovery"),
23729
- path37__default.join(cocoPath, "spec"),
23730
- path37__default.join(cocoPath, "architecture"),
23731
- path37__default.join(cocoPath, "architecture", "adrs"),
23732
- path37__default.join(cocoPath, "architecture", "diagrams"),
23733
- path37__default.join(cocoPath, "planning"),
23734
- path37__default.join(cocoPath, "planning", "epics"),
23735
- path37__default.join(cocoPath, "execution"),
23736
- path37__default.join(cocoPath, "versions"),
23737
- path37__default.join(cocoPath, "reviews"),
23738
- path37__default.join(cocoPath, "delivery")
24147
+ path38__default.join(cocoPath, "state"),
24148
+ path38__default.join(cocoPath, "checkpoints"),
24149
+ path38__default.join(cocoPath, "logs"),
24150
+ path38__default.join(cocoPath, "discovery"),
24151
+ path38__default.join(cocoPath, "spec"),
24152
+ path38__default.join(cocoPath, "architecture"),
24153
+ path38__default.join(cocoPath, "architecture", "adrs"),
24154
+ path38__default.join(cocoPath, "architecture", "diagrams"),
24155
+ path38__default.join(cocoPath, "planning"),
24156
+ path38__default.join(cocoPath, "planning", "epics"),
24157
+ path38__default.join(cocoPath, "execution"),
24158
+ path38__default.join(cocoPath, "versions"),
24159
+ path38__default.join(cocoPath, "reviews"),
24160
+ path38__default.join(cocoPath, "delivery")
23739
24161
  ];
23740
24162
  for (const dir of directories) {
23741
- await fs34__default.mkdir(dir, { recursive: true });
24163
+ await fs35__default.mkdir(dir, { recursive: true });
23742
24164
  }
23743
24165
  await createInitialConfig(cocoPath, info);
23744
24166
  await createProjectState(cocoPath, info);
@@ -23773,7 +24195,7 @@ async function createInitialConfig(cocoPath, info) {
23773
24195
  maxCheckpoints: 50
23774
24196
  }
23775
24197
  };
23776
- await fs34__default.writeFile(path37__default.join(cocoPath, "config.json"), JSON.stringify(config, null, 2), "utf-8");
24198
+ await fs35__default.writeFile(path38__default.join(cocoPath, "config.json"), JSON.stringify(config, null, 2), "utf-8");
23777
24199
  }
23778
24200
  async function createProjectState(cocoPath, info) {
23779
24201
  const state = {
@@ -23790,8 +24212,8 @@ async function createProjectState(cocoPath, info) {
23790
24212
  qualityHistory: [],
23791
24213
  lastCheckpoint: null
23792
24214
  };
23793
- await fs34__default.writeFile(
23794
- path37__default.join(cocoPath, "state", "project.json"),
24215
+ await fs35__default.writeFile(
24216
+ path38__default.join(cocoPath, "state", "project.json"),
23795
24217
  JSON.stringify(state, null, 2),
23796
24218
  "utf-8"
23797
24219
  );
@@ -23812,7 +24234,7 @@ checkpoints/
23812
24234
  state/session.json
23813
24235
  state/lock.json
23814
24236
  `;
23815
- await fs34__default.writeFile(path37__default.join(cocoPath, ".gitignore"), content, "utf-8");
24237
+ await fs35__default.writeFile(path38__default.join(cocoPath, ".gitignore"), content, "utf-8");
23816
24238
  }
23817
24239
  async function createReadme(cocoPath, info) {
23818
24240
  const content = `# Corbat-Coco Project: ${info.name}
@@ -23859,13 +24281,13 @@ Edit \`config.json\` to customize:
23859
24281
  ---
23860
24282
  Generated by Corbat-Coco v0.1.0
23861
24283
  `;
23862
- await fs34__default.writeFile(path37__default.join(cocoPath, "README.md"), content, "utf-8");
24284
+ await fs35__default.writeFile(path38__default.join(cocoPath, "README.md"), content, "utf-8");
23863
24285
  }
23864
24286
 
23865
24287
  // src/cli/commands/init.ts
23866
24288
  function registerInitCommand(program2) {
23867
- program2.command("init").description("Initialize a new Corbat-Coco project").argument("[path]", "Project directory path", ".").option("-t, --template <template>", "Project template to use").option("-y, --yes", "Skip prompts and use defaults").option("--skip-discovery", "Skip the discovery phase (use existing spec)").action(async (path59, options) => {
23868
- await runInit(path59, options);
24289
+ program2.command("init").description("Initialize a new Corbat-Coco project").argument("[path]", "Project directory path", ".").option("-t, --template <template>", "Project template to use").option("-y, --yes", "Skip prompts and use defaults").option("--skip-discovery", "Skip the discovery phase (use existing spec)").action(async (path60, options) => {
24290
+ await runInit(path60, options);
23869
24291
  });
23870
24292
  }
23871
24293
  async function runInit(projectPath, options) {
@@ -23944,18 +24366,18 @@ async function gatherProjectInfo() {
23944
24366
  language
23945
24367
  };
23946
24368
  }
23947
- function getDefaultProjectInfo(path59) {
23948
- const name = path59 === "." ? "my-project" : path59.split("/").pop() || "my-project";
24369
+ function getDefaultProjectInfo(path60) {
24370
+ const name = path60 === "." ? "my-project" : path60.split("/").pop() || "my-project";
23949
24371
  return {
23950
24372
  name,
23951
24373
  description: "",
23952
24374
  language: "typescript"
23953
24375
  };
23954
24376
  }
23955
- async function checkExistingProject(path59) {
24377
+ async function checkExistingProject(path60) {
23956
24378
  try {
23957
- const fs55 = await import('fs/promises');
23958
- await fs55.access(`${path59}/.coco`);
24379
+ const fs56 = await import('fs/promises');
24380
+ await fs56.access(`${path60}/.coco`);
23959
24381
  return true;
23960
24382
  } catch {
23961
24383
  return false;
@@ -25163,13 +25585,13 @@ function createSpecificationGenerator(llm, config) {
25163
25585
  // src/phases/converge/persistence.ts
25164
25586
  init_errors();
25165
25587
  function getPersistencePaths(projectPath) {
25166
- const baseDir = path37__default.join(projectPath, ".coco", "spec");
25588
+ const baseDir = path38__default.join(projectPath, ".coco", "spec");
25167
25589
  return {
25168
25590
  baseDir,
25169
- sessionFile: path37__default.join(baseDir, "discovery-session.json"),
25170
- specFile: path37__default.join(baseDir, "spec.md"),
25171
- conversationLog: path37__default.join(baseDir, "conversation.jsonl"),
25172
- checkpointFile: path37__default.join(baseDir, "checkpoint.json")
25591
+ sessionFile: path38__default.join(baseDir, "discovery-session.json"),
25592
+ specFile: path38__default.join(baseDir, "spec.md"),
25593
+ conversationLog: path38__default.join(baseDir, "conversation.jsonl"),
25594
+ checkpointFile: path38__default.join(baseDir, "checkpoint.json")
25173
25595
  };
25174
25596
  }
25175
25597
  var SessionPersistence = class {
@@ -25182,7 +25604,7 @@ var SessionPersistence = class {
25182
25604
  */
25183
25605
  async ensureDir() {
25184
25606
  try {
25185
- await fs34__default.mkdir(this.paths.baseDir, { recursive: true });
25607
+ await fs35__default.mkdir(this.paths.baseDir, { recursive: true });
25186
25608
  } catch {
25187
25609
  throw new FileSystemError(`Failed to create persistence directory: ${this.paths.baseDir}`, {
25188
25610
  path: this.paths.baseDir,
@@ -25197,7 +25619,7 @@ var SessionPersistence = class {
25197
25619
  await this.ensureDir();
25198
25620
  try {
25199
25621
  const data = JSON.stringify(session, null, 2);
25200
- await fs34__default.writeFile(this.paths.sessionFile, data, "utf-8");
25622
+ await fs35__default.writeFile(this.paths.sessionFile, data, "utf-8");
25201
25623
  } catch {
25202
25624
  throw new FileSystemError("Failed to save discovery session", {
25203
25625
  path: this.paths.sessionFile,
@@ -25210,7 +25632,7 @@ var SessionPersistence = class {
25210
25632
  */
25211
25633
  async loadSession() {
25212
25634
  try {
25213
- const data = await fs34__default.readFile(this.paths.sessionFile, "utf-8");
25635
+ const data = await fs35__default.readFile(this.paths.sessionFile, "utf-8");
25214
25636
  const parsed = JSON.parse(data);
25215
25637
  parsed.startedAt = new Date(parsed.startedAt);
25216
25638
  parsed.updatedAt = new Date(parsed.updatedAt);
@@ -25236,7 +25658,7 @@ var SessionPersistence = class {
25236
25658
  */
25237
25659
  async hasSession() {
25238
25660
  try {
25239
- await fs34__default.access(this.paths.sessionFile);
25661
+ await fs35__default.access(this.paths.sessionFile);
25240
25662
  return true;
25241
25663
  } catch {
25242
25664
  return false;
@@ -25247,7 +25669,7 @@ var SessionPersistence = class {
25247
25669
  */
25248
25670
  async deleteSession() {
25249
25671
  try {
25250
- await fs34__default.unlink(this.paths.sessionFile);
25672
+ await fs35__default.unlink(this.paths.sessionFile);
25251
25673
  } catch (error) {
25252
25674
  if (error.code !== "ENOENT") {
25253
25675
  throw new FileSystemError("Failed to delete discovery session", {
@@ -25263,7 +25685,7 @@ var SessionPersistence = class {
25263
25685
  async saveSpecification(content) {
25264
25686
  await this.ensureDir();
25265
25687
  try {
25266
- await fs34__default.writeFile(this.paths.specFile, content, "utf-8");
25688
+ await fs35__default.writeFile(this.paths.specFile, content, "utf-8");
25267
25689
  } catch {
25268
25690
  throw new FileSystemError("Failed to save specification", {
25269
25691
  path: this.paths.specFile,
@@ -25276,7 +25698,7 @@ var SessionPersistence = class {
25276
25698
  */
25277
25699
  async loadSpecification() {
25278
25700
  try {
25279
- return await fs34__default.readFile(this.paths.specFile, "utf-8");
25701
+ return await fs35__default.readFile(this.paths.specFile, "utf-8");
25280
25702
  } catch {
25281
25703
  return null;
25282
25704
  }
@@ -25292,7 +25714,7 @@ var SessionPersistence = class {
25292
25714
  content
25293
25715
  };
25294
25716
  try {
25295
- await fs34__default.appendFile(this.paths.conversationLog, JSON.stringify(entry) + "\n", "utf-8");
25717
+ await fs35__default.appendFile(this.paths.conversationLog, JSON.stringify(entry) + "\n", "utf-8");
25296
25718
  } catch {
25297
25719
  throw new FileSystemError("Failed to append to conversation log", {
25298
25720
  path: this.paths.conversationLog,
@@ -25305,7 +25727,7 @@ var SessionPersistence = class {
25305
25727
  */
25306
25728
  async loadConversationLog() {
25307
25729
  try {
25308
- const data = await fs34__default.readFile(this.paths.conversationLog, "utf-8");
25730
+ const data = await fs35__default.readFile(this.paths.conversationLog, "utf-8");
25309
25731
  const lines = data.trim().split("\n");
25310
25732
  return lines.filter((line) => line.trim()).map((line) => JSON.parse(line));
25311
25733
  } catch {
@@ -25319,7 +25741,7 @@ var SessionPersistence = class {
25319
25741
  await this.ensureDir();
25320
25742
  try {
25321
25743
  const data = JSON.stringify(checkpoint, null, 2);
25322
- await fs34__default.writeFile(this.paths.checkpointFile, data, "utf-8");
25744
+ await fs35__default.writeFile(this.paths.checkpointFile, data, "utf-8");
25323
25745
  } catch {
25324
25746
  throw new FileSystemError("Failed to save checkpoint", {
25325
25747
  path: this.paths.checkpointFile,
@@ -25332,7 +25754,7 @@ var SessionPersistence = class {
25332
25754
  */
25333
25755
  async loadCheckpoint() {
25334
25756
  try {
25335
- const data = await fs34__default.readFile(this.paths.checkpointFile, "utf-8");
25757
+ const data = await fs35__default.readFile(this.paths.checkpointFile, "utf-8");
25336
25758
  const parsed = JSON.parse(data);
25337
25759
  parsed.timestamp = new Date(parsed.timestamp);
25338
25760
  return parsed;
@@ -25345,7 +25767,7 @@ var SessionPersistence = class {
25345
25767
  */
25346
25768
  async clearAll() {
25347
25769
  try {
25348
- await fs34__default.rm(this.paths.baseDir, { recursive: true, force: true });
25770
+ await fs35__default.rm(this.paths.baseDir, { recursive: true, force: true });
25349
25771
  } catch (error) {
25350
25772
  if (error.code !== "ENOENT") {
25351
25773
  throw new FileSystemError("Failed to clear persistence data", {
@@ -27273,8 +27695,8 @@ var OrchestrateExecutor = class {
27273
27695
  }
27274
27696
  async loadSpecification(projectPath) {
27275
27697
  try {
27276
- const jsonPath = path37__default.join(projectPath, ".coco", "spec", "spec.json");
27277
- const jsonContent = await fs34__default.readFile(jsonPath, "utf-8");
27698
+ const jsonPath = path38__default.join(projectPath, ".coco", "spec", "spec.json");
27699
+ const jsonContent = await fs35__default.readFile(jsonPath, "utf-8");
27278
27700
  return JSON.parse(jsonContent);
27279
27701
  } catch {
27280
27702
  return this.createMinimalSpec(projectPath);
@@ -27285,7 +27707,7 @@ var OrchestrateExecutor = class {
27285
27707
  version: "1.0.0",
27286
27708
  generatedAt: /* @__PURE__ */ new Date(),
27287
27709
  overview: {
27288
- name: path37__default.basename(projectPath),
27710
+ name: path38__default.basename(projectPath),
27289
27711
  description: "Project specification",
27290
27712
  goals: [],
27291
27713
  targetUsers: ["developers"],
@@ -27312,53 +27734,53 @@ var OrchestrateExecutor = class {
27312
27734
  };
27313
27735
  }
27314
27736
  async saveArchitecture(projectPath, architecture) {
27315
- const dir = path37__default.join(projectPath, ".coco", "architecture");
27316
- await fs34__default.mkdir(dir, { recursive: true });
27317
- const mdPath = path37__default.join(dir, "ARCHITECTURE.md");
27318
- await fs34__default.writeFile(mdPath, generateArchitectureMarkdown(architecture), "utf-8");
27319
- const jsonPath = path37__default.join(dir, "architecture.json");
27320
- await fs34__default.writeFile(jsonPath, JSON.stringify(architecture, null, 2), "utf-8");
27737
+ const dir = path38__default.join(projectPath, ".coco", "architecture");
27738
+ await fs35__default.mkdir(dir, { recursive: true });
27739
+ const mdPath = path38__default.join(dir, "ARCHITECTURE.md");
27740
+ await fs35__default.writeFile(mdPath, generateArchitectureMarkdown(architecture), "utf-8");
27741
+ const jsonPath = path38__default.join(dir, "architecture.json");
27742
+ await fs35__default.writeFile(jsonPath, JSON.stringify(architecture, null, 2), "utf-8");
27321
27743
  return mdPath;
27322
27744
  }
27323
27745
  async saveADRs(projectPath, adrs) {
27324
- const dir = path37__default.join(projectPath, ".coco", "architecture", "adrs");
27325
- await fs34__default.mkdir(dir, { recursive: true });
27746
+ const dir = path38__default.join(projectPath, ".coco", "architecture", "adrs");
27747
+ await fs35__default.mkdir(dir, { recursive: true });
27326
27748
  const paths = [];
27327
- const indexPath = path37__default.join(dir, "README.md");
27328
- await fs34__default.writeFile(indexPath, generateADRIndexMarkdown(adrs), "utf-8");
27749
+ const indexPath = path38__default.join(dir, "README.md");
27750
+ await fs35__default.writeFile(indexPath, generateADRIndexMarkdown(adrs), "utf-8");
27329
27751
  paths.push(indexPath);
27330
27752
  for (const adr of adrs) {
27331
27753
  const filename = getADRFilename(adr);
27332
- const adrPath = path37__default.join(dir, filename);
27333
- await fs34__default.writeFile(adrPath, generateADRMarkdown(adr), "utf-8");
27754
+ const adrPath = path38__default.join(dir, filename);
27755
+ await fs35__default.writeFile(adrPath, generateADRMarkdown(adr), "utf-8");
27334
27756
  paths.push(adrPath);
27335
27757
  }
27336
27758
  return paths;
27337
27759
  }
27338
27760
  async saveBacklog(projectPath, backlogResult) {
27339
- const dir = path37__default.join(projectPath, ".coco", "planning");
27340
- await fs34__default.mkdir(dir, { recursive: true });
27341
- const mdPath = path37__default.join(dir, "BACKLOG.md");
27342
- await fs34__default.writeFile(mdPath, generateBacklogMarkdown(backlogResult.backlog), "utf-8");
27343
- const jsonPath = path37__default.join(dir, "backlog.json");
27344
- await fs34__default.writeFile(jsonPath, JSON.stringify(backlogResult, null, 2), "utf-8");
27761
+ const dir = path38__default.join(projectPath, ".coco", "planning");
27762
+ await fs35__default.mkdir(dir, { recursive: true });
27763
+ const mdPath = path38__default.join(dir, "BACKLOG.md");
27764
+ await fs35__default.writeFile(mdPath, generateBacklogMarkdown(backlogResult.backlog), "utf-8");
27765
+ const jsonPath = path38__default.join(dir, "backlog.json");
27766
+ await fs35__default.writeFile(jsonPath, JSON.stringify(backlogResult, null, 2), "utf-8");
27345
27767
  return mdPath;
27346
27768
  }
27347
27769
  async saveSprint(projectPath, sprint, backlogResult) {
27348
- const dir = path37__default.join(projectPath, ".coco", "planning", "sprints");
27349
- await fs34__default.mkdir(dir, { recursive: true });
27770
+ const dir = path38__default.join(projectPath, ".coco", "planning", "sprints");
27771
+ await fs35__default.mkdir(dir, { recursive: true });
27350
27772
  const filename = `${sprint.id}.md`;
27351
- const sprintPath = path37__default.join(dir, filename);
27352
- await fs34__default.writeFile(sprintPath, generateSprintMarkdown(sprint, backlogResult.backlog), "utf-8");
27353
- const jsonPath = path37__default.join(dir, `${sprint.id}.json`);
27354
- await fs34__default.writeFile(jsonPath, JSON.stringify(sprint, null, 2), "utf-8");
27773
+ const sprintPath = path38__default.join(dir, filename);
27774
+ await fs35__default.writeFile(sprintPath, generateSprintMarkdown(sprint, backlogResult.backlog), "utf-8");
27775
+ const jsonPath = path38__default.join(dir, `${sprint.id}.json`);
27776
+ await fs35__default.writeFile(jsonPath, JSON.stringify(sprint, null, 2), "utf-8");
27355
27777
  return sprintPath;
27356
27778
  }
27357
27779
  async saveDiagram(projectPath, id, mermaid) {
27358
- const dir = path37__default.join(projectPath, ".coco", "architecture", "diagrams");
27359
- await fs34__default.mkdir(dir, { recursive: true });
27360
- const diagramPath = path37__default.join(dir, `${id}.mmd`);
27361
- await fs34__default.writeFile(diagramPath, mermaid, "utf-8");
27780
+ const dir = path38__default.join(projectPath, ".coco", "architecture", "diagrams");
27781
+ await fs35__default.mkdir(dir, { recursive: true });
27782
+ const diagramPath = path38__default.join(dir, `${id}.mmd`);
27783
+ await fs35__default.writeFile(diagramPath, mermaid, "utf-8");
27362
27784
  return diagramPath;
27363
27785
  }
27364
27786
  };
@@ -27456,20 +27878,20 @@ async function createCliPhaseContext(projectPath, _onUserInput) {
27456
27878
  },
27457
27879
  tools: {
27458
27880
  file: {
27459
- async read(path59) {
27460
- const fs55 = await import('fs/promises');
27461
- return fs55.readFile(path59, "utf-8");
27881
+ async read(path60) {
27882
+ const fs56 = await import('fs/promises');
27883
+ return fs56.readFile(path60, "utf-8");
27462
27884
  },
27463
- async write(path59, content) {
27464
- const fs55 = await import('fs/promises');
27885
+ async write(path60, content) {
27886
+ const fs56 = await import('fs/promises');
27465
27887
  const nodePath = await import('path');
27466
- await fs55.mkdir(nodePath.dirname(path59), { recursive: true });
27467
- await fs55.writeFile(path59, content, "utf-8");
27888
+ await fs56.mkdir(nodePath.dirname(path60), { recursive: true });
27889
+ await fs56.writeFile(path60, content, "utf-8");
27468
27890
  },
27469
- async exists(path59) {
27470
- const fs55 = await import('fs/promises');
27891
+ async exists(path60) {
27892
+ const fs56 = await import('fs/promises');
27471
27893
  try {
27472
- await fs55.access(path59);
27894
+ await fs56.access(path60);
27473
27895
  return true;
27474
27896
  } catch {
27475
27897
  return false;
@@ -27708,16 +28130,16 @@ async function loadTasks(_options) {
27708
28130
  ];
27709
28131
  }
27710
28132
  async function checkProjectState() {
27711
- const fs55 = await import('fs/promises');
28133
+ const fs56 = await import('fs/promises');
27712
28134
  let hasProject = false;
27713
28135
  let hasPlan = false;
27714
28136
  try {
27715
- await fs55.access(".coco");
28137
+ await fs56.access(".coco");
27716
28138
  hasProject = true;
27717
28139
  } catch {
27718
28140
  }
27719
28141
  try {
27720
- await fs55.access(".coco/planning/backlog.json");
28142
+ await fs56.access(".coco/planning/backlog.json");
27721
28143
  hasPlan = true;
27722
28144
  } catch {
27723
28145
  }
@@ -27824,24 +28246,24 @@ function getPhaseStatusForPhase(phase) {
27824
28246
  return "in_progress";
27825
28247
  }
27826
28248
  async function loadProjectState(cwd, config) {
27827
- const fs55 = await import('fs/promises');
27828
- const path59 = await import('path');
27829
- const statePath = path59.join(cwd, ".coco", "state.json");
27830
- const backlogPath = path59.join(cwd, ".coco", "planning", "backlog.json");
27831
- const checkpointDir = path59.join(cwd, ".coco", "checkpoints");
28249
+ const fs56 = await import('fs/promises');
28250
+ const path60 = await import('path');
28251
+ const statePath = path60.join(cwd, ".coco", "state.json");
28252
+ const backlogPath = path60.join(cwd, ".coco", "planning", "backlog.json");
28253
+ const checkpointDir = path60.join(cwd, ".coco", "checkpoints");
27832
28254
  let currentPhase = "idle";
27833
28255
  let metrics;
27834
28256
  let sprint;
27835
28257
  let checkpoints = [];
27836
28258
  try {
27837
- const stateContent = await fs55.readFile(statePath, "utf-8");
28259
+ const stateContent = await fs56.readFile(statePath, "utf-8");
27838
28260
  const stateData = JSON.parse(stateContent);
27839
28261
  currentPhase = stateData.currentPhase || "idle";
27840
28262
  metrics = stateData.metrics;
27841
28263
  } catch {
27842
28264
  }
27843
28265
  try {
27844
- const backlogContent = await fs55.readFile(backlogPath, "utf-8");
28266
+ const backlogContent = await fs56.readFile(backlogPath, "utf-8");
27845
28267
  const backlogData = JSON.parse(backlogContent);
27846
28268
  if (backlogData.currentSprint) {
27847
28269
  const tasks = backlogData.tasks || [];
@@ -27863,7 +28285,7 @@ async function loadProjectState(cwd, config) {
27863
28285
  } catch {
27864
28286
  }
27865
28287
  try {
27866
- const files = await fs55.readdir(checkpointDir);
28288
+ const files = await fs56.readdir(checkpointDir);
27867
28289
  checkpoints = files.filter((f) => f.endsWith(".json")).sort().reverse();
27868
28290
  } catch {
27869
28291
  }
@@ -27999,8 +28421,8 @@ async function restoreFromCheckpoint(_checkpoint) {
27999
28421
  }
28000
28422
  async function checkProjectExists() {
28001
28423
  try {
28002
- const fs55 = await import('fs/promises');
28003
- await fs55.access(".coco");
28424
+ const fs56 = await import('fs/promises');
28425
+ await fs56.access(".coco");
28004
28426
  return true;
28005
28427
  } catch {
28006
28428
  return false;
@@ -29215,9 +29637,9 @@ var DEFAULT_CONFIG2 = {
29215
29637
  }
29216
29638
  };
29217
29639
  async function loadConfig2() {
29218
- const fs55 = await import('fs/promises');
29640
+ const fs56 = await import('fs/promises');
29219
29641
  try {
29220
- const raw = await fs55.readFile(CONFIG_PATH, "utf-8");
29642
+ const raw = await fs56.readFile(CONFIG_PATH, "utf-8");
29221
29643
  const parsed = JSON.parse(raw);
29222
29644
  return { ...DEFAULT_CONFIG2, ...parsed };
29223
29645
  } catch {
@@ -29225,13 +29647,13 @@ async function loadConfig2() {
29225
29647
  }
29226
29648
  }
29227
29649
  async function saveConfig2(config) {
29228
- const fs55 = await import('fs/promises');
29650
+ const fs56 = await import('fs/promises');
29229
29651
  const dir = join(CONFIG_PATH, "..");
29230
- await fs55.mkdir(dir, { recursive: true });
29231
- await fs55.writeFile(CONFIG_PATH, JSON.stringify(config, null, 2));
29652
+ await fs56.mkdir(dir, { recursive: true });
29653
+ await fs56.writeFile(CONFIG_PATH, JSON.stringify(config, null, 2));
29232
29654
  }
29233
- function getNestedValue(obj, path59) {
29234
- const keys = path59.split(".");
29655
+ function getNestedValue(obj, path60) {
29656
+ const keys = path60.split(".");
29235
29657
  let current = obj;
29236
29658
  for (const key of keys) {
29237
29659
  if (current === null || current === void 0 || typeof current !== "object") {
@@ -29241,8 +29663,8 @@ function getNestedValue(obj, path59) {
29241
29663
  }
29242
29664
  return current;
29243
29665
  }
29244
- function setNestedValue(obj, path59, value) {
29245
- const keys = path59.split(".");
29666
+ function setNestedValue(obj, path60, value) {
29667
+ const keys = path60.split(".");
29246
29668
  let current = obj;
29247
29669
  for (let i = 0; i < keys.length - 1; i++) {
29248
29670
  const key = keys[i];
@@ -29608,13 +30030,13 @@ async function runAdd(source, options) {
29608
30030
  const isGithubShorthand = source.includes("/") && !isGitUrl;
29609
30031
  const isLocalPath = source.startsWith(".") || source.startsWith("/");
29610
30032
  if (isLocalPath) {
29611
- const targetDir = options.global ? CONFIG_PATHS.skills : path37__default.join(process.cwd(), ".agents", "skills");
29612
- const sourcePath = path37__default.resolve(source);
29613
- const skillName = path37__default.basename(sourcePath);
29614
- const destPath = path37__default.join(targetDir, skillName);
30033
+ const targetDir = options.global ? CONFIG_PATHS.skills : path38__default.join(process.cwd(), ".agents", "skills");
30034
+ const sourcePath = path38__default.resolve(source);
30035
+ const skillName = path38__default.basename(sourcePath);
30036
+ const destPath = path38__default.join(targetDir, skillName);
29615
30037
  try {
29616
- await fs34__default.mkdir(targetDir, { recursive: true });
29617
- await fs34__default.cp(sourcePath, destPath, { recursive: true });
30038
+ await fs35__default.mkdir(targetDir, { recursive: true });
30039
+ await fs35__default.cp(sourcePath, destPath, { recursive: true });
29618
30040
  p26.log.success(`Installed "${skillName}" to ${destPath}`);
29619
30041
  } catch (error) {
29620
30042
  p26.log.error(
@@ -29645,10 +30067,10 @@ async function runAdd(source, options) {
29645
30067
  p26.log.info("Try installing manually: git clone the repo into .agents/skills/");
29646
30068
  }
29647
30069
  } else if (isGitUrl) {
29648
- const targetDir = options.global ? CONFIG_PATHS.skills : path37__default.join(process.cwd(), ".agents", "skills");
29649
- await fs34__default.mkdir(targetDir, { recursive: true });
30070
+ const targetDir = options.global ? CONFIG_PATHS.skills : path38__default.join(process.cwd(), ".agents", "skills");
30071
+ await fs35__default.mkdir(targetDir, { recursive: true });
29650
30072
  const skillName = source.split("/").pop()?.replace(".git", "") ?? "skill";
29651
- const skillDir = path37__default.join(targetDir, skillName);
30073
+ const skillDir = path38__default.join(targetDir, skillName);
29652
30074
  const spinner18 = p26.spinner();
29653
30075
  spinner18.start(`Cloning ${source}...`);
29654
30076
  try {
@@ -29674,15 +30096,15 @@ async function runAdd(source, options) {
29674
30096
  }
29675
30097
  async function runRemove(name, options) {
29676
30098
  p26.intro(chalk.magenta("Remove Skill"));
29677
- const targetDir = options.global ? CONFIG_PATHS.skills : path37__default.join(process.cwd(), ".agents", "skills");
29678
- const skillPath = path37__default.resolve(targetDir, name);
29679
- if (!skillPath.startsWith(path37__default.resolve(targetDir) + path37__default.sep)) {
30099
+ const targetDir = options.global ? CONFIG_PATHS.skills : path38__default.join(process.cwd(), ".agents", "skills");
30100
+ const skillPath = path38__default.resolve(targetDir, name);
30101
+ if (!skillPath.startsWith(path38__default.resolve(targetDir) + path38__default.sep)) {
29680
30102
  p26.log.error(`Invalid skill name: "${name}"`);
29681
30103
  p26.outro("");
29682
30104
  return;
29683
30105
  }
29684
30106
  try {
29685
- await fs34__default.access(skillPath);
30107
+ await fs35__default.access(skillPath);
29686
30108
  } catch {
29687
30109
  p26.log.error(`Skill "${name}" not found at ${skillPath}`);
29688
30110
  p26.outro("");
@@ -29698,7 +30120,7 @@ async function runRemove(name, options) {
29698
30120
  return;
29699
30121
  }
29700
30122
  }
29701
- await fs34__default.rm(skillPath, { recursive: true });
30123
+ await fs35__default.rm(skillPath, { recursive: true });
29702
30124
  p26.log.success(`Removed "${name}"`);
29703
30125
  p26.outro("");
29704
30126
  }
@@ -29760,10 +30182,10 @@ async function runInfo(name) {
29760
30182
  }
29761
30183
  async function runCreate(name, options) {
29762
30184
  p26.intro(chalk.magenta("Create Skill"));
29763
- const targetDir = options.global ? CONFIG_PATHS.skills : path37__default.join(process.cwd(), ".agents", "skills");
29764
- const skillDir = path37__default.join(targetDir, name);
30185
+ const targetDir = options.global ? CONFIG_PATHS.skills : path38__default.join(process.cwd(), ".agents", "skills");
30186
+ const skillDir = path38__default.join(targetDir, name);
29765
30187
  try {
29766
- await fs34__default.access(skillDir);
30188
+ await fs35__default.access(skillDir);
29767
30189
  p26.log.error(`Skill "${name}" already exists at ${skillDir}`);
29768
30190
  p26.outro("");
29769
30191
  return;
@@ -29792,7 +30214,7 @@ async function runCreate(name, options) {
29792
30214
  p26.outro("Cancelled.");
29793
30215
  return;
29794
30216
  }
29795
- await fs34__default.mkdir(skillDir, { recursive: true });
30217
+ await fs35__default.mkdir(skillDir, { recursive: true });
29796
30218
  const skillMd = `---
29797
30219
  name: "${name}"
29798
30220
  description: "${description}"
@@ -29814,10 +30236,10 @@ when this skill is activated (automatically via matching or manually via /${name
29814
30236
  2. Include examples when helpful
29815
30237
  3. Keep instructions under 500 lines
29816
30238
  `;
29817
- await fs34__default.writeFile(path37__default.join(skillDir, "SKILL.md"), skillMd, "utf-8");
29818
- await fs34__default.mkdir(path37__default.join(skillDir, "references"), { recursive: true });
30239
+ await fs35__default.writeFile(path38__default.join(skillDir, "SKILL.md"), skillMd, "utf-8");
30240
+ await fs35__default.mkdir(path38__default.join(skillDir, "references"), { recursive: true });
29819
30241
  p26.log.success(`Created skill at ${skillDir}`);
29820
- p26.log.info(`Edit ${path37__default.join(skillDir, "SKILL.md")} to add instructions.`);
30242
+ p26.log.info(`Edit ${path38__default.join(skillDir, "SKILL.md")} to add instructions.`);
29821
30243
  p26.outro("");
29822
30244
  }
29823
30245
  function registerWinner(winners, candidate, candidateScanOrder, scanOrderById) {
@@ -30273,10 +30695,10 @@ function registerCheckCommand(program2) {
30273
30695
 
30274
30696
  // src/swarm/spec-parser.ts
30275
30697
  async function parseSwarmSpec(filePath) {
30276
- const fs55 = await import('fs/promises');
30277
- const path59 = await import('path');
30278
- const rawContent = await fs55.readFile(filePath, "utf-8");
30279
- const ext = path59.extname(filePath).toLowerCase();
30698
+ const fs56 = await import('fs/promises');
30699
+ const path60 = await import('path');
30700
+ const rawContent = await fs56.readFile(filePath, "utf-8");
30701
+ const ext = path60.extname(filePath).toLowerCase();
30280
30702
  if (ext === ".yaml" || ext === ".yml") {
30281
30703
  return parseYamlSpec(rawContent);
30282
30704
  }
@@ -30605,11 +31027,11 @@ var DEFAULT_AGENT_CONFIG = {
30605
31027
  integrator: { maxTurns: 20, temperature: 0.2 }
30606
31028
  };
30607
31029
  async function loadAgentConfig(projectPath) {
30608
- const fs55 = await import('fs/promises');
30609
- const path59 = await import('path');
30610
- const configPath = path59.join(projectPath, ".coco", "swarm", "agents.json");
31030
+ const fs56 = await import('fs/promises');
31031
+ const path60 = await import('path');
31032
+ const configPath = path60.join(projectPath, ".coco", "swarm", "agents.json");
30611
31033
  try {
30612
- const raw = await fs55.readFile(configPath, "utf-8");
31034
+ const raw = await fs56.readFile(configPath, "utf-8");
30613
31035
  const parsed = JSON.parse(raw);
30614
31036
  const merged = { ...DEFAULT_AGENT_CONFIG };
30615
31037
  for (const role of Object.keys(DEFAULT_AGENT_CONFIG)) {
@@ -30797,19 +31219,19 @@ async function createBoard(projectPath, spec) {
30797
31219
  return board;
30798
31220
  }
30799
31221
  async function loadBoard(projectPath) {
30800
- const fs55 = await import('fs/promises');
30801
- const path59 = await import('path');
30802
- const boardPath = path59.join(projectPath, ".coco", "swarm", "task-board.json");
30803
- const raw = await fs55.readFile(boardPath, "utf-8");
31222
+ const fs56 = await import('fs/promises');
31223
+ const path60 = await import('path');
31224
+ const boardPath = path60.join(projectPath, ".coco", "swarm", "task-board.json");
31225
+ const raw = await fs56.readFile(boardPath, "utf-8");
30804
31226
  return JSON.parse(raw);
30805
31227
  }
30806
31228
  async function saveBoard(projectPath, board) {
30807
- const fs55 = await import('fs/promises');
30808
- const path59 = await import('path');
30809
- const boardDir = path59.join(projectPath, ".coco", "swarm");
30810
- const boardPath = path59.join(boardDir, "task-board.json");
30811
- await fs55.mkdir(boardDir, { recursive: true });
30812
- await fs55.writeFile(boardPath, JSON.stringify(board, null, 2), "utf-8");
31229
+ const fs56 = await import('fs/promises');
31230
+ const path60 = await import('path');
31231
+ const boardDir = path60.join(projectPath, ".coco", "swarm");
31232
+ const boardPath = path60.join(boardDir, "task-board.json");
31233
+ await fs56.mkdir(boardDir, { recursive: true });
31234
+ await fs56.writeFile(boardPath, JSON.stringify(board, null, 2), "utf-8");
30813
31235
  }
30814
31236
  function markTaskInProgress(board, taskId, role) {
30815
31237
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -30974,11 +31396,11 @@ async function defaultPromptHandler(q) {
30974
31396
  }
30975
31397
  }
30976
31398
  async function writeAssumptionsFile(projectPath, projectName, questions, assumptions) {
30977
- const fs55 = await import('fs/promises');
30978
- const path59 = await import('path');
30979
- const swarmDir = path59.join(projectPath, ".coco", "swarm");
30980
- const assumptionsPath = path59.join(swarmDir, "assumptions.md");
30981
- await fs55.mkdir(swarmDir, { recursive: true });
31399
+ const fs56 = await import('fs/promises');
31400
+ const path60 = await import('path');
31401
+ const swarmDir = path60.join(projectPath, ".coco", "swarm");
31402
+ const assumptionsPath = path60.join(swarmDir, "assumptions.md");
31403
+ await fs56.mkdir(swarmDir, { recursive: true });
30982
31404
  const now = (/* @__PURE__ */ new Date()).toISOString();
30983
31405
  const content = [
30984
31406
  `# Swarm Assumptions \u2014 ${projectName}`,
@@ -30994,18 +31416,18 @@ async function writeAssumptionsFile(projectPath, projectName, questions, assumpt
30994
31416
  assumptions.length > 0 ? assumptions.join("\n\n") : `_(none)_`,
30995
31417
  ``
30996
31418
  ].join("\n");
30997
- await fs55.writeFile(assumptionsPath, content, "utf-8");
31419
+ await fs56.writeFile(assumptionsPath, content, "utf-8");
30998
31420
  return assumptionsPath;
30999
31421
  }
31000
31422
 
31001
31423
  // src/swarm/events.ts
31002
31424
  async function appendSwarmEvent(projectPath, event) {
31003
- const fs55 = await import('fs/promises');
31004
- const path59 = await import('path');
31005
- const eventsDir = path59.join(projectPath, ".coco", "swarm");
31006
- const eventsFile = path59.join(eventsDir, "events.jsonl");
31007
- await fs55.mkdir(eventsDir, { recursive: true });
31008
- await fs55.appendFile(eventsFile, JSON.stringify(event) + "\n", "utf-8");
31425
+ const fs56 = await import('fs/promises');
31426
+ const path60 = await import('path');
31427
+ const eventsDir = path60.join(projectPath, ".coco", "swarm");
31428
+ const eventsFile = path60.join(eventsDir, "events.jsonl");
31429
+ await fs56.mkdir(eventsDir, { recursive: true });
31430
+ await fs56.appendFile(eventsFile, JSON.stringify(event) + "\n", "utf-8");
31009
31431
  }
31010
31432
  function createEventId() {
31011
31433
  return `evt-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
@@ -31013,12 +31435,12 @@ function createEventId() {
31013
31435
 
31014
31436
  // src/swarm/knowledge.ts
31015
31437
  async function appendKnowledge(projectPath, entry) {
31016
- const fs55 = await import('fs/promises');
31017
- const path59 = await import('path');
31018
- const knowledgeDir = path59.join(projectPath, ".coco", "swarm");
31019
- const knowledgeFile = path59.join(knowledgeDir, "knowledge.jsonl");
31020
- await fs55.mkdir(knowledgeDir, { recursive: true });
31021
- await fs55.appendFile(knowledgeFile, JSON.stringify(entry) + "\n", "utf-8");
31438
+ const fs56 = await import('fs/promises');
31439
+ const path60 = await import('path');
31440
+ const knowledgeDir = path60.join(projectPath, ".coco", "swarm");
31441
+ const knowledgeFile = path60.join(knowledgeDir, "knowledge.jsonl");
31442
+ await fs56.mkdir(knowledgeDir, { recursive: true });
31443
+ await fs56.appendFile(knowledgeFile, JSON.stringify(entry) + "\n", "utf-8");
31022
31444
  }
31023
31445
 
31024
31446
  // src/swarm/agents/prompts.ts
@@ -31322,11 +31744,11 @@ async function runSwarmLifecycle(options) {
31322
31744
  }
31323
31745
  async function stageInit(ctx) {
31324
31746
  const { projectPath, spec } = ctx.options;
31325
- const fs55 = await import('fs/promises');
31326
- const path59 = await import('path');
31327
- await fs55.mkdir(path59.join(projectPath, ".coco", "swarm"), { recursive: true });
31328
- await fs55.mkdir(ctx.options.outputPath, { recursive: true });
31329
- const specSummaryPath = path59.join(projectPath, ".coco", "swarm", "spec-summary.json");
31747
+ const fs56 = await import('fs/promises');
31748
+ const path60 = await import('path');
31749
+ await fs56.mkdir(path60.join(projectPath, ".coco", "swarm"), { recursive: true });
31750
+ await fs56.mkdir(ctx.options.outputPath, { recursive: true });
31751
+ const specSummaryPath = path60.join(projectPath, ".coco", "swarm", "spec-summary.json");
31330
31752
  const specSummary = {
31331
31753
  projectName: spec.projectName,
31332
31754
  description: spec.description,
@@ -31340,7 +31762,7 @@ async function stageInit(ctx) {
31340
31762
  })),
31341
31763
  qualityConfig: spec.qualityConfig
31342
31764
  };
31343
- await fs55.writeFile(specSummaryPath, JSON.stringify(specSummary, null, 2), "utf-8");
31765
+ await fs56.writeFile(specSummaryPath, JSON.stringify(specSummary, null, 2), "utf-8");
31344
31766
  await emitEvent(projectPath, {
31345
31767
  agentRole: "pm",
31346
31768
  agentTurn: 0,
@@ -31397,10 +31819,10 @@ async function stagePlan(ctx) {
31397
31819
  })
31398
31820
  ]);
31399
31821
  await createBoard(projectPath, spec);
31400
- const fs55 = await import('fs/promises');
31401
- const path59 = await import('path');
31402
- const planPath = path59.join(projectPath, ".coco", "swarm", "plan.json");
31403
- await fs55.writeFile(
31822
+ const fs56 = await import('fs/promises');
31823
+ const path60 = await import('path');
31824
+ const planPath = path60.join(projectPath, ".coco", "swarm", "plan.json");
31825
+ await fs56.writeFile(
31404
31826
  planPath,
31405
31827
  JSON.stringify({ pm: pmResult, architect: archResult, bestPractices: bpResult }, null, 2),
31406
31828
  "utf-8"
@@ -31615,8 +32037,8 @@ async function stageIntegrate(ctx) {
31615
32037
  }
31616
32038
  async function stageOutput(ctx) {
31617
32039
  const { projectPath, outputPath } = ctx.options;
31618
- const fs55 = await import('fs/promises');
31619
- const path59 = await import('path');
32040
+ const fs56 = await import('fs/promises');
32041
+ const path60 = await import('path');
31620
32042
  const board = await loadBoard(projectPath);
31621
32043
  const featureResults = Array.from(ctx.featureResults.values());
31622
32044
  const summary = {
@@ -31630,9 +32052,9 @@ async function stageOutput(ctx) {
31630
32052
  },
31631
32053
  globalScore: computeGlobalScore(featureResults)
31632
32054
  };
31633
- await fs55.mkdir(outputPath, { recursive: true });
31634
- const summaryPath = path59.join(outputPath, "swarm-summary.json");
31635
- await fs55.writeFile(summaryPath, JSON.stringify(summary, null, 2), "utf-8");
32055
+ await fs56.mkdir(outputPath, { recursive: true });
32056
+ const summaryPath = path60.join(outputPath, "swarm-summary.json");
32057
+ await fs56.writeFile(summaryPath, JSON.stringify(summary, null, 2), "utf-8");
31636
32058
  const passed = summary.globalScore >= ctx.options.minScore;
31637
32059
  await emitGate(projectPath, "global-score", passed, `Global score: ${summary.globalScore}`);
31638
32060
  await emitEvent(projectPath, {
@@ -31978,8 +32400,8 @@ var SwarmOrchestrator = class {
31978
32400
  noQuestions = false,
31979
32401
  onProgress
31980
32402
  } = options;
31981
- const path59 = await import('path');
31982
- const projectPath = path59.dirname(path59.resolve(specFile));
32403
+ const path60 = await import('path');
32404
+ const projectPath = path60.dirname(path60.resolve(specFile));
31983
32405
  onProgress?.("init", `Parsing spec file: ${specFile}`);
31984
32406
  const spec = await parseSwarmSpec(specFile);
31985
32407
  onProgress?.("init", `Initializing provider: ${providerType}`);
@@ -31990,7 +32412,7 @@ var SwarmOrchestrator = class {
31990
32412
  await runSwarmLifecycle({
31991
32413
  spec,
31992
32414
  projectPath,
31993
- outputPath: path59.resolve(outputPath),
32415
+ outputPath: path60.resolve(outputPath),
31994
32416
  provider,
31995
32417
  agentConfig,
31996
32418
  minScore,
@@ -32828,8 +33250,8 @@ async function setupGcloudADC(provider) {
32828
33250
  console.log(chalk.dim(" (Complete the sign-in in your browser, then return here)"));
32829
33251
  console.log();
32830
33252
  const { exec: exec3 } = await import('child_process');
32831
- const { promisify: promisify5 } = await import('util');
32832
- const execAsync3 = promisify5(exec3);
33253
+ const { promisify: promisify6 } = await import('util');
33254
+ const execAsync3 = promisify6(exec3);
32833
33255
  try {
32834
33256
  await execAsync3("gcloud auth application-default login", {
32835
33257
  timeout: 12e4
@@ -33514,15 +33936,15 @@ async function saveConfiguration(result) {
33514
33936
  }
33515
33937
  async function saveEnvVars(filePath, vars, createDir = false) {
33516
33938
  if (createDir) {
33517
- const dir = path37.dirname(filePath);
33939
+ const dir = path38.dirname(filePath);
33518
33940
  try {
33519
- await fs34.mkdir(dir, { recursive: true, mode: 448 });
33941
+ await fs35.mkdir(dir, { recursive: true, mode: 448 });
33520
33942
  } catch {
33521
33943
  }
33522
33944
  }
33523
33945
  let existingVars = {};
33524
33946
  try {
33525
- const content = await fs34.readFile(filePath, "utf-8");
33947
+ const content = await fs35.readFile(filePath, "utf-8");
33526
33948
  for (const line of content.split("\n")) {
33527
33949
  const trimmed = line.trim();
33528
33950
  if (trimmed && !trimmed.startsWith("#")) {
@@ -33545,7 +33967,7 @@ async function saveEnvVars(filePath, vars, createDir = false) {
33545
33967
  for (const [key, value] of Object.entries(allVars)) {
33546
33968
  lines.push(`${key}=${value}`);
33547
33969
  }
33548
- await fs34.writeFile(filePath, lines.join("\n") + "\n", { mode: 384 });
33970
+ await fs35.writeFile(filePath, lines.join("\n") + "\n", { mode: 384 });
33549
33971
  }
33550
33972
  async function handleLocalProviderUnavailable(providerType, config) {
33551
33973
  const cfg = LOCAL_PROVIDER_CONFIG[providerType];
@@ -33635,6 +34057,7 @@ async function ensureConfiguredV2(config) {
33635
34057
  const preferredHasCopilotCreds = preferredProviderDef?.id === "copilot" && isProviderConfigured();
33636
34058
  const preferredIsConfigured = preferredIsLocal || preferredHasApiKey || preferredHasOpenAIOAuth || preferredHasCopilotCreds;
33637
34059
  let preferredWasConfiguredButUnavailable = false;
34060
+ let preferredUnavailableWasLocal = false;
33638
34061
  if (preferredProviderDef && preferredIsConfigured) {
33639
34062
  try {
33640
34063
  const preferredInternalProviderId = preferredProviderDef.id === "openai" && preferredHasOpenAIOAuth ? "codex" : preferredProviderDef.id;
@@ -33654,8 +34077,9 @@ async function ensureConfiguredV2(config) {
33654
34077
  if (retryResult !== null) return retryResult;
33655
34078
  }
33656
34079
  preferredWasConfiguredButUnavailable = true;
34080
+ preferredUnavailableWasLocal = preferredIsLocal;
33657
34081
  }
33658
- if (!preferredWasConfiguredButUnavailable) {
34082
+ if (!preferredWasConfiguredButUnavailable || !preferredUnavailableWasLocal) {
33659
34083
  const configuredProviders = providers.filter((p45) => {
33660
34084
  if (p45.id === "copilot") return isProviderConfigured();
33661
34085
  if (p45.id === "openai") {
@@ -33676,6 +34100,7 @@ async function ensureConfiguredV2(config) {
33676
34100
  }
33677
34101
  const provider = await createProvider(providerId, { model });
33678
34102
  if (await provider.isAvailable()) {
34103
+ await saveProviderPreference(prov.id, model);
33679
34104
  return {
33680
34105
  ...config,
33681
34106
  provider: {
@@ -33690,7 +34115,7 @@ async function ensureConfiguredV2(config) {
33690
34115
  }
33691
34116
  }
33692
34117
  }
33693
- if (config.provider.type !== "openai" && config.provider.type !== "codex" && hasOpenAIOAuthTokens && !preferredWasConfiguredButUnavailable) {
34118
+ if (config.provider.type !== "openai" && config.provider.type !== "codex" && hasOpenAIOAuthTokens && (!preferredWasConfiguredButUnavailable || !preferredUnavailableWasLocal)) {
33694
34119
  try {
33695
34120
  const tokenResult = await getOrRefreshOAuthToken("openai");
33696
34121
  if (tokenResult) {
@@ -34174,8 +34599,8 @@ async function setupGcloudADCForProvider(_provider) {
34174
34599
  return false;
34175
34600
  }
34176
34601
  const { exec: exec3 } = await import('child_process');
34177
- const { promisify: promisify5 } = await import('util');
34178
- const execAsync3 = promisify5(exec3);
34602
+ const { promisify: promisify6 } = await import('util');
34603
+ const execAsync3 = promisify6(exec3);
34179
34604
  try {
34180
34605
  await execAsync3("gcloud auth application-default login", { timeout: 12e4 });
34181
34606
  const token = await getADCAccessToken();
@@ -34911,8 +35336,8 @@ async function listTrustedProjects2(trustStore) {
34911
35336
  p26.log.message("");
34912
35337
  for (const project of projects) {
34913
35338
  const level = project.approvalLevel.toUpperCase().padEnd(5);
34914
- const path59 = project.path.length > 50 ? "..." + project.path.slice(-47) : project.path;
34915
- p26.log.message(` [${level}] ${path59}`);
35339
+ const path60 = project.path.length > 50 ? "..." + project.path.slice(-47) : project.path;
35340
+ p26.log.message(` [${level}] ${path60}`);
34916
35341
  p26.log.message(` Last accessed: ${new Date(project.lastAccessed).toLocaleString()}`);
34917
35342
  }
34918
35343
  p26.log.message("");
@@ -35082,8 +35507,8 @@ var buildCommand = {
35082
35507
  };
35083
35508
  async function loadBacklog(projectPath) {
35084
35509
  try {
35085
- const backlogPath = path37.join(projectPath, ".coco", "planning", "backlog.json");
35086
- const content = await fs34.readFile(backlogPath, "utf-8");
35510
+ const backlogPath = path38.join(projectPath, ".coco", "planning", "backlog.json");
35511
+ const content = await fs35.readFile(backlogPath, "utf-8");
35087
35512
  const data = JSON.parse(content);
35088
35513
  return data.backlog;
35089
35514
  } catch {
@@ -35092,25 +35517,25 @@ async function loadBacklog(projectPath) {
35092
35517
  }
35093
35518
  async function loadSprint(projectPath, sprintId) {
35094
35519
  try {
35095
- const sprintsDir = path37.join(projectPath, ".coco", "planning", "sprints");
35096
- const files = await fs34.readdir(sprintsDir);
35520
+ const sprintsDir = path38.join(projectPath, ".coco", "planning", "sprints");
35521
+ const files = await fs35.readdir(sprintsDir);
35097
35522
  const jsonFiles = files.filter((f) => f.endsWith(".json"));
35098
35523
  if (jsonFiles.length === 0) return null;
35099
35524
  const targetFile = sprintId ? jsonFiles.find((f) => f.includes(sprintId)) : jsonFiles[0];
35100
35525
  if (!targetFile) return null;
35101
- const sprintPath = path37.join(sprintsDir, targetFile);
35102
- const content = await fs34.readFile(sprintPath, "utf-8");
35526
+ const sprintPath = path38.join(sprintsDir, targetFile);
35527
+ const content = await fs35.readFile(sprintPath, "utf-8");
35103
35528
  return JSON.parse(content);
35104
35529
  } catch {
35105
35530
  return null;
35106
35531
  }
35107
35532
  }
35108
35533
  async function saveBacklog(projectPath, backlog) {
35109
- const backlogPath = path37.join(projectPath, ".coco", "planning", "backlog.json");
35110
- const content = await fs34.readFile(backlogPath, "utf-8");
35534
+ const backlogPath = path38.join(projectPath, ".coco", "planning", "backlog.json");
35535
+ const content = await fs35.readFile(backlogPath, "utf-8");
35111
35536
  const data = JSON.parse(content);
35112
35537
  data.backlog = backlog;
35113
- await fs34.writeFile(backlogPath, JSON.stringify(data, null, 2), "utf-8");
35538
+ await fs35.writeFile(backlogPath, JSON.stringify(data, null, 2), "utf-8");
35114
35539
  }
35115
35540
  function getStatusEmoji(status) {
35116
35541
  const emojis = {
@@ -35816,7 +36241,7 @@ function getLevelName(level) {
35816
36241
  function displayMemoryFile(file) {
35817
36242
  const { emoji, color } = getLevelStyle(file.level);
35818
36243
  const levelName = getLevelName(file.level);
35819
- const fileName = path37__default.basename(file.path);
36244
+ const fileName = path38__default.basename(file.path);
35820
36245
  console.log();
35821
36246
  console.log(
35822
36247
  `${emoji} ${color.bold(levelName)} ${chalk.dim(`(${fileName})`)} ${chalk.dim(file.path)}`
@@ -35911,7 +36336,7 @@ var memoryCommand = {
35911
36336
  )
35912
36337
  );
35913
36338
  for (const f of reloaded) {
35914
- const fileName = path37__default.basename(f.path);
36339
+ const fileName = path38__default.basename(f.path);
35915
36340
  console.log(chalk.dim(` ${fileName} (${formatSize(f.content?.length ?? 0)})`));
35916
36341
  }
35917
36342
  } else {
@@ -36053,7 +36478,7 @@ async function getCheckpoint(session, checkpointId) {
36053
36478
  return store.checkpoints.find((cp) => cp.id === checkpointId) ?? null;
36054
36479
  }
36055
36480
  async function restoreFiles(checkpoint, excludeFiles) {
36056
- const fs55 = await import('fs/promises');
36481
+ const fs56 = await import('fs/promises');
36057
36482
  const restored = [];
36058
36483
  const failed = [];
36059
36484
  for (const fileCheckpoint of checkpoint.files) {
@@ -36061,7 +36486,7 @@ async function restoreFiles(checkpoint, excludeFiles) {
36061
36486
  continue;
36062
36487
  }
36063
36488
  try {
36064
- await fs55.writeFile(fileCheckpoint.filePath, fileCheckpoint.originalContent, "utf-8");
36489
+ await fs56.writeFile(fileCheckpoint.filePath, fileCheckpoint.originalContent, "utf-8");
36065
36490
  restored.push(fileCheckpoint.filePath);
36066
36491
  } catch (error) {
36067
36492
  const message = error instanceof Error ? error.message : "Unknown error";
@@ -36143,8 +36568,8 @@ function displayRewindResult(result) {
36143
36568
  const fileName = filePath.split("/").pop() ?? filePath;
36144
36569
  console.log(`${chalk.green(String.fromCodePoint(10003))} Restored: ${fileName}`);
36145
36570
  }
36146
- for (const { path: path59, error } of result.filesFailed) {
36147
- const fileName = path59.split("/").pop() ?? path59;
36571
+ for (const { path: path60, error } of result.filesFailed) {
36572
+ const fileName = path60.split("/").pop() ?? path60;
36148
36573
  console.log(`${chalk.red(String.fromCodePoint(10007))} Failed: ${fileName} (${error})`);
36149
36574
  }
36150
36575
  if (result.conversationRestored) {
@@ -36782,8 +37207,8 @@ var NPM_REGISTRY_URL = "https://registry.npmjs.org/@corbat-tech/coco/latest";
36782
37207
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
36783
37208
  var FETCH_TIMEOUT_MS = 5e3;
36784
37209
  var STARTUP_TIMEOUT_MS = 5500;
36785
- var CACHE_DIR = path37__default.join(os4__default.homedir(), ".coco");
36786
- var CACHE_FILE = path37__default.join(CACHE_DIR, "version-check-cache.json");
37210
+ var CACHE_DIR = path38__default.join(os4__default.homedir(), ".coco");
37211
+ var CACHE_FILE = path38__default.join(CACHE_DIR, "version-check-cache.json");
36787
37212
  function compareVersions(a, b) {
36788
37213
  const partsA = a.replace(/^v/, "").split(".").map((p45) => Number(p45.replace(/-.*$/, "")));
36789
37214
  const partsB = b.replace(/^v/, "").split(".").map((p45) => Number(p45.replace(/-.*$/, "")));
@@ -37125,7 +37550,7 @@ async function readClipboardImage() {
37125
37550
  return null;
37126
37551
  }
37127
37552
  async function readClipboardImageMacOS() {
37128
- const tmpFile = path37.join(os4.tmpdir(), `coco-clipboard-${Date.now()}.png`);
37553
+ const tmpFile = path38.join(os4.tmpdir(), `coco-clipboard-${Date.now()}.png`);
37129
37554
  try {
37130
37555
  const script = `
37131
37556
  set theFile to POSIX file "${tmpFile}"
@@ -37148,7 +37573,7 @@ end try
37148
37573
  if (!result.startsWith("ok")) {
37149
37574
  return null;
37150
37575
  }
37151
- const buffer = await fs34.readFile(tmpFile);
37576
+ const buffer = await fs35.readFile(tmpFile);
37152
37577
  return {
37153
37578
  data: buffer.toString("base64"),
37154
37579
  media_type: "image/png"
@@ -37157,7 +37582,7 @@ end try
37157
37582
  return null;
37158
37583
  } finally {
37159
37584
  try {
37160
- await fs34.unlink(tmpFile);
37585
+ await fs35.unlink(tmpFile);
37161
37586
  } catch {
37162
37587
  }
37163
37588
  }
@@ -37187,7 +37612,7 @@ async function readClipboardImageLinux() {
37187
37612
  }
37188
37613
  }
37189
37614
  async function readClipboardImageWindows() {
37190
- const tmpFile = path37.join(os4.tmpdir(), `coco-clipboard-${Date.now()}.png`);
37615
+ const tmpFile = path38.join(os4.tmpdir(), `coco-clipboard-${Date.now()}.png`);
37191
37616
  try {
37192
37617
  const escapedPath = tmpFile.replace(/'/g, "''");
37193
37618
  const script = `
@@ -37205,7 +37630,7 @@ if ($img -ne $null) {
37205
37630
  timeout: 1e4
37206
37631
  }).trim();
37207
37632
  if (result !== "ok") return null;
37208
- const buffer = await fs34.readFile(tmpFile);
37633
+ const buffer = await fs35.readFile(tmpFile);
37209
37634
  return {
37210
37635
  data: buffer.toString("base64"),
37211
37636
  media_type: "image/png"
@@ -37214,7 +37639,7 @@ if ($img -ne $null) {
37214
37639
  return null;
37215
37640
  } finally {
37216
37641
  try {
37217
- await fs34.unlink(tmpFile);
37642
+ await fs35.unlink(tmpFile);
37218
37643
  } catch {
37219
37644
  }
37220
37645
  }
@@ -37312,9 +37737,9 @@ var allowPathCommand = {
37312
37737
  }
37313
37738
  };
37314
37739
  async function addPath(dirPath, session) {
37315
- const absolute = path37__default.resolve(dirPath);
37740
+ const absolute = path38__default.resolve(dirPath);
37316
37741
  try {
37317
- const stat2 = await fs34__default.stat(absolute);
37742
+ const stat2 = await fs35__default.stat(absolute);
37318
37743
  if (!stat2.isDirectory()) {
37319
37744
  p26.log.error(`Not a directory: ${absolute}`);
37320
37745
  return;
@@ -37324,19 +37749,19 @@ async function addPath(dirPath, session) {
37324
37749
  return;
37325
37750
  }
37326
37751
  for (const blocked of BLOCKED_SYSTEM_PATHS) {
37327
- const normalizedBlocked = path37__default.normalize(blocked);
37328
- if (absolute === normalizedBlocked || absolute.startsWith(normalizedBlocked + path37__default.sep)) {
37752
+ const normalizedBlocked = path38__default.normalize(blocked);
37753
+ if (absolute === normalizedBlocked || absolute.startsWith(normalizedBlocked + path38__default.sep)) {
37329
37754
  p26.log.error(`System path '${blocked}' cannot be allowed`);
37330
37755
  return;
37331
37756
  }
37332
37757
  }
37333
- const normalizedCwd = path37__default.normalize(session.projectPath);
37334
- if (absolute === normalizedCwd || absolute.startsWith(normalizedCwd + path37__default.sep)) {
37758
+ const normalizedCwd = path38__default.normalize(session.projectPath);
37759
+ if (absolute === normalizedCwd || absolute.startsWith(normalizedCwd + path38__default.sep)) {
37335
37760
  p26.log.info("That path is already within the project directory");
37336
37761
  return;
37337
37762
  }
37338
37763
  const existing = getAllowedPaths();
37339
- if (existing.some((e) => path37__default.normalize(e.path) === path37__default.normalize(absolute))) {
37764
+ if (existing.some((e) => path38__default.normalize(e.path) === path38__default.normalize(absolute))) {
37340
37765
  p26.log.info(`Already allowed: ${absolute}`);
37341
37766
  return;
37342
37767
  }
@@ -37407,7 +37832,7 @@ async function revokePath(dirPath, _session) {
37407
37832
  }
37408
37833
  dirPath = selected;
37409
37834
  }
37410
- const absolute = path37__default.resolve(dirPath);
37835
+ const absolute = path38__default.resolve(dirPath);
37411
37836
  const removed = removeAllowedPathFromSession(absolute);
37412
37837
  await removePersistedAllowedPath(absolute);
37413
37838
  if (removed) {
@@ -37760,11 +38185,12 @@ var RECOMMENDED_DENY = [
37760
38185
  ];
37761
38186
  async function loadPermissionPreferences() {
37762
38187
  try {
37763
- const content = await fs34__default.readFile(CONFIG_PATHS.config, "utf-8");
38188
+ const content = await fs35__default.readFile(CONFIG_PATHS.config, "utf-8");
37764
38189
  const config = JSON.parse(content);
37765
38190
  return {
37766
38191
  recommendedAllowlistApplied: config.recommendedAllowlistApplied,
37767
- recommendedAllowlistDismissed: config.recommendedAllowlistDismissed
38192
+ recommendedAllowlistDismissed: config.recommendedAllowlistDismissed,
38193
+ recommendedAllowlistPrompted: config.recommendedAllowlistPrompted
37768
38194
  };
37769
38195
  } catch {
37770
38196
  return {};
@@ -37774,34 +38200,28 @@ async function savePermissionPreference(key, value) {
37774
38200
  try {
37775
38201
  let config = {};
37776
38202
  try {
37777
- const content = await fs34__default.readFile(CONFIG_PATHS.config, "utf-8");
38203
+ const content = await fs35__default.readFile(CONFIG_PATHS.config, "utf-8");
37778
38204
  config = JSON.parse(content);
37779
38205
  } catch {
37780
38206
  }
37781
38207
  config[key] = value;
37782
- await fs34__default.mkdir(path37__default.dirname(CONFIG_PATHS.config), { recursive: true });
37783
- await fs34__default.writeFile(CONFIG_PATHS.config, JSON.stringify(config, null, 2), "utf-8");
38208
+ await fs35__default.mkdir(path38__default.dirname(CONFIG_PATHS.config), { recursive: true });
38209
+ await fs35__default.writeFile(CONFIG_PATHS.config, JSON.stringify(config, null, 2), "utf-8");
37784
38210
  } catch {
37785
38211
  }
37786
38212
  }
37787
38213
  async function shouldShowPermissionSuggestion() {
37788
38214
  const prefs = await loadPermissionPreferences();
37789
- if (prefs.recommendedAllowlistDismissed) {
38215
+ if (prefs.recommendedAllowlistPrompted) {
37790
38216
  return false;
37791
38217
  }
37792
- if (!prefs.recommendedAllowlistApplied) {
37793
- return true;
38218
+ if (prefs.recommendedAllowlistDismissed) {
38219
+ return false;
37794
38220
  }
37795
- try {
37796
- const content = await fs34__default.readFile(CONFIG_PATHS.trustedTools, "utf-8");
37797
- const settings = JSON.parse(content);
37798
- if (!settings.globalTrusted || settings.globalTrusted.length === 0) {
37799
- return true;
37800
- }
37801
- } catch {
37802
- return true;
38221
+ if (prefs.recommendedAllowlistApplied) {
38222
+ return false;
37803
38223
  }
37804
- return false;
38224
+ return true;
37805
38225
  }
37806
38226
  async function applyRecommendedPermissions() {
37807
38227
  for (const tool of [...RECOMMENDED_GLOBAL, ...RECOMMENDED_PROJECT]) {
@@ -37810,6 +38230,7 @@ async function applyRecommendedPermissions() {
37810
38230
  await savePermissionPreference("recommendedAllowlistApplied", true);
37811
38231
  }
37812
38232
  async function showPermissionSuggestion() {
38233
+ await savePermissionPreference("recommendedAllowlistPrompted", true);
37813
38234
  console.log();
37814
38235
  console.log(chalk.magenta.bold(" \u{1F4CB} Recommended Permissions"));
37815
38236
  console.log();
@@ -38029,7 +38450,7 @@ async function resetPermissions(session) {
38029
38450
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
38030
38451
  };
38031
38452
  try {
38032
- await fs34__default.writeFile(CONFIG_PATHS.trustedTools, JSON.stringify(emptySettings, null, 2), "utf-8");
38453
+ await fs35__default.writeFile(CONFIG_PATHS.trustedTools, JSON.stringify(emptySettings, null, 2), "utf-8");
38033
38454
  } catch {
38034
38455
  }
38035
38456
  await savePermissionPreference("recommendedAllowlistApplied", false);
@@ -38111,7 +38532,7 @@ function formatQualityResult(result) {
38111
38532
  }
38112
38533
  async function loadQualityLoopPreference() {
38113
38534
  try {
38114
- const content = await fs34__default.readFile(CONFIG_PATHS.config, "utf-8");
38535
+ const content = await fs35__default.readFile(CONFIG_PATHS.config, "utf-8");
38115
38536
  const config = JSON.parse(content);
38116
38537
  const value = config.qualityLoop ?? config.cocoMode;
38117
38538
  if (typeof value === "boolean") {
@@ -38126,12 +38547,12 @@ async function saveQualityLoopPreference(enabled) {
38126
38547
  try {
38127
38548
  let config = {};
38128
38549
  try {
38129
- const content = await fs34__default.readFile(CONFIG_PATHS.config, "utf-8");
38550
+ const content = await fs35__default.readFile(CONFIG_PATHS.config, "utf-8");
38130
38551
  config = JSON.parse(content);
38131
38552
  } catch {
38132
38553
  }
38133
38554
  config.qualityLoop = enabled;
38134
- await fs34__default.writeFile(CONFIG_PATHS.config, JSON.stringify(config, null, 2) + "\n");
38555
+ await fs35__default.writeFile(CONFIG_PATHS.config, JSON.stringify(config, null, 2) + "\n");
38135
38556
  } catch {
38136
38557
  }
38137
38558
  }
@@ -38977,9 +39398,9 @@ Response format (JSON only, no prose):
38977
39398
  cancel5("Build cancelled.");
38978
39399
  }
38979
39400
  }
38980
- const cocoDir = path37__default.join(outputPath, ".coco");
38981
- await fs34__default.mkdir(cocoDir, { recursive: true });
38982
- await fs34__default.writeFile(path37__default.join(cocoDir, "backlog.json"), JSON.stringify(spec, null, 2), "utf-8");
39401
+ const cocoDir = path38__default.join(outputPath, ".coco");
39402
+ await fs35__default.mkdir(cocoDir, { recursive: true });
39403
+ await fs35__default.writeFile(path38__default.join(cocoDir, "backlog.json"), JSON.stringify(spec, null, 2), "utf-8");
38983
39404
  p26.outro(" Spec saved \u2014 starting sprints");
38984
39405
  return spec;
38985
39406
  }
@@ -39529,20 +39950,20 @@ init_errors();
39529
39950
  init_subprocess_registry();
39530
39951
  async function detectTestFramework2(cwd) {
39531
39952
  try {
39532
- await fs34__default.access(path37__default.join(cwd, "pom.xml"));
39953
+ await fs35__default.access(path38__default.join(cwd, "pom.xml"));
39533
39954
  return "maven";
39534
39955
  } catch {
39535
39956
  }
39536
39957
  for (const gradleFile of ["build.gradle", "build.gradle.kts"]) {
39537
39958
  try {
39538
- await fs34__default.access(path37__default.join(cwd, gradleFile));
39959
+ await fs35__default.access(path38__default.join(cwd, gradleFile));
39539
39960
  return "gradle";
39540
39961
  } catch {
39541
39962
  }
39542
39963
  }
39543
39964
  try {
39544
- const pkgPath = path37__default.join(cwd, "package.json");
39545
- const pkgContent = await fs34__default.readFile(pkgPath, "utf-8");
39965
+ const pkgPath = path38__default.join(cwd, "package.json");
39966
+ const pkgContent = await fs35__default.readFile(pkgPath, "utf-8");
39546
39967
  const pkg = JSON.parse(pkgContent);
39547
39968
  const deps = {
39548
39969
  ...pkg.dependencies,
@@ -39558,16 +39979,16 @@ async function detectTestFramework2(cwd) {
39558
39979
  }
39559
39980
  }
39560
39981
  function toMavenTestFilter(pattern) {
39561
- const base = path37__default.basename(pattern).replace(/\.java$/, "");
39982
+ const base = path38__default.basename(pattern).replace(/\.java$/, "");
39562
39983
  return base;
39563
39984
  }
39564
39985
  function toGradleTestFilter(pattern) {
39565
- const base = path37__default.basename(pattern).replace(/\.java$/, "");
39986
+ const base = path38__default.basename(pattern).replace(/\.java$/, "");
39566
39987
  return `*${base}`;
39567
39988
  }
39568
39989
  async function mavenExecutable(cwd) {
39569
39990
  try {
39570
- await fs34__default.access(path37__default.join(cwd, "mvnw"));
39991
+ await fs35__default.access(path38__default.join(cwd, "mvnw"));
39571
39992
  return "./mvnw";
39572
39993
  } catch {
39573
39994
  return "mvn";
@@ -39575,7 +39996,7 @@ async function mavenExecutable(cwd) {
39575
39996
  }
39576
39997
  async function gradleExecutable(cwd) {
39577
39998
  try {
39578
- await fs34__default.access(path37__default.join(cwd, "gradlew"));
39999
+ await fs35__default.access(path38__default.join(cwd, "gradlew"));
39579
40000
  return "./gradlew";
39580
40001
  } catch {
39581
40002
  return "gradle";
@@ -39816,18 +40237,18 @@ Examples:
39816
40237
  const projectDir = cwd ?? process.cwd();
39817
40238
  try {
39818
40239
  const coverageLocations = [
39819
- path37__default.join(projectDir, "coverage", "coverage-summary.json"),
39820
- path37__default.join(projectDir, "coverage", "coverage-final.json"),
39821
- path37__default.join(projectDir, ".nyc_output", "coverage-summary.json"),
40240
+ path38__default.join(projectDir, "coverage", "coverage-summary.json"),
40241
+ path38__default.join(projectDir, "coverage", "coverage-final.json"),
40242
+ path38__default.join(projectDir, ".nyc_output", "coverage-summary.json"),
39822
40243
  // Maven JaCoCo
39823
- path37__default.join(projectDir, "target", "site", "jacoco", "jacoco.csv"),
39824
- path37__default.join(projectDir, "target", "site", "jacoco-ut", "jacoco.csv"),
40244
+ path38__default.join(projectDir, "target", "site", "jacoco", "jacoco.csv"),
40245
+ path38__default.join(projectDir, "target", "site", "jacoco-ut", "jacoco.csv"),
39825
40246
  // Gradle JaCoCo
39826
- path37__default.join(projectDir, "build", "reports", "jacoco", "test", "jacocoTestReport.csv")
40247
+ path38__default.join(projectDir, "build", "reports", "jacoco", "test", "jacocoTestReport.csv")
39827
40248
  ];
39828
40249
  for (const location of coverageLocations) {
39829
40250
  try {
39830
- const content = await fs34__default.readFile(location, "utf-8");
40251
+ const content = await fs35__default.readFile(location, "utf-8");
39831
40252
  if (location.endsWith(".csv")) {
39832
40253
  const result = parseJacocoCsvCoverage(content);
39833
40254
  if (result) {
@@ -39936,7 +40357,7 @@ async function findFileRecursive(rootDir, target, options = {}) {
39936
40357
  const results = [];
39937
40358
  const startTime = Date.now();
39938
40359
  const isTimedOut = () => Date.now() - startTime > opts.timeoutMs;
39939
- const queue = [[path37__default.resolve(rootDir), 0]];
40360
+ const queue = [[path38__default.resolve(rootDir), 0]];
39940
40361
  const visited = /* @__PURE__ */ new Set();
39941
40362
  while (queue.length > 0 && results.length < opts.maxResults) {
39942
40363
  if (isTimedOut()) break;
@@ -39945,11 +40366,11 @@ async function findFileRecursive(rootDir, target, options = {}) {
39945
40366
  visited.add(currentDir);
39946
40367
  if (depth > opts.maxDepth) continue;
39947
40368
  try {
39948
- const entries = await fs34__default.readdir(currentDir, { withFileTypes: true });
40369
+ const entries = await fs35__default.readdir(currentDir, { withFileTypes: true });
39949
40370
  for (const entry of entries) {
39950
40371
  if (isTimedOut()) break;
39951
40372
  const entryName = entry.name;
39952
- const entryPath = path37__default.join(currentDir, entryName);
40373
+ const entryPath = path38__default.join(currentDir, entryName);
39953
40374
  if (!opts.includeHidden && entryName.startsWith(".")) continue;
39954
40375
  if (entry.isDirectory() && opts.excludeDirs.has(entryName)) continue;
39955
40376
  const isMatch = opts.type === "file" && entry.isFile() || opts.type === "directory" && entry.isDirectory() || opts.type === "both";
@@ -39983,19 +40404,19 @@ async function suggestSimilarFilesDeep(missingPath, rootDir = process.cwd(), opt
39983
40404
  if (fastResults.length > 0) {
39984
40405
  return fastResults;
39985
40406
  }
39986
- const absPath = path37__default.resolve(missingPath);
39987
- const target = path37__default.basename(absPath);
40407
+ const absPath = path38__default.resolve(missingPath);
40408
+ const target = path38__default.basename(absPath);
39988
40409
  return findFileRecursive(rootDir, target, options);
39989
40410
  }
39990
40411
  async function suggestSimilarDirsDeep(missingPath, rootDir = process.cwd(), options) {
39991
- const absPath = path37__default.resolve(missingPath);
39992
- const target = path37__default.basename(absPath);
39993
- const parentDir = path37__default.dirname(absPath);
40412
+ const absPath = path38__default.resolve(missingPath);
40413
+ const target = path38__default.basename(absPath);
40414
+ const parentDir = path38__default.dirname(absPath);
39994
40415
  try {
39995
- const entries = await fs34__default.readdir(parentDir, { withFileTypes: true });
40416
+ const entries = await fs35__default.readdir(parentDir, { withFileTypes: true });
39996
40417
  const dirs = entries.filter((e) => e.isDirectory());
39997
40418
  const scored = dirs.map((d) => ({
39998
- path: path37__default.join(parentDir, d.name),
40419
+ path: path38__default.join(parentDir, d.name),
39999
40420
  distance: levenshtein(target.toLowerCase(), d.name.toLowerCase())
40000
40421
  })).filter((s) => s.distance <= Math.max(target.length * 0.6, 3)).sort((a, b) => a.distance - b.distance).slice(0, options?.maxResults ?? MAX_SUGGESTIONS);
40001
40422
  if (scored.length > 0) {
@@ -40006,15 +40427,15 @@ async function suggestSimilarDirsDeep(missingPath, rootDir = process.cwd(), opti
40006
40427
  return findFileRecursive(rootDir, target, { ...options, type: "directory" });
40007
40428
  }
40008
40429
  async function suggestSimilarFiles(missingPath, options) {
40009
- const absPath = path37__default.resolve(missingPath);
40010
- const dir = path37__default.dirname(absPath);
40011
- const target = path37__default.basename(absPath);
40430
+ const absPath = path38__default.resolve(missingPath);
40431
+ const dir = path38__default.dirname(absPath);
40432
+ const target = path38__default.basename(absPath);
40012
40433
  const maxResults = options?.maxResults;
40013
40434
  try {
40014
- const entries = await fs34__default.readdir(dir);
40435
+ const entries = await fs35__default.readdir(dir);
40015
40436
  const limited = entries.slice(0, MAX_DIR_ENTRIES);
40016
40437
  const scored = limited.map((name) => ({
40017
- path: path37__default.join(dir, name),
40438
+ path: path38__default.join(dir, name),
40018
40439
  distance: levenshtein(target.toLowerCase(), name.toLowerCase())
40019
40440
  })).filter((s) => s.distance <= Math.max(target.length * 0.6, 3)).sort((a, b) => a.distance - b.distance);
40020
40441
  return scored.slice(0, maxResults);
@@ -40026,7 +40447,7 @@ function formatSuggestions(suggestions, baseDir) {
40026
40447
  if (suggestions.length === 0) return "";
40027
40448
  const base = baseDir ?? process.cwd();
40028
40449
  const lines = suggestions.map((s) => {
40029
- const rel = path37__default.relative(base, s.path);
40450
+ const rel = path38__default.relative(base, s.path);
40030
40451
  return ` - ${rel}`;
40031
40452
  });
40032
40453
  return `
@@ -40060,7 +40481,7 @@ function hasNullByte2(str) {
40060
40481
  }
40061
40482
  function normalizePath2(filePath) {
40062
40483
  let normalized = filePath.replace(/\0/g, "");
40063
- normalized = path37__default.normalize(normalized);
40484
+ normalized = path38__default.normalize(normalized);
40064
40485
  return normalized;
40065
40486
  }
40066
40487
  function isPathAllowed(filePath, operation) {
@@ -40068,31 +40489,31 @@ function isPathAllowed(filePath, operation) {
40068
40489
  return { allowed: false, reason: "Path contains invalid characters" };
40069
40490
  }
40070
40491
  const normalized = normalizePath2(filePath);
40071
- const absolute = path37__default.resolve(normalized);
40492
+ const absolute = path38__default.resolve(normalized);
40072
40493
  const cwd = process.cwd();
40073
40494
  for (const blocked of BLOCKED_PATHS2) {
40074
- const normalizedBlocked = path37__default.normalize(blocked);
40075
- if (absolute === normalizedBlocked || absolute.startsWith(normalizedBlocked + path37__default.sep)) {
40495
+ const normalizedBlocked = path38__default.normalize(blocked);
40496
+ if (absolute === normalizedBlocked || absolute.startsWith(normalizedBlocked + path38__default.sep)) {
40076
40497
  return { allowed: false, reason: `Access to system path '${blocked}' is not allowed` };
40077
40498
  }
40078
40499
  }
40079
40500
  const home = process.env.HOME;
40080
40501
  if (home) {
40081
- const normalizedHome = path37__default.normalize(home);
40082
- const normalizedCwd = path37__default.normalize(cwd);
40502
+ const normalizedHome = path38__default.normalize(home);
40503
+ const normalizedCwd = path38__default.normalize(cwd);
40083
40504
  if (absolute.startsWith(normalizedHome) && !absolute.startsWith(normalizedCwd)) {
40084
40505
  if (isWithinAllowedPath(absolute, operation)) ; else if (operation === "read") {
40085
40506
  const allowedHomeReads = [".gitconfig", ".zshrc", ".bashrc"];
40086
- const basename4 = path37__default.basename(absolute);
40507
+ const basename4 = path38__default.basename(absolute);
40087
40508
  if (!allowedHomeReads.includes(basename4)) {
40088
- const targetDir = path37__default.dirname(absolute);
40509
+ const targetDir = path38__default.dirname(absolute);
40089
40510
  return {
40090
40511
  allowed: false,
40091
40512
  reason: `Reading files outside project directory is not allowed. Use /allow-path ${targetDir} to grant access.`
40092
40513
  };
40093
40514
  }
40094
40515
  } else {
40095
- const targetDir = path37__default.dirname(absolute);
40516
+ const targetDir = path38__default.dirname(absolute);
40096
40517
  return {
40097
40518
  allowed: false,
40098
40519
  reason: `${operation} operations outside project directory are not allowed. Use /allow-path ${targetDir} to grant access.`
@@ -40101,7 +40522,7 @@ function isPathAllowed(filePath, operation) {
40101
40522
  }
40102
40523
  }
40103
40524
  if (operation === "write" || operation === "delete") {
40104
- const basename4 = path37__default.basename(absolute);
40525
+ const basename4 = path38__default.basename(absolute);
40105
40526
  for (const pattern of SENSITIVE_PATTERNS) {
40106
40527
  if (pattern.test(basename4)) {
40107
40528
  return {
@@ -40124,17 +40545,17 @@ function isENOENT(error) {
40124
40545
  return error.code === "ENOENT";
40125
40546
  }
40126
40547
  async function enrichENOENT(filePath, operation) {
40127
- const absPath = path37__default.resolve(filePath);
40548
+ const absPath = path38__default.resolve(filePath);
40128
40549
  const suggestions = await suggestSimilarFilesDeep(absPath, process.cwd());
40129
- const hint = formatSuggestions(suggestions, path37__default.dirname(absPath));
40550
+ const hint = formatSuggestions(suggestions, path38__default.dirname(absPath));
40130
40551
  const action = operation === "read" ? "Use glob or list_dir to find the correct path." : "Check that the parent directory exists.";
40131
40552
  return `File not found: ${filePath}${hint}
40132
40553
  ${action}`;
40133
40554
  }
40134
40555
  async function enrichDirENOENT(dirPath) {
40135
- const absPath = path37__default.resolve(dirPath);
40556
+ const absPath = path38__default.resolve(dirPath);
40136
40557
  const suggestions = await suggestSimilarDirsDeep(absPath, process.cwd());
40137
- const hint = formatSuggestions(suggestions, path37__default.dirname(absPath));
40558
+ const hint = formatSuggestions(suggestions, path38__default.dirname(absPath));
40138
40559
  return `Directory not found: ${dirPath}${hint}
40139
40560
  Use list_dir or glob to find the correct path.`;
40140
40561
  }
@@ -40155,13 +40576,13 @@ Examples:
40155
40576
  async execute({ path: filePath, encoding, maxSize }) {
40156
40577
  validatePath(filePath, "read");
40157
40578
  try {
40158
- const absolutePath = path37__default.resolve(filePath);
40159
- const stats = await fs34__default.stat(absolutePath);
40579
+ const absolutePath = path38__default.resolve(filePath);
40580
+ const stats = await fs35__default.stat(absolutePath);
40160
40581
  const maxBytes = maxSize ?? DEFAULT_MAX_FILE_SIZE;
40161
40582
  let truncated = false;
40162
40583
  let content;
40163
40584
  if (stats.size > maxBytes) {
40164
- const handle = await fs34__default.open(absolutePath, "r");
40585
+ const handle = await fs35__default.open(absolutePath, "r");
40165
40586
  try {
40166
40587
  const buffer = Buffer.alloc(maxBytes);
40167
40588
  await handle.read(buffer, 0, maxBytes, 0);
@@ -40171,7 +40592,7 @@ Examples:
40171
40592
  await handle.close();
40172
40593
  }
40173
40594
  } else {
40174
- content = await fs34__default.readFile(absolutePath, encoding);
40595
+ content = await fs35__default.readFile(absolutePath, encoding);
40175
40596
  }
40176
40597
  return {
40177
40598
  content,
@@ -40214,10 +40635,10 @@ Examples:
40214
40635
  async execute({ path: filePath, content, createDirs, dryRun }) {
40215
40636
  validatePath(filePath, "write");
40216
40637
  try {
40217
- const absolutePath = path37__default.resolve(filePath);
40638
+ const absolutePath = path38__default.resolve(filePath);
40218
40639
  let wouldCreate = false;
40219
40640
  try {
40220
- await fs34__default.access(absolutePath);
40641
+ await fs35__default.access(absolutePath);
40221
40642
  } catch {
40222
40643
  wouldCreate = true;
40223
40644
  }
@@ -40230,10 +40651,10 @@ Examples:
40230
40651
  };
40231
40652
  }
40232
40653
  if (createDirs) {
40233
- await fs34__default.mkdir(path37__default.dirname(absolutePath), { recursive: true });
40654
+ await fs35__default.mkdir(path38__default.dirname(absolutePath), { recursive: true });
40234
40655
  }
40235
- await fs34__default.writeFile(absolutePath, content, "utf-8");
40236
- const stats = await fs34__default.stat(absolutePath);
40656
+ await fs35__default.writeFile(absolutePath, content, "utf-8");
40657
+ const stats = await fs35__default.stat(absolutePath);
40237
40658
  return {
40238
40659
  path: absolutePath,
40239
40660
  size: stats.size,
@@ -40276,8 +40697,8 @@ Examples:
40276
40697
  async execute({ path: filePath, oldText, newText, all, dryRun }) {
40277
40698
  validatePath(filePath, "write");
40278
40699
  try {
40279
- const absolutePath = path37__default.resolve(filePath);
40280
- let content = await fs34__default.readFile(absolutePath, "utf-8");
40700
+ const absolutePath = path38__default.resolve(filePath);
40701
+ let content = await fs35__default.readFile(absolutePath, "utf-8");
40281
40702
  let replacements = 0;
40282
40703
  if (all) {
40283
40704
  const regex = new RegExp(escapeRegex(oldText), "g");
@@ -40326,7 +40747,7 @@ Hint: Use read_file first to verify the exact content.`
40326
40747
  preview
40327
40748
  };
40328
40749
  }
40329
- await fs34__default.writeFile(absolutePath, content, "utf-8");
40750
+ await fs35__default.writeFile(absolutePath, content, "utf-8");
40330
40751
  return {
40331
40752
  path: absolutePath,
40332
40753
  replacements,
@@ -40397,8 +40818,8 @@ Examples:
40397
40818
  }),
40398
40819
  async execute({ path: filePath }) {
40399
40820
  try {
40400
- const absolutePath = path37__default.resolve(filePath);
40401
- const stats = await fs34__default.stat(absolutePath);
40821
+ const absolutePath = path38__default.resolve(filePath);
40822
+ const stats = await fs35__default.stat(absolutePath);
40402
40823
  return {
40403
40824
  exists: true,
40404
40825
  isFile: stats.isFile(),
@@ -40428,12 +40849,12 @@ Examples:
40428
40849
  }),
40429
40850
  async execute({ path: dirPath, recursive }) {
40430
40851
  try {
40431
- const absolutePath = path37__default.resolve(dirPath);
40852
+ const absolutePath = path38__default.resolve(dirPath);
40432
40853
  const entries = [];
40433
40854
  async function listDir(dir, prefix = "") {
40434
- const items = await fs34__default.readdir(dir, { withFileTypes: true });
40855
+ const items = await fs35__default.readdir(dir, { withFileTypes: true });
40435
40856
  for (const item of items) {
40436
- const fullPath = path37__default.join(dir, item.name);
40857
+ const fullPath = path38__default.join(dir, item.name);
40437
40858
  const relativePath = prefix ? `${prefix}/${item.name}` : item.name;
40438
40859
  if (item.isDirectory()) {
40439
40860
  entries.push({ name: relativePath, type: "directory" });
@@ -40441,7 +40862,7 @@ Examples:
40441
40862
  await listDir(fullPath, relativePath);
40442
40863
  }
40443
40864
  } else if (item.isFile()) {
40444
- const stats = await fs34__default.stat(fullPath);
40865
+ const stats = await fs35__default.stat(fullPath);
40445
40866
  entries.push({ name: relativePath, type: "file", size: stats.size });
40446
40867
  }
40447
40868
  }
@@ -40488,23 +40909,23 @@ Examples:
40488
40909
  }
40489
40910
  validatePath(filePath, "delete");
40490
40911
  try {
40491
- const absolutePath = path37__default.resolve(filePath);
40492
- const stats = await fs34__default.stat(absolutePath);
40912
+ const absolutePath = path38__default.resolve(filePath);
40913
+ const stats = await fs35__default.stat(absolutePath);
40493
40914
  if (stats.isDirectory()) {
40494
40915
  if (!recursive) {
40495
40916
  throw new ToolError("Cannot delete directory without recursive: true", {
40496
40917
  tool: "delete_file"
40497
40918
  });
40498
40919
  }
40499
- await fs34__default.rm(absolutePath, { recursive: true });
40920
+ await fs35__default.rm(absolutePath, { recursive: true });
40500
40921
  } else {
40501
- await fs34__default.unlink(absolutePath);
40922
+ await fs35__default.unlink(absolutePath);
40502
40923
  }
40503
40924
  return { deleted: true, path: absolutePath };
40504
40925
  } catch (error) {
40505
40926
  if (error instanceof ToolError) throw error;
40506
40927
  if (error.code === "ENOENT") {
40507
- return { deleted: false, path: path37__default.resolve(filePath) };
40928
+ return { deleted: false, path: path38__default.resolve(filePath) };
40508
40929
  }
40509
40930
  throw new FileSystemError(`Failed to delete: ${filePath}`, {
40510
40931
  path: filePath,
@@ -40532,11 +40953,11 @@ Examples:
40532
40953
  validatePath(source, "read");
40533
40954
  validatePath(destination, "write");
40534
40955
  try {
40535
- const srcPath = path37__default.resolve(source);
40536
- const destPath = path37__default.resolve(destination);
40956
+ const srcPath = path38__default.resolve(source);
40957
+ const destPath = path38__default.resolve(destination);
40537
40958
  if (!overwrite) {
40538
40959
  try {
40539
- await fs34__default.access(destPath);
40960
+ await fs35__default.access(destPath);
40540
40961
  throw new ToolError(
40541
40962
  `Destination already exists: ${destination}. Use overwrite: true to replace.`,
40542
40963
  {
@@ -40549,9 +40970,9 @@ Examples:
40549
40970
  }
40550
40971
  }
40551
40972
  }
40552
- await fs34__default.mkdir(path37__default.dirname(destPath), { recursive: true });
40553
- await fs34__default.copyFile(srcPath, destPath);
40554
- const stats = await fs34__default.stat(destPath);
40973
+ await fs35__default.mkdir(path38__default.dirname(destPath), { recursive: true });
40974
+ await fs35__default.copyFile(srcPath, destPath);
40975
+ const stats = await fs35__default.stat(destPath);
40555
40976
  return {
40556
40977
  source: srcPath,
40557
40978
  destination: destPath,
@@ -40593,11 +41014,11 @@ Examples:
40593
41014
  validatePath(source, "delete");
40594
41015
  validatePath(destination, "write");
40595
41016
  try {
40596
- const srcPath = path37__default.resolve(source);
40597
- const destPath = path37__default.resolve(destination);
41017
+ const srcPath = path38__default.resolve(source);
41018
+ const destPath = path38__default.resolve(destination);
40598
41019
  if (!overwrite) {
40599
41020
  try {
40600
- await fs34__default.access(destPath);
41021
+ await fs35__default.access(destPath);
40601
41022
  throw new ToolError(
40602
41023
  `Destination already exists: ${destination}. Use overwrite: true to replace.`,
40603
41024
  {
@@ -40610,8 +41031,8 @@ Examples:
40610
41031
  }
40611
41032
  }
40612
41033
  }
40613
- await fs34__default.mkdir(path37__default.dirname(destPath), { recursive: true });
40614
- await fs34__default.rename(srcPath, destPath);
41034
+ await fs35__default.mkdir(path38__default.dirname(destPath), { recursive: true });
41035
+ await fs35__default.rename(srcPath, destPath);
40615
41036
  return {
40616
41037
  source: srcPath,
40617
41038
  destination: destPath
@@ -40680,15 +41101,15 @@ Examples:
40680
41101
  }),
40681
41102
  async execute({ path: dirPath, depth, showHidden, dirsOnly }) {
40682
41103
  try {
40683
- const absolutePath = path37__default.resolve(dirPath ?? ".");
41104
+ const absolutePath = path38__default.resolve(dirPath ?? ".");
40684
41105
  let totalFiles = 0;
40685
41106
  let totalDirs = 0;
40686
- const lines = [path37__default.basename(absolutePath) + "/"];
41107
+ const lines = [path38__default.basename(absolutePath) + "/"];
40687
41108
  let truncated = false;
40688
41109
  async function buildTree(dir, prefix, currentDepth) {
40689
41110
  if (currentDepth > (depth ?? 4)) return;
40690
41111
  if (lines.length >= MAX_TREE_LINES) return;
40691
- let items = await fs34__default.readdir(dir, { withFileTypes: true });
41112
+ let items = await fs35__default.readdir(dir, { withFileTypes: true });
40692
41113
  items = items.filter((item) => !TREE_IGNORED_DIRS.has(item.name));
40693
41114
  if (!showHidden) {
40694
41115
  items = items.filter((item) => !item.name.startsWith("."));
@@ -40713,7 +41134,7 @@ Examples:
40713
41134
  if (item.isDirectory()) {
40714
41135
  totalDirs++;
40715
41136
  lines.push(`${prefix}${connector}${item.name}/`);
40716
- await buildTree(path37__default.join(dir, item.name), prefix + childPrefix, currentDepth + 1);
41137
+ await buildTree(path38__default.join(dir, item.name), prefix + childPrefix, currentDepth + 1);
40717
41138
  } else {
40718
41139
  totalFiles++;
40719
41140
  lines.push(`${prefix}${connector}${item.name}`);
@@ -41981,7 +42402,7 @@ Examples:
41981
42402
  caseSensitive,
41982
42403
  wholeWord
41983
42404
  }) {
41984
- const targetPath = searchPath ? path37__default.resolve(searchPath) : process.cwd();
42405
+ const targetPath = searchPath ? path38__default.resolve(searchPath) : process.cwd();
41985
42406
  const matches = [];
41986
42407
  let filesSearched = 0;
41987
42408
  const filesWithMatches = /* @__PURE__ */ new Set();
@@ -42003,7 +42424,7 @@ Examples:
42003
42424
  tool: "grep"
42004
42425
  });
42005
42426
  }
42006
- const stats = await fs34__default.stat(targetPath);
42427
+ const stats = await fs35__default.stat(targetPath);
42007
42428
  let filesToSearch;
42008
42429
  if (stats.isFile()) {
42009
42430
  filesToSearch = [targetPath];
@@ -42025,7 +42446,7 @@ Examples:
42025
42446
  }
42026
42447
  filesSearched++;
42027
42448
  try {
42028
- const content = await fs34__default.readFile(file, "utf-8");
42449
+ const content = await fs35__default.readFile(file, "utf-8");
42029
42450
  const lines = content.split("\n");
42030
42451
  let fileHasMatch = false;
42031
42452
  for (let i = 0; i < lines.length; i++) {
@@ -42048,7 +42469,7 @@ Examples:
42048
42469
  contextAfter.push(lines[j] ?? "");
42049
42470
  }
42050
42471
  matches.push({
42051
- file: path37__default.relative(process.cwd(), file),
42472
+ file: path38__default.relative(process.cwd(), file),
42052
42473
  line: i + 1,
42053
42474
  column: match.index + 1,
42054
42475
  content: line,
@@ -42099,8 +42520,8 @@ Examples:
42099
42520
  }),
42100
42521
  async execute({ file, pattern, caseSensitive }) {
42101
42522
  try {
42102
- const absolutePath = path37__default.resolve(file);
42103
- const content = await fs34__default.readFile(absolutePath, "utf-8");
42523
+ const absolutePath = path38__default.resolve(file);
42524
+ const content = await fs35__default.readFile(absolutePath, "utf-8");
42104
42525
  const lines = content.split("\n");
42105
42526
  const matches = [];
42106
42527
  const flags = caseSensitive ? "" : "i";
@@ -42118,7 +42539,7 @@ Examples:
42118
42539
  } catch (error) {
42119
42540
  if (error.code === "ENOENT") {
42120
42541
  const suggestions = await suggestSimilarFilesDeep(file, process.cwd());
42121
- const hint = formatSuggestions(suggestions, path37__default.dirname(file));
42542
+ const hint = formatSuggestions(suggestions, path38__default.dirname(file));
42122
42543
  throw new ToolError(`File not found: ${file}${hint}
42123
42544
  Use glob to find the correct path.`, {
42124
42545
  tool: "find_in_file"
@@ -42309,7 +42730,7 @@ async function detectPackageManager2(cwd) {
42309
42730
  ];
42310
42731
  for (const { file, pm } of lockfiles) {
42311
42732
  try {
42312
- await fs34__default.access(path37__default.join(cwd, file));
42733
+ await fs35__default.access(path38__default.join(cwd, file));
42313
42734
  return pm;
42314
42735
  } catch {
42315
42736
  }
@@ -42582,7 +43003,7 @@ ${message}
42582
43003
  });
42583
43004
  try {
42584
43005
  try {
42585
- await fs34__default.access(path37__default.join(projectDir, "Makefile"));
43006
+ await fs35__default.access(path38__default.join(projectDir, "Makefile"));
42586
43007
  } catch {
42587
43008
  throw new ToolError("No Makefile found in directory", { tool: "make" });
42588
43009
  }
@@ -42752,7 +43173,7 @@ ${message}
42752
43173
  });
42753
43174
  async function resolveMaven(cwd) {
42754
43175
  try {
42755
- await fs34__default.access(path37__default.join(cwd, "mvnw"));
43176
+ await fs35__default.access(path38__default.join(cwd, "mvnw"));
42756
43177
  return "./mvnw";
42757
43178
  } catch {
42758
43179
  return "mvn";
@@ -42760,7 +43181,7 @@ async function resolveMaven(cwd) {
42760
43181
  }
42761
43182
  async function resolveGradle(cwd) {
42762
43183
  try {
42763
- await fs34__default.access(path37__default.join(cwd, "gradlew"));
43184
+ await fs35__default.access(path38__default.join(cwd, "gradlew"));
42764
43185
  return "./gradlew";
42765
43186
  } catch {
42766
43187
  return "gradle";
@@ -43627,8 +44048,8 @@ init_review();
43627
44048
  // src/tools/codebase-map.ts
43628
44049
  init_registry4();
43629
44050
  init_errors();
43630
- var fs37 = await import('fs/promises');
43631
- var path40 = await import('path');
44051
+ var fs38 = await import('fs/promises');
44052
+ var path41 = await import('path');
43632
44053
  var { glob: glob14 } = await import('glob');
43633
44054
  var DEFAULT_MAX_FILES = 200;
43634
44055
  var LANGUAGE_EXTENSIONS = {
@@ -43654,7 +44075,7 @@ var DEFAULT_EXCLUDES = [
43654
44075
  "**/*.d.ts"
43655
44076
  ];
43656
44077
  function detectLanguage3(filePath) {
43657
- const ext = path40.extname(filePath).toLowerCase();
44078
+ const ext = path41.extname(filePath).toLowerCase();
43658
44079
  for (const [lang, extensions] of Object.entries(LANGUAGE_EXTENSIONS)) {
43659
44080
  if (extensions.includes(ext)) return lang;
43660
44081
  }
@@ -44063,9 +44484,9 @@ Examples:
44063
44484
  }),
44064
44485
  async execute({ path: rootPath, include, exclude, languages, maxFiles, depth }) {
44065
44486
  const startTime = performance.now();
44066
- const absPath = path40.resolve(rootPath);
44487
+ const absPath = path41.resolve(rootPath);
44067
44488
  try {
44068
- const stat2 = await fs37.stat(absPath);
44489
+ const stat2 = await fs38.stat(absPath);
44069
44490
  if (!stat2.isDirectory()) {
44070
44491
  throw new ToolError(`Path is not a directory: ${absPath}`, {
44071
44492
  tool: "codebase_map"
@@ -44102,14 +44523,14 @@ Examples:
44102
44523
  let totalDefinitions = 0;
44103
44524
  let exportedSymbols = 0;
44104
44525
  for (const file of limitedFiles) {
44105
- const fullPath = path40.join(absPath, file);
44526
+ const fullPath = path41.join(absPath, file);
44106
44527
  const language = detectLanguage3(file);
44107
44528
  if (!language) continue;
44108
44529
  if (languages && !languages.includes(language)) {
44109
44530
  continue;
44110
44531
  }
44111
44532
  try {
44112
- const content = await fs37.readFile(fullPath, "utf-8");
44533
+ const content = await fs38.readFile(fullPath, "utf-8");
44113
44534
  const lineCount = content.split("\n").length;
44114
44535
  const parsed = parseFile(content, language);
44115
44536
  const definitions = depth === "overview" ? parsed.definitions.filter((d) => d.exported) : parsed.definitions;
@@ -44146,23 +44567,23 @@ var codebaseMapTools = [codebaseMapTool];
44146
44567
  init_registry4();
44147
44568
  init_errors();
44148
44569
  init_paths();
44149
- var fs38 = await import('fs/promises');
44150
- var path41 = await import('path');
44570
+ var fs39 = await import('fs/promises');
44571
+ var path42 = await import('path');
44151
44572
  var crypto2 = await import('crypto');
44152
- var GLOBAL_MEMORIES_DIR = path41.join(COCO_HOME, "memories");
44573
+ var GLOBAL_MEMORIES_DIR = path42.join(COCO_HOME, "memories");
44153
44574
  var PROJECT_MEMORIES_DIR = ".coco/memories";
44154
44575
  var DEFAULT_MAX_MEMORIES = 1e3;
44155
44576
  async function ensureDir2(dirPath) {
44156
- await fs38.mkdir(dirPath, { recursive: true });
44577
+ await fs39.mkdir(dirPath, { recursive: true });
44157
44578
  }
44158
44579
  function getMemoriesDir(scope) {
44159
44580
  return scope === "global" ? GLOBAL_MEMORIES_DIR : PROJECT_MEMORIES_DIR;
44160
44581
  }
44161
44582
  async function loadIndex(scope) {
44162
44583
  const dir = getMemoriesDir(scope);
44163
- const indexPath = path41.join(dir, "index.json");
44584
+ const indexPath = path42.join(dir, "index.json");
44164
44585
  try {
44165
- const content = await fs38.readFile(indexPath, "utf-8");
44586
+ const content = await fs39.readFile(indexPath, "utf-8");
44166
44587
  return JSON.parse(content);
44167
44588
  } catch {
44168
44589
  return [];
@@ -44171,14 +44592,14 @@ async function loadIndex(scope) {
44171
44592
  async function saveIndex(scope, index) {
44172
44593
  const dir = getMemoriesDir(scope);
44173
44594
  await ensureDir2(dir);
44174
- const indexPath = path41.join(dir, "index.json");
44175
- await fs38.writeFile(indexPath, JSON.stringify(index, null, 2), "utf-8");
44595
+ const indexPath = path42.join(dir, "index.json");
44596
+ await fs39.writeFile(indexPath, JSON.stringify(index, null, 2), "utf-8");
44176
44597
  }
44177
44598
  async function loadMemory(scope, id) {
44178
44599
  const dir = getMemoriesDir(scope);
44179
- const memPath = path41.join(dir, `${id}.json`);
44600
+ const memPath = path42.join(dir, `${id}.json`);
44180
44601
  try {
44181
- const content = await fs38.readFile(memPath, "utf-8");
44602
+ const content = await fs39.readFile(memPath, "utf-8");
44182
44603
  return JSON.parse(content);
44183
44604
  } catch {
44184
44605
  return null;
@@ -44187,8 +44608,8 @@ async function loadMemory(scope, id) {
44187
44608
  async function saveMemory(scope, memory) {
44188
44609
  const dir = getMemoriesDir(scope);
44189
44610
  await ensureDir2(dir);
44190
- const memPath = path41.join(dir, `${memory.id}.json`);
44191
- await fs38.writeFile(memPath, JSON.stringify(memory, null, 2), "utf-8");
44611
+ const memPath = path42.join(dir, `${memory.id}.json`);
44612
+ await fs39.writeFile(memPath, JSON.stringify(memory, null, 2), "utf-8");
44192
44613
  }
44193
44614
  var createMemoryTool = defineTool({
44194
44615
  name: "create_memory",
@@ -44344,17 +44765,17 @@ var memoryTools = [createMemoryTool, recallMemoryTool, listMemoriesTool];
44344
44765
  // src/tools/checkpoint.ts
44345
44766
  init_registry4();
44346
44767
  init_errors();
44347
- var fs39 = await import('fs/promises');
44768
+ var fs40 = await import('fs/promises');
44348
44769
  var crypto3 = await import('crypto');
44349
44770
  var CHECKPOINT_FILE = ".coco/checkpoints.json";
44350
44771
  var DEFAULT_MAX_CHECKPOINTS = 50;
44351
44772
  var STASH_PREFIX = "coco-cp";
44352
44773
  async function ensureCocoDir() {
44353
- await fs39.mkdir(".coco", { recursive: true });
44774
+ await fs40.mkdir(".coco", { recursive: true });
44354
44775
  }
44355
44776
  async function loadCheckpoints() {
44356
44777
  try {
44357
- const content = await fs39.readFile(CHECKPOINT_FILE, "utf-8");
44778
+ const content = await fs40.readFile(CHECKPOINT_FILE, "utf-8");
44358
44779
  return JSON.parse(content);
44359
44780
  } catch {
44360
44781
  return [];
@@ -44362,7 +44783,7 @@ async function loadCheckpoints() {
44362
44783
  }
44363
44784
  async function saveCheckpoints(checkpoints) {
44364
44785
  await ensureCocoDir();
44365
- await fs39.writeFile(CHECKPOINT_FILE, JSON.stringify(checkpoints, null, 2), "utf-8");
44786
+ await fs40.writeFile(CHECKPOINT_FILE, JSON.stringify(checkpoints, null, 2), "utf-8");
44366
44787
  }
44367
44788
  async function execGit(args) {
44368
44789
  const { execaCommand } = await import('execa');
@@ -44527,8 +44948,8 @@ var checkpointTools = [createCheckpointTool, restoreCheckpointTool, listCheckpoi
44527
44948
 
44528
44949
  // src/tools/semantic-search.ts
44529
44950
  init_registry4();
44530
- var fs40 = await import('fs/promises');
44531
- var path42 = await import('path');
44951
+ var fs41 = await import('fs/promises');
44952
+ var path43 = await import('path');
44532
44953
  var { glob: glob15 } = await import('glob');
44533
44954
  var INDEX_DIR = ".coco/search-index";
44534
44955
  var DEFAULT_CHUNK_SIZE = 20;
@@ -44656,20 +45077,20 @@ async function getEmbedding(text13) {
44656
45077
  }
44657
45078
  async function loadIndex2(indexDir) {
44658
45079
  try {
44659
- const indexPath = path42.join(indexDir, "index.json");
44660
- const content = await fs40.readFile(indexPath, "utf-8");
45080
+ const indexPath = path43.join(indexDir, "index.json");
45081
+ const content = await fs41.readFile(indexPath, "utf-8");
44661
45082
  return JSON.parse(content);
44662
45083
  } catch {
44663
45084
  return null;
44664
45085
  }
44665
45086
  }
44666
45087
  async function saveIndex2(indexDir, index) {
44667
- await fs40.mkdir(indexDir, { recursive: true });
44668
- const indexPath = path42.join(indexDir, "index.json");
44669
- await fs40.writeFile(indexPath, JSON.stringify(index), "utf-8");
45088
+ await fs41.mkdir(indexDir, { recursive: true });
45089
+ const indexPath = path43.join(indexDir, "index.json");
45090
+ await fs41.writeFile(indexPath, JSON.stringify(index), "utf-8");
44670
45091
  }
44671
45092
  function isBinary(filePath) {
44672
- return BINARY_EXTENSIONS.has(path42.extname(filePath).toLowerCase());
45093
+ return BINARY_EXTENSIONS.has(path43.extname(filePath).toLowerCase());
44673
45094
  }
44674
45095
  var semanticSearchTool = defineTool({
44675
45096
  name: "semantic_search",
@@ -44694,8 +45115,8 @@ Examples:
44694
45115
  const effectivePath = rootPath ?? ".";
44695
45116
  const effectiveMaxResults = maxResults ?? 10;
44696
45117
  const effectiveThreshold = threshold ?? 0.3;
44697
- const absPath = path42.resolve(effectivePath);
44698
- const indexDir = path42.join(absPath, INDEX_DIR);
45118
+ const absPath = path43.resolve(effectivePath);
45119
+ const indexDir = path43.join(absPath, INDEX_DIR);
44699
45120
  let index = reindex ? null : await loadIndex2(indexDir);
44700
45121
  let warnings = [];
44701
45122
  if (!index) {
@@ -44711,10 +45132,10 @@ Examples:
44711
45132
  let indexSaveWarning = "";
44712
45133
  for (const file of files) {
44713
45134
  if (isBinary(file)) continue;
44714
- const fullPath = path42.join(absPath, file);
45135
+ const fullPath = path43.join(absPath, file);
44715
45136
  try {
44716
- const stat2 = await fs40.stat(fullPath);
44717
- const content = await fs40.readFile(fullPath, "utf-8");
45137
+ const stat2 = await fs41.stat(fullPath);
45138
+ const content = await fs41.readFile(fullPath, "utf-8");
44718
45139
  if (content.length > 1e5) continue;
44719
45140
  const fileChunks = chunkContent(content, DEFAULT_CHUNK_SIZE);
44720
45141
  for (const chunk of fileChunks) {
@@ -44794,8 +45215,8 @@ var semanticSearchTools = [semanticSearchTool];
44794
45215
  // src/tools/diagram.ts
44795
45216
  init_registry4();
44796
45217
  init_errors();
44797
- var fs41 = await import('fs/promises');
44798
- var path43 = await import('path');
45218
+ var fs42 = await import('fs/promises');
45219
+ var path44 = await import('path');
44799
45220
  var { glob: glob16 } = await import('glob');
44800
45221
  async function parseClassRelationships(rootPath, include) {
44801
45222
  const pattern = include ?? "**/*.{ts,tsx,js,jsx}";
@@ -44808,7 +45229,7 @@ async function parseClassRelationships(rootPath, include) {
44808
45229
  const interfaces = [];
44809
45230
  for (const file of files.slice(0, 100)) {
44810
45231
  try {
44811
- const content = await fs41.readFile(path43.join(rootPath, file), "utf-8");
45232
+ const content = await fs42.readFile(path44.join(rootPath, file), "utf-8");
44812
45233
  const lines = content.split("\n");
44813
45234
  for (let i = 0; i < lines.length; i++) {
44814
45235
  const line = lines[i];
@@ -44927,14 +45348,14 @@ async function generateClassDiagram(rootPath, include) {
44927
45348
  };
44928
45349
  }
44929
45350
  async function generateArchitectureDiagram(rootPath) {
44930
- const entries = await fs41.readdir(rootPath, { withFileTypes: true });
45351
+ const entries = await fs42.readdir(rootPath, { withFileTypes: true });
44931
45352
  const dirs = entries.filter(
44932
45353
  (e) => e.isDirectory() && !e.name.startsWith(".") && !["node_modules", "dist", "build", "coverage", "__pycache__", "target"].includes(e.name)
44933
45354
  );
44934
45355
  const lines = ["graph TD"];
44935
45356
  let nodeCount = 0;
44936
45357
  let edgeCount = 0;
44937
- const rootName = path43.basename(rootPath);
45358
+ const rootName = path44.basename(rootPath);
44938
45359
  lines.push(` ROOT["${rootName}"]`);
44939
45360
  nodeCount++;
44940
45361
  for (const dir of dirs) {
@@ -44944,7 +45365,7 @@ async function generateArchitectureDiagram(rootPath) {
44944
45365
  nodeCount++;
44945
45366
  edgeCount++;
44946
45367
  try {
44947
- const subEntries = await fs41.readdir(path43.join(rootPath, dir.name), {
45368
+ const subEntries = await fs42.readdir(path44.join(rootPath, dir.name), {
44948
45369
  withFileTypes: true
44949
45370
  });
44950
45371
  const subDirs = subEntries.filter(
@@ -45067,7 +45488,7 @@ Examples:
45067
45488
  tool: "generate_diagram"
45068
45489
  });
45069
45490
  }
45070
- const absPath = rootPath ? path43.resolve(rootPath) : process.cwd();
45491
+ const absPath = rootPath ? path44.resolve(rootPath) : process.cwd();
45071
45492
  switch (type) {
45072
45493
  case "class":
45073
45494
  return generateClassDiagram(absPath, include);
@@ -45132,8 +45553,8 @@ var diagramTools = [generateDiagramTool];
45132
45553
  // src/tools/pdf.ts
45133
45554
  init_registry4();
45134
45555
  init_errors();
45135
- var fs42 = await import('fs/promises');
45136
- var path44 = await import('path');
45556
+ var fs43 = await import('fs/promises');
45557
+ var path45 = await import('path');
45137
45558
  var DEFAULT_MAX_PAGES = 20;
45138
45559
  var MAX_FILE_SIZE = 50 * 1024 * 1024;
45139
45560
  function parsePageRange(rangeStr, totalPages) {
@@ -45168,9 +45589,9 @@ Examples:
45168
45589
  }),
45169
45590
  async execute({ path: filePath, pages, maxPages }) {
45170
45591
  const startTime = performance.now();
45171
- const absPath = path44.resolve(filePath);
45592
+ const absPath = path45.resolve(filePath);
45172
45593
  try {
45173
- const stat2 = await fs42.stat(absPath);
45594
+ const stat2 = await fs43.stat(absPath);
45174
45595
  if (!stat2.isFile()) {
45175
45596
  throw new ToolError(`Path is not a file: ${absPath}`, {
45176
45597
  tool: "read_pdf"
@@ -45201,7 +45622,7 @@ Examples:
45201
45622
  }
45202
45623
  try {
45203
45624
  const pdfParse = await import('pdf-parse');
45204
- const dataBuffer = await fs42.readFile(absPath);
45625
+ const dataBuffer = await fs43.readFile(absPath);
45205
45626
  const pdfData = await pdfParse.default(dataBuffer, {
45206
45627
  max: maxPages
45207
45628
  });
@@ -45252,8 +45673,8 @@ var pdfTools = [readPdfTool];
45252
45673
  // src/tools/image.ts
45253
45674
  init_registry4();
45254
45675
  init_errors();
45255
- var fs43 = await import('fs/promises');
45256
- var path45 = await import('path');
45676
+ var fs44 = await import('fs/promises');
45677
+ var path46 = await import('path');
45257
45678
  var SUPPORTED_FORMATS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".webp", ".bmp"]);
45258
45679
  var MAX_IMAGE_SIZE = 20 * 1024 * 1024;
45259
45680
  var MIME_TYPES = {
@@ -45281,15 +45702,15 @@ Examples:
45281
45702
  async execute({ path: filePath, prompt, provider }) {
45282
45703
  const startTime = performance.now();
45283
45704
  const effectivePrompt = prompt ?? "Describe this image in detail. If it's code or a UI, identify the key elements.";
45284
- const absPath = path45.resolve(filePath);
45705
+ const absPath = path46.resolve(filePath);
45285
45706
  const cwd = process.cwd();
45286
- if (!absPath.startsWith(cwd + path45.sep) && absPath !== cwd) {
45707
+ if (!absPath.startsWith(cwd + path46.sep) && absPath !== cwd) {
45287
45708
  throw new ToolError(
45288
45709
  `Path traversal denied: '${filePath}' resolves outside the project directory`,
45289
45710
  { tool: "read_image" }
45290
45711
  );
45291
45712
  }
45292
- const ext = path45.extname(absPath).toLowerCase();
45713
+ const ext = path46.extname(absPath).toLowerCase();
45293
45714
  if (!SUPPORTED_FORMATS.has(ext)) {
45294
45715
  throw new ToolError(
45295
45716
  `Unsupported image format '${ext}'. Supported: ${Array.from(SUPPORTED_FORMATS).join(", ")}`,
@@ -45297,7 +45718,7 @@ Examples:
45297
45718
  );
45298
45719
  }
45299
45720
  try {
45300
- const stat2 = await fs43.stat(absPath);
45721
+ const stat2 = await fs44.stat(absPath);
45301
45722
  if (!stat2.isFile()) {
45302
45723
  throw new ToolError(`Path is not a file: ${absPath}`, {
45303
45724
  tool: "read_image"
@@ -45318,7 +45739,7 @@ Examples:
45318
45739
  if (error instanceof ToolError) throw error;
45319
45740
  throw error;
45320
45741
  }
45321
- const imageBuffer = await fs43.readFile(absPath);
45742
+ const imageBuffer = await fs44.readFile(absPath);
45322
45743
  const base64 = imageBuffer.toString("base64");
45323
45744
  const mimeType = MIME_TYPES[ext] ?? "image/png";
45324
45745
  const selectedProvider = provider ?? "anthropic";
@@ -45440,7 +45861,7 @@ var imageTools = [readImageTool];
45440
45861
  // src/tools/database.ts
45441
45862
  init_registry4();
45442
45863
  init_errors();
45443
- var path46 = await import('path');
45864
+ var path47 = await import('path');
45444
45865
  var DANGEROUS_PATTERNS = [
45445
45866
  /\bDROP\s+(?:TABLE|DATABASE|INDEX|VIEW)\b/i,
45446
45867
  /\bTRUNCATE\b/i,
@@ -45471,7 +45892,7 @@ Examples:
45471
45892
  async execute({ database, query, params, readonly: isReadonlyParam }) {
45472
45893
  const isReadonly = isReadonlyParam ?? true;
45473
45894
  const startTime = performance.now();
45474
- const absPath = path46.resolve(database);
45895
+ const absPath = path47.resolve(database);
45475
45896
  if (isReadonly && isDangerousSql(query)) {
45476
45897
  throw new ToolError(
45477
45898
  "Write operations (INSERT, UPDATE, DELETE, DROP, ALTER, TRUNCATE, CREATE) are blocked in readonly mode. Set readonly: false to allow writes.",
@@ -45554,7 +45975,7 @@ Examples:
45554
45975
  }),
45555
45976
  async execute({ database, table }) {
45556
45977
  const startTime = performance.now();
45557
- const absPath = path46.resolve(database);
45978
+ const absPath = path47.resolve(database);
45558
45979
  try {
45559
45980
  const { default: Database } = await import('better-sqlite3');
45560
45981
  const db = new Database(absPath, { readonly: true, fileMustExist: true });
@@ -45737,14 +46158,14 @@ var astValidatorTools = [validateCodeTool, findMissingImportsTool];
45737
46158
 
45738
46159
  // src/tools/code-analyzer.ts
45739
46160
  init_registry4();
45740
- var fs44 = await import('fs/promises');
45741
- var path47 = await import('path');
46161
+ var fs45 = await import('fs/promises');
46162
+ var path48 = await import('path');
45742
46163
  var AnalyzeFileSchema = z.object({
45743
46164
  filePath: z.string().describe("Path to file to analyze"),
45744
46165
  includeAst: z.boolean().default(false).describe("Include AST in result")
45745
46166
  });
45746
46167
  async function analyzeFile(filePath, includeAst = false) {
45747
- const content = await fs44.readFile(filePath, "utf-8");
46168
+ const content = await fs45.readFile(filePath, "utf-8");
45748
46169
  const lines = content.split("\n").length;
45749
46170
  const functions = [];
45750
46171
  const classes = [];
@@ -45848,10 +46269,10 @@ async function analyzeDirectory(dirPath) {
45848
46269
  try {
45849
46270
  const analysis = await analyzeFile(file, false);
45850
46271
  totalLines += analysis.lines;
45851
- const ext = path47.extname(file);
46272
+ const ext = path48.extname(file);
45852
46273
  filesByType[ext] = (filesByType[ext] || 0) + 1;
45853
46274
  fileStats.push({
45854
- file: path47.relative(dirPath, file),
46275
+ file: path48.relative(dirPath, file),
45855
46276
  lines: analysis.lines,
45856
46277
  complexity: analysis.complexity.cyclomatic
45857
46278
  });
@@ -46222,13 +46643,13 @@ var agentCoordinatorTools = [createAgentPlanTool, delegateTaskTool, aggregateRes
46222
46643
 
46223
46644
  // src/tools/smart-suggestions.ts
46224
46645
  init_registry4();
46225
- var fs45 = await import('fs/promises');
46646
+ var fs46 = await import('fs/promises');
46226
46647
  var SuggestImprovementsSchema = z.object({
46227
46648
  filePath: z.string().describe("File to analyze for improvement suggestions"),
46228
46649
  context: z.string().optional().describe("Additional context about the code")
46229
46650
  });
46230
46651
  async function analyzeAndSuggest(filePath, _context) {
46231
- const content = await fs45.readFile(filePath, "utf-8");
46652
+ const content = await fs46.readFile(filePath, "utf-8");
46232
46653
  const lines = content.split("\n");
46233
46654
  const suggestions = [];
46234
46655
  for (let i = 0; i < lines.length; i++) {
@@ -46320,7 +46741,7 @@ async function analyzeAndSuggest(filePath, _context) {
46320
46741
  if (filePath.endsWith(".ts") && !filePath.includes("test") && !filePath.includes(".d.ts") && line.includes("export ")) {
46321
46742
  const testPath = filePath.replace(".ts", ".test.ts");
46322
46743
  try {
46323
- await fs45.access(testPath);
46744
+ await fs46.access(testPath);
46324
46745
  } catch {
46325
46746
  suggestions.push({
46326
46747
  type: "testing",
@@ -46377,7 +46798,7 @@ var calculateCodeScoreTool = defineTool({
46377
46798
  async execute(input) {
46378
46799
  const { filePath } = input;
46379
46800
  const suggestions = await analyzeAndSuggest(filePath);
46380
- const content = await fs45.readFile(filePath, "utf-8");
46801
+ const content = await fs46.readFile(filePath, "utf-8");
46381
46802
  const lines = content.split("\n");
46382
46803
  const nonEmptyLines = lines.filter((l) => l.trim()).length;
46383
46804
  let score = 100;
@@ -46414,8 +46835,8 @@ var smartSuggestionsTools = [suggestImprovementsTool, calculateCodeScoreTool];
46414
46835
 
46415
46836
  // src/tools/context-enhancer.ts
46416
46837
  init_registry4();
46417
- var fs46 = await import('fs/promises');
46418
- var path48 = await import('path');
46838
+ var fs47 = await import('fs/promises');
46839
+ var path49 = await import('path');
46419
46840
  var ContextMemoryStore = class {
46420
46841
  items = /* @__PURE__ */ new Map();
46421
46842
  learnings = /* @__PURE__ */ new Map();
@@ -46427,7 +46848,7 @@ var ContextMemoryStore = class {
46427
46848
  }
46428
46849
  async load() {
46429
46850
  try {
46430
- const content = await fs46.readFile(this.storePath, "utf-8");
46851
+ const content = await fs47.readFile(this.storePath, "utf-8");
46431
46852
  const data = JSON.parse(content);
46432
46853
  this.items = new Map(Object.entries(data.items || {}));
46433
46854
  this.learnings = new Map(Object.entries(data.learnings || {}));
@@ -46435,15 +46856,15 @@ var ContextMemoryStore = class {
46435
46856
  }
46436
46857
  }
46437
46858
  async save() {
46438
- const dir = path48.dirname(this.storePath);
46439
- await fs46.mkdir(dir, { recursive: true });
46859
+ const dir = path49.dirname(this.storePath);
46860
+ await fs47.mkdir(dir, { recursive: true });
46440
46861
  const data = {
46441
46862
  sessionId: this.sessionId,
46442
46863
  items: Object.fromEntries(this.items),
46443
46864
  learnings: Object.fromEntries(this.learnings),
46444
46865
  savedAt: Date.now()
46445
46866
  };
46446
- await fs46.writeFile(this.storePath, JSON.stringify(data, null, 2));
46867
+ await fs47.writeFile(this.storePath, JSON.stringify(data, null, 2));
46447
46868
  }
46448
46869
  addContext(id, item) {
46449
46870
  this.items.set(id, item);
@@ -46611,11 +47032,11 @@ var contextEnhancerTools = [
46611
47032
 
46612
47033
  // src/tools/skill-enhancer.ts
46613
47034
  init_registry4();
46614
- var fs47 = await import('fs/promises');
46615
- var path49 = await import('path');
47035
+ var fs48 = await import('fs/promises');
47036
+ var path50 = await import('path');
46616
47037
  async function discoverSkills(skillsDir) {
46617
47038
  try {
46618
- const files = await fs47.readdir(skillsDir);
47039
+ const files = await fs48.readdir(skillsDir);
46619
47040
  return files.filter((f) => f.endsWith(".ts") || f.endsWith(".js"));
46620
47041
  } catch {
46621
47042
  return [];
@@ -46623,12 +47044,12 @@ async function discoverSkills(skillsDir) {
46623
47044
  }
46624
47045
  async function loadSkillMetadata(skillPath) {
46625
47046
  try {
46626
- const content = await fs47.readFile(skillPath, "utf-8");
47047
+ const content = await fs48.readFile(skillPath, "utf-8");
46627
47048
  const nameMatch = content.match(/@name\s+(\S+)/);
46628
47049
  const descMatch = content.match(/@description\s+(.+)/);
46629
47050
  const versionMatch = content.match(/@version\s+(\S+)/);
46630
47051
  return {
46631
- name: nameMatch?.[1] || path49.basename(skillPath, path49.extname(skillPath)),
47052
+ name: nameMatch?.[1] || path50.basename(skillPath, path50.extname(skillPath)),
46632
47053
  description: descMatch?.[1] || "No description",
46633
47054
  version: versionMatch?.[1] || "1.0.0",
46634
47055
  dependencies: []
@@ -46672,7 +47093,7 @@ var discoverSkillsTool = defineTool({
46672
47093
  const { skillsDir } = input;
46673
47094
  const skills = await discoverSkills(skillsDir);
46674
47095
  const metadata = await Promise.all(
46675
- skills.map((s) => loadSkillMetadata(path49.join(skillsDir, s)))
47096
+ skills.map((s) => loadSkillMetadata(path50.join(skillsDir, s)))
46676
47097
  );
46677
47098
  return {
46678
47099
  skillsDir,
@@ -46843,7 +47264,7 @@ Examples:
46843
47264
  reason: z.string().optional().describe("Why access is needed (shown to user for context)")
46844
47265
  }),
46845
47266
  async execute({ path: dirPath, reason }) {
46846
- const absolute = path37__default.resolve(dirPath);
47267
+ const absolute = path38__default.resolve(dirPath);
46847
47268
  if (isWithinAllowedPath(absolute, "read")) {
46848
47269
  return {
46849
47270
  authorized: true,
@@ -46852,8 +47273,8 @@ Examples:
46852
47273
  };
46853
47274
  }
46854
47275
  for (const blocked of BLOCKED_SYSTEM_PATHS2) {
46855
- const normalizedBlocked = path37__default.normalize(blocked);
46856
- if (absolute === normalizedBlocked || absolute.startsWith(normalizedBlocked + path37__default.sep)) {
47276
+ const normalizedBlocked = path38__default.normalize(blocked);
47277
+ if (absolute === normalizedBlocked || absolute.startsWith(normalizedBlocked + path38__default.sep)) {
46857
47278
  return {
46858
47279
  authorized: false,
46859
47280
  path: absolute,
@@ -46862,7 +47283,7 @@ Examples:
46862
47283
  }
46863
47284
  }
46864
47285
  const cwd = process.cwd();
46865
- if (absolute === path37__default.normalize(cwd) || absolute.startsWith(path37__default.normalize(cwd) + path37__default.sep)) {
47286
+ if (absolute === path38__default.normalize(cwd) || absolute.startsWith(path38__default.normalize(cwd) + path38__default.sep)) {
46866
47287
  return {
46867
47288
  authorized: true,
46868
47289
  path: absolute,
@@ -46870,7 +47291,7 @@ Examples:
46870
47291
  };
46871
47292
  }
46872
47293
  try {
46873
- const stat2 = await fs34__default.stat(absolute);
47294
+ const stat2 = await fs35__default.stat(absolute);
46874
47295
  if (!stat2.isDirectory()) {
46875
47296
  return {
46876
47297
  authorized: false,
@@ -46886,7 +47307,7 @@ Examples:
46886
47307
  };
46887
47308
  }
46888
47309
  const existing = getAllowedPaths();
46889
- if (existing.some((e) => path37__default.normalize(e.path) === path37__default.normalize(absolute))) {
47310
+ if (existing.some((e) => path38__default.normalize(e.path) === path38__default.normalize(absolute))) {
46890
47311
  return {
46891
47312
  authorized: true,
46892
47313
  path: absolute,
@@ -46971,9 +47392,9 @@ async function runSprints(options) {
46971
47392
  Object.entries(AGENT_ROLES).map(([role, def]) => [role, { ...def, maxTurns: 20 }])
46972
47393
  );
46973
47394
  const coordinator = createAgentCoordinator(executor, agentDefsMap);
46974
- await fs34__default.mkdir(spec.outputPath, { recursive: true });
46975
- const sprintsDir = path37__default.join(spec.outputPath, ".coco", "sprints");
46976
- await fs34__default.mkdir(sprintsDir, { recursive: true });
47395
+ await fs35__default.mkdir(spec.outputPath, { recursive: true });
47396
+ const sprintsDir = path38__default.join(spec.outputPath, ".coco", "sprints");
47397
+ await fs35__default.mkdir(sprintsDir, { recursive: true });
46977
47398
  for (const sprint of spec.sprints) {
46978
47399
  onProgress(`Starting ${sprint.id}: ${sprint.name}`);
46979
47400
  const sprintStart = Date.now();
@@ -47226,8 +47647,8 @@ Assess: overall architecture, consistency, error handling, and production readin
47226
47647
  };
47227
47648
  }
47228
47649
  async function saveSprintResult(sprintsDir, result) {
47229
- const filePath = path37__default.join(sprintsDir, `${result.sprintId}.json`);
47230
- await fs34__default.writeFile(filePath, JSON.stringify(result, null, 2), "utf-8");
47650
+ const filePath = path38__default.join(sprintsDir, `${result.sprintId}.json`);
47651
+ await fs35__default.writeFile(filePath, JSON.stringify(result, null, 2), "utf-8");
47231
47652
  }
47232
47653
 
47233
47654
  // src/cli/repl/commands/build-app.ts
@@ -47252,9 +47673,9 @@ function parseArgs6(args) {
47252
47673
  return { description, specFile, outputDir, skipConfirmation };
47253
47674
  }
47254
47675
  function isWithinRoot(resolvedPath, rootDir) {
47255
- const normalRoot = path37__default.normalize(rootDir) + path37__default.sep;
47256
- const normalPath = path37__default.normalize(resolvedPath);
47257
- return normalPath === path37__default.normalize(rootDir) || normalPath.startsWith(normalRoot);
47676
+ const normalRoot = path38__default.normalize(rootDir) + path38__default.sep;
47677
+ const normalPath = path38__default.normalize(resolvedPath);
47678
+ return normalPath === path38__default.normalize(rootDir) || normalPath.startsWith(normalRoot);
47258
47679
  }
47259
47680
  var buildAppCommand = {
47260
47681
  name: "build-app",
@@ -47277,20 +47698,20 @@ var buildAppCommand = {
47277
47698
  }
47278
47699
  let initialDescription = parsed.description;
47279
47700
  if (parsed.specFile) {
47280
- const specPath = path37__default.resolve(session.projectPath, parsed.specFile);
47701
+ const specPath = path38__default.resolve(session.projectPath, parsed.specFile);
47281
47702
  if (!isWithinRoot(specPath, session.projectPath)) {
47282
47703
  p26.log.error(`--spec path must be within the project directory: ${specPath}`);
47283
47704
  return false;
47284
47705
  }
47285
47706
  try {
47286
- initialDescription = await fs34__default.readFile(specPath, "utf-8");
47707
+ initialDescription = await fs35__default.readFile(specPath, "utf-8");
47287
47708
  } catch (err) {
47288
47709
  const msg = err instanceof Error ? err.message : String(err);
47289
47710
  p26.log.error(`Error reading spec file: ${msg}`);
47290
47711
  return false;
47291
47712
  }
47292
47713
  }
47293
- const outputPath = parsed.outputDir ? path37__default.resolve(session.projectPath, parsed.outputDir) : path37__default.join(session.projectPath, "build-app-output");
47714
+ const outputPath = parsed.outputDir ? path38__default.resolve(session.projectPath, parsed.outputDir) : path38__default.join(session.projectPath, "build-app-output");
47294
47715
  if (parsed.outputDir && !isWithinRoot(outputPath, session.projectPath)) {
47295
47716
  p26.log.error(`--output path must be within the project directory: ${outputPath}`);
47296
47717
  return false;
@@ -47454,7 +47875,7 @@ function buildProgressBar(pct) {
47454
47875
 
47455
47876
  // src/cli/repl/worktree/manager.ts
47456
47877
  init_logger();
47457
- var execFileAsync2 = promisify(execFile);
47878
+ var execFileAsync3 = promisify(execFile);
47458
47879
  var WORKTREES_DIR = ".worktrees";
47459
47880
  var WorktreeManager = class {
47460
47881
  worktrees = /* @__PURE__ */ new Map();
@@ -47474,7 +47895,7 @@ var WorktreeManager = class {
47474
47895
  const id = randomUUID();
47475
47896
  const branchPrefix = options.branchPrefix ?? "coco-agent";
47476
47897
  const branchName = `${branchPrefix}/${name}-${id.slice(0, 8)}`;
47477
- const worktreePath = path37__default.join(this.projectRoot, WORKTREES_DIR, `${name}-${id.slice(0, 8)}`);
47898
+ const worktreePath = path38__default.join(this.projectRoot, WORKTREES_DIR, `${name}-${id.slice(0, 8)}`);
47478
47899
  const worktree = {
47479
47900
  id,
47480
47901
  name,
@@ -47485,7 +47906,7 @@ var WorktreeManager = class {
47485
47906
  };
47486
47907
  this.worktrees.set(id, worktree);
47487
47908
  try {
47488
- await fs34__default.mkdir(path37__default.join(this.projectRoot, WORKTREES_DIR), { recursive: true });
47909
+ await fs35__default.mkdir(path38__default.join(this.projectRoot, WORKTREES_DIR), { recursive: true });
47489
47910
  const baseBranch = options.baseBranch ?? "HEAD";
47490
47911
  await this.git(["worktree", "add", "-b", branchName, worktreePath, baseBranch]);
47491
47912
  worktree.status = "active";
@@ -47678,7 +48099,7 @@ var WorktreeManager = class {
47678
48099
  try {
47679
48100
  await this.git(["push", "-u", "origin", worktree.branch]);
47680
48101
  const title = options.message ?? `Agent: ${worktree.name}`;
47681
- const { stdout } = await execFileAsync2(
48102
+ const { stdout } = await execFileAsync3(
47682
48103
  "gh",
47683
48104
  [
47684
48105
  "pr",
@@ -47704,10 +48125,10 @@ var WorktreeManager = class {
47704
48125
  }
47705
48126
  // ── Helpers ──────────────────────────────────────────────────────
47706
48127
  async git(args) {
47707
- return execFileAsync2("git", args, { cwd: this.projectRoot });
48128
+ return execFileAsync3("git", args, { cwd: this.projectRoot });
47708
48129
  }
47709
48130
  async gitIn(cwd, args) {
47710
- return execFileAsync2("git", args, { cwd });
48131
+ return execFileAsync3("git", args, { cwd });
47711
48132
  }
47712
48133
  async countChangedFiles(branch) {
47713
48134
  try {
@@ -47732,7 +48153,7 @@ var DEFAULT_CONFIG5 = {
47732
48153
  };
47733
48154
  async function runBestOfN(projectRoot, executor, config, callbacks = {}) {
47734
48155
  const cfg = { ...DEFAULT_CONFIG5, ...config };
47735
- const logger = getLogger();
48156
+ const logger2 = getLogger();
47736
48157
  const startTime = Date.now();
47737
48158
  if (cfg.attempts < 2) {
47738
48159
  return {
@@ -47755,7 +48176,7 @@ async function runBestOfN(projectRoot, executor, config, callbacks = {}) {
47755
48176
  const worktreeManager = new WorktreeManager(projectRoot);
47756
48177
  const attempts = [];
47757
48178
  try {
47758
- logger.info(`Best-of-N: Creating ${cfg.attempts} worktrees...`);
48179
+ logger2.info(`Best-of-N: Creating ${cfg.attempts} worktrees...`);
47759
48180
  const worktrees = await Promise.all(
47760
48181
  Array.from(
47761
48182
  { length: cfg.attempts },
@@ -47779,7 +48200,7 @@ async function runBestOfN(projectRoot, executor, config, callbacks = {}) {
47779
48200
  durationMs: 0
47780
48201
  });
47781
48202
  }
47782
- logger.info(`Best-of-N: Running ${cfg.attempts} parallel attempts...`);
48203
+ logger2.info(`Best-of-N: Running ${cfg.attempts} parallel attempts...`);
47783
48204
  await Promise.all(
47784
48205
  attempts.map(async (attempt) => {
47785
48206
  const attemptStart = Date.now();
@@ -47833,7 +48254,7 @@ async function runBestOfN(projectRoot, executor, config, callbacks = {}) {
47833
48254
  attempt.status = "discarded";
47834
48255
  }
47835
48256
  }
47836
- logger.info(`Best-of-N: Winner is attempt #${winner.index} with score ${winner.score}`);
48257
+ logger2.info(`Best-of-N: Winner is attempt #${winner.index} with score ${winner.score}`);
47837
48258
  for (const attempt of attempts) {
47838
48259
  if (attempt.id !== winner.id) {
47839
48260
  try {
@@ -47848,7 +48269,7 @@ async function runBestOfN(projectRoot, executor, config, callbacks = {}) {
47848
48269
  message: `Best-of-N winner (attempt #${winner.index}, score: ${winner.score})`
47849
48270
  });
47850
48271
  if (!mergeResult.success) {
47851
- logger.warn(`Best-of-N: Auto-merge failed: ${mergeResult.error}`);
48272
+ logger2.warn(`Best-of-N: Auto-merge failed: ${mergeResult.error}`);
47852
48273
  }
47853
48274
  }
47854
48275
  return {
@@ -48831,8 +49252,8 @@ function formatToolSummary(toolName, input) {
48831
49252
  case "grep":
48832
49253
  case "search_files": {
48833
49254
  const pattern = String(input.pattern || "");
48834
- const path59 = input.path ? ` in ${input.path}` : "";
48835
- return `"${pattern}"${path59}`;
49255
+ const path60 = input.path ? ` in ${input.path}` : "";
49256
+ return `"${pattern}"${path60}`;
48836
49257
  }
48837
49258
  case "bash_exec": {
48838
49259
  const cmd = String(input.command || "");
@@ -48853,8 +49274,8 @@ function formatToolSummary(toolName, input) {
48853
49274
  function formatUrl(url) {
48854
49275
  try {
48855
49276
  const u = new URL(url);
48856
- const path59 = u.pathname.replace(/\/$/, "");
48857
- const display = path59 ? `${u.hostname} \u203A ${path59.slice(1)}` : u.hostname;
49277
+ const path60 = u.pathname.replace(/\/$/, "");
49278
+ const display = path60 ? `${u.hostname} \u203A ${path60.slice(1)}` : u.hostname;
48858
49279
  const max = Math.max(getTerminalWidth2() - 20, 50);
48859
49280
  return display.length > max ? display.slice(0, max - 1) + "\u2026" : display;
48860
49281
  } catch {
@@ -49084,7 +49505,7 @@ function getAllCommands() {
49084
49505
  }
49085
49506
 
49086
49507
  // src/cli/repl/input/handler.ts
49087
- var HISTORY_FILE = path37.join(os4.homedir(), ".coco", "history");
49508
+ var HISTORY_FILE = path38.join(os4.homedir(), ".coco", "history");
49088
49509
  async function handleOptionC(copyFn = copyToClipboard, getLastBlockFn = getLastBlock) {
49089
49510
  const block = getLastBlockFn();
49090
49511
  if (!block) return null;
@@ -49105,7 +49526,7 @@ function loadHistory() {
49105
49526
  }
49106
49527
  function saveHistory(history) {
49107
49528
  try {
49108
- const dir = path37.dirname(HISTORY_FILE);
49529
+ const dir = path38.dirname(HISTORY_FILE);
49109
49530
  if (!fs5.existsSync(dir)) {
49110
49531
  fs5.mkdirSync(dir, { recursive: true });
49111
49532
  }
@@ -50459,7 +50880,7 @@ function formatDiffPreview(toolCall) {
50459
50880
  }
50460
50881
  async function checkFileExists(filePath) {
50461
50882
  try {
50462
- await fs34__default.access(filePath);
50883
+ await fs35__default.access(filePath);
50463
50884
  return true;
50464
50885
  } catch {
50465
50886
  return false;
@@ -52256,7 +52677,7 @@ function formatContextUsage(percent) {
52256
52677
  }
52257
52678
  function formatStatusBar(projectPath, config, gitCtx, contextUsagePercent) {
52258
52679
  const parts = [];
52259
- const projectName = path37__default.basename(projectPath);
52680
+ const projectName = path38__default.basename(projectPath);
52260
52681
  parts.push(chalk.dim("\u{1F4C1} ") + chalk.magenta(projectName));
52261
52682
  const providerName = config.provider.type;
52262
52683
  const modelName = config.provider.model || "default";
@@ -52361,13 +52782,13 @@ async function startRepl(options = {}) {
52361
52782
  }
52362
52783
  await session.skillRegistry.discoverAndRegister(projectPath, getBuiltinSkillsForDiscovery2());
52363
52784
  } catch (skillError) {
52364
- const logger2 = (await Promise.resolve().then(() => (init_logger(), logger_exports))).getLogger();
52365
- logger2.warn(
52785
+ const logger3 = (await Promise.resolve().then(() => (init_logger(), logger_exports))).getLogger();
52786
+ logger3.warn(
52366
52787
  `[Skills] Failed to initialize skills: ${skillError instanceof Error ? skillError.message : String(skillError)}`
52367
52788
  );
52368
52789
  }
52369
52790
  let mcpManager = null;
52370
- const logger = (await Promise.resolve().then(() => (init_logger(), logger_exports))).getLogger();
52791
+ const logger2 = (await Promise.resolve().then(() => (init_logger(), logger_exports))).getLogger();
52371
52792
  try {
52372
52793
  const { getMCPServerManager: getMCPServerManager2 } = await Promise.resolve().then(() => (init_lifecycle(), lifecycle_exports));
52373
52794
  const { MCPRegistryImpl: MCPRegistryImpl2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
@@ -52387,7 +52808,7 @@ async function startRepl(options = {}) {
52387
52808
  try {
52388
52809
  connections = await mcpManager.startAll(enabledServers);
52389
52810
  } catch (startError) {
52390
- logger.warn(
52811
+ logger2.warn(
52391
52812
  `[MCP] Failed to start servers: ${startError instanceof Error ? startError.message : String(startError)}`
52392
52813
  );
52393
52814
  try {
@@ -52401,18 +52822,18 @@ async function startRepl(options = {}) {
52401
52822
  try {
52402
52823
  await registerMCPTools2(toolRegistry, connection.name, connection.client);
52403
52824
  } catch (toolError) {
52404
- logger.warn(
52825
+ logger2.warn(
52405
52826
  `[MCP] Failed to register tools for server '${connection.name}': ${toolError instanceof Error ? toolError.message : String(toolError)}`
52406
52827
  );
52407
52828
  }
52408
52829
  }
52409
52830
  const activeCount = connections.size;
52410
52831
  if (activeCount > 0) {
52411
- logger.info(`[MCP] ${activeCount} MCP server(s) active`);
52832
+ logger2.info(`[MCP] ${activeCount} MCP server(s) active`);
52412
52833
  }
52413
52834
  }
52414
52835
  } catch (mcpError) {
52415
- logger.warn(
52836
+ logger2.warn(
52416
52837
  `[MCP] Initialization failed: ${mcpError instanceof Error ? mcpError.message : String(mcpError)}`
52417
52838
  );
52418
52839
  }
@@ -52426,12 +52847,12 @@ async function startRepl(options = {}) {
52426
52847
  if (registry.size > 0) {
52427
52848
  hookRegistry = registry;
52428
52849
  hookExecutor = createHookExecutor2();
52429
- logger.info(`[Hooks] Loaded ${registry.size} hook(s) from ${hooksConfigPath}`);
52850
+ logger2.info(`[Hooks] Loaded ${registry.size} hook(s) from ${hooksConfigPath}`);
52430
52851
  }
52431
52852
  } catch (hookError) {
52432
52853
  const msg = hookError instanceof Error ? hookError.message : String(hookError);
52433
52854
  if (!msg.includes("ENOENT")) {
52434
- logger.warn(`[Hooks] Failed to load hooks: ${msg}`);
52855
+ logger2.warn(`[Hooks] Failed to load hooks: ${msg}`);
52435
52856
  }
52436
52857
  }
52437
52858
  const inputHandler = createInputHandler();