loren-code 0.2.1 → 0.2.3

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/package.json +1 -1
  2. package/scripts/loren.js +85 -35
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loren-code",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Ollama Cloud Model Manager - Dynamic model switching, API key rotation, and real-time configuration updates",
5
5
  "author": "lorenzune",
6
6
  "license": "MIT",
package/scripts/loren.js CHANGED
@@ -19,15 +19,28 @@ const logFilePath = path.join(runtimeDir, "bridge.log");
19
19
  const errorLogFilePath = path.join(runtimeDir, "bridge.err.log");
20
20
  const userHome = process.env.USERPROFILE || process.env.HOME || projectRoot;
21
21
  const claudeSettingsPath = path.join(userHome, ".claude", "settings.json");
22
+ const displayName = getDisplayName();
22
23
 
23
24
  process.chdir(projectRoot);
24
25
  ensureRuntimeDir();
25
26
  const envStatus = ensureEnvLocal(projectRoot, { logger: { warn() {} } });
26
27
 
27
- const BANNER = `
28
+ const ASCII_BANNER = `
29
+ ██╗ ██████╗ ██████╗ ███████╗███╗ ██╗ ██████╗ ██████╗ ██████╗ ███████╗
30
+ ██║ ██╔═══██╗██╔══██╗██╔════╝████╗ ██║ ██╔════╝██╔═══██╗██╔══██╗██╔════╝
31
+ ██║ ██║ ██║██████╔╝█████╗ ██╔██╗ ██║ ██║ ██║ ██║██║ ██║█████╗
32
+ ██║ ██║ ██║██╔══██╗██╔══╝ ██║╚██╗██║ ██║ ██║ ██║██║ ██║██╔══╝
33
+ ███████╗╚██████╔╝██║ ██║███████╗██║ ╚████║ ╚██████╗╚██████╔╝██████╔╝███████╗
34
+ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═══╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
35
+ `;
36
+
37
+ const BANNER = `${ASCII_BANNER}
28
38
  LOREN CODE
29
39
  Smarter bridge, fewer rituals.
30
40
  `;
41
+ const GREEN = "\x1b[32m";
42
+ const YELLOW = "\x1b[33m";
43
+ const RESET = "\x1b[0m";
31
44
 
32
45
  const COMMANDS = {
33
46
  model: {
@@ -342,13 +355,16 @@ function showPaths() {
342
355
  console.log("");
343
356
  }
344
357
 
345
- function startServer() {
358
+ function startServer(options = {}) {
359
+ const quiet = options.quiet === true;
346
360
  const existingPid = readPidFile();
347
361
  if (existingPid && isProcessRunning(existingPid)) {
348
362
  const config = loadConfig();
349
- console.log("\nLoren is already running.");
350
- console.log(`URL: ${getBridgeBaseUrl(config)}`);
351
- console.log("");
363
+ if (!quiet) {
364
+ console.log("\nLoren is already running.");
365
+ console.log(`URL: ${getBridgeBaseUrl(config)}`);
366
+ console.log("");
367
+ }
352
368
  return;
353
369
  }
354
370
 
@@ -364,10 +380,12 @@ function startServer() {
364
380
  child.unref();
365
381
  fs.writeFileSync(pidFilePath, `${child.pid}\n`, "utf8");
366
382
 
367
- const config = loadConfig();
368
- console.log("\nLoren is up and listening.");
369
- console.log(`URL: ${getBridgeBaseUrl(config)}`);
370
- console.log("");
383
+ if (!quiet) {
384
+ const config = loadConfig();
385
+ console.log("\nLoren is up and listening.");
386
+ console.log(`URL: ${getBridgeBaseUrl(config)}`);
387
+ console.log("");
388
+ }
371
389
  }
372
390
 
373
391
  function stopServer() {
@@ -495,32 +513,31 @@ async function runSetupWizard(config) {
495
513
  });
496
514
 
497
515
  try {
498
- const rawKeys = (await rl.question("Paste your Ollama API key(s), separated by commas: ")).trim();
499
-
500
- if (rawKeys) {
501
- const keys = splitKeyList(rawKeys);
502
- const envVars = loadEnvFile(envFilePath);
503
- envVars.OLLAMA_API_KEYS = keys.join(",");
504
- saveEnvFile(envFilePath, envVars);
505
- console.log(`\nNice. Loren is holding ${keys.length} key(s) and feeling organized.`);
506
- } else {
507
- console.log("\nNo keys yet. Loren will wait here and act casual about it.");
508
- }
509
-
510
- const startNow = (await rl.question("Start the bridge now? [Y/n] ")).trim().toLowerCase();
511
- if (startNow === "" || startNow === "y" || startNow === "yes") {
512
- startServer();
513
- }
516
+ const keys = await promptForApiKeys(rl);
517
+ const envVars = loadEnvFile(envFilePath);
518
+ envVars.OLLAMA_API_KEYS = keys.join(",");
519
+ saveEnvFile(envFilePath, envVars);
520
+ console.log(`${GREEN}✓ Saved ${keys.length} API key(s).${RESET}`);
521
+ console.log("");
514
522
 
515
523
  if (process.platform === "win32") {
516
- const installClaude = (await rl.question("Install Claude Code integration too? [y/N] ")).trim().toLowerCase();
517
- if (installClaude === "y" || installClaude === "yes") {
524
+ const installClaude = (await rl.question("Install Claude Code integration too? [Y/n] ")).trim().toLowerCase();
525
+ if (installClaude === "" || installClaude === "y" || installClaude === "yes") {
518
526
  installClaudeIntegration();
527
+ console.log(`${GREEN}✓ Claude Code integration installed.${RESET}`);
528
+ console.log("");
519
529
  } else {
520
530
  console.log("\nNo problem. You can wire Claude in later.");
521
531
  }
522
532
  }
523
533
 
534
+ const startNow = (await rl.question("Start the bridge now? [Y/n] ")).trim().toLowerCase();
535
+ if (startNow === "" || startNow === "y" || startNow === "yes") {
536
+ startServer({ quiet: true });
537
+ console.log(`${GREEN}✓ Bridge started.${RESET}`);
538
+ console.log("");
539
+ }
540
+
524
541
  console.log("Setup complete. Fewer steps, fewer goblins.");
525
542
  console.log("");
526
543
  } finally {
@@ -535,29 +552,34 @@ function printWizardIntro() {
535
552
  } else if (envStatus.created) {
536
553
  console.log("A fresh config is ready.");
537
554
  }
555
+ console.log(`Welcome${displayName ? `, ${displayName}` : ""}.`);
556
+ console.log(`${YELLOW}Run \`loren\` in an interactive terminal to finish setup.${RESET}`);
538
557
  console.log("Let's get Loren ready in one quick pass.");
