@geravant/sinain 1.6.5 → 1.6.6

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/launcher.js +53 -29
  2. package/package.json +1 -1
package/launcher.js CHANGED
@@ -71,6 +71,11 @@ async function main() {
71
71
  // Load user config
72
72
  loadUserEnv();
73
73
 
74
+ // Ensure Ollama is running (if local vision enabled)
75
+ if (process.env.LOCAL_VISION_ENABLED === "true") {
76
+ await ensureOllama();
77
+ }
78
+
74
79
  // Auto-detect transcription backend
75
80
  detectTranscription();
76
81
 
@@ -348,25 +353,38 @@ async function preflight() {
348
353
  ok("port 9500 free");
349
354
  }
350
355
 
351
- // Ollama (if local vision enabled)
352
- if (process.env.LOCAL_VISION_ENABLED === "true") {
353
- try {
354
- const resp = await fetch("http://localhost:11434/api/tags", { signal: AbortSignal.timeout(2000) });
355
- if (resp.ok) {
356
- ok("ollama server running");
357
- } else {
358
- warn("ollama server not responding — local vision will be unavailable");
359
- }
360
- } catch {
361
- // Try to start Ollama in background
356
+ }
357
+
358
+ async function ensureOllama() {
359
+ try {
360
+ const resp = await fetch("http://localhost:11434/api/tags", { signal: AbortSignal.timeout(2000) });
361
+ if (resp.ok) {
362
+ ok("ollama server running");
363
+ return true;
364
+ }
365
+ } catch { /* not running */ }
366
+
367
+ // Try to start Ollama in background
368
+ log("Starting ollama server...");
369
+ try {
370
+ const { spawn: spawnProc } = await import("child_process");
371
+ spawnProc("ollama", ["serve"], { detached: true, stdio: "ignore" }).unref();
372
+ // Wait for it to become ready
373
+ for (let i = 0; i < 10; i++) {
374
+ await sleep(500);
362
375
  try {
363
- const { spawn: spawnProc } = await import("child_process");
364
- spawnProc("ollama", ["serve"], { detached: true, stdio: "ignore" }).unref();
365
- ok("ollama server started in background");
366
- } catch {
367
- warn("ollama not running and could not auto-start — local vision disabled");
368
- }
376
+ const resp = await fetch("http://localhost:11434/api/tags", { signal: AbortSignal.timeout(1000) });
377
+ if (resp.ok) {
378
+ ok("ollama server started");
379
+ return true;
380
+ }
381
+ } catch { /* not ready yet */ }
369
382
  }
383
+ warn("ollama started but not responding — local vision may not work");
384
+ return false;
385
+ } catch {
386
+ warn("ollama not found — local vision disabled. Install: brew install ollama");
387
+ return false;
370
388
  }
371
389
  }
372
390
 
@@ -480,20 +498,24 @@ async function setupWizard(envPath) {
480
498
  const useVision = await ask(` Enable local vision AI? [Y/n] (Ollama — screen understanding without cloud API): `);
481
499
  if (!useVision.trim() || useVision.trim().toLowerCase() === "y") {
482
500
  vars.LOCAL_VISION_ENABLED = "true";
483
- try {
484
- const models = execSync("ollama list 2>/dev/null", { encoding: "utf-8" });
485
- if (!models.includes("llava")) {
486
- const pull = await ask(` Pull llava vision model (~4GB)? [Y/n]: `);
487
- if (!pull.trim() || pull.trim().toLowerCase() === "y") {
488
- console.log(` ${DIM}Pulling llava...${RESET}`);
489
- execSync("ollama pull llava", { stdio: "inherit" });
490
- ok("llava model pulled");
501
+ // Ensure ollama serve is running before list/pull
502
+ const ollamaReady = await ensureOllama();
503
+ if (ollamaReady) {
504
+ try {
505
+ const models = execSync("ollama list 2>/dev/null", { encoding: "utf-8" });
506
+ if (!models.includes("llava")) {
507
+ const pull = await ask(` Pull llava vision model (~4GB)? [Y/n]: `);
508
+ if (!pull.trim() || pull.trim().toLowerCase() === "y") {
509
+ console.log(` ${DIM}Pulling llava...${RESET}`);
510
+ execSync("ollama pull llava", { stdio: "inherit" });
511
+ ok("llava model pulled");
512
+ }
513
+ } else {
514
+ ok("llava model already available");
491
515
  }
492
- } else {
493
- ok("llava model already available");
516
+ } catch {
517
+ warn("Could not check Ollama models");
494
518
  }
495
- } catch {
496
- warn("Could not check Ollama models");
497
519
  }
498
520
  vars.LOCAL_VISION_MODEL = "llava";
499
521
  }
@@ -508,6 +530,8 @@ async function setupWizard(envPath) {
508
530
  console.log(` ${DIM}Installing Ollama...${RESET}`);
509
531
  execSync("curl -fsSL https://ollama.com/install.sh | sh", { stdio: "inherit" });
510
532
  }
533
+ // Start ollama serve before pulling
534
+ await ensureOllama();
511
535
  console.log(` ${DIM}Pulling llava vision model...${RESET}`);
512
536
  execSync("ollama pull llava", { stdio: "inherit" });
513
537
  vars.LOCAL_VISION_ENABLED = "true";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geravant/sinain",
3
- "version": "1.6.5",
3
+ "version": "1.6.6",
4
4
  "description": "Ambient AI overlay invisible to screen capture — real-time insights from audio + screen context",
5
5
  "type": "module",
6
6
  "bin": {