nunmai 0.1.0 → 0.1.1

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/nunmai.js +48 -2
  2. package/package.json +2 -2
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.1",
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": {