nunmai 0.1.0 → 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
@@ -14,9 +14,15 @@ directories — your system toolchain is never modified. Then `nunmai` starts th
14
14
  engine; the first run opens the AI-account wizard (Claude, ChatGPT, Kimi,
15
15
  Gemini, OpenRouter).
16
16
 
17
- - macOS, Linux, Windows 10/11 (PowerShell), Android (Termux). `npx nunmai` works too.
18
- - If npm ran with `--ignore-scripts` (or `CI` is set), the install happens on the
19
- first `nunmai` run instead.
17
+ - macOS, Linux, Windows 10/11 (PowerShell), Android (Termux).
18
+ - **Local install** (`npm install nunmai`, no `-g`): run it with `npx nunmai`.
19
+ npm 11.19 blocks dependency install scripts by default, so the engine is
20
+ installed on the first `npx nunmai` run. To get a plain `nunmai` command from
21
+ a local install, allow the script: `npm install nunmai --allow-scripts=nunmai`.
22
+ - If npm skipped the install script (`--ignore-scripts`, `CI` set, or the
23
+ allow-scripts policy above), the install simply happens on the first run.
24
+ - After `nunmai uninstall`, the `nunmai` command falls back to this launcher —
25
+ running `nunmai` again reinstalls the engine.
20
26
  - Lightweight install (no browser/computer-use): `NUNMAI_INSTALL_LITE=1 npm i -g nunmai`.
21
27
  - Extra installer flags: `NUNMAI_INSTALL_ARGS="--branch dev" npm i -g nunmai`.
22
28
  - Updates: `nunmai update`. Remove: `nunmai uninstall`, then `npm uninstall -g nunmai`.
package/bin/nunmai.js CHANGED
@@ -6,10 +6,12 @@
6
6
  * Nunmai Engine is a Python application (managed by uv), so this package is a
7
7
  * small launcher around the official installer (https://nunmai-engine.nunmai.in):
8
8
  *
9
- * npm install -g nunmai -> postinstall runs the FULL, non-interactive install
9
+ * npm install nunmai -> (with or without -g) postinstall runs the FULL, non-interactive install
10
10
  * (engine, Python, git, Node, browser + computer-use
11
11
  * tools). Nothing on the system is modified — every
12
12
  * dependency is provisioned into Nunmai's own dirs.
13
+ * A `nunmai` command is always left on PATH
14
+ * (~/.local/bin), even for local, non -g installs.
13
15
  * nunmai -> launches the installed engine (first run opens the
14
16
  * AI-account wizard). If the engine is missing (e.g.
15
17
  * npm ran with --ignore-scripts), it installs first.
@@ -57,8 +59,49 @@ function findLauncher() {
57
59
  return null;
58
60
  }
59
61
 
62
+ function ensureFallbackLauncher() {
63
+ // Local installs (`npm install nunmai` without -g) leave the bin shim in
64
+ // ./node_modules/.bin, which is not on PATH. Make sure `nunmai` resolves
65
+ // anyway by linking this shim into ~/.local/bin (or $PREFIX/bin on Termux).
66
+ // The real installer replaces the link with the engine launcher (ln -sf).
67
+ if (IS_WIN) return null;
68
+ const binDir = process.env.PREFIX && fs.existsSync(path.join(process.env.PREFIX, "bin"))
69
+ ? path.join(process.env.PREFIX, "bin")
70
+ : path.join(os.homedir(), ".local", "bin");
71
+ const target = path.join(binDir, "nunmai");
72
+ try {
73
+ fs.mkdirSync(binDir, { recursive: true });
74
+ try { if (fs.realpathSync(target) === SELF) return target; } catch (_) { /* absent or dangling */ }
75
+ try { fs.unlinkSync(target); } catch (_) { /* nothing to remove */ }
76
+ fs.symlinkSync(SELF, target);
77
+ fs.chmodSync(SELF, 0o755);
78
+ ensurePathLine(binDir);
79
+ return target;
80
+ } catch (e) {
81
+ console.error(`nunmai: could not link launcher into ${binDir}: ${e.message}`);
82
+ return null;
83
+ }
84
+ }
85
+
86
+ function ensurePathLine(binDir) {
87
+ // Add ~/.local/bin to PATH in the user's shell rc if it is not there already.
88
+ if (binDir !== path.join(os.homedir(), ".local", "bin")) return;
89
+ const onPath = (process.env.PATH || "").split(path.delimiter).includes(binDir);
90
+ if (onPath) return;
91
+ const shell = path.basename(process.env.SHELL || "");
92
+ const rc = shell === "zsh" ? ".zshrc" : shell === "fish" ? null : ".bashrc";
93
+ if (!rc) return;
94
+ const rcPath = path.join(os.homedir(), rc);
95
+ try {
96
+ const cur = fs.existsSync(rcPath) ? fs.readFileSync(rcPath, "utf8") : "";
97
+ if (cur.includes(".local/bin")) return;
98
+ fs.appendFileSync(rcPath, '\n# Nunmai Engine — ensure ~/.local/bin is on PATH\nexport PATH="$HOME/.local/bin:$PATH"\n');
99
+ console.log(`nunmai: added ~/.local/bin to PATH in ~/${rc} (open a new terminal).`);
100
+ } catch (_) { /* best effort */ }
101
+ }
102
+
60
103
  function run(cmd, args, opts) {
61
- const env = Object.assign({}, process.env, { NUNMAI_NPM_SHIM: "1" });
104
+ const env = Object.assign({}, process.env, { NUNMAI_NPM_SHIM: "1", NUNMAI_NPM_SHIM_PATH: SELF });
62
105
  const r = spawnSync(cmd, args, Object.assign({ stdio: "inherit", env }, opts || {}));
63
106
  if (r.error) {
64
107
  console.error(`nunmai: could not start ${cmd}: ${r.error.message}`);
@@ -106,6 +149,7 @@ function postinstall() {
106
149
  // Runs from `npm install -g nunmai`. Must never fail the npm install: on any
107
150
  // problem we exit 0 and the first `nunmai` run retries interactively.
108
151
  if (process.env.NUNMAI_NPM_NO_POSTINSTALL === "1" || process.env.CI) {
152
+ if (!findLauncher()) ensureFallbackLauncher();
109
153
  console.log("nunmai: engine install deferred to first run.");
110
154
  return 0;
111
155
  }
@@ -115,9 +159,11 @@ function postinstall() {
115
159
  }
116
160
  const code = install(true);
117
161
  if (code !== 0) {
162
+ ensureFallbackLauncher();
118
163
  console.error(`\nnunmai: installer exited with code ${code}. Run \`nunmai\` to retry, or install manually:\n${manualHint()}`);
119
164
  return 0;
120
165
  }
166
+ if (!DRY && !findLauncher()) ensureFallbackLauncher();
121
167
  console.log("\n✓ Nunmai Engine installed. Open a new terminal and run: nunmai");
122
168
  return 0;
123
169
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nunmai",
3
- "version": "0.1.0",
4
- "description": "Nunmai Engine — `npm i -g nunmai` installs the engine with all features and dependencies; run `nunmai` to start.",
3
+ "version": "0.1.2",
4
+ "description": "Nunmai Engine — `npm i nunmai` (global or local) installs the engine with all features and dependencies; run `nunmai` to start.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://nunmai.in",
7
7
  "repository": {