komodo-cli 2.9.0 → 2.10.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/README.md +26 -0
- package/dist/chunk-BK2YSCS2.js +6784 -0
- package/dist/{chunk-GGBZF72M.js → chunk-EU4PZLPQ.js} +1598 -4276
- package/dist/index.js +204 -6
- package/dist/mcp/index.js +5906 -0
- package/dist/{server-JOKWCY3W.js → server-G6XWHEZX.js} +2276 -10946
- package/package.json +8 -4
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
Komodo,
|
|
4
4
|
KomodoChat,
|
|
5
5
|
TEMPLATES,
|
|
6
|
+
analyzeCodebase,
|
|
6
7
|
analyzeEnvironment,
|
|
7
8
|
analyzeHealth,
|
|
8
9
|
analyzeOptimizations,
|
|
@@ -14,6 +15,7 @@ import {
|
|
|
14
15
|
diffPackages,
|
|
15
16
|
executeRepair,
|
|
16
17
|
explainPackage,
|
|
18
|
+
exportEnvironment,
|
|
17
19
|
formatDiff,
|
|
18
20
|
formatDoctorReport,
|
|
19
21
|
formatExplanation,
|
|
@@ -21,17 +23,22 @@ import {
|
|
|
21
23
|
formatOptimizationReport,
|
|
22
24
|
formatRepoAnalysis,
|
|
23
25
|
formatTemplateList,
|
|
26
|
+
generateHashSnapshot,
|
|
24
27
|
generateOptimizationScript,
|
|
28
|
+
getCodebaseSummary,
|
|
25
29
|
getInstallCommandsForTemplate,
|
|
26
30
|
getInstalledPackages,
|
|
27
31
|
getTemplateById,
|
|
32
|
+
importEnvironment,
|
|
33
|
+
loadAndVerifySnapshot,
|
|
28
34
|
loadState,
|
|
29
35
|
parseGitHubUrl,
|
|
30
36
|
resolveConflicts,
|
|
31
37
|
runDoctor,
|
|
38
|
+
saveSnapshot,
|
|
32
39
|
searchTemplates,
|
|
33
40
|
visualizeTree
|
|
34
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-EU4PZLPQ.js";
|
|
35
42
|
|
|
36
43
|
// src/index.ts
|
|
37
44
|
import { Command } from "commander";
|
|
@@ -40,6 +47,8 @@ import ora from "ora";
|
|
|
40
47
|
import boxen from "boxen";
|
|
41
48
|
import * as readline from "readline";
|
|
42
49
|
import { createRequire } from "module";
|
|
50
|
+
import os from "os";
|
|
51
|
+
import { writeFile, readFile } from "fs/promises";
|
|
43
52
|
var require2 = createRequire(import.meta.url);
|
|
44
53
|
var packageJson = require2("../package.json");
|
|
45
54
|
var CEREBRAS_API_KEY = "csk-m4vcnx94p854xmvnhxx38chwmxxwtffpnymk2ewexktk3962";
|
|
@@ -82,9 +91,9 @@ function printBanner() {
|
|
|
82
91
|
console.log(chalk.hex("#78ff78").dim(" Just say what you want to build."));
|
|
83
92
|
console.log();
|
|
84
93
|
}
|
|
85
|
-
function formatOs(
|
|
94
|
+
function formatOs(os2) {
|
|
86
95
|
const names = { darwin: "Mac", linux: "Linux", windows: "Windows" };
|
|
87
|
-
return names[
|
|
96
|
+
return names[os2] ?? os2;
|
|
88
97
|
}
|
|
89
98
|
function formatGpu(hardware) {
|
|
90
99
|
if (hardware.gpu === "apple-silicon") {
|
|
@@ -96,6 +105,8 @@ function formatGpu(hardware) {
|
|
|
96
105
|
}
|
|
97
106
|
return "CPU";
|
|
98
107
|
}
|
|
108
|
+
var cachedCodebaseSummary;
|
|
109
|
+
var codebaseAnalyzed = false;
|
|
99
110
|
async function updateChatContext(projectPath) {
|
|
100
111
|
const hardware = komodo.getHardware();
|
|
101
112
|
const state = await loadState(projectPath);
|
|
@@ -115,6 +126,15 @@ async function updateChatContext(projectPath) {
|
|
|
115
126
|
healthIssues = health.issues;
|
|
116
127
|
}
|
|
117
128
|
}
|
|
129
|
+
if (!codebaseAnalyzed) {
|
|
130
|
+
try {
|
|
131
|
+
const project = await analyzeCodebase(projectPath, { maxFiles: 300 });
|
|
132
|
+
cachedCodebaseSummary = getCodebaseSummary(project);
|
|
133
|
+
codebaseAnalyzed = true;
|
|
134
|
+
} catch {
|
|
135
|
+
codebaseAnalyzed = true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
118
138
|
const context = {
|
|
119
139
|
hardware,
|
|
120
140
|
runtime,
|
|
@@ -122,7 +142,8 @@ async function updateChatContext(projectPath) {
|
|
|
122
142
|
conflicts,
|
|
123
143
|
healthIssues,
|
|
124
144
|
projectPath,
|
|
125
|
-
environmentName
|
|
145
|
+
environmentName,
|
|
146
|
+
codebaseSummary: cachedCodebaseSummary
|
|
126
147
|
};
|
|
127
148
|
chat.setContext(context);
|
|
128
149
|
return { installedPackages, conflicts, healthIssues, runtime, environmentName };
|
|
@@ -635,7 +656,7 @@ async function handleUI(projectPath) {
|
|
|
635
656
|
console.log();
|
|
636
657
|
console.log(chalk.hex("#b4ffb4").dim(" Starting dashboard..."));
|
|
637
658
|
try {
|
|
638
|
-
const { startServer } = await import("./server-
|
|
659
|
+
const { startServer } = await import("./server-G6XWHEZX.js");
|
|
639
660
|
await startServer(projectPath, port);
|
|
640
661
|
console.log(chalk.hex("#5aff5a")(` \u2713 Dashboard ready at ${chalk.bold(url)}`));
|
|
641
662
|
console.log();
|
|
@@ -964,7 +985,7 @@ program.command("ui").description("Open the visual dashboard").option("-p, --pat
|
|
|
964
985
|
const url = `http://localhost:${port}`;
|
|
965
986
|
console.log(chalk.dim(" Starting dashboard..."));
|
|
966
987
|
try {
|
|
967
|
-
const { startServer } = await import("./server-
|
|
988
|
+
const { startServer } = await import("./server-G6XWHEZX.js");
|
|
968
989
|
await startServer(options.path, port);
|
|
969
990
|
console.log();
|
|
970
991
|
console.log(chalk.green(` \u2713 Dashboard ready at ${chalk.bold(url)}`));
|
|
@@ -1272,4 +1293,181 @@ function formatTimeAgo(date) {
|
|
|
1272
1293
|
if (seconds < 604800) return `${Math.floor(seconds / 86400)}d ago`;
|
|
1273
1294
|
return date.toLocaleDateString();
|
|
1274
1295
|
}
|
|
1296
|
+
program.command("export").description("Export environment to shareable file").option("-p, --path <path>", "Project folder", process.cwd()).option("-o, --output <file>", "Output file", ".komodo-env.json").option("--notes <notes>", "Description or notes about this environment").option("--tags <tags>", "Comma-separated tags for categorization").action(async (options) => {
|
|
1297
|
+
const spinner = ora(chalk.hex("#b4ffb4")("Exporting environment...")).start();
|
|
1298
|
+
try {
|
|
1299
|
+
const state = await loadState(options.path);
|
|
1300
|
+
if (!state.activeEnvironmentId) {
|
|
1301
|
+
spinner.fail(chalk.red("No environment to export"));
|
|
1302
|
+
console.log();
|
|
1303
|
+
console.log(chalk.dim(' Set up an environment first with: komodo "install <packages>"'));
|
|
1304
|
+
console.log();
|
|
1305
|
+
return;
|
|
1306
|
+
}
|
|
1307
|
+
const activeEnv = state.environments.find((e) => e.id === state.activeEnvironmentId);
|
|
1308
|
+
if (!activeEnv) {
|
|
1309
|
+
spinner.fail(chalk.red("Environment not found"));
|
|
1310
|
+
return;
|
|
1311
|
+
}
|
|
1312
|
+
const exported = await exportEnvironment(options.path, activeEnv.runtime, {
|
|
1313
|
+
includeDevDeps: true,
|
|
1314
|
+
cleanVersions: false
|
|
1315
|
+
});
|
|
1316
|
+
exported.exportedBy = os.userInfo().username;
|
|
1317
|
+
if (options.notes) exported.notes = options.notes;
|
|
1318
|
+
if (options.tags) exported.tags = options.tags.split(",").map((t) => t.trim());
|
|
1319
|
+
exported.komodoVersion = packageJson.version;
|
|
1320
|
+
await writeFile(options.output, JSON.stringify(exported, null, 2));
|
|
1321
|
+
spinner.succeed(chalk.hex("#5aff5a")("Environment exported!"));
|
|
1322
|
+
console.log();
|
|
1323
|
+
console.log(chalk.hex("#b4ffb4")(" File: ") + chalk.white(options.output));
|
|
1324
|
+
console.log(chalk.hex("#b4ffb4")(" Runtime: ") + chalk.white(activeEnv.runtime));
|
|
1325
|
+
console.log(chalk.hex("#b4ffb4")(" Packages: ") + chalk.white(`${exported.packages.length}`));
|
|
1326
|
+
console.log(chalk.hex("#b4ffb4")(" Hardware: ") + chalk.white(`${exported.hardware?.gpu || "CPU"}`));
|
|
1327
|
+
console.log();
|
|
1328
|
+
console.log(chalk.dim(" Share this file with teammates: komodo import .komodo-env.json"));
|
|
1329
|
+
console.log();
|
|
1330
|
+
} catch (error) {
|
|
1331
|
+
spinner.fail();
|
|
1332
|
+
console.log();
|
|
1333
|
+
console.log(chalk.red(" Export failed"));
|
|
1334
|
+
console.log(chalk.dim(` ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
1335
|
+
console.log();
|
|
1336
|
+
}
|
|
1337
|
+
});
|
|
1338
|
+
program.command("import").description("Import environment from file or URL").argument("<source>", "File path or URL to environment").option("-p, --path <path>", "Target project folder", process.cwd()).option("--force", "Skip hardware compatibility check").action(async (source, options) => {
|
|
1339
|
+
const spinner = ora(chalk.hex("#b4ffb4")("Importing environment...")).start();
|
|
1340
|
+
try {
|
|
1341
|
+
let data;
|
|
1342
|
+
if (source.startsWith("http://") || source.startsWith("https://")) {
|
|
1343
|
+
spinner.text = chalk.hex("#b4ffb4")("Fetching environment...");
|
|
1344
|
+
const response = await fetch(source);
|
|
1345
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
1346
|
+
data = await response.json();
|
|
1347
|
+
} else {
|
|
1348
|
+
const content = await readFile(source, "utf-8");
|
|
1349
|
+
data = JSON.parse(content);
|
|
1350
|
+
}
|
|
1351
|
+
if (!data.runtime || !data.packages || !Array.isArray(data.packages)) {
|
|
1352
|
+
throw new Error("Invalid environment file format");
|
|
1353
|
+
}
|
|
1354
|
+
spinner.stop();
|
|
1355
|
+
console.log();
|
|
1356
|
+
const hardware = komodo.getHardware();
|
|
1357
|
+
if (data.hardware && !options.force) {
|
|
1358
|
+
console.log(chalk.hex("#b4ffb4")(" Hardware check:"));
|
|
1359
|
+
console.log(chalk.dim(` Your machine: ${hardware.gpu || "CPU"}, ${hardware.totalMemoryGb}GB RAM`));
|
|
1360
|
+
console.log(chalk.dim(` Environment: ${data.hardware.gpu || "CPU"}, ${data.hardware.totalMemoryGb}GB RAM`));
|
|
1361
|
+
if (data.hardware.gpu !== hardware.gpu) {
|
|
1362
|
+
console.log(chalk.yellow(` \u26A0 GPU mismatch - packages will be adapted`));
|
|
1363
|
+
}
|
|
1364
|
+
if (data.hardware.totalMemoryGb > hardware.totalMemoryGb) {
|
|
1365
|
+
console.log(chalk.yellow(` \u26A0 Less memory than original - some packages may be slow`));
|
|
1366
|
+
}
|
|
1367
|
+
console.log();
|
|
1368
|
+
}
|
|
1369
|
+
console.log(chalk.hex("#a5ffa5")(" Installing:"));
|
|
1370
|
+
data.packages.slice(0, 10).forEach((pkg) => {
|
|
1371
|
+
const plus = chalk.hex("#5aff5a")("+");
|
|
1372
|
+
console.log(` ${plus} ${friendlyPackageName(pkg.name)}@${pkg.version}`);
|
|
1373
|
+
});
|
|
1374
|
+
if (data.packages.length > 10) {
|
|
1375
|
+
console.log(chalk.dim(` ...and ${data.packages.length - 10} more`));
|
|
1376
|
+
}
|
|
1377
|
+
console.log();
|
|
1378
|
+
const installSpinner = ora(chalk.hex("#b4ffb4")("Installing packages...")).start();
|
|
1379
|
+
const result = await importEnvironment(options.path, data);
|
|
1380
|
+
if (result.success) {
|
|
1381
|
+
installSpinner.succeed(chalk.hex("#5aff5a")("Environment imported!"));
|
|
1382
|
+
console.log();
|
|
1383
|
+
console.log(chalk.hex("#5aff5a")(` \u2713 ${result.installed?.length || 0} packages installed`));
|
|
1384
|
+
if (data.exportedBy) {
|
|
1385
|
+
console.log(chalk.dim(` From: ${data.exportedBy}`));
|
|
1386
|
+
}
|
|
1387
|
+
if (data.notes) {
|
|
1388
|
+
console.log(chalk.dim(` Notes: ${data.notes}`));
|
|
1389
|
+
}
|
|
1390
|
+
console.log();
|
|
1391
|
+
} else {
|
|
1392
|
+
installSpinner.fail(chalk.red("Import failed"));
|
|
1393
|
+
console.log();
|
|
1394
|
+
console.log(chalk.dim(` ${result.error || "Could not install packages"}`));
|
|
1395
|
+
console.log();
|
|
1396
|
+
}
|
|
1397
|
+
} catch (error) {
|
|
1398
|
+
spinner.fail();
|
|
1399
|
+
console.log();
|
|
1400
|
+
console.log(chalk.red(" Import failed"));
|
|
1401
|
+
console.log(chalk.dim(` ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
1402
|
+
console.log();
|
|
1403
|
+
}
|
|
1404
|
+
});
|
|
1405
|
+
program.command("verify").description("Verify environment matches reproducible snapshot").option("-p, --path <path>", "Project folder", process.cwd()).option("--create", "Create a new reproducible snapshot").action(async (options) => {
|
|
1406
|
+
const spinner = ora(chalk.hex("#b4ffb4")("Verifying environment...")).start();
|
|
1407
|
+
try {
|
|
1408
|
+
const state = await loadState(options.path);
|
|
1409
|
+
if (!state.activeEnvironmentId) {
|
|
1410
|
+
spinner.fail(chalk.red("No environment to verify"));
|
|
1411
|
+
console.log();
|
|
1412
|
+
console.log(chalk.dim(' Set up an environment first with: komodo "install <packages>"'));
|
|
1413
|
+
console.log();
|
|
1414
|
+
return;
|
|
1415
|
+
}
|
|
1416
|
+
const activeEnv = state.environments.find((e) => e.id === state.activeEnvironmentId);
|
|
1417
|
+
if (!activeEnv) {
|
|
1418
|
+
spinner.fail(chalk.red("Environment not found"));
|
|
1419
|
+
return;
|
|
1420
|
+
}
|
|
1421
|
+
if (options.create) {
|
|
1422
|
+
spinner.text = chalk.hex("#b4ffb4")("Creating reproducible snapshot...");
|
|
1423
|
+
const snapshot2 = await generateHashSnapshot(
|
|
1424
|
+
options.path,
|
|
1425
|
+
activeEnv.runtime,
|
|
1426
|
+
`Created at ${(/* @__PURE__ */ new Date()).toISOString()}`
|
|
1427
|
+
);
|
|
1428
|
+
await saveSnapshot(options.path, snapshot2);
|
|
1429
|
+
spinner.succeed(chalk.hex("#5aff5a")("Snapshot created!"));
|
|
1430
|
+
console.log();
|
|
1431
|
+
console.log(chalk.hex("#b4ffb4")(" Snapshot: .komodo-snapshot.json"));
|
|
1432
|
+
console.log(chalk.hex("#b4ffb4")(" Packages: ") + chalk.white(snapshot2.hashes.length.toString()));
|
|
1433
|
+
console.log(chalk.dim(" Use 'komodo verify' to check reproducibility"));
|
|
1434
|
+
console.log();
|
|
1435
|
+
return;
|
|
1436
|
+
}
|
|
1437
|
+
const { snapshot, verification } = await loadAndVerifySnapshot(options.path);
|
|
1438
|
+
spinner.stop();
|
|
1439
|
+
console.log();
|
|
1440
|
+
if (verification.valid) {
|
|
1441
|
+
console.log(chalk.hex("#5aff5a")(" \u2713 Environment is reproducible!"));
|
|
1442
|
+
console.log(chalk.hex("#b4ffb4")(" Packages verified: ") + chalk.white(snapshot.hashes.length.toString()));
|
|
1443
|
+
console.log(chalk.dim(` Snapshot from: ${snapshot.timestamp.split("T")[0]}`));
|
|
1444
|
+
console.log();
|
|
1445
|
+
} else {
|
|
1446
|
+
console.log(chalk.red(` \u2717 Hash mismatches (${verification.mismatches.length}):`));
|
|
1447
|
+
verification.mismatches.slice(0, 5).forEach((m) => {
|
|
1448
|
+
console.log(chalk.dim(` \u2022 ${m}`));
|
|
1449
|
+
});
|
|
1450
|
+
if (verification.mismatches.length > 5) {
|
|
1451
|
+
console.log(chalk.dim(` ...and ${verification.mismatches.length - 5} more`));
|
|
1452
|
+
}
|
|
1453
|
+
console.log();
|
|
1454
|
+
console.log(chalk.dim(" Packages may have been upgraded or changed."));
|
|
1455
|
+
console.log(chalk.dim(" Run 'komodo verify --create' to create a new snapshot."));
|
|
1456
|
+
console.log();
|
|
1457
|
+
}
|
|
1458
|
+
} catch (error) {
|
|
1459
|
+
spinner.fail();
|
|
1460
|
+
console.log();
|
|
1461
|
+
if (error instanceof Error && error.message.includes("Snapshot not found")) {
|
|
1462
|
+
console.log(chalk.yellow(" No snapshot found"));
|
|
1463
|
+
console.log();
|
|
1464
|
+
console.log(chalk.dim(" Create one with: komodo verify --create"));
|
|
1465
|
+
console.log();
|
|
1466
|
+
} else {
|
|
1467
|
+
console.log(chalk.red(" Verification failed"));
|
|
1468
|
+
console.log(chalk.dim(` ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
1469
|
+
console.log();
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
});
|
|
1275
1473
|
program.parse();
|