@gorlitzer-labs/seldon 0.1.1 → 0.1.2

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/README.md CHANGED
@@ -49,6 +49,13 @@ It's a stack, not a bundle — install only what you use:
49
49
  - **A team of agents** → add **apiary** (shared rooms) + **factory** (the supervisor).
50
50
  - **Across machines / from your phone** → add **bifrost**.
51
51
 
52
+ ## Package managers
53
+
54
+ Node tools install via **pnpm** or **bun** if present (much faster than npm), else npm —
55
+ override with `seldon install --pm=pnpm|bun|npm`. demerzel (Python) always installs into
56
+ its **own isolated venv** — never your system/active Python — using **uv** if available,
57
+ else `python3 -m venv` + pip.
58
+
52
59
  ## From a checkout
53
60
 
54
61
  ```bash
package/bin/seldon.js CHANGED
@@ -52,14 +52,31 @@ function run(cmd, args, opts = {}) {
52
52
  return r.status === 0;
53
53
  }
54
54
 
55
+ // Is a command on PATH? (used to pick the fastest package manager)
56
+ const has = (bin) => { try { execSync(`command -v ${bin}`, { stdio: "ignore" }); return true; } catch { return false; } };
57
+
58
+ // Pick the node package manager: --pm=<x> override, else the fastest present.
59
+ // pnpm/bun install globally far faster than npm; npm is the universal fallback.
60
+ function nodePM() {
61
+ const ov = (process.argv.find((a) => a.startsWith("--pm=")) || "").split("=")[1];
62
+ if (ov) return ov;
63
+ if (has("pnpm")) return "pnpm";
64
+ if (has("bun")) return "bun";
65
+ return "npm";
66
+ }
67
+
55
68
  function installNpm(m, dev) {
69
+ const pm = nodePM();
56
70
  if (dev && IN_CHECKOUT) {
57
71
  const dir = path.join(REPO_ROOT, m.dir);
58
72
  const pj = JSON.parse(fs.readFileSync(path.join(dir, "package.json")));
59
- if (pj.scripts?.build) run("npm", ["--prefix", dir, "run", "build"]);
60
- return run("npm", ["link"], { cwd: dir });
73
+ if (pj.scripts?.build) run(pm, ["run", "build"], { cwd: dir });
74
+ const link = pm === "pnpm" ? ["link", "--global"] : ["link"]; // bun/npm: `link`
75
+ return run(pm, link, { cwd: dir });
61
76
  }
62
- return run("npm", ["install", "-g", m.pkg]);
77
+ // pnpm/bun: `add -g` · npm: `install -g` — a global CLI, no project touched
78
+ const add = pm === "npm" ? ["install", "-g", m.pkg] : ["add", "-g", m.pkg];
79
+ return run(pm, add);
63
80
  }
64
81
 
65
82
  function installShell(m, dev) {
@@ -86,10 +103,21 @@ function installPython(m, dev) {
86
103
  fs.rmSync(dest + ".tmp", { recursive: true, force: true });
87
104
  }
88
105
  }
106
+ // Always a DEDICATED venv under the module dir — we never install into the
107
+ // user's system/global/active Python. uv (if present) is faster and can even
108
+ // fetch its own CPython, so it doesn't touch their interpreter at all; plain
109
+ // venv+pip is the isolated fallback. No `--system`, no active-env writes.
89
110
  const venv = path.join(dest, ".venv");
90
- run("python3", ["-m", "venv", venv]);
91
- const ok = run(path.join(venv, "bin", "pip"), ["install", "-r", path.join(dest, "requirements.txt")]);
92
- if (ok) console.log(C.dim(` run it: ${path.join(dest, m.bin)} (venv at ${venv})`));
111
+ const req = path.join(dest, "requirements.txt");
112
+ let ok;
113
+ if (has("uv")) {
114
+ if (!run("uv", ["venv", venv])) return false;
115
+ ok = run("uv", ["pip", "install", "--python", path.join(venv, "bin", "python"), "-r", req]);
116
+ } else {
117
+ run("python3", ["-m", "venv", venv]);
118
+ ok = run(path.join(venv, "bin", "pip"), ["install", "-r", req]);
119
+ }
120
+ if (ok) console.log(C.dim(` run it: ${path.join(dest, m.bin)} (isolated venv at ${venv})`));
93
121
  return ok;
94
122
  }
95
123
 
@@ -138,7 +166,7 @@ function tui() {
138
166
  const sel = r.on ? C.green("[x]") : "[ ]";
139
167
  const cursor = i === cur ? C.gold("❯") : " ";
140
168
  const okp = !platformOk(r.m);
141
- const name = (i === cur ? C.bold(r.m.id) : r.m.id).padEnd(11);
169
+ const name = i === cur ? C.bold(r.m.id.padEnd(11)) : r.m.id.padEnd(11);
142
170
  const deps = r.m.needs.map((d) => (depOk(d) ? d : C.red(d))).join(" ");
143
171
  const platNote = okp ? C.red(" (unsupported OS)") : "";
144
172
  out.push(` ${cursor} ${sel} ${name} ${C.dim(methodTag(r.m).padEnd(7))} ${C.dim(r.m.blurb)}${platNote}`);
@@ -186,6 +214,11 @@ ${C.bold("seldon")} — install the Seldon stack, pick what you use.
186
214
  ${C.bold("seldon doctor")} [ids…] check external deps (tmux, sops, age, tailscale, python…)
187
215
  ${C.bold("seldon list")} list the modules
188
216
  ${C.bold("seldon --dev")} link node modules from this checkout instead of npm
217
+ ${C.bold("seldon install --pm=pnpm")} force the node package manager (pnpm|bun|npm; auto-detected)
218
+
219
+ ${C.dim("node tools install via pnpm/bun if present (faster), else npm.")}
220
+ ${C.dim("python (demerzel) installs into its own isolated venv — never your system Python;")}
221
+ ${C.dim("uses uv if present, else python3 -m venv + pip.")}
189
222
 
190
223
  modules: ${MODULES.map((m) => m.id).join(", ")}
191
224
  `);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gorlitzer-labs/seldon",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
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": {