@gorlitzer-labs/seldon 0.1.11 → 0.1.13

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/bin/seldon.js +16 -4
  2. package/package.json +1 -1
package/bin/seldon.js CHANGED
@@ -155,7 +155,9 @@ function installPython(m, dev) {
155
155
  let ok;
156
156
  const uv = ensureUv();
157
157
  if (uv) {
158
- const venvArgs = ["venv", venv];
158
+ const venvArgs = ["venv", venv, "--seed"]; // --seed puts pip in the venv:
159
+ // kokoro/misaki/spaCy shells out to pip at runtime to load its model, and a
160
+ // bare uv venv has none (crashes the voice on start otherwise).
159
161
  if (m.pyVersion) venvArgs.push("--python", m.pyVersion); // uv fetches a standalone CPython
160
162
  if (!run(uv, venvArgs)) return false;
161
163
  ok = run(uv, ["pip", "install", "--python", path.join(venv, "bin", "python"), "-r", req]);
@@ -253,6 +255,8 @@ function confirm(question) {
253
255
  readline.emitKeypressEvents(process.stdin);
254
256
  process.stdin.setRawMode(true);
255
257
  process.stdin.resume();
258
+ process.stdin.ref(); // a prior picker/prompt may have unref'd stdin; without
259
+ // this the loop empties and we exit before reading a key
256
260
  const onKey = (str, key) => {
257
261
  process.stdin.off("keypress", onKey);
258
262
  process.stdin.setRawMode(false);
@@ -437,7 +441,14 @@ const BANNER = [
437
441
  ];
438
442
  function tui() {
439
443
  return new Promise((resolve) => {
440
- const rows = MODULES.map((m) => ({ m, on: platformOk(m) && ["apiary", "foundation", "factory"].includes(m.id) }));
444
+ // Pre-check what's already installed so the picker mirrors reality. On a
445
+ // fresh machine (nothing installed) fall back to the recommended starter set.
446
+ const anyInstalled = MODULES.some((m) => moduleInstalled(m));
447
+ const rows = MODULES.map((m) => ({
448
+ m,
449
+ installed: moduleInstalled(m),
450
+ on: platformOk(m) && (anyInstalled ? moduleInstalled(m) : ["apiary", "foundation", "factory"].includes(m.id)),
451
+ }));
441
452
  let cur = 0;
442
453
  const methodTag = (m) => ({ npm: "npm", shell: "shell", python: "python" }[m.method]);
443
454
  const draw = () => {
@@ -445,7 +456,7 @@ function tui() {
445
456
  readline.clearScreenDown(process.stdout);
446
457
  const out = [];
447
458
  BANNER.forEach((l) => out.push(C.gold(l)));
448
- out.push(C.dim(" the AI-agent-factory stack — pick your tools"));
459
+ out.push(C.dim(" the AI-agent-factory stack — pick your tools ") + C.green("✓ = installed"));
449
460
  out.push(C.dim(" ↑↓ move · space toggle · a all · enter install · q quit\n"));
450
461
  rows.forEach((r, i) => {
451
462
  const sel = r.on ? C.green("[x]") : "[ ]";
@@ -454,7 +465,8 @@ function tui() {
454
465
  const name = i === cur ? C.bold(r.m.id.padEnd(11)) : r.m.id.padEnd(11);
455
466
  const deps = r.m.needs.map((d) => (depOk(d) ? d : C.red(d))).join(" ");
456
467
  const platNote = okp ? C.red(" (unsupported OS)") : "";
457
- out.push(` ${cursor} ${sel} ${name} ${C.dim(methodTag(r.m).padEnd(7))} ${C.dim(r.m.blurb)}${platNote}`);
468
+ const mark = r.installed ? C.green("✓") : " ";
469
+ out.push(` ${cursor} ${sel} ${mark} ${name} ${C.dim(methodTag(r.m).padEnd(7))} ${C.dim(r.m.blurb)}${platNote}`);
458
470
  if (i === cur) out.push(` ${C.dim("needs: " + (deps || "nothing"))}${r.m.requires.length ? C.dim(" · pulls in: " + r.m.requires.join(", ")) : ""}`);
459
471
  });
460
472
  process.stdout.write(out.join("\n") + "\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gorlitzer-labs/seldon",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "Install the Seldon stack — pick your tools from a checklist; each installs via its native method.",
5
5
  "type": "module",
6
6
  "bin": {