komodo-cli 2.7.0 → 2.8.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 +182 -160
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -131,170 +131,192 @@ function stripMarkdown(text) {
|
|
|
131
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();
|
|
132
132
|
}
|
|
133
133
|
async function startInteractiveMode(projectPath) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
});
|
|
150
|
-
const handleInput = async (input) => {
|
|
151
|
-
const trimmed = input.trim();
|
|
152
|
-
if (!trimmed) {
|
|
153
|
-
prompt();
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
if (trimmed === "exit" || trimmed === "quit" || trimmed === "q") {
|
|
157
|
-
console.log();
|
|
158
|
-
console.log(chalk.hex("#a5ffa5")(" See you next time!"));
|
|
159
|
-
console.log();
|
|
160
|
-
rl.close();
|
|
134
|
+
try {
|
|
135
|
+
printBanner();
|
|
136
|
+
const hardware = komodo.getHardware();
|
|
137
|
+
console.log(chalk.hex("#b4ffb4").dim(` ${formatOs(hardware.os)} \xB7 ${formatGpu(hardware)} \xB7 ${hardware.totalMemoryGb}GB memory`));
|
|
138
|
+
console.log();
|
|
139
|
+
console.log(chalk.dim(" Type anything naturally. Komodo understands what you need."));
|
|
140
|
+
console.log(chalk.dim(` Try: "set up a venv for pytorch" or "what's installed?"`));
|
|
141
|
+
console.log(chalk.dim(" Type ") + chalk.hex("#d2ffd2")("help") + chalk.dim(" for commands, ") + chalk.hex("#d2ffd2")("exit") + chalk.dim(" to quit."));
|
|
142
|
+
console.log();
|
|
143
|
+
await updateChatContext(projectPath);
|
|
144
|
+
const rl = readline.createInterface({
|
|
145
|
+
input: process.stdin,
|
|
146
|
+
output: process.stdout
|
|
147
|
+
});
|
|
148
|
+
rl.on("close", () => {
|
|
161
149
|
process.exit(0);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
console.
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
if (trimmed === "help" || trimmed === "?") {
|
|
170
|
-
console.log();
|
|
171
|
-
console.log(chalk.hex("#a5ffa5")(" Just type what you want in plain English:"));
|
|
172
|
-
console.log(chalk.dim(' "set up a venv to train llada 8b"'));
|
|
173
|
-
console.log(chalk.dim(' "install pytorch and transformers"'));
|
|
174
|
-
console.log(chalk.dim(' "what packages are installed?"'));
|
|
175
|
-
console.log(chalk.dim(' "are there any conflicts?"'));
|
|
176
|
-
console.log();
|
|
177
|
-
console.log(chalk.hex("#a5ffa5")(" Shortcuts:"));
|
|
178
|
-
console.log(` ${chalk.hex("#d2ffd2")("list")} See installed packages`);
|
|
179
|
-
console.log(` ${chalk.hex("#d2ffd2")("check")} Check for problems`);
|
|
180
|
-
console.log(` ${chalk.hex("#d2ffd2")("fix")} Auto-repair environment`);
|
|
181
|
-
console.log(` ${chalk.hex("#d2ffd2")("conflicts")} Find package conflicts`);
|
|
182
|
-
console.log(` ${chalk.hex("#d2ffd2")("doctor")} Full health audit`);
|
|
183
|
-
console.log(` ${chalk.hex("#d2ffd2")("tree")} Dependency tree`);
|
|
184
|
-
console.log(` ${chalk.hex("#d2ffd2")("undo")} Undo last change`);
|
|
185
|
-
console.log(` ${chalk.hex("#d2ffd2")("clear")} Clear screen`);
|
|
186
|
-
console.log(` ${chalk.hex("#d2ffd2")("exit")} Quit Komodo`);
|
|
187
|
-
console.log();
|
|
188
|
-
prompt();
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
if (trimmed === "undo") {
|
|
192
|
-
await handleUndo(projectPath);
|
|
193
|
-
await updateChatContext(projectPath);
|
|
194
|
-
prompt();
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
if (trimmed === "list" || trimmed === "ls") {
|
|
198
|
-
await handleList(projectPath);
|
|
199
|
-
prompt();
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
if (trimmed === "check") {
|
|
203
|
-
await handleCheck(projectPath);
|
|
204
|
-
prompt();
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
if (trimmed === "history") {
|
|
208
|
-
await handleHistory(projectPath);
|
|
209
|
-
prompt();
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
if (trimmed === "doctor") {
|
|
213
|
-
await handleDoctor(projectPath);
|
|
214
|
-
prompt();
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
if (trimmed === "optimize") {
|
|
218
|
-
await handleOptimize(projectPath);
|
|
219
|
-
prompt();
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
if (trimmed === "tree") {
|
|
223
|
-
await handleTree(projectPath);
|
|
224
|
-
prompt();
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
if (trimmed === "templates" || trimmed === "template") {
|
|
228
|
-
await handleTemplates();
|
|
229
|
-
prompt();
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
if (trimmed.startsWith("template ") || trimmed.startsWith("use ")) {
|
|
233
|
-
const templateId = trimmed.replace(/^(template|use)\s+/, "").trim();
|
|
234
|
-
await handleUseTemplate(templateId, projectPath);
|
|
235
|
-
prompt();
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
if (trimmed.startsWith("explain ")) {
|
|
239
|
-
const packageName = trimmed.slice(8).trim();
|
|
240
|
-
await handleExplain(packageName);
|
|
241
|
-
prompt();
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
if (trimmed.startsWith("clone ") || trimmed.startsWith("setup ")) {
|
|
245
|
-
const url = trimmed.replace(/^(clone|setup)\s+/, "").trim();
|
|
246
|
-
await handleClone(url);
|
|
247
|
-
prompt();
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
if (trimmed === "insights" || trimmed === "analytics") {
|
|
251
|
-
await handleInsights(projectPath);
|
|
252
|
-
prompt();
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
if (trimmed === "ui") {
|
|
256
|
-
await handleUI(projectPath);
|
|
257
|
-
prompt();
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
const spinner = ora(chalk.hex("#b4ffb4")("Thinking...")).start();
|
|
261
|
-
try {
|
|
262
|
-
await updateChatContext(projectPath);
|
|
263
|
-
const response = await chat.chat(trimmed);
|
|
264
|
-
spinner.stop();
|
|
265
|
-
const cleanMessage = stripMarkdown(response.message);
|
|
266
|
-
console.log();
|
|
267
|
-
console.log(chalk.hex("#b4ffb4")(cleanMessage));
|
|
268
|
-
console.log();
|
|
269
|
-
if (response.packages) {
|
|
270
|
-
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;
|
|
271
|
-
if (hasActions) {
|
|
272
|
-
await executePackageActions(response.packages, projectPath);
|
|
273
|
-
await updateChatContext(projectPath);
|
|
274
|
-
}
|
|
150
|
+
});
|
|
151
|
+
process.on("unhandledRejection", (reason) => {
|
|
152
|
+
console.error(chalk.red("\n[DEBUG] Unhandled rejection:"), reason);
|
|
153
|
+
if (!rl.closed) {
|
|
154
|
+
prompt();
|
|
275
155
|
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
console.log(chalk.dim(" " + errMsg));
|
|
281
|
-
console.log(chalk.dim(" Try again or type 'help' for options."));
|
|
282
|
-
console.log();
|
|
283
|
-
}
|
|
284
|
-
prompt();
|
|
285
|
-
};
|
|
286
|
-
const prompt = () => {
|
|
287
|
-
if (rl.closed) {
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
rl.question(chalk.hex("#5aff5a")("\u276F "), (input) => {
|
|
291
|
-
handleInput(input).catch((err) => {
|
|
292
|
-
console.error(chalk.red("Error:"), err);
|
|
156
|
+
});
|
|
157
|
+
process.on("uncaughtException", (error) => {
|
|
158
|
+
console.error(chalk.red("\n[DEBUG] Uncaught exception:"), error);
|
|
159
|
+
if (!rl.closed) {
|
|
293
160
|
prompt();
|
|
294
|
-
}
|
|
161
|
+
}
|
|
295
162
|
});
|
|
296
|
-
|
|
297
|
-
|
|
163
|
+
const handleInput = async (input) => {
|
|
164
|
+
const trimmed = input.trim();
|
|
165
|
+
if (!trimmed) {
|
|
166
|
+
prompt();
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (trimmed === "exit" || trimmed === "quit" || trimmed === "q") {
|
|
170
|
+
console.log();
|
|
171
|
+
console.log(chalk.hex("#a5ffa5")(" See you next time!"));
|
|
172
|
+
console.log();
|
|
173
|
+
rl.close();
|
|
174
|
+
process.exit(0);
|
|
175
|
+
}
|
|
176
|
+
if (trimmed === "clear" || trimmed === "cls") {
|
|
177
|
+
console.clear();
|
|
178
|
+
printBanner();
|
|
179
|
+
prompt();
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (trimmed === "help" || trimmed === "?") {
|
|
183
|
+
console.log();
|
|
184
|
+
console.log(chalk.hex("#a5ffa5")(" Just type what you want in plain English:"));
|
|
185
|
+
console.log(chalk.dim(' "set up a venv to train llada 8b"'));
|
|
186
|
+
console.log(chalk.dim(' "install pytorch and transformers"'));
|
|
187
|
+
console.log(chalk.dim(' "what packages are installed?"'));
|
|
188
|
+
console.log(chalk.dim(' "are there any conflicts?"'));
|
|
189
|
+
console.log();
|
|
190
|
+
console.log(chalk.hex("#a5ffa5")(" Shortcuts:"));
|
|
191
|
+
console.log(` ${chalk.hex("#d2ffd2")("list")} See installed packages`);
|
|
192
|
+
console.log(` ${chalk.hex("#d2ffd2")("check")} Check for problems`);
|
|
193
|
+
console.log(` ${chalk.hex("#d2ffd2")("fix")} Auto-repair environment`);
|
|
194
|
+
console.log(` ${chalk.hex("#d2ffd2")("conflicts")} Find package conflicts`);
|
|
195
|
+
console.log(` ${chalk.hex("#d2ffd2")("doctor")} Full health audit`);
|
|
196
|
+
console.log(` ${chalk.hex("#d2ffd2")("tree")} Dependency tree`);
|
|
197
|
+
console.log(` ${chalk.hex("#d2ffd2")("undo")} Undo last change`);
|
|
198
|
+
console.log(` ${chalk.hex("#d2ffd2")("clear")} Clear screen`);
|
|
199
|
+
console.log(` ${chalk.hex("#d2ffd2")("exit")} Quit Komodo`);
|
|
200
|
+
console.log();
|
|
201
|
+
prompt();
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (trimmed === "undo") {
|
|
205
|
+
await handleUndo(projectPath);
|
|
206
|
+
await updateChatContext(projectPath);
|
|
207
|
+
prompt();
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (trimmed === "list" || trimmed === "ls") {
|
|
211
|
+
await handleList(projectPath);
|
|
212
|
+
prompt();
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (trimmed === "check") {
|
|
216
|
+
await handleCheck(projectPath);
|
|
217
|
+
prompt();
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (trimmed === "history") {
|
|
221
|
+
await handleHistory(projectPath);
|
|
222
|
+
prompt();
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
if (trimmed === "doctor") {
|
|
226
|
+
await handleDoctor(projectPath);
|
|
227
|
+
prompt();
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (trimmed === "optimize") {
|
|
231
|
+
await handleOptimize(projectPath);
|
|
232
|
+
prompt();
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (trimmed === "tree") {
|
|
236
|
+
await handleTree(projectPath);
|
|
237
|
+
prompt();
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (trimmed === "templates" || trimmed === "template") {
|
|
241
|
+
await handleTemplates();
|
|
242
|
+
prompt();
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
if (trimmed.startsWith("template ") || trimmed.startsWith("use ")) {
|
|
246
|
+
const templateId = trimmed.replace(/^(template|use)\s+/, "").trim();
|
|
247
|
+
await handleUseTemplate(templateId, projectPath);
|
|
248
|
+
prompt();
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
if (trimmed.startsWith("explain ")) {
|
|
252
|
+
const packageName = trimmed.slice(8).trim();
|
|
253
|
+
await handleExplain(packageName);
|
|
254
|
+
prompt();
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (trimmed.startsWith("clone ") || trimmed.startsWith("setup ")) {
|
|
258
|
+
const url = trimmed.replace(/^(clone|setup)\s+/, "").trim();
|
|
259
|
+
await handleClone(url);
|
|
260
|
+
prompt();
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
if (trimmed === "insights" || trimmed === "analytics") {
|
|
264
|
+
await handleInsights(projectPath);
|
|
265
|
+
prompt();
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (trimmed === "ui") {
|
|
269
|
+
await handleUI(projectPath);
|
|
270
|
+
prompt();
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const spinner = ora(chalk.hex("#b4ffb4")("Thinking...")).start();
|
|
274
|
+
try {
|
|
275
|
+
await updateChatContext(projectPath);
|
|
276
|
+
const response = await chat.chat(trimmed);
|
|
277
|
+
spinner.stop();
|
|
278
|
+
const cleanMessage = stripMarkdown(response.message);
|
|
279
|
+
console.log();
|
|
280
|
+
console.log(chalk.hex("#b4ffb4")(cleanMessage));
|
|
281
|
+
console.log();
|
|
282
|
+
if (response.packages) {
|
|
283
|
+
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;
|
|
284
|
+
if (hasActions) {
|
|
285
|
+
await executePackageActions(response.packages, projectPath);
|
|
286
|
+
await updateChatContext(projectPath);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
} catch (error) {
|
|
290
|
+
spinner.fail(chalk.red("Something went wrong"));
|
|
291
|
+
const errMsg = error instanceof Error ? error.message : "Unknown error";
|
|
292
|
+
console.log();
|
|
293
|
+
console.log(chalk.dim(" " + errMsg));
|
|
294
|
+
console.log(chalk.dim(" Try again or type 'help' for options."));
|
|
295
|
+
console.log();
|
|
296
|
+
}
|
|
297
|
+
prompt();
|
|
298
|
+
};
|
|
299
|
+
const prompt = () => {
|
|
300
|
+
if (rl.closed) {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
rl.question(chalk.hex("#5aff5a")("\u276F "), (input) => {
|
|
304
|
+
handleInput(input).catch((err) => {
|
|
305
|
+
console.error(chalk.red("\nError:"), err instanceof Error ? err.message : String(err));
|
|
306
|
+
console.log();
|
|
307
|
+
prompt();
|
|
308
|
+
}).catch(() => {
|
|
309
|
+
if (!rl.closed) {
|
|
310
|
+
prompt();
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
};
|
|
315
|
+
prompt();
|
|
316
|
+
} catch (error) {
|
|
317
|
+
console.error(chalk.red("Fatal error:"), error instanceof Error ? error.message : String(error));
|
|
318
|
+
process.exit(1);
|
|
319
|
+
}
|
|
298
320
|
}
|
|
299
321
|
async function executePackageActions(packages, projectPath) {
|
|
300
322
|
const allActions = [
|