komodo-cli 2.8.0 → 2.9.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.
Files changed (2) hide show
  1. package/dist/index.js +149 -183
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -131,192 +131,158 @@ 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
- 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
134
+ printBanner();
135
+ const hardware = komodo.getHardware();
136
+ console.log(chalk.hex("#b4ffb4").dim(` ${formatOs(hardware.os)} \xB7 ${formatGpu(hardware)} \xB7 ${hardware.totalMemoryGb}GB memory`));
137
+ console.log();
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."));
141
+ console.log();
142
+ await updateChatContext(projectPath);
143
+ process.stdin.resume();
144
+ process.stdin.setEncoding("utf8");
145
+ const rl = readline.createInterface({
146
+ input: process.stdin,
147
+ output: process.stdout,
148
+ terminal: process.stdin.isTTY ?? false
149
+ });
150
+ const showPrompt = () => {
151
+ process.stdout.write(chalk.hex("#5aff5a")("\u276F "));
152
+ };
153
+ const askQuestion = () => {
154
+ rl.once("line", (input) => {
155
+ handleInput(input).then(() => {
156
+ askQuestion();
157
+ }).catch((err) => {
158
+ console.error(chalk.red("\nError:"), err instanceof Error ? err.message : String(err));
159
+ console.log();
160
+ showPrompt();
161
+ askQuestion();
162
+ });
147
163
  });
148
- rl.on("close", () => {
164
+ showPrompt();
165
+ };
166
+ const handleInput = async (input) => {
167
+ const trimmed = input.trim();
168
+ if (!trimmed) {
169
+ return;
170
+ }
171
+ if (trimmed === "exit" || trimmed === "quit" || trimmed === "q") {
172
+ console.log();
173
+ console.log(chalk.hex("#a5ffa5")(" See you next time!"));
174
+ console.log();
149
175
  process.exit(0);
150
- });
151
- process.on("unhandledRejection", (reason) => {
152
- console.error(chalk.red("\n[DEBUG] Unhandled rejection:"), reason);
153
- if (!rl.closed) {
154
- prompt();
155
- }
156
- });
157
- process.on("uncaughtException", (error) => {
158
- console.error(chalk.red("\n[DEBUG] Uncaught exception:"), error);
159
- if (!rl.closed) {
160
- prompt();
161
- }
162
- });
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
- }
176
+ }
177
+ if (trimmed === "clear" || trimmed === "cls") {
178
+ console.clear();
179
+ printBanner();
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
+ return;
202
+ }
203
+ if (trimmed === "undo") {
204
+ await handleUndo(projectPath);
205
+ await updateChatContext(projectPath);
206
+ return;
207
+ }
208
+ if (trimmed === "list" || trimmed === "ls") {
209
+ await handleList(projectPath);
210
+ return;
211
+ }
212
+ if (trimmed === "check") {
213
+ await handleCheck(projectPath);
214
+ return;
215
+ }
216
+ if (trimmed === "history") {
217
+ await handleHistory(projectPath);
218
+ return;
219
+ }
220
+ if (trimmed === "doctor") {
221
+ await handleDoctor(projectPath);
222
+ return;
223
+ }
224
+ if (trimmed === "optimize") {
225
+ await handleOptimize(projectPath);
226
+ return;
227
+ }
228
+ if (trimmed === "tree") {
229
+ await handleTree(projectPath);
230
+ return;
231
+ }
232
+ if (trimmed === "templates" || trimmed === "template") {
233
+ await handleTemplates();
234
+ return;
235
+ }
236
+ if (trimmed.startsWith("template ") || trimmed.startsWith("use ")) {
237
+ const templateId = trimmed.replace(/^(template|use)\s+/, "").trim();
238
+ await handleUseTemplate(templateId, projectPath);
239
+ return;
240
+ }
241
+ if (trimmed.startsWith("explain ")) {
242
+ const packageName = trimmed.slice(8).trim();
243
+ await handleExplain(packageName);
244
+ return;
245
+ }
246
+ if (trimmed.startsWith("clone ") || trimmed.startsWith("setup ")) {
247
+ const url = trimmed.replace(/^(clone|setup)\s+/, "").trim();
248
+ await handleClone(url);
249
+ return;
250
+ }
251
+ if (trimmed === "insights" || trimmed === "analytics") {
252
+ await handleInsights(projectPath);
253
+ return;
254
+ }
255
+ if (trimmed === "ui") {
256
+ await handleUI(projectPath);
257
+ return;
258
+ }
259
+ process.stdout.write(chalk.hex("#b4ffb4")(" Thinking...\r"));
260
+ try {
261
+ await updateChatContext(projectPath);
262
+ const response = await chat.chat(trimmed);
263
+ process.stdout.write(" \r");
264
+ const cleanMessage = stripMarkdown(response.message);
265
+ console.log();
266
+ console.log(chalk.hex("#b4ffb4")(cleanMessage));
267
+ console.log();
268
+ if (response.packages) {
269
+ 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;
270
+ if (hasActions) {
271
+ await executePackageActions(response.packages, projectPath);
272
+ await updateChatContext(projectPath);
288
273
  }
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
274
  }
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
- }
275
+ } catch (error) {
276
+ process.stdout.write(" \r");
277
+ console.log(chalk.red(" Something went wrong"));
278
+ const errMsg = error instanceof Error ? error.message : "Unknown error";
279
+ console.log();
280
+ console.log(chalk.dim(" " + errMsg));
281
+ console.log(chalk.dim(" Try again or type 'help' for options."));
282
+ console.log();
283
+ }
284
+ };
285
+ askQuestion();
320
286
  }
321
287
  async function executePackageActions(packages, projectPath) {
322
288
  const allActions = [
@@ -707,7 +673,7 @@ program.argument("[intent]", "What you want to build").option("-p, --path <path>
707
673
  path: options.path,
708
674
  dryRun: options.preview,
709
675
  useAI: true,
710
- apiKey: API_KEY,
676
+ apiKey: CEREBRAS_API_KEY,
711
677
  onProgress: (message) => {
712
678
  const friendly = friendlyMessage(message);
713
679
  if (spinner.isSpinning) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "komodo-cli",
3
- "version": "2.8.0",
3
+ "version": "2.9.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": {