539
558
  console.log("");
559
+ printCommandSummary();
540
560
  }
541
561
 
542
562
  function printWelcomeBack(config) {
543
563
  console.log(BANNER);
544
- console.log(`Welcome back. ${config.apiKeys.length} key(s) loaded.`);
564
+ console.log(`Welcome back${displayName ? `, ${displayName}` : ""}.`);
565
+ console.log(`${config.apiKeys.length} key(s) loaded.`);
545
566
  console.log(`Current default model: ${config.defaultModel}`);
567
+ console.log(`${GREEN}Run \`loren start\` to launch the bridge.${RESET}`);
546
568
  console.log("");
547
- console.log("Useful commands:");
548
- console.log(" loren start");
549
- console.log(" loren model:list");
550
- console.log(" loren config:show");
551
- console.log("");
569
+ printCommandSummary();
552
570
  }
553
571
 
554
572
  function printQuickSetup(config) {
555
573
  if (config.apiKeys.length > 0) {
556
- console.log("Run `loren start` to launch the bridge.");
557
- console.log("");
574
+ printWelcomeBack(config);
558
575
  return;
559
576
  }
560
577
 
578
+ console.log(BANNER);
579
+ console.log(`Welcome${displayName ? `, ${displayName}` : ""}.`);
580
+ console.log(`${YELLOW}Run \`loren\` in an interactive terminal to finish setup.${RESET}`);
581
+ console.log("");
582
+ printCommandSummary();
561
583
  console.log("Quick start:");
562
584
  console.log(" 1. Run `loren` in an interactive terminal");
563
585
  console.log(" 2. Add your Ollama API key(s)");
@@ -577,8 +599,26 @@ function installClaudeIntegration() {
577
599
  }
578
600
  }
579
601
 
602
+ async function promptForApiKeys(rl) {
603
+ while (true) {
604
+ const rawKeys = (await rl.question("Paste your Ollama API key(s), separated by commas: ")).trim();
605
+ const keys = splitKeyList(rawKeys);
606
+
607
+ if (keys.length > 0) {
608
+ return keys;
609
+ }
610
+
611
+ console.log("At least one API key is required to continue.");
612
+ console.log("");
613
+ }
614
+ }
615
+
580
616
  function printHelp() {
581
617
  console.log(BANNER);
618
+ printCommandSummary();
619
+ }
620
+
621
+ function printCommandSummary() {
582
622
  console.log("Commands:");
583
623
  console.log(" loren setup Run the setup wizard");
584
624
  console.log(" loren start Start the bridge");
@@ -602,6 +642,16 @@ function printHelp() {
602
642
  console.log("");
603
643
  }
604
644
 
645
+ function getDisplayName() {
646
+ const explicit = process.env.USERNAME || process.env.USER;
647
+ if (explicit && explicit.trim()) {
648
+ return explicit.trim();
649
+ }
650
+
651
+ const baseName = path.basename(userHome || "").trim();
652
+ return baseName || "";
653
+ }
654
+
605
655
  main().catch((error) => {
606
656
  console.error(error instanceof Error ? error.message : String(error));
607
657
  process.exit(1);