@corbat-tech/coco 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +325 -72
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -12,11 +12,11 @@ import { z } from 'zod';
|
|
|
12
12
|
import chalk42 from 'chalk';
|
|
13
13
|
import * as p9 from '@clack/prompts';
|
|
14
14
|
import { execa } from 'execa';
|
|
15
|
+
import * as crypto from 'crypto';
|
|
16
|
+
import { randomUUID } from 'crypto';
|
|
15
17
|
import { Command } from 'commander';
|
|
16
18
|
import { fileURLToPath, URL as URL$1 } from 'url';
|
|
17
19
|
import JSON5 from 'json5';
|
|
18
|
-
import * as crypto from 'crypto';
|
|
19
|
-
import { randomUUID } from 'crypto';
|
|
20
20
|
import Anthropic from '@anthropic-ai/sdk';
|
|
21
21
|
import OpenAI from 'openai';
|
|
22
22
|
import * as http from 'http';
|
|
@@ -448,8 +448,8 @@ __export(trust_store_exports, {
|
|
|
448
448
|
saveTrustStore: () => saveTrustStore,
|
|
449
449
|
updateLastAccessed: () => updateLastAccessed
|
|
450
450
|
});
|
|
451
|
-
async function ensureDir(
|
|
452
|
-
await mkdir(dirname(
|
|
451
|
+
async function ensureDir(path44) {
|
|
452
|
+
await mkdir(dirname(path44), { recursive: true });
|
|
453
453
|
}
|
|
454
454
|
async function loadTrustStore(storePath = TRUST_STORE_PATH) {
|
|
455
455
|
try {
|
|
@@ -527,8 +527,8 @@ function canPerformOperation(store, projectPath, operation) {
|
|
|
527
527
|
};
|
|
528
528
|
return permissions[level]?.includes(operation) ?? false;
|
|
529
529
|
}
|
|
530
|
-
function normalizePath(
|
|
531
|
-
return join(
|
|
530
|
+
function normalizePath(path44) {
|
|
531
|
+
return join(path44);
|
|
532
532
|
}
|
|
533
533
|
function createTrustStore(storePath = TRUST_STORE_PATH) {
|
|
534
534
|
let store = null;
|
|
@@ -1260,6 +1260,224 @@ Examples:
|
|
|
1260
1260
|
bashTools = [bashExecTool, bashBackgroundTool, commandExistsTool, getEnvTool];
|
|
1261
1261
|
}
|
|
1262
1262
|
});
|
|
1263
|
+
async function fileExists(filePath) {
|
|
1264
|
+
try {
|
|
1265
|
+
await fs23__default.access(filePath);
|
|
1266
|
+
return true;
|
|
1267
|
+
} catch {
|
|
1268
|
+
return false;
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
var init_files = __esm({
|
|
1272
|
+
"src/utils/files.ts"() {
|
|
1273
|
+
init_errors();
|
|
1274
|
+
}
|
|
1275
|
+
});
|
|
1276
|
+
|
|
1277
|
+
// src/cli/repl/context/stack-detector.ts
|
|
1278
|
+
var stack_detector_exports = {};
|
|
1279
|
+
__export(stack_detector_exports, {
|
|
1280
|
+
detectProjectStack: () => detectProjectStack
|
|
1281
|
+
});
|
|
1282
|
+
async function detectStack(cwd) {
|
|
1283
|
+
if (await fileExists(path20__default.join(cwd, "package.json"))) return "node";
|
|
1284
|
+
if (await fileExists(path20__default.join(cwd, "Cargo.toml"))) return "rust";
|
|
1285
|
+
if (await fileExists(path20__default.join(cwd, "pyproject.toml"))) return "python";
|
|
1286
|
+
if (await fileExists(path20__default.join(cwd, "go.mod"))) return "go";
|
|
1287
|
+
if (await fileExists(path20__default.join(cwd, "pom.xml"))) return "java";
|
|
1288
|
+
if (await fileExists(path20__default.join(cwd, "build.gradle"))) return "java";
|
|
1289
|
+
if (await fileExists(path20__default.join(cwd, "build.gradle.kts"))) return "java";
|
|
1290
|
+
return "unknown";
|
|
1291
|
+
}
|
|
1292
|
+
async function detectPackageManager2(cwd, stack) {
|
|
1293
|
+
if (stack === "rust") return "cargo";
|
|
1294
|
+
if (stack === "python") return "pip";
|
|
1295
|
+
if (stack === "go") return "go";
|
|
1296
|
+
if (stack === "java") {
|
|
1297
|
+
if (await fileExists(path20__default.join(cwd, "build.gradle")) || await fileExists(path20__default.join(cwd, "build.gradle.kts"))) {
|
|
1298
|
+
return "gradle";
|
|
1299
|
+
}
|
|
1300
|
+
if (await fileExists(path20__default.join(cwd, "pom.xml"))) {
|
|
1301
|
+
return "maven";
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
if (stack === "node") {
|
|
1305
|
+
if (await fileExists(path20__default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
1306
|
+
if (await fileExists(path20__default.join(cwd, "yarn.lock"))) return "yarn";
|
|
1307
|
+
if (await fileExists(path20__default.join(cwd, "bun.lockb"))) return "bun";
|
|
1308
|
+
return "npm";
|
|
1309
|
+
}
|
|
1310
|
+
return null;
|
|
1311
|
+
}
|
|
1312
|
+
async function parsePackageJson(cwd) {
|
|
1313
|
+
const packageJsonPath = path20__default.join(cwd, "package.json");
|
|
1314
|
+
try {
|
|
1315
|
+
const content = await fs23__default.readFile(packageJsonPath, "utf-8");
|
|
1316
|
+
const pkg = JSON.parse(content);
|
|
1317
|
+
const allDeps = {
|
|
1318
|
+
...pkg.dependencies,
|
|
1319
|
+
...pkg.devDependencies
|
|
1320
|
+
};
|
|
1321
|
+
const frameworks = [];
|
|
1322
|
+
if (allDeps.react) frameworks.push("React");
|
|
1323
|
+
if (allDeps.vue) frameworks.push("Vue");
|
|
1324
|
+
if (allDeps["@angular/core"]) frameworks.push("Angular");
|
|
1325
|
+
if (allDeps.next) frameworks.push("Next.js");
|
|
1326
|
+
if (allDeps.nuxt) frameworks.push("Nuxt");
|
|
1327
|
+
if (allDeps.express) frameworks.push("Express");
|
|
1328
|
+
if (allDeps.fastify) frameworks.push("Fastify");
|
|
1329
|
+
if (allDeps.nestjs || allDeps["@nestjs/core"]) frameworks.push("NestJS");
|
|
1330
|
+
const buildTools2 = [];
|
|
1331
|
+
if (allDeps.webpack) buildTools2.push("webpack");
|
|
1332
|
+
if (allDeps.vite) buildTools2.push("vite");
|
|
1333
|
+
if (allDeps.rollup) buildTools2.push("rollup");
|
|
1334
|
+
if (allDeps.tsup) buildTools2.push("tsup");
|
|
1335
|
+
if (allDeps.esbuild) buildTools2.push("esbuild");
|
|
1336
|
+
if (pkg.scripts?.build) buildTools2.push("build");
|
|
1337
|
+
const testingFrameworks = [];
|
|
1338
|
+
if (allDeps.vitest) testingFrameworks.push("vitest");
|
|
1339
|
+
if (allDeps.jest) testingFrameworks.push("jest");
|
|
1340
|
+
if (allDeps.mocha) testingFrameworks.push("mocha");
|
|
1341
|
+
if (allDeps.chai) testingFrameworks.push("chai");
|
|
1342
|
+
if (allDeps["@playwright/test"]) testingFrameworks.push("playwright");
|
|
1343
|
+
if (allDeps.cypress) testingFrameworks.push("cypress");
|
|
1344
|
+
const languages = ["JavaScript"];
|
|
1345
|
+
if (allDeps.typescript || await fileExists(path20__default.join(cwd, "tsconfig.json"))) {
|
|
1346
|
+
languages.push("TypeScript");
|
|
1347
|
+
}
|
|
1348
|
+
return {
|
|
1349
|
+
dependencies: allDeps,
|
|
1350
|
+
frameworks,
|
|
1351
|
+
buildTools: buildTools2,
|
|
1352
|
+
testingFrameworks,
|
|
1353
|
+
languages
|
|
1354
|
+
};
|
|
1355
|
+
} catch {
|
|
1356
|
+
return {
|
|
1357
|
+
dependencies: {},
|
|
1358
|
+
frameworks: [],
|
|
1359
|
+
buildTools: [],
|
|
1360
|
+
testingFrameworks: [],
|
|
1361
|
+
languages: []
|
|
1362
|
+
};
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
async function parsePomXml(cwd) {
|
|
1366
|
+
const pomPath = path20__default.join(cwd, "pom.xml");
|
|
1367
|
+
try {
|
|
1368
|
+
const content = await fs23__default.readFile(pomPath, "utf-8");
|
|
1369
|
+
const dependencies = {};
|
|
1370
|
+
const frameworks = [];
|
|
1371
|
+
const buildTools2 = ["maven"];
|
|
1372
|
+
const testingFrameworks = [];
|
|
1373
|
+
const depRegex = /<groupId>([^<]+)<\/groupId>\s*<artifactId>([^<]+)<\/artifactId>/g;
|
|
1374
|
+
let match;
|
|
1375
|
+
while ((match = depRegex.exec(content)) !== null) {
|
|
1376
|
+
const groupId = match[1];
|
|
1377
|
+
const artifactId = match[2];
|
|
1378
|
+
if (!groupId || !artifactId) continue;
|
|
1379
|
+
const fullName = `${groupId}:${artifactId}`;
|
|
1380
|
+
dependencies[fullName] = "unknown";
|
|
1381
|
+
if (artifactId.includes("spring-boot")) {
|
|
1382
|
+
if (!frameworks.includes("Spring Boot")) frameworks.push("Spring Boot");
|
|
1383
|
+
}
|
|
1384
|
+
if (artifactId.includes("spring-webmvc") || artifactId.includes("spring-web")) {
|
|
1385
|
+
if (!frameworks.includes("Spring MVC")) frameworks.push("Spring MVC");
|
|
1386
|
+
}
|
|
1387
|
+
if (artifactId.includes("hibernate")) {
|
|
1388
|
+
if (!frameworks.includes("Hibernate")) frameworks.push("Hibernate");
|
|
1389
|
+
}
|
|
1390
|
+
if (artifactId === "junit-jupiter" || artifactId === "junit") {
|
|
1391
|
+
if (!testingFrameworks.includes("JUnit")) testingFrameworks.push("JUnit");
|
|
1392
|
+
}
|
|
1393
|
+
if (artifactId === "mockito-core") {
|
|
1394
|
+
if (!testingFrameworks.includes("Mockito")) testingFrameworks.push("Mockito");
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
return { dependencies, frameworks, buildTools: buildTools2, testingFrameworks };
|
|
1398
|
+
} catch {
|
|
1399
|
+
return { dependencies: {}, frameworks: [], buildTools: ["maven"], testingFrameworks: [] };
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
async function parsePyprojectToml(cwd) {
|
|
1403
|
+
const pyprojectPath = path20__default.join(cwd, "pyproject.toml");
|
|
1404
|
+
try {
|
|
1405
|
+
const content = await fs23__default.readFile(pyprojectPath, "utf-8");
|
|
1406
|
+
const dependencies = {};
|
|
1407
|
+
const frameworks = [];
|
|
1408
|
+
const buildTools2 = ["pip"];
|
|
1409
|
+
const testingFrameworks = [];
|
|
1410
|
+
const lines = content.split("\n");
|
|
1411
|
+
for (const line of lines) {
|
|
1412
|
+
const trimmed = line.trim();
|
|
1413
|
+
if (trimmed.match(/^["']?[\w-]+["']?\s*=\s*["'][\^~>=<]+[\d.]+["']/)) {
|
|
1414
|
+
const depMatch = trimmed.match(/^["']?([\w-]+)["']?\s*=\s*["']([\^~>=<]+[\d.]+)["']/);
|
|
1415
|
+
if (depMatch && depMatch[1] && depMatch[2]) {
|
|
1416
|
+
dependencies[depMatch[1]] = depMatch[2];
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
if (trimmed.includes("fastapi")) frameworks.push("FastAPI");
|
|
1420
|
+
if (trimmed.includes("django")) frameworks.push("Django");
|
|
1421
|
+
if (trimmed.includes("flask")) frameworks.push("Flask");
|
|
1422
|
+
if (trimmed.includes("pytest")) testingFrameworks.push("pytest");
|
|
1423
|
+
if (trimmed.includes("unittest")) testingFrameworks.push("unittest");
|
|
1424
|
+
}
|
|
1425
|
+
return { dependencies, frameworks, buildTools: buildTools2, testingFrameworks };
|
|
1426
|
+
} catch {
|
|
1427
|
+
return { dependencies: {}, frameworks: [], buildTools: ["pip"], testingFrameworks: [] };
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
async function detectProjectStack(cwd) {
|
|
1431
|
+
const stack = await detectStack(cwd);
|
|
1432
|
+
const packageManager = await detectPackageManager2(cwd, stack);
|
|
1433
|
+
let dependencies = {};
|
|
1434
|
+
let frameworks = [];
|
|
1435
|
+
let buildTools2 = [];
|
|
1436
|
+
let testingFrameworks = [];
|
|
1437
|
+
let languages = [];
|
|
1438
|
+
if (stack === "node") {
|
|
1439
|
+
const parsed = await parsePackageJson(cwd);
|
|
1440
|
+
dependencies = parsed.dependencies;
|
|
1441
|
+
frameworks = parsed.frameworks;
|
|
1442
|
+
buildTools2 = parsed.buildTools;
|
|
1443
|
+
testingFrameworks = parsed.testingFrameworks;
|
|
1444
|
+
languages = parsed.languages;
|
|
1445
|
+
} else if (stack === "java") {
|
|
1446
|
+
const parsed = await parsePomXml(cwd);
|
|
1447
|
+
dependencies = parsed.dependencies;
|
|
1448
|
+
frameworks = parsed.frameworks;
|
|
1449
|
+
buildTools2 = parsed.buildTools;
|
|
1450
|
+
testingFrameworks = parsed.testingFrameworks;
|
|
1451
|
+
languages = ["Java"];
|
|
1452
|
+
} else if (stack === "python") {
|
|
1453
|
+
const parsed = await parsePyprojectToml(cwd);
|
|
1454
|
+
dependencies = parsed.dependencies;
|
|
1455
|
+
frameworks = parsed.frameworks;
|
|
1456
|
+
buildTools2 = parsed.buildTools;
|
|
1457
|
+
testingFrameworks = parsed.testingFrameworks;
|
|
1458
|
+
languages = ["Python"];
|
|
1459
|
+
} else if (stack === "go") {
|
|
1460
|
+
languages = ["Go"];
|
|
1461
|
+
buildTools2 = ["go"];
|
|
1462
|
+
} else if (stack === "rust") {
|
|
1463
|
+
languages = ["Rust"];
|
|
1464
|
+
buildTools2 = ["cargo"];
|
|
1465
|
+
}
|
|
1466
|
+
return {
|
|
1467
|
+
stack,
|
|
1468
|
+
packageManager,
|
|
1469
|
+
dependencies,
|
|
1470
|
+
frameworks,
|
|
1471
|
+
buildTools: buildTools2,
|
|
1472
|
+
testingFrameworks,
|
|
1473
|
+
languages
|
|
1474
|
+
};
|
|
1475
|
+
}
|
|
1476
|
+
var init_stack_detector = __esm({
|
|
1477
|
+
"src/cli/repl/context/stack-detector.ts"() {
|
|
1478
|
+
init_files();
|
|
1479
|
+
}
|
|
1480
|
+
});
|
|
1263
1481
|
function findPackageJson() {
|
|
1264
1482
|
let dir = dirname(fileURLToPath(import.meta.url));
|
|
1265
1483
|
for (let i = 0; i < 10; i++) {
|
|
@@ -1418,8 +1636,8 @@ Generated by Corbat-Coco v0.1.0
|
|
|
1418
1636
|
|
|
1419
1637
|
// src/cli/commands/init.ts
|
|
1420
1638
|
function registerInitCommand(program2) {
|
|
1421
|
-
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 (
|
|
1422
|
-
await runInit(
|
|
1639
|
+
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 (path44, options) => {
|
|
1640
|
+
await runInit(path44, options);
|
|
1423
1641
|
});
|
|
1424
1642
|
}
|
|
1425
1643
|
async function runInit(projectPath, options) {
|
|
@@ -1498,18 +1716,18 @@ async function gatherProjectInfo() {
|
|
|
1498
1716
|
language
|
|
1499
1717
|
};
|
|
1500
1718
|
}
|
|
1501
|
-
function getDefaultProjectInfo(
|
|
1502
|
-
const name =
|
|
1719
|
+
function getDefaultProjectInfo(path44) {
|
|
1720
|
+
const name = path44 === "." ? "my-project" : path44.split("/").pop() || "my-project";
|
|
1503
1721
|
return {
|
|
1504
1722
|
name,
|
|
1505
1723
|
description: "",
|
|
1506
1724
|
language: "typescript"
|
|
1507
1725
|
};
|
|
1508
1726
|
}
|
|
1509
|
-
async function checkExistingProject(
|
|
1727
|
+
async function checkExistingProject(path44) {
|
|
1510
1728
|
try {
|
|
1511
|
-
const
|
|
1512
|
-
await
|
|
1729
|
+
const fs44 = await import('fs/promises');
|
|
1730
|
+
await fs44.access(`${path44}/.coco`);
|
|
1513
1731
|
return true;
|
|
1514
1732
|
} catch {
|
|
1515
1733
|
return false;
|
|
@@ -8368,20 +8586,20 @@ async function createCliPhaseContext(projectPath, _onUserInput) {
|
|
|
8368
8586
|
},
|
|
8369
8587
|
tools: {
|
|
8370
8588
|
file: {
|
|
8371
|
-
async read(
|
|
8372
|
-
const
|
|
8373
|
-
return
|
|
8589
|
+
async read(path44) {
|
|
8590
|
+
const fs44 = await import('fs/promises');
|
|
8591
|
+
return fs44.readFile(path44, "utf-8");
|
|
8374
8592
|
},
|
|
8375
|
-
async write(
|
|
8376
|
-
const
|
|
8593
|
+
async write(path44, content) {
|
|
8594
|
+
const fs44 = await import('fs/promises');
|
|
8377
8595
|
const nodePath = await import('path');
|
|
8378
|
-
await
|
|
8379
|
-
await
|
|
8596
|
+
await fs44.mkdir(nodePath.dirname(path44), { recursive: true });
|
|
8597
|
+
await fs44.writeFile(path44, content, "utf-8");
|
|
8380
8598
|
},
|
|
8381
|
-
async exists(
|
|
8382
|
-
const
|
|
8599
|
+
async exists(path44) {
|
|
8600
|
+
const fs44 = await import('fs/promises');
|
|
8383
8601
|
try {
|
|
8384
|
-
await
|
|
8602
|
+
await fs44.access(path44);
|
|
8385
8603
|
return true;
|
|
8386
8604
|
} catch {
|
|
8387
8605
|
return false;
|
|
@@ -8620,16 +8838,16 @@ async function loadTasks(_options) {
|
|
|
8620
8838
|
];
|
|
8621
8839
|
}
|
|
8622
8840
|
async function checkProjectState() {
|
|
8623
|
-
const
|
|
8841
|
+
const fs44 = await import('fs/promises');
|
|
8624
8842
|
let hasProject = false;
|
|
8625
8843
|
let hasPlan = false;
|
|
8626
8844
|
try {
|
|
8627
|
-
await
|
|
8845
|
+
await fs44.access(".coco");
|
|
8628
8846
|
hasProject = true;
|
|
8629
8847
|
} catch {
|
|
8630
8848
|
}
|
|
8631
8849
|
try {
|
|
8632
|
-
await
|
|
8850
|
+
await fs44.access(".coco/planning/backlog.json");
|
|
8633
8851
|
hasPlan = true;
|
|
8634
8852
|
} catch {
|
|
8635
8853
|
}
|
|
@@ -8733,24 +8951,24 @@ function getPhaseStatusForPhase(phase) {
|
|
|
8733
8951
|
return "in_progress";
|
|
8734
8952
|
}
|
|
8735
8953
|
async function loadProjectState(cwd, config) {
|
|
8736
|
-
const
|
|
8737
|
-
const
|
|
8738
|
-
const statePath =
|
|
8739
|
-
const backlogPath =
|
|
8740
|
-
const checkpointDir =
|
|
8954
|
+
const fs44 = await import('fs/promises');
|
|
8955
|
+
const path44 = await import('path');
|
|
8956
|
+
const statePath = path44.join(cwd, ".coco", "state.json");
|
|
8957
|
+
const backlogPath = path44.join(cwd, ".coco", "planning", "backlog.json");
|
|
8958
|
+
const checkpointDir = path44.join(cwd, ".coco", "checkpoints");
|
|
8741
8959
|
let currentPhase = "idle";
|
|
8742
8960
|
let metrics;
|
|
8743
8961
|
let sprint;
|
|
8744
8962
|
let checkpoints = [];
|
|
8745
8963
|
try {
|
|
8746
|
-
const stateContent = await
|
|
8964
|
+
const stateContent = await fs44.readFile(statePath, "utf-8");
|
|
8747
8965
|
const stateData = JSON.parse(stateContent);
|
|
8748
8966
|
currentPhase = stateData.currentPhase || "idle";
|
|
8749
8967
|
metrics = stateData.metrics;
|
|
8750
8968
|
} catch {
|
|
8751
8969
|
}
|
|
8752
8970
|
try {
|
|
8753
|
-
const backlogContent = await
|
|
8971
|
+
const backlogContent = await fs44.readFile(backlogPath, "utf-8");
|
|
8754
8972
|
const backlogData = JSON.parse(backlogContent);
|
|
8755
8973
|
if (backlogData.currentSprint) {
|
|
8756
8974
|
const tasks = backlogData.tasks || [];
|
|
@@ -8772,7 +8990,7 @@ async function loadProjectState(cwd, config) {
|
|
|
8772
8990
|
} catch {
|
|
8773
8991
|
}
|
|
8774
8992
|
try {
|
|
8775
|
-
const files = await
|
|
8993
|
+
const files = await fs44.readdir(checkpointDir);
|
|
8776
8994
|
checkpoints = files.filter((f) => f.endsWith(".json")).sort().reverse();
|
|
8777
8995
|
} catch {
|
|
8778
8996
|
}
|
|
@@ -8908,8 +9126,8 @@ async function restoreFromCheckpoint(_checkpoint) {
|
|
|
8908
9126
|
}
|
|
8909
9127
|
async function checkProjectExists() {
|
|
8910
9128
|
try {
|
|
8911
|
-
const
|
|
8912
|
-
await
|
|
9129
|
+
const fs44 = await import('fs/promises');
|
|
9130
|
+
await fs44.access(".coco");
|
|
8913
9131
|
return true;
|
|
8914
9132
|
} catch {
|
|
8915
9133
|
return false;
|
|
@@ -9570,12 +9788,12 @@ async function loadConfig2() {
|
|
|
9570
9788
|
};
|
|
9571
9789
|
}
|
|
9572
9790
|
async function saveConfig(config) {
|
|
9573
|
-
const
|
|
9574
|
-
await
|
|
9575
|
-
await
|
|
9791
|
+
const fs44 = await import('fs/promises');
|
|
9792
|
+
await fs44.mkdir(".coco", { recursive: true });
|
|
9793
|
+
await fs44.writeFile(".coco/config.json", JSON.stringify(config, null, 2));
|
|
9576
9794
|
}
|
|
9577
|
-
function getNestedValue(obj,
|
|
9578
|
-
const keys =
|
|
9795
|
+
function getNestedValue(obj, path44) {
|
|
9796
|
+
const keys = path44.split(".");
|
|
9579
9797
|
let current = obj;
|
|
9580
9798
|
for (const key of keys) {
|
|
9581
9799
|
if (current === null || current === void 0 || typeof current !== "object") {
|
|
@@ -9585,8 +9803,8 @@ function getNestedValue(obj, path43) {
|
|
|
9585
9803
|
}
|
|
9586
9804
|
return current;
|
|
9587
9805
|
}
|
|
9588
|
-
function setNestedValue(obj,
|
|
9589
|
-
const keys =
|
|
9806
|
+
function setNestedValue(obj, path44, value) {
|
|
9807
|
+
const keys = path44.split(".");
|
|
9590
9808
|
let current = obj;
|
|
9591
9809
|
for (let i = 0; i < keys.length - 1; i++) {
|
|
9592
9810
|
const key = keys[i];
|
|
@@ -9807,8 +10025,8 @@ var MCPRegistryImpl = class {
|
|
|
9807
10025
|
/**
|
|
9808
10026
|
* Ensure directory exists
|
|
9809
10027
|
*/
|
|
9810
|
-
async ensureDir(
|
|
9811
|
-
await mkdir(dirname(
|
|
10028
|
+
async ensureDir(path44) {
|
|
10029
|
+
await mkdir(dirname(path44), { recursive: true });
|
|
9812
10030
|
}
|
|
9813
10031
|
};
|
|
9814
10032
|
function createMCPRegistry(registryPath) {
|
|
@@ -10327,9 +10545,9 @@ function createEmptyMemoryContext() {
|
|
|
10327
10545
|
errors: []
|
|
10328
10546
|
};
|
|
10329
10547
|
}
|
|
10330
|
-
function createMissingMemoryFile(
|
|
10548
|
+
function createMissingMemoryFile(path44, level) {
|
|
10331
10549
|
return {
|
|
10332
|
-
path:
|
|
10550
|
+
path: path44,
|
|
10333
10551
|
level,
|
|
10334
10552
|
content: "",
|
|
10335
10553
|
sections: [],
|
|
@@ -10506,9 +10724,45 @@ function getConversationContext(session, toolRegistry) {
|
|
|
10506
10724
|
# Project Instructions (from COCO.md/CLAUDE.md)
|
|
10507
10725
|
|
|
10508
10726
|
${session.memoryContext.combinedContent}`;
|
|
10727
|
+
}
|
|
10728
|
+
if (session.projectContext) {
|
|
10729
|
+
const stackInfo = formatStackContext(session.projectContext);
|
|
10730
|
+
systemPrompt = `${systemPrompt}
|
|
10731
|
+
|
|
10732
|
+
${stackInfo}`;
|
|
10509
10733
|
}
|
|
10510
10734
|
return [{ role: "system", content: systemPrompt }, ...session.messages];
|
|
10511
10735
|
}
|
|
10736
|
+
function formatStackContext(ctx) {
|
|
10737
|
+
const parts = [];
|
|
10738
|
+
parts.push("# Project Technology Stack");
|
|
10739
|
+
parts.push("");
|
|
10740
|
+
parts.push(`**Language/Runtime:** ${ctx.stack}`);
|
|
10741
|
+
if (ctx.packageManager) {
|
|
10742
|
+
parts.push(`**Package Manager:** ${ctx.packageManager}`);
|
|
10743
|
+
}
|
|
10744
|
+
if (ctx.frameworks.length > 0) {
|
|
10745
|
+
parts.push(`**Frameworks:** ${ctx.frameworks.join(", ")}`);
|
|
10746
|
+
}
|
|
10747
|
+
if (ctx.languages.length > 0) {
|
|
10748
|
+
parts.push(`**Languages:** ${ctx.languages.join(", ")}`);
|
|
10749
|
+
}
|
|
10750
|
+
if (ctx.testingFrameworks.length > 0) {
|
|
10751
|
+
parts.push(`**Testing Frameworks:** ${ctx.testingFrameworks.join(", ")}`);
|
|
10752
|
+
}
|
|
10753
|
+
if (ctx.buildTools.length > 0) {
|
|
10754
|
+
parts.push(`**Build Tools:** ${ctx.buildTools.join(", ")}`);
|
|
10755
|
+
}
|
|
10756
|
+
const keyDeps = Object.entries(ctx.dependencies).slice(0, 10).map(([name, version]) => `${name}@${version}`).join(", ");
|
|
10757
|
+
if (keyDeps) {
|
|
10758
|
+
parts.push(`**Key Dependencies:** ${keyDeps}`);
|
|
10759
|
+
}
|
|
10760
|
+
parts.push("");
|
|
10761
|
+
parts.push(
|
|
10762
|
+
"**IMPORTANT:** When suggesting libraries, frameworks, or dependencies, ONLY recommend technologies compatible with the stack above. Do not suggest installing Node.js packages in a Java project, or Java libraries in a Python project."
|
|
10763
|
+
);
|
|
10764
|
+
return parts.join("\n");
|
|
10765
|
+
}
|
|
10512
10766
|
function clearSession(session) {
|
|
10513
10767
|
session.messages = [];
|
|
10514
10768
|
}
|
|
@@ -13259,8 +13513,8 @@ async function listTrustedProjects2(trustStore) {
|
|
|
13259
13513
|
p9.log.message("");
|
|
13260
13514
|
for (const project of projects) {
|
|
13261
13515
|
const level = project.approvalLevel.toUpperCase().padEnd(5);
|
|
13262
|
-
const
|
|
13263
|
-
p9.log.message(` [${level}] ${
|
|
13516
|
+
const path44 = project.path.length > 50 ? "..." + project.path.slice(-47) : project.path;
|
|
13517
|
+
p9.log.message(` [${level}] ${path44}`);
|
|
13264
13518
|
p9.log.message(` Last accessed: ${new Date(project.lastAccessed).toLocaleString()}`);
|
|
13265
13519
|
}
|
|
13266
13520
|
p9.log.message("");
|
|
@@ -14430,7 +14684,7 @@ async function getCheckpoint(session, checkpointId) {
|
|
|
14430
14684
|
return store.checkpoints.find((cp) => cp.id === checkpointId) ?? null;
|
|
14431
14685
|
}
|
|
14432
14686
|
async function restoreFiles(checkpoint, excludeFiles) {
|
|
14433
|
-
const
|
|
14687
|
+
const fs44 = await import('fs/promises');
|
|
14434
14688
|
const restored = [];
|
|
14435
14689
|
const failed = [];
|
|
14436
14690
|
for (const fileCheckpoint of checkpoint.files) {
|
|
@@ -14438,7 +14692,7 @@ async function restoreFiles(checkpoint, excludeFiles) {
|
|
|
14438
14692
|
continue;
|
|
14439
14693
|
}
|
|
14440
14694
|
try {
|
|
14441
|
-
await
|
|
14695
|
+
await fs44.writeFile(fileCheckpoint.filePath, fileCheckpoint.originalContent, "utf-8");
|
|
14442
14696
|
restored.push(fileCheckpoint.filePath);
|
|
14443
14697
|
} catch (error) {
|
|
14444
14698
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
@@ -14520,8 +14774,8 @@ function displayRewindResult(result) {
|
|
|
14520
14774
|
const fileName = filePath.split("/").pop() ?? filePath;
|
|
14521
14775
|
console.log(`${chalk42.green(String.fromCodePoint(10003))} Restored: ${fileName}`);
|
|
14522
14776
|
}
|
|
14523
|
-
for (const { path:
|
|
14524
|
-
const fileName =
|
|
14777
|
+
for (const { path: path44, error } of result.filesFailed) {
|
|
14778
|
+
const fileName = path44.split("/").pop() ?? path44;
|
|
14525
14779
|
console.log(`${chalk42.red(String.fromCodePoint(10007))} Failed: ${fileName} (${error})`);
|
|
14526
14780
|
}
|
|
14527
14781
|
if (result.conversationRestored) {
|
|
@@ -15954,8 +16208,8 @@ function formatToolSummary(toolName, input) {
|
|
|
15954
16208
|
return String(input.path || ".");
|
|
15955
16209
|
case "search_files": {
|
|
15956
16210
|
const pattern = String(input.pattern || "");
|
|
15957
|
-
const
|
|
15958
|
-
return `"${pattern}"${
|
|
16211
|
+
const path44 = input.path ? ` in ${input.path}` : "";
|
|
16212
|
+
return `"${pattern}"${path44}`;
|
|
15959
16213
|
}
|
|
15960
16214
|
case "bash_exec": {
|
|
15961
16215
|
const cmd = String(input.command || "");
|
|
@@ -20989,10 +21243,10 @@ var CoverageAnalyzer = class {
|
|
|
20989
21243
|
join(this.projectPath, ".coverage", "coverage-summary.json"),
|
|
20990
21244
|
join(this.projectPath, "coverage", "lcov-report", "coverage-summary.json")
|
|
20991
21245
|
];
|
|
20992
|
-
for (const
|
|
21246
|
+
for (const path44 of possiblePaths) {
|
|
20993
21247
|
try {
|
|
20994
|
-
await access(
|
|
20995
|
-
const content = await readFile(
|
|
21248
|
+
await access(path44, constants.R_OK);
|
|
21249
|
+
const content = await readFile(path44, "utf-8");
|
|
20996
21250
|
const report = JSON.parse(content);
|
|
20997
21251
|
return parseCoverageSummary(report);
|
|
20998
21252
|
} catch {
|
|
@@ -25202,20 +25456,10 @@ var diffTools = [showDiffTool];
|
|
|
25202
25456
|
// src/tools/review.ts
|
|
25203
25457
|
init_registry();
|
|
25204
25458
|
init_errors();
|
|
25205
|
-
|
|
25206
|
-
|
|
25207
|
-
init_errors();
|
|
25208
|
-
async function fileExists(filePath) {
|
|
25209
|
-
try {
|
|
25210
|
-
await fs23__default.access(filePath);
|
|
25211
|
-
return true;
|
|
25212
|
-
} catch {
|
|
25213
|
-
return false;
|
|
25214
|
-
}
|
|
25215
|
-
}
|
|
25216
|
-
async function fileExists2(path43) {
|
|
25459
|
+
init_files();
|
|
25460
|
+
async function fileExists2(path44) {
|
|
25217
25461
|
try {
|
|
25218
|
-
await access(
|
|
25462
|
+
await access(path44);
|
|
25219
25463
|
return true;
|
|
25220
25464
|
} catch {
|
|
25221
25465
|
return false;
|
|
@@ -25305,7 +25549,7 @@ async function detectMaturity(cwd) {
|
|
|
25305
25549
|
if (!hasLintConfig && hasPackageJson) {
|
|
25306
25550
|
try {
|
|
25307
25551
|
const pkgRaw = await import('fs/promises').then(
|
|
25308
|
-
(
|
|
25552
|
+
(fs44) => fs44.readFile(join(cwd, "package.json"), "utf-8")
|
|
25309
25553
|
);
|
|
25310
25554
|
const pkg = JSON.parse(pkgRaw);
|
|
25311
25555
|
if (pkg.scripts?.lint || pkg.scripts?.["lint:fix"]) {
|
|
@@ -29964,6 +30208,13 @@ var terminalOptions = {
|
|
|
29964
30208
|
var marked = new Marked();
|
|
29965
30209
|
marked.use(markedTerminal(terminalOptions));
|
|
29966
30210
|
init_bash();
|
|
30211
|
+
init_files();
|
|
30212
|
+
|
|
30213
|
+
// src/cli/repl/skills/builtin/ship/version-detector.ts
|
|
30214
|
+
init_files();
|
|
30215
|
+
|
|
30216
|
+
// src/cli/repl/skills/builtin/ship/changelog.ts
|
|
30217
|
+
init_files();
|
|
29967
30218
|
|
|
29968
30219
|
// src/cli/repl/skills/builtin/ship/steps/test-coverage.ts
|
|
29969
30220
|
init_bash();
|
|
@@ -30038,6 +30289,8 @@ async function startRepl(options = {}) {
|
|
|
30038
30289
|
process.exit(1);
|
|
30039
30290
|
}
|
|
30040
30291
|
initializeContextManager(session, provider);
|
|
30292
|
+
const { detectProjectStack: detectProjectStack2 } = await Promise.resolve().then(() => (init_stack_detector(), stack_detector_exports));
|
|
30293
|
+
session.projectContext = await detectProjectStack2(projectPath);
|
|
30041
30294
|
await loadAllowedPaths(projectPath);
|
|
30042
30295
|
if (await shouldShowPermissionSuggestion()) {
|
|
30043
30296
|
await showPermissionSuggestion();
|