komodo-cli 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -9,7 +9,10 @@ import {
|
|
|
9
9
|
analyzeRepoStructure,
|
|
10
10
|
buildDependencyTree,
|
|
11
11
|
detectConflicts,
|
|
12
|
+
detectRealConflicts,
|
|
13
|
+
diagnoseEnvironment,
|
|
12
14
|
diffPackages,
|
|
15
|
+
executeRepair,
|
|
13
16
|
explainPackage,
|
|
14
17
|
formatDiff,
|
|
15
18
|
formatDoctorReport,
|
|
@@ -24,10 +27,11 @@ import {
|
|
|
24
27
|
getTemplateById,
|
|
25
28
|
loadState,
|
|
26
29
|
parseGitHubUrl,
|
|
30
|
+
resolveConflicts,
|
|
27
31
|
runDoctor,
|
|
28
32
|
searchTemplates,
|
|
29
33
|
visualizeTree
|
|
30
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-JV7H5NE4.js";
|
|
31
35
|
|
|
32
36
|
// src/index.ts
|
|
33
37
|
import { Command } from "commander";
|
|
@@ -38,10 +42,9 @@ import * as readline from "readline";
|
|
|
38
42
|
import { createRequire } from "module";
|
|
39
43
|
var require2 = createRequire(import.meta.url);
|
|
40
44
|
var packageJson = require2("../package.json");
|
|
41
|
-
var
|
|
42
|
-
var
|
|
43
|
-
var
|
|
44
|
-
var chat = new KomodoChat(API_KEY);
|
|
45
|
+
var CEREBRAS_API_KEY = "csk-m4vcnx94p854xmvnhxx38chwmxxwtffpnymk2ewexktk3962";
|
|
46
|
+
var komodo = new Komodo(CEREBRAS_API_KEY);
|
|
47
|
+
var chat = new KomodoChat(CEREBRAS_API_KEY);
|
|
45
48
|
var program = new Command();
|
|
46
49
|
program.name("komodo").description("The simple way to set up your project").version(packageJson.version);
|
|
47
50
|
var gradientColors = [
|
|
@@ -173,9 +176,9 @@ async function startInteractiveMode(projectPath) {
|
|
|
173
176
|
const hardware = komodo.getHardware();
|
|
174
177
|
console.log(chalk.hex("#b4ffb4").dim(` ${formatOs(hardware.os)} \xB7 ${formatGpu(hardware)} \xB7 ${hardware.totalMemoryGb}GB memory`));
|
|
175
178
|
console.log();
|
|
176
|
-
console.log(chalk.hex("#96ff96").dim(" Commands: ") + chalk.hex("#d2ffd2")("
|
|
177
|
-
console.log(chalk.hex("#96ff96").dim(" ") + chalk.hex("#d2ffd2")("undo") + chalk.dim(" \xB7 ") + chalk.hex("#d2ffd2")("list") + chalk.dim(" \xB7 ") + chalk.hex("#d2ffd2")("check") + chalk.dim(" \xB7 ") + chalk.hex("#d2ffd2")("
|
|
178
|
-
console.log(chalk.dim(" Or just
|
|
179
|
+
console.log(chalk.hex("#96ff96").dim(" Commands: ") + chalk.hex("#d2ffd2")("fix") + chalk.dim(" \xB7 ") + chalk.hex("#d2ffd2")("conflicts") + chalk.dim(" \xB7 ") + chalk.hex("#d2ffd2")("doctor") + chalk.dim(" \xB7 ") + chalk.hex("#d2ffd2")("optimize") + chalk.dim(" \xB7 ") + chalk.hex("#d2ffd2")("tree"));
|
|
180
|
+
console.log(chalk.hex("#96ff96").dim(" ") + chalk.hex("#d2ffd2")("undo") + chalk.dim(" \xB7 ") + chalk.hex("#d2ffd2")("list") + chalk.dim(" \xB7 ") + chalk.hex("#d2ffd2")("check") + chalk.dim(" \xB7 ") + chalk.hex("#d2ffd2")("clear") + chalk.dim(" \xB7 ") + chalk.hex("#d2ffd2")("exit"));
|
|
181
|
+
console.log(chalk.dim(" Or just type anything in natural language! The AI understands context."));
|
|
179
182
|
console.log();
|
|
180
183
|
await updateChatContext(projectPath);
|
|
181
184
|
const rl = readline.createInterface({
|
|
@@ -239,6 +242,17 @@ async function startInteractiveMode(projectPath) {
|
|
|
239
242
|
prompt();
|
|
240
243
|
return;
|
|
241
244
|
}
|
|
245
|
+
if (trimmed === "fix" || trimmed === "repair" || trimmed.includes("broken") || trimmed.includes("nothing works") || trimmed.includes("everything is broken") || trimmed.includes("help me fix")) {
|
|
246
|
+
await handleFix(projectPath);
|
|
247
|
+
await updateChatContext(projectPath);
|
|
248
|
+
prompt();
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
if (trimmed === "conflicts" || trimmed.includes("check conflicts") || trimmed.includes("find conflicts")) {
|
|
252
|
+
await handleConflicts(projectPath);
|
|
253
|
+
prompt();
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
242
256
|
if (trimmed === "list" || trimmed === "ls") {
|
|
243
257
|
await handleList(projectPath);
|
|
244
258
|
prompt();
|
|
@@ -313,19 +327,52 @@ async function startInteractiveMode(projectPath) {
|
|
|
313
327
|
}
|
|
314
328
|
if (trimmed === "ask" || trimmed.startsWith("ask ")) {
|
|
315
329
|
const question = trimmed === "ask" ? "" : trimmed.slice(4).trim();
|
|
316
|
-
if (
|
|
317
|
-
console.log();
|
|
318
|
-
console.log(chalk.hex("#b4ffb4")(" Ask me anything about your environment!"));
|
|
319
|
-
console.log(chalk.dim(" Example: ask what should I install for a REST API?"));
|
|
320
|
-
console.log();
|
|
321
|
-
} else {
|
|
330
|
+
if (question) {
|
|
322
331
|
const spinner = ora(chalk.hex("#b4ffb4")("Thinking...")).start();
|
|
323
332
|
await updateChatContext(projectPath);
|
|
324
333
|
const response = await chat.chat(question);
|
|
325
334
|
spinner.stop();
|
|
326
335
|
displayAIResponse(response);
|
|
336
|
+
} else {
|
|
337
|
+
console.log();
|
|
338
|
+
console.log(chalk.hex("#b4ffb4")(" Ask me anything about your environment and what you want to build!"));
|
|
339
|
+
console.log(chalk.dim(" Examples:"));
|
|
340
|
+
console.log(chalk.dim(" \u2022 What should I install for a REST API?"));
|
|
341
|
+
console.log(chalk.dim(" \u2022 How do I train an LLM?"));
|
|
342
|
+
console.log(chalk.dim(" \u2022 Set up a venv for LLADA 8B"));
|
|
343
|
+
console.log(chalk.dim(" \u2022 Type 'exit' to go back to main menu"));
|
|
344
|
+
console.log();
|
|
345
|
+
const chatRl = readline.createInterface({
|
|
346
|
+
input: process.stdin,
|
|
347
|
+
output: process.stdout
|
|
348
|
+
});
|
|
349
|
+
const chatPrompt = () => {
|
|
350
|
+
chatRl.question(chalk.hex("#5aff5a")(" ai> "), async (chatInput) => {
|
|
351
|
+
const chatTrimmed = chatInput.trim();
|
|
352
|
+
if (!chatTrimmed) {
|
|
353
|
+
chatPrompt();
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
if (chatTrimmed === "exit" || chatTrimmed === "quit" || chatTrimmed === "q") {
|
|
357
|
+
chatRl.close();
|
|
358
|
+
console.log();
|
|
359
|
+
prompt();
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
const spinner = ora(chalk.hex("#b4ffb4")("Thinking...")).start();
|
|
363
|
+
try {
|
|
364
|
+
const response = await chat.chat(chatTrimmed);
|
|
365
|
+
spinner.stop();
|
|
366
|
+
displayAIResponse(response);
|
|
367
|
+
} catch (error) {
|
|
368
|
+
spinner.fail();
|
|
369
|
+
console.error(chalk.red("Error: " + (error instanceof Error ? error.message : "Unknown error")));
|
|
370
|
+
}
|
|
371
|
+
chatPrompt();
|
|
372
|
+
});
|
|
373
|
+
};
|
|
374
|
+
chatPrompt();
|
|
327
375
|
}
|
|
328
|
-
prompt();
|
|
329
376
|
return;
|
|
330
377
|
}
|
|
331
378
|
if (isAIQuestion(trimmed)) {
|
|
@@ -354,7 +401,7 @@ async function handleInstall(intent, projectPath) {
|
|
|
354
401
|
path: projectPath,
|
|
355
402
|
dryRun: false,
|
|
356
403
|
useAI: true,
|
|
357
|
-
apiKey:
|
|
404
|
+
apiKey: CEREBRAS_API_KEY,
|
|
358
405
|
onProgress: (message) => {
|
|
359
406
|
const friendly = friendlyMessage(message);
|
|
360
407
|
if (spinner.isSpinning) {
|
|
@@ -502,6 +549,135 @@ async function handleCheck(projectPath) {
|
|
|
502
549
|
}
|
|
503
550
|
console.log();
|
|
504
551
|
}
|
|
552
|
+
async function handleFix(projectPath) {
|
|
553
|
+
const spinner = ora(chalk.hex("#b4ffb4")("Scanning your project...")).start();
|
|
554
|
+
const state = await loadState(projectPath);
|
|
555
|
+
let runtime;
|
|
556
|
+
if (state.activeEnvironmentId) {
|
|
557
|
+
const env = state.environments.find((e) => e.id === state.activeEnvironmentId);
|
|
558
|
+
runtime = env?.runtime;
|
|
559
|
+
}
|
|
560
|
+
const diagnosis = await diagnoseEnvironment(projectPath, runtime);
|
|
561
|
+
spinner.stop();
|
|
562
|
+
console.log();
|
|
563
|
+
if (diagnosis.status === "healthy") {
|
|
564
|
+
console.log(chalk.hex("#5aff5a")(" \u2713 Everything looks good!"));
|
|
565
|
+
console.log(chalk.dim(" No issues found with your environment."));
|
|
566
|
+
console.log();
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
console.log(chalk.hex("#ffb347")(` Found ${diagnosis.problems.length} issue${diagnosis.problems.length > 1 ? "s" : ""}:`));
|
|
570
|
+
console.log();
|
|
571
|
+
diagnosis.problems.slice(0, 3).forEach((problem) => {
|
|
572
|
+
const icon = problem.severity === "critical" ? chalk.red("\u2717") : problem.severity === "warning" ? chalk.yellow("\u26A0") : chalk.blue("\u2139");
|
|
573
|
+
console.log(` ${icon} ${problem.friendlyTitle}`);
|
|
574
|
+
console.log(chalk.dim(` ${problem.description}`));
|
|
575
|
+
});
|
|
576
|
+
if (diagnosis.problems.length > 3) {
|
|
577
|
+
console.log(chalk.dim(` ...and ${diagnosis.problems.length - 3} more`));
|
|
578
|
+
}
|
|
579
|
+
console.log();
|
|
580
|
+
if (diagnosis.repairPlan.length === 0) {
|
|
581
|
+
console.log(chalk.dim(" No automatic fixes available. Try creating a new environment."));
|
|
582
|
+
console.log();
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
console.log(chalk.hex("#b4ffb4")(` Fixing ${diagnosis.repairPlan.length} issue${diagnosis.repairPlan.length > 1 ? "s" : ""}...`));
|
|
586
|
+
console.log();
|
|
587
|
+
const repairSpinner = ora().start();
|
|
588
|
+
const result = await executeRepair(projectPath, diagnosis, {
|
|
589
|
+
autoBackup: true,
|
|
590
|
+
dryRun: false,
|
|
591
|
+
onProgress: (step, status) => {
|
|
592
|
+
if (status === "starting") {
|
|
593
|
+
repairSpinner.text = chalk.hex("#b4ffb4")(step.friendlyDescription);
|
|
594
|
+
} else if (status === "complete") {
|
|
595
|
+
repairSpinner.succeed(chalk.hex("#5aff5a")(step.friendlyDescription));
|
|
596
|
+
repairSpinner.start();
|
|
597
|
+
} else if (status === "failed") {
|
|
598
|
+
repairSpinner.fail(chalk.red(step.friendlyDescription));
|
|
599
|
+
repairSpinner.start();
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
if (repairSpinner.isSpinning) {
|
|
604
|
+
repairSpinner.stop();
|
|
605
|
+
}
|
|
606
|
+
console.log();
|
|
607
|
+
if (result.success) {
|
|
608
|
+
console.log(chalk.hex("#5aff5a")(` \u2713 All fixed! Resolved ${result.problemsFixed.length} issue${result.problemsFixed.length > 1 ? "s" : ""}.`));
|
|
609
|
+
} else {
|
|
610
|
+
console.log(chalk.yellow(` \u26A0 Partially fixed. Resolved ${result.stepsCompleted}/${result.stepsTotal} issues.`));
|
|
611
|
+
}
|
|
612
|
+
console.log();
|
|
613
|
+
}
|
|
614
|
+
async function handleConflicts(projectPath) {
|
|
615
|
+
const spinner = ora(chalk.hex("#b4ffb4")("Checking for conflicts...")).start();
|
|
616
|
+
const state = await loadState(projectPath);
|
|
617
|
+
let runtime;
|
|
618
|
+
if (state.activeEnvironmentId) {
|
|
619
|
+
const env = state.environments.find((e) => e.id === state.activeEnvironmentId);
|
|
620
|
+
runtime = env?.runtime;
|
|
621
|
+
}
|
|
622
|
+
if (!runtime) {
|
|
623
|
+
spinner.fail("No environment found");
|
|
624
|
+
console.log();
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
const conflicts = await detectRealConflicts(projectPath, runtime);
|
|
628
|
+
spinner.stop();
|
|
629
|
+
console.log();
|
|
630
|
+
if (conflicts.length === 0) {
|
|
631
|
+
console.log(chalk.hex("#5aff5a")(" \u2713 No conflicts found!"));
|
|
632
|
+
console.log(chalk.dim(" All packages are compatible."));
|
|
633
|
+
console.log();
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
console.log(chalk.yellow(` Found ${conflicts.length} conflict${conflicts.length > 1 ? "s" : ""}:`));
|
|
637
|
+
console.log();
|
|
638
|
+
conflicts.slice(0, 3).forEach((conflict) => {
|
|
639
|
+
const icon = conflict.severity === "error" ? chalk.red("\u2717") : chalk.yellow("\u26A0");
|
|
640
|
+
console.log(` ${icon} ${conflict.package1} \u2194 ${conflict.package2}`);
|
|
641
|
+
console.log(chalk.dim(` ${conflict.reason}`));
|
|
642
|
+
if (conflict.suggestion) {
|
|
643
|
+
console.log(chalk.hex("#87cefa")(` \u{1F4A1} ${conflict.suggestion}`));
|
|
644
|
+
}
|
|
645
|
+
});
|
|
646
|
+
if (conflicts.length > 3) {
|
|
647
|
+
console.log(chalk.dim(` ...and ${conflicts.length - 3} more`));
|
|
648
|
+
}
|
|
649
|
+
console.log();
|
|
650
|
+
console.log(chalk.hex("#b4ffb4")(" Attempting to resolve..."));
|
|
651
|
+
console.log();
|
|
652
|
+
const resolveSpinner = ora().start();
|
|
653
|
+
const result = await resolveConflicts(
|
|
654
|
+
projectPath,
|
|
655
|
+
runtime,
|
|
656
|
+
conflicts,
|
|
657
|
+
(message) => {
|
|
658
|
+
resolveSpinner.text = chalk.hex("#b4ffb4")(message);
|
|
659
|
+
}
|
|
660
|
+
);
|
|
661
|
+
if (resolveSpinner.isSpinning) {
|
|
662
|
+
resolveSpinner.stop();
|
|
663
|
+
}
|
|
664
|
+
console.log();
|
|
665
|
+
if (result.success) {
|
|
666
|
+
console.log(chalk.hex("#5aff5a")(" \u2713 All conflicts resolved!"));
|
|
667
|
+
result.resolved.forEach((r) => console.log(chalk.dim(` \u2022 ${r}`)));
|
|
668
|
+
} else {
|
|
669
|
+
if (result.resolved.length > 0) {
|
|
670
|
+
console.log(chalk.hex("#5aff5a")(" Resolved:"));
|
|
671
|
+
result.resolved.forEach((r) => console.log(chalk.dim(` \u2022 ${r}`)));
|
|
672
|
+
console.log();
|
|
673
|
+
}
|
|
674
|
+
console.log(chalk.yellow(" Cannot auto-resolve:"));
|
|
675
|
+
result.remaining.slice(0, 3).forEach(
|
|
676
|
+
(c) => console.log(chalk.dim(` \u2022 ${c.package1} \u2194 ${c.package2}`))
|
|
677
|
+
);
|
|
678
|
+
}
|
|
679
|
+
console.log();
|
|
680
|
+
}
|
|
505
681
|
async function handleHistory(projectPath) {
|
|
506
682
|
const snapshots = await komodo.listSnapshots(projectPath);
|
|
507
683
|
console.log();
|
|
@@ -725,7 +901,7 @@ async function handleUI(projectPath) {
|
|
|
725
901
|
console.log();
|
|
726
902
|
console.log(chalk.hex("#b4ffb4").dim(" Starting dashboard..."));
|
|
727
903
|
try {
|
|
728
|
-
const { startServer } = await import("./server-
|
|
904
|
+
const { startServer } = await import("./server-GJZAY4WK.js");
|
|
729
905
|
await startServer(projectPath, port);
|
|
730
906
|
console.log(chalk.hex("#5aff5a")(` \u2713 Dashboard ready at ${chalk.bold(url)}`));
|
|
731
907
|
console.log();
|
|
@@ -864,6 +1040,188 @@ program.command("undo").description("Undo your last change").option("-p, --path
|
|
|
864
1040
|
process.exit(1);
|
|
865
1041
|
}
|
|
866
1042
|
});
|
|
1043
|
+
program.command("fix").alias("repair").description("Fix a broken environment").option("-p, --path <path>", "Project folder", process.cwd()).option("--dry-run", "Show what would be fixed without making changes").action(async (options) => {
|
|
1044
|
+
console.log();
|
|
1045
|
+
console.log(chalk.bold("\u{1F98E} Komodo Fix"));
|
|
1046
|
+
console.log();
|
|
1047
|
+
const spinner = ora("Scanning your project...").start();
|
|
1048
|
+
const state = await loadState(options.path);
|
|
1049
|
+
let runtime;
|
|
1050
|
+
if (state.activeEnvironmentId) {
|
|
1051
|
+
const env = state.environments.find((e) => e.id === state.activeEnvironmentId);
|
|
1052
|
+
runtime = env?.runtime;
|
|
1053
|
+
}
|
|
1054
|
+
const diagnosis = await diagnoseEnvironment(options.path, runtime);
|
|
1055
|
+
spinner.stop();
|
|
1056
|
+
if (diagnosis.status === "healthy") {
|
|
1057
|
+
console.log(chalk.green(" \u2713 Everything looks good!"));
|
|
1058
|
+
console.log();
|
|
1059
|
+
console.log(chalk.dim(" No issues found with your environment."));
|
|
1060
|
+
console.log();
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
console.log(chalk.bold(` Found ${diagnosis.problems.length} issue${diagnosis.problems.length > 1 ? "s" : ""}:`));
|
|
1064
|
+
console.log();
|
|
1065
|
+
diagnosis.problems.forEach((problem) => {
|
|
1066
|
+
const icon = problem.severity === "critical" ? "\u2717" : problem.severity === "warning" ? "\u26A0" : "\u2139";
|
|
1067
|
+
const color = problem.severity === "critical" ? chalk.red : problem.severity === "warning" ? chalk.yellow : chalk.blue;
|
|
1068
|
+
console.log(color(` ${icon} ${problem.friendlyTitle}`));
|
|
1069
|
+
console.log(chalk.dim(` ${problem.description}`));
|
|
1070
|
+
console.log();
|
|
1071
|
+
});
|
|
1072
|
+
if (diagnosis.repairPlan.length === 0) {
|
|
1073
|
+
console.log(chalk.yellow(" No automatic fixes available."));
|
|
1074
|
+
console.log();
|
|
1075
|
+
console.log(chalk.dim(" Try:"));
|
|
1076
|
+
console.log(chalk.dim(" \u2022 Check the technical details above"));
|
|
1077
|
+
console.log(chalk.dim(" \u2022 Create a new environment: komodo <your-intent>"));
|
|
1078
|
+
console.log();
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
if (options.dryRun) {
|
|
1082
|
+
console.log(chalk.cyan(" Would fix:"));
|
|
1083
|
+
console.log();
|
|
1084
|
+
diagnosis.repairPlan.forEach((step, i) => {
|
|
1085
|
+
console.log(chalk.dim(` ${i + 1}. ${step.friendlyDescription}`));
|
|
1086
|
+
});
|
|
1087
|
+
console.log();
|
|
1088
|
+
console.log(chalk.dim(` Estimated time: ${diagnosis.estimatedTime}`));
|
|
1089
|
+
console.log();
|
|
1090
|
+
console.log(chalk.cyan(" Run without --dry-run to apply these fixes."));
|
|
1091
|
+
console.log();
|
|
1092
|
+
return;
|
|
1093
|
+
}
|
|
1094
|
+
console.log(chalk.bold(` Fix all ${diagnosis.problems.length} issue${diagnosis.problems.length > 1 ? "s" : ""}?`));
|
|
1095
|
+
console.log(chalk.dim(` Estimated time: ${diagnosis.estimatedTime}`));
|
|
1096
|
+
console.log();
|
|
1097
|
+
const rl = readline.createInterface({
|
|
1098
|
+
input: process.stdin,
|
|
1099
|
+
output: process.stdout
|
|
1100
|
+
});
|
|
1101
|
+
const answer = await new Promise((resolve) => {
|
|
1102
|
+
rl.question(chalk.dim(" Continue? (Y/n) "), resolve);
|
|
1103
|
+
});
|
|
1104
|
+
rl.close();
|
|
1105
|
+
if (answer.toLowerCase() === "n" || answer.toLowerCase() === "no") {
|
|
1106
|
+
console.log();
|
|
1107
|
+
console.log(chalk.dim(" Cancelled."));
|
|
1108
|
+
console.log();
|
|
1109
|
+
return;
|
|
1110
|
+
}
|
|
1111
|
+
console.log();
|
|
1112
|
+
const repairSpinner = ora().start();
|
|
1113
|
+
const result = await executeRepair(options.path, diagnosis, {
|
|
1114
|
+
autoBackup: true,
|
|
1115
|
+
dryRun: false,
|
|
1116
|
+
onProgress: (step, status) => {
|
|
1117
|
+
if (status === "starting") {
|
|
1118
|
+
repairSpinner.text = step.friendlyDescription;
|
|
1119
|
+
} else if (status === "complete") {
|
|
1120
|
+
repairSpinner.succeed(step.friendlyDescription);
|
|
1121
|
+
repairSpinner.start();
|
|
1122
|
+
} else if (status === "failed") {
|
|
1123
|
+
repairSpinner.fail(step.friendlyDescription);
|
|
1124
|
+
repairSpinner.start();
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
});
|
|
1128
|
+
if (repairSpinner.isSpinning) {
|
|
1129
|
+
repairSpinner.stop();
|
|
1130
|
+
}
|
|
1131
|
+
console.log();
|
|
1132
|
+
if (result.success) {
|
|
1133
|
+
console.log(
|
|
1134
|
+
boxen(
|
|
1135
|
+
chalk.green("All fixed!") + "\n\n" + chalk.dim(`Fixed ${result.problemsFixed.length} issue${result.problemsFixed.length > 1 ? "s" : ""}.`) + "\n\n" + chalk.dim("Changed your mind? Run: ") + chalk.white("komodo undo"),
|
|
1136
|
+
{ padding: 1, borderStyle: "round", borderColor: "green" }
|
|
1137
|
+
)
|
|
1138
|
+
);
|
|
1139
|
+
} else {
|
|
1140
|
+
console.log(
|
|
1141
|
+
boxen(
|
|
1142
|
+
chalk.yellow("Partially fixed") + "\n\n" + chalk.dim(`Fixed ${result.stepsCompleted}/${result.stepsTotal} issues.`) + (result.problemsRemaining.length > 0 ? "\n\n" + chalk.dim("Remaining issues:") + "\n" + result.problemsRemaining.map((p) => chalk.dim(` \u2022 ${p}`)).join("\n") : ""),
|
|
1143
|
+
{ padding: 1, borderStyle: "round", borderColor: "yellow" }
|
|
1144
|
+
)
|
|
1145
|
+
);
|
|
1146
|
+
}
|
|
1147
|
+
console.log();
|
|
1148
|
+
});
|
|
1149
|
+
program.command("conflicts").description("Find and fix package conflicts").option("-p, --path <path>", "Project folder", process.cwd()).option("--fix", "Automatically fix conflicts").action(async (options) => {
|
|
1150
|
+
console.log();
|
|
1151
|
+
console.log(chalk.bold("\u{1F98E} Conflict Check"));
|
|
1152
|
+
console.log();
|
|
1153
|
+
const spinner = ora("Checking for conflicts...").start();
|
|
1154
|
+
const state = await loadState(options.path);
|
|
1155
|
+
let runtime;
|
|
1156
|
+
if (state.activeEnvironmentId) {
|
|
1157
|
+
const env = state.environments.find((e) => e.id === state.activeEnvironmentId);
|
|
1158
|
+
runtime = env?.runtime;
|
|
1159
|
+
}
|
|
1160
|
+
if (!runtime) {
|
|
1161
|
+
spinner.fail("No environment found");
|
|
1162
|
+
console.log();
|
|
1163
|
+
console.log(chalk.dim(" No active environment detected."));
|
|
1164
|
+
console.log();
|
|
1165
|
+
return;
|
|
1166
|
+
}
|
|
1167
|
+
const conflicts = await detectRealConflicts(options.path, runtime);
|
|
1168
|
+
spinner.stop();
|
|
1169
|
+
if (conflicts.length === 0) {
|
|
1170
|
+
console.log(chalk.green(" \u2713 No conflicts found!"));
|
|
1171
|
+
console.log();
|
|
1172
|
+
console.log(chalk.dim(" All packages are compatible."));
|
|
1173
|
+
console.log();
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
console.log(chalk.bold(` Found ${conflicts.length} conflict${conflicts.length > 1 ? "s" : ""}:`));
|
|
1177
|
+
console.log();
|
|
1178
|
+
conflicts.forEach((conflict) => {
|
|
1179
|
+
const icon = conflict.severity === "error" ? "\u2717" : "\u26A0";
|
|
1180
|
+
const color = conflict.severity === "error" ? chalk.red : chalk.yellow;
|
|
1181
|
+
console.log(color(` ${icon} ${conflict.package1} \u2194 ${conflict.package2}`));
|
|
1182
|
+
console.log(chalk.dim(` ${conflict.reason}`));
|
|
1183
|
+
if (conflict.suggestion) {
|
|
1184
|
+
console.log(chalk.dim(` \u{1F4A1} ${conflict.suggestion}`));
|
|
1185
|
+
}
|
|
1186
|
+
console.log();
|
|
1187
|
+
});
|
|
1188
|
+
if (!options.fix) {
|
|
1189
|
+
console.log(chalk.dim(" Run with --fix to automatically resolve conflicts."));
|
|
1190
|
+
console.log();
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1193
|
+
console.log(chalk.bold(" Attempting to resolve..."));
|
|
1194
|
+
console.log();
|
|
1195
|
+
const resolveSpinner = ora().start();
|
|
1196
|
+
const result = await resolveConflicts(
|
|
1197
|
+
options.path,
|
|
1198
|
+
runtime,
|
|
1199
|
+
conflicts,
|
|
1200
|
+
(message) => {
|
|
1201
|
+
resolveSpinner.text = message;
|
|
1202
|
+
}
|
|
1203
|
+
);
|
|
1204
|
+
if (resolveSpinner.isSpinning) {
|
|
1205
|
+
resolveSpinner.stop();
|
|
1206
|
+
}
|
|
1207
|
+
console.log();
|
|
1208
|
+
if (result.success) {
|
|
1209
|
+
console.log(
|
|
1210
|
+
boxen(
|
|
1211
|
+
chalk.green("All conflicts resolved!") + "\n\n" + result.resolved.map((r) => chalk.dim(` \u2713 ${r}`)).join("\n"),
|
|
1212
|
+
{ padding: 1, borderStyle: "round", borderColor: "green" }
|
|
1213
|
+
)
|
|
1214
|
+
);
|
|
1215
|
+
} else {
|
|
1216
|
+
console.log(
|
|
1217
|
+
boxen(
|
|
1218
|
+
chalk.yellow("Some conflicts resolved") + "\n\n" + (result.resolved.length > 0 ? chalk.dim("Resolved:") + "\n" + result.resolved.map((r) => chalk.dim(` \u2713 ${r}`)).join("\n") + "\n\n" : "") + chalk.dim("Cannot auto-resolve:") + "\n" + result.remaining.map((c) => chalk.dim(` \u2022 ${c.package1} \u2194 ${c.package2}`)).join("\n") + "\n\n" + chalk.dim("These require manual intervention or separate environments."),
|
|
1219
|
+
{ padding: 1, borderStyle: "round", borderColor: "yellow" }
|
|
1220
|
+
)
|
|
1221
|
+
);
|
|
1222
|
+
}
|
|
1223
|
+
console.log();
|
|
1224
|
+
});
|
|
867
1225
|
program.command("ui").description("Open the visual dashboard").option("-p, --path <path>", "Project folder", process.cwd()).option("--port <port>", "Port number", "3333").action(async (options) => {
|
|
868
1226
|
console.log();
|
|
869
1227
|
console.log(chalk.bold("\u{1F98E} Komodo"));
|
|
@@ -872,7 +1230,7 @@ program.command("ui").description("Open the visual dashboard").option("-p, --pat
|
|
|
872
1230
|
const url = `http://localhost:${port}`;
|
|
873
1231
|
console.log(chalk.dim(" Starting dashboard..."));
|
|
874
1232
|
try {
|
|
875
|
-
const { startServer } = await import("./server-
|
|
1233
|
+
const { startServer } = await import("./server-GJZAY4WK.js");
|
|
876
1234
|
await startServer(options.path, port);
|
|
877
1235
|
console.log();
|
|
878
1236
|
console.log(chalk.green(` \u2713 Dashboard ready at ${chalk.bold(url)}`));
|
package/package.json
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "komodo-cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "The simple way to set up your project. Just say what you want to build.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"komodo": "./dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"main": "./dist/index.js",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsup && chmod +x dist/index.js",
|
|
12
|
+
"dev": "tsup src/index.ts --format esm --watch",
|
|
13
|
+
"typecheck": "tsc --noEmit",
|
|
14
|
+
"clean": "rm -rf dist",
|
|
15
|
+
"prepublishOnly": "pnpm build"
|
|
16
|
+
},
|
|
10
17
|
"files": [
|
|
11
18
|
"dist"
|
|
12
19
|
],
|
|
@@ -35,13 +42,7 @@
|
|
|
35
42
|
"cross-spawn": "^7.0.6"
|
|
36
43
|
},
|
|
37
44
|
"devDependencies": {
|
|
38
|
-
"@komodo/core": "
|
|
39
|
-
"@komodo/ui": "
|
|
40
|
-
},
|
|
41
|
-
"scripts": {
|
|
42
|
-
"build": "tsup && chmod +x dist/index.js",
|
|
43
|
-
"dev": "tsup src/index.ts --format esm --watch",
|
|
44
|
-
"typecheck": "tsc --noEmit",
|
|
45
|
-
"clean": "rm -rf dist"
|
|
45
|
+
"@komodo/core": "workspace:*",
|
|
46
|
+
"@komodo/ui": "workspace:*"
|
|
46
47
|
}
|
|
47
|
-
}
|
|
48
|
+
}
|