komodo-cli 2.3.0 → 2.6.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.
|
@@ -4955,9 +4955,9 @@ async function getLatestSnapshot(basePath, environmentId) {
|
|
|
4955
4955
|
);
|
|
4956
4956
|
return snapshots[0];
|
|
4957
4957
|
}
|
|
4958
|
-
var DEFAULT_MODEL = "
|
|
4959
|
-
var DEFAULT_MAX_TOKENS =
|
|
4960
|
-
var DEFAULT_TEMPERATURE = 0.
|
|
4958
|
+
var DEFAULT_MODEL = "zai-glm-4.7";
|
|
4959
|
+
var DEFAULT_MAX_TOKENS = 4096;
|
|
4960
|
+
var DEFAULT_TEMPERATURE = 0.7;
|
|
4961
4961
|
var CerebrasAI = class {
|
|
4962
4962
|
apiKey;
|
|
4963
4963
|
model;
|
|
@@ -5163,7 +5163,7 @@ var KomodoChat = class {
|
|
|
5163
5163
|
baseUrl = "https://api.cerebras.ai/v1";
|
|
5164
5164
|
conversationHistory = [];
|
|
5165
5165
|
context = null;
|
|
5166
|
-
constructor(apiKey, model = "
|
|
5166
|
+
constructor(apiKey, model = "zai-glm-4.7") {
|
|
5167
5167
|
this.apiKey = apiKey;
|
|
5168
5168
|
this.model = model;
|
|
5169
5169
|
}
|
|
@@ -5172,7 +5172,6 @@ var KomodoChat = class {
|
|
|
5172
5172
|
*/
|
|
5173
5173
|
setContext(context) {
|
|
5174
5174
|
this.context = context;
|
|
5175
|
-
this.conversationHistory = [];
|
|
5176
5175
|
}
|
|
5177
5176
|
/**
|
|
5178
5177
|
* Clear conversation history
|
|
@@ -5240,7 +5239,9 @@ var KomodoChat = class {
|
|
|
5240
5239
|
const installedList = ctx.installedPackages.length > 0 ? ctx.installedPackages.map((p) => ` - ${p.name}@${p.version}`).join("\n") : " (none)";
|
|
5241
5240
|
const conflictsList = ctx.conflicts.length > 0 ? ctx.conflicts.map((c) => ` - ${c.package1} vs ${c.package2}: ${c.reason}`).join("\n") : " (none)";
|
|
5242
5241
|
const issuesList = ctx.healthIssues.length > 0 ? ctx.healthIssues.map((i) => ` - [${i.severity}] ${i.title}: ${i.description}`).join("\n") : " (none)";
|
|
5243
|
-
return `You are Komodo
|
|
5242
|
+
return `You are Komodo, an AI assistant that manages Python and Node.js environments. You live inside a CLI tool. When users ask you to do something, you DO it -- you don't just explain how.
|
|
5243
|
+
|
|
5244
|
+
You are conversational, friendly, and concise. Think of yourself like a knowledgeable friend who just gets things done. Keep responses short and to the point. No lectures.
|
|
5244
5245
|
|
|
5245
5246
|
CURRENT ENVIRONMENT:
|
|
5246
5247
|
- Project: ${ctx.environmentName || "Unknown"}
|
|
@@ -5257,17 +5258,17 @@ ${conflictsList}
|
|
|
5257
5258
|
HEALTH ISSUES (${ctx.healthIssues.length}):
|
|
5258
5259
|
${issuesList}
|
|
5259
5260
|
|
|
5260
|
-
|
|
5261
|
-
1.
|
|
5262
|
-
2.
|
|
5263
|
-
3.
|
|
5264
|
-
4.
|
|
5265
|
-
5.
|
|
5261
|
+
RULES:
|
|
5262
|
+
1. When the user asks to install, set up, or build something -- DO IT. Include the actions JSON so the system auto-executes. Don't say "you can run pip install X" -- just include it in the actions and say "On it, installing X for you."
|
|
5263
|
+
2. Be concise. 2-4 sentences max for most responses. No walls of text.
|
|
5264
|
+
3. NEVER use markdown. No **bold**, no backticks, no code blocks, no # headers, no bullet points with *. Just plain text with simple dashes if you need lists.
|
|
5265
|
+
4. When you set things up, briefly explain what you're installing and why, then include the actions.
|
|
5266
|
+
5. If something needs a venv, create it. If packages conflict, fix them. Just handle it.
|
|
5267
|
+
6. Remember the conversation -- the user might ask follow-up questions.
|
|
5266
5268
|
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
+
ACTION FORMAT:
|
|
5270
|
+
When you need to install, remove, or update packages, append this JSON at the very end of your response (after your message):
|
|
5269
5271
|
|
|
5270
|
-
If you recommend installing, removing, or updating packages, include a JSON block at the end of your response in this format:
|
|
5271
5272
|
\`\`\`json
|
|
5272
5273
|
{
|
|
5273
5274
|
"actions": [
|
|
@@ -5278,7 +5279,7 @@ If you recommend installing, removing, or updating packages, include a JSON bloc
|
|
|
5278
5279
|
}
|
|
5279
5280
|
\`\`\`
|
|
5280
5281
|
|
|
5281
|
-
Only include the JSON block
|
|
5282
|
+
Only include actions when there are actual packages to change. Your conversational text comes first, then the JSON block at the end.`;
|
|
5282
5283
|
}
|
|
5283
5284
|
async callAPI(messages) {
|
|
5284
5285
|
const response = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
@@ -5290,13 +5291,14 @@ Only include the JSON block if you're recommending specific package changes.`;
|
|
|
5290
5291
|
body: JSON.stringify({
|
|
5291
5292
|
model: this.model,
|
|
5292
5293
|
messages,
|
|
5293
|
-
max_tokens:
|
|
5294
|
-
temperature: 0.
|
|
5294
|
+
max_tokens: 4096,
|
|
5295
|
+
temperature: 0.7,
|
|
5295
5296
|
top_p: 1
|
|
5296
5297
|
})
|
|
5297
5298
|
});
|
|
5298
5299
|
if (!response.ok) {
|
|
5299
|
-
|
|
5300
|
+
const error = await response.text();
|
|
5301
|
+
throw new Error(`API error: ${response.status} - ${error}`);
|
|
5300
5302
|
}
|
|
5301
5303
|
const data = await response.json();
|
|
5302
5304
|
return data.choices[0]?.message?.content ?? "";
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
runDoctor,
|
|
32
32
|
searchTemplates,
|
|
33
33
|
visualizeTree
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-7BIJZKAM.js";
|
|
35
35
|
|
|
36
36
|
// src/index.ts
|
|
37
37
|
import { Command } from "commander";
|
|
@@ -42,10 +42,9 @@ import * as readline from "readline";
|
|
|
42
42
|
import { createRequire } from "module";
|
|
43
43
|
var require2 = createRequire(import.meta.url);
|
|
44
44
|
var packageJson = require2("../package.json");
|
|
45
|
-
var
|
|
46
|
-
var
|
|
47
|
-
var
|
|
48
|
-
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);
|
|
49
48
|
var program = new Command();
|
|
50
49
|
program.name("komodo").description("The simple way to set up your project").version(packageJson.version);
|
|
51
50
|
var gradientColors = [
|
|
@@ -128,58 +127,17 @@ async function updateChatContext(projectPath) {
|
|
|
128
127
|
chat.setContext(context);
|
|
129
128
|
return { installedPackages, conflicts, healthIssues, runtime, environmentName };
|
|
130
129
|
}
|
|
131
|
-
function
|
|
132
|
-
|
|
133
|
-
if (input.endsWith("?")) return true;
|
|
134
|
-
const questionWords = ["what", "why", "how", "when", "where", "which", "who", "can", "could", "should", "would", "is", "are", "do", "does", "tell me", "explain", "show me", "help me"];
|
|
135
|
-
if (questionWords.some((w) => lowerInput.startsWith(w))) return true;
|
|
136
|
-
const envKeywords = ["installed", "packages", "conflicts", "issues", "problems", "wrong", "fix", "update", "upgrade", "remove", "alternatives", "suggest", "recommend", "analyze", "status"];
|
|
137
|
-
if (envKeywords.some((k) => lowerInput.includes(k))) return true;
|
|
138
|
-
return false;
|
|
139
|
-
}
|
|
140
|
-
function displayAIResponse(response) {
|
|
141
|
-
console.log();
|
|
142
|
-
console.log(chalk.hex("#b4ffb4")(response.message));
|
|
143
|
-
if (response.suggestions && response.suggestions.length > 0) {
|
|
144
|
-
console.log();
|
|
145
|
-
console.log(chalk.hex("#87cefa")(" Suggestions:"));
|
|
146
|
-
response.suggestions.forEach((s) => {
|
|
147
|
-
console.log(chalk.hex("#87cefa")(` \u2022 ${s}`));
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
if (response.packages) {
|
|
151
|
-
if (response.packages.toInstall && response.packages.toInstall.length > 0) {
|
|
152
|
-
console.log();
|
|
153
|
-
console.log(chalk.hex("#5aff5a")(" Packages to install:"));
|
|
154
|
-
response.packages.toInstall.forEach((p) => {
|
|
155
|
-
console.log(chalk.hex("#5aff5a")(` + ${p}`));
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
if (response.packages.toRemove && response.packages.toRemove.length > 0) {
|
|
159
|
-
console.log();
|
|
160
|
-
console.log(chalk.yellow(" Packages to remove:"));
|
|
161
|
-
response.packages.toRemove.forEach((p) => {
|
|
162
|
-
console.log(chalk.yellow(` - ${p}`));
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
if (response.packages.toUpdate && response.packages.toUpdate.length > 0) {
|
|
166
|
-
console.log();
|
|
167
|
-
console.log(chalk.hex("#87cefa")(" Packages to update:"));
|
|
168
|
-
response.packages.toUpdate.forEach((p) => {
|
|
169
|
-
console.log(chalk.hex("#87cefa")(` \u2191 ${p.name}: ${p.from} \u2192 ${p.to}`));
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
console.log();
|
|
130
|
+
function stripMarkdown(text) {
|
|
131
|
+
return text.replace(/```[\s\S]*?```/g, "").replace(/`([^`]+)`/g, "$1").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/\*([^*]+)\*/g, "$1").replace(/__([^_]+)__/g, "$1").replace(/_([^_]+)_/g, "$1").replace(/^#{1,6}\s+/gm, "").replace(/^\s*[-*+]\s+/gm, " - ").replace(/^\s*\d+\.\s+/gm, (m) => m).replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/\n{3,}/g, "\n\n").trim();
|
|
174
132
|
}
|
|
175
133
|
async function startInteractiveMode(projectPath) {
|
|
176
134
|
printBanner();
|
|
177
135
|
const hardware = komodo.getHardware();
|
|
178
136
|
console.log(chalk.hex("#b4ffb4").dim(` ${formatOs(hardware.os)} \xB7 ${formatGpu(hardware)} \xB7 ${hardware.totalMemoryGb}GB memory`));
|
|
179
137
|
console.log();
|
|
180
|
-
console.log(chalk.
|
|
181
|
-
console.log(chalk.
|
|
182
|
-
console.log(chalk.dim("
|
|
138
|
+
console.log(chalk.dim(" Type anything naturally. Komodo understands what you need."));
|
|
139
|
+
console.log(chalk.dim(` Try: "set up a venv for pytorch" or "what's installed?"`));
|
|
140
|
+
console.log(chalk.dim(" Type ") + chalk.hex("#d2ffd2")("help") + chalk.dim(" for commands, ") + chalk.hex("#d2ffd2")("exit") + chalk.dim(" to quit."));
|
|
183
141
|
console.log();
|
|
184
142
|
await updateChatContext(projectPath);
|
|
185
143
|
const rl = readline.createInterface({
|
|
@@ -195,7 +153,7 @@ async function startInteractiveMode(projectPath) {
|
|
|
195
153
|
}
|
|
196
154
|
if (trimmed === "exit" || trimmed === "quit" || trimmed === "q") {
|
|
197
155
|
console.log();
|
|
198
|
-
console.log(chalk.hex("#a5ffa5")(" See you next time!
|
|
156
|
+
console.log(chalk.hex("#a5ffa5")(" See you next time!"));
|
|
199
157
|
console.log();
|
|
200
158
|
rl.close();
|
|
201
159
|
process.exit(0);
|
|
@@ -208,31 +166,22 @@ async function startInteractiveMode(projectPath) {
|
|
|
208
166
|
}
|
|
209
167
|
if (trimmed === "help" || trimmed === "?") {
|
|
210
168
|
console.log();
|
|
211
|
-
console.log(chalk.hex("#a5ffa5")(" Just type what you want
|
|
212
|
-
console.log(chalk.dim(' "
|
|
169
|
+
console.log(chalk.hex("#a5ffa5")(" Just type what you want in plain English:"));
|
|
170
|
+
console.log(chalk.dim(' "set up a venv to train llada 8b"'));
|
|
171
|
+
console.log(chalk.dim(' "install pytorch and transformers"'));
|
|
213
172
|
console.log(chalk.dim(' "what packages are installed?"'));
|
|
214
173
|
console.log(chalk.dim(' "are there any conflicts?"'));
|
|
215
|
-
console.log(chalk.dim(' "suggest alternatives to express"'));
|
|
216
174
|
console.log();
|
|
217
|
-
console.log(chalk.hex("#a5ffa5")("
|
|
218
|
-
console.log(` ${chalk.hex("#d2ffd2")("
|
|
219
|
-
console.log(` ${chalk.hex("#d2ffd2")("optimize")} Find ways to reduce bloat`);
|
|
220
|
-
console.log(` ${chalk.hex("#d2ffd2")("tree")} Visualize dependency tree`);
|
|
221
|
-
console.log(` ${chalk.hex("#d2ffd2")("templates")} Browse pre-built environment templates`);
|
|
222
|
-
console.log(` ${chalk.hex("#d2ffd2")("explain")} Get info about any package (e.g. explain torch)`);
|
|
223
|
-
console.log(` ${chalk.hex("#d2ffd2")("clone")} Set up from GitHub URL`);
|
|
224
|
-
console.log(` ${chalk.hex("#d2ffd2")("insights")} Analytics and insights`);
|
|
225
|
-
console.log();
|
|
226
|
-
console.log(chalk.hex("#a5ffa5")(" Basic Commands:"));
|
|
227
|
-
console.log(` ${chalk.hex("#d2ffd2")("undo")} Undo last change`);
|
|
228
|
-
console.log(` ${chalk.hex("#d2ffd2")("list")} See what's installed`);
|
|
175
|
+
console.log(chalk.hex("#a5ffa5")(" Shortcuts:"));
|
|
176
|
+
console.log(` ${chalk.hex("#d2ffd2")("list")} See installed packages`);
|
|
229
177
|
console.log(` ${chalk.hex("#d2ffd2")("check")} Check for problems`);
|
|
230
|
-
console.log(` ${chalk.hex("#d2ffd2")("
|
|
231
|
-
console.log(` ${chalk.hex("#d2ffd2")("
|
|
232
|
-
console.log(` ${chalk.hex("#d2ffd2")("
|
|
233
|
-
console.log(` ${chalk.hex("#d2ffd2")("
|
|
178
|
+
console.log(` ${chalk.hex("#d2ffd2")("fix")} Auto-repair environment`);
|
|
179
|
+
console.log(` ${chalk.hex("#d2ffd2")("conflicts")} Find package conflicts`);
|
|
180
|
+
console.log(` ${chalk.hex("#d2ffd2")("doctor")} Full health audit`);
|
|
181
|
+
console.log(` ${chalk.hex("#d2ffd2")("tree")} Dependency tree`);
|
|
182
|
+
console.log(` ${chalk.hex("#d2ffd2")("undo")} Undo last change`);
|
|
234
183
|
console.log(` ${chalk.hex("#d2ffd2")("clear")} Clear screen`);
|
|
235
|
-
console.log(` ${chalk.hex("#d2ffd2")("exit")}
|
|
184
|
+
console.log(` ${chalk.hex("#d2ffd2")("exit")} Quit Komodo`);
|
|
236
185
|
console.log();
|
|
237
186
|
prompt();
|
|
238
187
|
return;
|
|
@@ -243,17 +192,6 @@ async function startInteractiveMode(projectPath) {
|
|
|
243
192
|
prompt();
|
|
244
193
|
return;
|
|
245
194
|
}
|
|
246
|
-
if (trimmed === "fix" || trimmed === "repair" || trimmed.includes("broken") || trimmed.includes("nothing works") || trimmed.includes("everything is broken") || trimmed.includes("help me fix")) {
|
|
247
|
-
await handleFix(projectPath);
|
|
248
|
-
await updateChatContext(projectPath);
|
|
249
|
-
prompt();
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
if (trimmed === "conflicts" || trimmed.includes("check conflicts") || trimmed.includes("find conflicts")) {
|
|
253
|
-
await handleConflicts(projectPath);
|
|
254
|
-
prompt();
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
195
|
if (trimmed === "list" || trimmed === "ls") {
|
|
258
196
|
await handleList(projectPath);
|
|
259
197
|
prompt();
|
|
@@ -269,11 +207,6 @@ async function startInteractiveMode(projectPath) {
|
|
|
269
207
|
prompt();
|
|
270
208
|
return;
|
|
271
209
|
}
|
|
272
|
-
if (trimmed === "ui") {
|
|
273
|
-
await handleUI(projectPath);
|
|
274
|
-
prompt();
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
210
|
if (trimmed === "doctor") {
|
|
278
211
|
await handleDoctor(projectPath);
|
|
279
212
|
prompt();
|
|
@@ -317,123 +250,85 @@ async function startInteractiveMode(projectPath) {
|
|
|
317
250
|
prompt();
|
|
318
251
|
return;
|
|
319
252
|
}
|
|
320
|
-
if (trimmed === "
|
|
321
|
-
|
|
322
|
-
await updateChatContext(projectPath);
|
|
323
|
-
const response = await chat.analyzeEnvironment();
|
|
324
|
-
spinner.stop();
|
|
325
|
-
displayAIResponse(response);
|
|
326
|
-
prompt();
|
|
327
|
-
return;
|
|
328
|
-
}
|
|
329
|
-
if (trimmed === "ask" || trimmed.startsWith("ask ")) {
|
|
330
|
-
const question = trimmed === "ask" ? "" : trimmed.slice(4).trim();
|
|
331
|
-
if (!question) {
|
|
332
|
-
console.log();
|
|
333
|
-
console.log(chalk.hex("#b4ffb4")(" Ask me anything about your environment!"));
|
|
334
|
-
console.log(chalk.dim(" Example: ask what should I install for a REST API?"));
|
|
335
|
-
console.log();
|
|
336
|
-
} else {
|
|
337
|
-
const spinner = ora(chalk.hex("#b4ffb4")("Thinking...")).start();
|
|
338
|
-
await updateChatContext(projectPath);
|
|
339
|
-
const response = await chat.chat(question);
|
|
340
|
-
spinner.stop();
|
|
341
|
-
displayAIResponse(response);
|
|
342
|
-
}
|
|
253
|
+
if (trimmed === "ui") {
|
|
254
|
+
await handleUI(projectPath);
|
|
343
255
|
prompt();
|
|
344
256
|
return;
|
|
345
257
|
}
|
|
346
|
-
|
|
347
|
-
|
|
258
|
+
const spinner = ora(chalk.hex("#b4ffb4")("Thinking...")).start();
|
|
259
|
+
try {
|
|
348
260
|
await updateChatContext(projectPath);
|
|
349
261
|
const response = await chat.chat(trimmed);
|
|
350
262
|
spinner.stop();
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
263
|
+
const cleanMessage = stripMarkdown(response.message);
|
|
264
|
+
console.log();
|
|
265
|
+
console.log(chalk.hex("#b4ffb4")(cleanMessage));
|
|
266
|
+
console.log();
|
|
267
|
+
if (response.packages) {
|
|
268
|
+
const hasActions = response.packages.toInstall && response.packages.toInstall.length > 0 || response.packages.toRemove && response.packages.toRemove.length > 0 || response.packages.toUpdate && response.packages.toUpdate.length > 0;
|
|
269
|
+
if (hasActions) {
|
|
270
|
+
await executePackageActions(response.packages, projectPath);
|
|
271
|
+
await updateChatContext(projectPath);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
} catch (error) {
|
|
275
|
+
spinner.fail(chalk.red("Something went wrong"));
|
|
276
|
+
const errMsg = error instanceof Error ? error.message : "Unknown error";
|
|
277
|
+
console.log();
|
|
278
|
+
console.log(chalk.dim(" " + errMsg));
|
|
279
|
+
console.log(chalk.dim(" Try again or type 'help' for options."));
|
|
280
|
+
console.log();
|
|
354
281
|
}
|
|
355
|
-
await handleInstall(trimmed, projectPath);
|
|
356
282
|
prompt();
|
|
357
283
|
});
|
|
358
284
|
};
|
|
359
285
|
prompt();
|
|
360
286
|
}
|
|
361
|
-
async function
|
|
362
|
-
const
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
287
|
+
async function executePackageActions(packages, projectPath) {
|
|
288
|
+
const allActions = [
|
|
289
|
+
...(packages.toInstall || []).map((p) => ({ type: "install", name: p })),
|
|
290
|
+
...(packages.toRemove || []).map((p) => ({ type: "remove", name: p })),
|
|
291
|
+
...(packages.toUpdate || []).map((p) => ({ type: "update", name: p.name, version: p.to }))
|
|
292
|
+
];
|
|
293
|
+
if (allActions.length === 0) return;
|
|
294
|
+
for (const action of allActions) {
|
|
295
|
+
const spinner = ora();
|
|
296
|
+
try {
|
|
297
|
+
if (action.type === "install") {
|
|
298
|
+
spinner.start(chalk.hex("#b4ffb4")(`Installing ${action.name}...`));
|
|
299
|
+
const result = await komodo.install({
|
|
300
|
+
intent: `install ${action.name}`,
|
|
301
|
+
path: projectPath,
|
|
302
|
+
dryRun: false,
|
|
303
|
+
useAI: false,
|
|
304
|
+
apiKey: CEREBRAS_API_KEY
|
|
305
|
+
});
|
|
306
|
+
spinner.succeed(chalk.hex("#5aff5a")(`Installed ${action.name}`));
|
|
307
|
+
} else if (action.type === "remove") {
|
|
308
|
+
spinner.start(chalk.hex("#b4ffb4")(`Removing ${action.name}...`));
|
|
309
|
+
await komodo.install({
|
|
310
|
+
intent: `uninstall ${action.name}`,
|
|
311
|
+
path: projectPath,
|
|
312
|
+
dryRun: false,
|
|
313
|
+
useAI: false,
|
|
314
|
+
apiKey: CEREBRAS_API_KEY
|
|
315
|
+
});
|
|
316
|
+
spinner.succeed(chalk.yellow(`Removed ${action.name}`));
|
|
317
|
+
} else if (action.type === "update") {
|
|
318
|
+
spinner.start(chalk.hex("#b4ffb4")(`Updating ${action.name}...`));
|
|
319
|
+
await komodo.install({
|
|
320
|
+
intent: `update ${action.name} to ${action.version}`,
|
|
321
|
+
path: projectPath,
|
|
322
|
+
dryRun: false,
|
|
323
|
+
useAI: false,
|
|
324
|
+
apiKey: CEREBRAS_API_KEY
|
|
325
|
+
});
|
|
326
|
+
spinner.succeed(chalk.hex("#87cefa")(`Updated ${action.name}`));
|
|
377
327
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
explanations.push(friendlyExplanation(explanation));
|
|
382
|
-
},
|
|
383
|
-
onWarning: (warning) => {
|
|
384
|
-
warnings.push(friendlyWarning(warning));
|
|
385
|
-
},
|
|
386
|
-
onTip: (tip) => {
|
|
387
|
-
tips.push(tip);
|
|
388
|
-
}
|
|
389
|
-
});
|
|
390
|
-
if (spinner.isSpinning) {
|
|
391
|
-
spinner.succeed();
|
|
392
|
-
}
|
|
393
|
-
console.log();
|
|
394
|
-
if (result.success) {
|
|
395
|
-
if (result.aiAnalysis) {
|
|
396
|
-
console.log(chalk.hex("#5aff5a").bold(` \u2713 ${result.aiAnalysis.goal}`));
|
|
397
|
-
if (result.aiAnalysis.description) {
|
|
398
|
-
console.log(chalk.dim(` ${result.aiAnalysis.description}`));
|
|
399
|
-
}
|
|
400
|
-
console.log();
|
|
401
|
-
}
|
|
402
|
-
if (result.resolution && result.resolution.packages.length > 0) {
|
|
403
|
-
console.log(chalk.hex("#a5ffa5")(" Set up:"));
|
|
404
|
-
result.resolution.packages.forEach((pkg) => {
|
|
405
|
-
const reason = pkg.reason ? chalk.dim(` - ${pkg.reason}`) : "";
|
|
406
|
-
console.log(chalk.hex("#5aff5a")(` \u2713 ${friendlyPackageName(pkg.name)}`) + reason);
|
|
407
|
-
});
|
|
408
|
-
console.log();
|
|
409
|
-
}
|
|
410
|
-
if (explanations.length > 0) {
|
|
411
|
-
console.log(chalk.hex("#b4ffb4").dim(" Good to know:"));
|
|
412
|
-
explanations.forEach((e) => {
|
|
413
|
-
console.log(chalk.dim(` \u2022 ${e}`));
|
|
414
|
-
});
|
|
415
|
-
console.log();
|
|
416
|
-
}
|
|
417
|
-
if (tips.length > 0) {
|
|
418
|
-
console.log(chalk.hex("#87cefa")(" Tips:"));
|
|
419
|
-
tips.forEach((t) => {
|
|
420
|
-
console.log(chalk.hex("#87cefa")(` \u{1F4A1} ${t}`));
|
|
421
|
-
});
|
|
422
|
-
console.log();
|
|
328
|
+
} catch (error) {
|
|
329
|
+
spinner.fail();
|
|
330
|
+
console.error(chalk.red(`Failed to ${action.type} ${action.name}: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
423
331
|
}
|
|
424
|
-
if (warnings.length > 0) {
|
|
425
|
-
console.log(chalk.yellow(" Heads up:"));
|
|
426
|
-
warnings.forEach((w) => {
|
|
427
|
-
console.log(chalk.yellow(` \u2022 ${w}`));
|
|
428
|
-
});
|
|
429
|
-
console.log();
|
|
430
|
-
}
|
|
431
|
-
console.log(chalk.hex("#5aff5a")(" \u2713 All set! ") + chalk.dim("Type 'undo' to revert."));
|
|
432
|
-
console.log();
|
|
433
|
-
} else {
|
|
434
|
-
console.log(chalk.red(" \u2717 Couldn't set that up"));
|
|
435
|
-
console.log(chalk.dim(` ${result.error ?? "Try being more specific about what you want to build."}`));
|
|
436
|
-
console.log();
|
|
437
332
|
}
|
|
438
333
|
}
|
|
439
334
|
async function handleUndo(projectPath) {
|
|
@@ -517,135 +412,6 @@ async function handleCheck(projectPath) {
|
|
|
517
412
|
}
|
|
518
413
|
console.log();
|
|
519
414
|
}
|
|
520
|
-
async function handleFix(projectPath) {
|
|
521
|
-
const spinner = ora(chalk.hex("#b4ffb4")("Scanning your project...")).start();
|
|
522
|
-
const state = await loadState(projectPath);
|
|
523
|
-
let runtime;
|
|
524
|
-
if (state.activeEnvironmentId) {
|
|
525
|
-
const env = state.environments.find((e) => e.id === state.activeEnvironmentId);
|
|
526
|
-
runtime = env?.runtime;
|
|
527
|
-
}
|
|
528
|
-
const diagnosis = await diagnoseEnvironment(projectPath, runtime);
|
|
529
|
-
spinner.stop();
|
|
530
|
-
console.log();
|
|
531
|
-
if (diagnosis.status === "healthy") {
|
|
532
|
-
console.log(chalk.hex("#5aff5a")(" \u2713 Everything looks good!"));
|
|
533
|
-
console.log(chalk.dim(" No issues found with your environment."));
|
|
534
|
-
console.log();
|
|
535
|
-
return;
|
|
536
|
-
}
|
|
537
|
-
console.log(chalk.hex("#ffb347")(` Found ${diagnosis.problems.length} issue${diagnosis.problems.length > 1 ? "s" : ""}:`));
|
|
538
|
-
console.log();
|
|
539
|
-
diagnosis.problems.slice(0, 3).forEach((problem) => {
|
|
540
|
-
const icon = problem.severity === "critical" ? chalk.red("\u2717") : problem.severity === "warning" ? chalk.yellow("\u26A0") : chalk.blue("\u2139");
|
|
541
|
-
console.log(` ${icon} ${problem.friendlyTitle}`);
|
|
542
|
-
console.log(chalk.dim(` ${problem.description}`));
|
|
543
|
-
});
|
|
544
|
-
if (diagnosis.problems.length > 3) {
|
|
545
|
-
console.log(chalk.dim(` ...and ${diagnosis.problems.length - 3} more`));
|
|
546
|
-
}
|
|
547
|
-
console.log();
|
|
548
|
-
if (diagnosis.repairPlan.length === 0) {
|
|
549
|
-
console.log(chalk.dim(" No automatic fixes available. Try creating a new environment."));
|
|
550
|
-
console.log();
|
|
551
|
-
return;
|
|
552
|
-
}
|
|
553
|
-
console.log(chalk.hex("#b4ffb4")(` Fixing ${diagnosis.repairPlan.length} issue${diagnosis.repairPlan.length > 1 ? "s" : ""}...`));
|
|
554
|
-
console.log();
|
|
555
|
-
const repairSpinner = ora().start();
|
|
556
|
-
const result = await executeRepair(projectPath, diagnosis, {
|
|
557
|
-
autoBackup: true,
|
|
558
|
-
dryRun: false,
|
|
559
|
-
onProgress: (step, status) => {
|
|
560
|
-
if (status === "starting") {
|
|
561
|
-
repairSpinner.text = chalk.hex("#b4ffb4")(step.friendlyDescription);
|
|
562
|
-
} else if (status === "complete") {
|
|
563
|
-
repairSpinner.succeed(chalk.hex("#5aff5a")(step.friendlyDescription));
|
|
564
|
-
repairSpinner.start();
|
|
565
|
-
} else if (status === "failed") {
|
|
566
|
-
repairSpinner.fail(chalk.red(step.friendlyDescription));
|
|
567
|
-
repairSpinner.start();
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
});
|
|
571
|
-
if (repairSpinner.isSpinning) {
|
|
572
|
-
repairSpinner.stop();
|
|
573
|
-
}
|
|
574
|
-
console.log();
|
|
575
|
-
if (result.success) {
|
|
576
|
-
console.log(chalk.hex("#5aff5a")(` \u2713 All fixed! Resolved ${result.problemsFixed.length} issue${result.problemsFixed.length > 1 ? "s" : ""}.`));
|
|
577
|
-
} else {
|
|
578
|
-
console.log(chalk.yellow(` \u26A0 Partially fixed. Resolved ${result.stepsCompleted}/${result.stepsTotal} issues.`));
|
|
579
|
-
}
|
|
580
|
-
console.log();
|
|
581
|
-
}
|
|
582
|
-
async function handleConflicts(projectPath) {
|
|
583
|
-
const spinner = ora(chalk.hex("#b4ffb4")("Checking for conflicts...")).start();
|
|
584
|
-
const state = await loadState(projectPath);
|
|
585
|
-
let runtime;
|
|
586
|
-
if (state.activeEnvironmentId) {
|
|
587
|
-
const env = state.environments.find((e) => e.id === state.activeEnvironmentId);
|
|
588
|
-
runtime = env?.runtime;
|
|
589
|
-
}
|
|
590
|
-
if (!runtime) {
|
|
591
|
-
spinner.fail("No environment found");
|
|
592
|
-
console.log();
|
|
593
|
-
return;
|
|
594
|
-
}
|
|
595
|
-
const conflicts = await detectRealConflicts(projectPath, runtime);
|
|
596
|
-
spinner.stop();
|
|
597
|
-
console.log();
|
|
598
|
-
if (conflicts.length === 0) {
|
|
599
|
-
console.log(chalk.hex("#5aff5a")(" \u2713 No conflicts found!"));
|
|
600
|
-
console.log(chalk.dim(" All packages are compatible."));
|
|
601
|
-
console.log();
|
|
602
|
-
return;
|
|
603
|
-
}
|
|
604
|
-
console.log(chalk.yellow(` Found ${conflicts.length} conflict${conflicts.length > 1 ? "s" : ""}:`));
|
|
605
|
-
console.log();
|
|
606
|
-
conflicts.slice(0, 3).forEach((conflict) => {
|
|
607
|
-
const icon = conflict.severity === "error" ? chalk.red("\u2717") : chalk.yellow("\u26A0");
|
|
608
|
-
console.log(` ${icon} ${conflict.package1} \u2194 ${conflict.package2}`);
|
|
609
|
-
console.log(chalk.dim(` ${conflict.reason}`));
|
|
610
|
-
if (conflict.suggestion) {
|
|
611
|
-
console.log(chalk.hex("#87cefa")(` \u{1F4A1} ${conflict.suggestion}`));
|
|
612
|
-
}
|
|
613
|
-
});
|
|
614
|
-
if (conflicts.length > 3) {
|
|
615
|
-
console.log(chalk.dim(` ...and ${conflicts.length - 3} more`));
|
|
616
|
-
}
|
|
617
|
-
console.log();
|
|
618
|
-
console.log(chalk.hex("#b4ffb4")(" Attempting to resolve..."));
|
|
619
|
-
console.log();
|
|
620
|
-
const resolveSpinner = ora().start();
|
|
621
|
-
const result = await resolveConflicts(
|
|
622
|
-
projectPath,
|
|
623
|
-
runtime,
|
|
624
|
-
conflicts,
|
|
625
|
-
(message) => {
|
|
626
|
-
resolveSpinner.text = chalk.hex("#b4ffb4")(message);
|
|
627
|
-
}
|
|
628
|
-
);
|
|
629
|
-
if (resolveSpinner.isSpinning) {
|
|
630
|
-
resolveSpinner.stop();
|
|
631
|
-
}
|
|
632
|
-
console.log();
|
|
633
|
-
if (result.success) {
|
|
634
|
-
console.log(chalk.hex("#5aff5a")(" \u2713 All conflicts resolved!"));
|
|
635
|
-
result.resolved.forEach((r) => console.log(chalk.dim(` \u2022 ${r}`)));
|
|
636
|
-
} else {
|
|
637
|
-
if (result.resolved.length > 0) {
|
|
638
|
-
console.log(chalk.hex("#5aff5a")(" Resolved:"));
|
|
639
|
-
result.resolved.forEach((r) => console.log(chalk.dim(` \u2022 ${r}`)));
|
|
640
|
-
console.log();
|
|
641
|
-
}
|
|
642
|
-
console.log(chalk.yellow(" Cannot auto-resolve:"));
|
|
643
|
-
result.remaining.slice(0, 3).forEach(
|
|
644
|
-
(c) => console.log(chalk.dim(` \u2022 ${c.package1} \u2194 ${c.package2}`))
|
|
645
|
-
);
|
|
646
|
-
}
|
|
647
|
-
console.log();
|
|
648
|
-
}
|
|
649
415
|
async function handleHistory(projectPath) {
|
|
650
416
|
const snapshots = await komodo.listSnapshots(projectPath);
|
|
651
417
|
console.log();
|
|
@@ -869,7 +635,7 @@ async function handleUI(projectPath) {
|
|
|
869
635
|
console.log();
|
|
870
636
|
console.log(chalk.hex("#b4ffb4").dim(" Starting dashboard..."));
|
|
871
637
|
try {
|
|
872
|
-
const { startServer } = await import("./server-
|
|
638
|
+
const { startServer } = await import("./server-EPYAUU24.js");
|
|
873
639
|
await startServer(projectPath, port);
|
|
874
640
|
console.log(chalk.hex("#5aff5a")(` \u2713 Dashboard ready at ${chalk.bold(url)}`));
|
|
875
641
|
console.log();
|
|
@@ -1198,7 +964,7 @@ program.command("ui").description("Open the visual dashboard").option("-p, --pat
|
|
|
1198
964
|
const url = `http://localhost:${port}`;
|
|
1199
965
|
console.log(chalk.dim(" Starting dashboard..."));
|
|
1200
966
|
try {
|
|
1201
|
-
const { startServer } = await import("./server-
|
|
967
|
+
const { startServer } = await import("./server-EPYAUU24.js");
|
|
1202
968
|
await startServer(options.path, port);
|
|
1203
969
|
console.log();
|
|
1204
970
|
console.log(chalk.green(` \u2713 Dashboard ready at ${chalk.bold(url)}`));
|