@souhengai/naxos 2.8.1 → 2.9.0

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/lib/postinstall.js +102 -31
  2. package/package.json +1 -1
@@ -106,52 +106,123 @@ function download(url, dest) {
106
106
  }
107
107
 
108
108
  /**
109
- * Check if npm's global bin directory is in PATH.
110
- * If not, warn the user with exact instructions for their platform.
109
+ * Get npm's global bin directory (where `naxos.cmd` / `naxos` shim is installed).
111
110
  */
112
- function checkPath() {
113
- let npmBin;
111
+ function getNpmBinDir() {
114
112
  try {
115
- npmBin = execSync("npm bin -g", { encoding: "utf-8" }).trim();
113
+ const prefix = execSync("npm config get prefix", { encoding: "utf-8" }).trim();
114
+ return process.platform === "win32" ? prefix : join(prefix, "bin");
116
115
  } catch {
116
+ return null;
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Check if a directory is in the runtime PATH.
122
+ */
123
+ function isDirInRuntimePath(dir) {
124
+ const pathSep = process.platform === "win32" ? ";" : ":";
125
+ const pathParts = (process.env.PATH || "")
126
+ .split(pathSep)
127
+ .map(p => p.toLowerCase().replace(/[\\\/]+$/, ""));
128
+ const needle = dir.toLowerCase().replace(/[\\\/]+$/, "");
129
+ return pathParts.includes(needle);
130
+ }
131
+
132
+ /**
133
+ * Add directory to the user's PATH on Windows via PowerShell.
134
+ * Uses User-level env var — no admin required.
135
+ * Returns true on success.
136
+ */
137
+ function addToUserPathWindows(dir) {
138
+ const { spawnSync } = require("child_process");
139
+ const script = `
140
+ $dir = '${dir.replace(/'/g, "''")}'
141
+ $userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
142
+ if ($null -eq $userPath) { $userPath = '' }
143
+ $parts = $userPath -split ';' | Where-Object { $_ -ne '' }
144
+ $alreadyIn = $false
145
+ foreach ($p in $parts) {
146
+ if ($p.TrimEnd('\\') -ieq $dir.TrimEnd('\\')) { $alreadyIn = $true; break }
147
+ }
148
+ if (-not $alreadyIn) {
149
+ if ($userPath -eq '') { $newPath = $dir } else { $newPath = "$userPath;$dir" }
150
+ [Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
151
+ Write-Output 'ADDED'
152
+ } else {
153
+ Write-Output 'EXISTS'
154
+ }
155
+ `;
156
+ const result = spawnSync("powershell.exe",
157
+ ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", script],
158
+ { encoding: "utf-8", timeout: 10000 }
159
+ );
160
+ if (result.error || result.status !== 0) return false;
161
+ return true;
162
+ }
163
+
164
+ /**
165
+ * Add the export line to shell rc files on Unix if not already present.
166
+ */
167
+ function addToUserPathUnix(dir) {
168
+ const { readFileSync, appendFileSync } = require("fs");
169
+ const { homedir } = require("os");
170
+
171
+ const candidates = [
172
+ join(homedir(), ".bashrc"),
173
+ join(homedir(), ".zshrc"),
174
+ join(homedir(), ".profile"),
175
+ ];
176
+
177
+ const exportLine = `\n# Added by @souhengai/naxos\nexport PATH="$PATH:${dir}"\n`;
178
+ const marker = `# Added by @souhengai/naxos`;
179
+ let modified = false;
180
+
181
+ for (const rc of candidates) {
182
+ if (!existsSync(rc)) continue;
117
183
  try {
118
- // Fallback: compute from npm prefix
119
- const prefix = execSync("npm config get prefix", { encoding: "utf-8" }).trim();
120
- npmBin = process.platform === "win32" ? prefix : join(prefix, "bin");
184
+ const content = readFileSync(rc, "utf-8");
185
+ if (content.includes(marker) || content.includes(dir)) continue;
186
+ appendFileSync(rc, exportLine);
187
+ modified = true;
121
188
  } catch {
122
- return; // Can't determine — skip check
189
+ // Skip unreadable
123
190
  }
124
191
  }
192
+ return modified;
193
+ }
125
194
 
126
- const pathSep = process.platform === "win32" ? ";" : ":";
127
- const pathParts = (process.env.PATH || "").split(pathSep).map(p => p.toLowerCase().replace(/\\$/, "").replace(/\/$/, ""));
128
- const needle = npmBin.toLowerCase().replace(/\\$/, "").replace(/\/$/, "");
195
+ /**
196
+ * Check PATH and auto-fix on supported platforms.
197
+ */
198
+ function checkPath() {
199
+ const npmBin = getNpmBinDir();
200
+ if (!npmBin) return;
129
201
 
130
- if (pathParts.includes(needle)) {
131
- return; // npm bin is in PATH — all good
132
- }
202
+ if (isDirInRuntimePath(npmBin)) return; // already good
133
203
 
134
- // Not in PATH — print warning
135
- console.log(" \x1b[33m⚠\x1b[0m npm's global bin directory is not in your PATH:");
136
- console.log("");
204
+ console.log(" \x1b[33m⚠\x1b[0m npm's global bin is not in PATH — fixing automatically...");
137
205
  console.log(" " + npmBin);
138
206
  console.log("");
139
207
 
140
208
  if (process.platform === "win32") {
141
- console.log(" \x1b[1mTo fix on Windows:\x1b[0m");
142
- console.log("");
143
- console.log(" 1. Open \x1b[36mSystem Properties Environment Variables\x1b[0m");
144
- console.log(" 2. Edit \x1b[36mPath\x1b[0m under 'User variables'");
145
- console.log(" 3. Click 'New' and add: \x1b[36m" + npmBin + "\x1b[0m");
146
- console.log(" 4. Click OK and \x1b[1mopen a NEW terminal window\x1b[0m");
147
- console.log("");
148
- console.log(" \x1b[2mOr run this in PowerShell (restart terminal after):\x1b[0m");
149
- console.log(" \x1b[36msetx PATH \"$env:PATH;" + npmBin + "\"\x1b[0m");
209
+ if (addToUserPathWindows(npmBin)) {
210
+ console.log(" \x1b[32m✓\x1b[0m Added to User PATH.");
211
+ console.log(" \x1b[1mIMPORTANT: Open a NEW terminal window\x1b[0m (PATH changes don't affect running terminals).");
212
+ } else {
213
+ console.log(" \x1b[31m✗\x1b[0m Could not update PATH automatically. Manual fix:");
214
+ console.log(" 1. Open System Properties Environment Variables User PATH");
215
+ console.log(" 2. Add: \x1b[36m" + npmBin + "\x1b[0m");
216
+ console.log(" 3. Open a NEW terminal");
217
+ }
150
218
  } else {
151
- console.log(" \x1b[1mTo fix:\x1b[0m add this to your ~/.bashrc or ~/.zshrc:");
152
- console.log(" \x1b[36mexport PATH=\"$PATH:" + npmBin + "\"\x1b[0m");
153
- console.log("");
154
- console.log(" Then restart your terminal or run: \x1b[36msource ~/.bashrc\x1b[0m");
219
+ if (addToUserPathUnix(npmBin)) {
220
+ console.log(" \x1b[32m✓\x1b[0m Added to ~/.bashrc and ~/.zshrc (where they exist).");
221
+ console.log(" \x1b[1mRun:\x1b[0m \x1b[36msource ~/.bashrc\x1b[0m \x1b[2m(or open a new terminal)\x1b[0m");
222
+ } else {
223
+ console.log(" Add this to your shell rc file:");
224
+ console.log(" \x1b[36mexport PATH=\"$PATH:" + npmBin + "\"\x1b[0m");
225
+ }
155
226
  }
156
227
  console.log("");
157
228
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@souhengai/naxos",
3
- "version": "2.8.1",
3
+ "version": "2.9.0",
4
4
  "description": "Naxos — SouhengAI Autonomous Coding Agent",
5
5
  "bin": {
6
6
  "naxos": "bin/cli.js"