droid 0.72.0 → 0.74.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 (3) hide show
  1. package/README.md +24 -0
  2. package/install.js +124 -4
  3. package/package.json +10 -10
package/README.md CHANGED
@@ -8,6 +8,30 @@
8
8
  npm install -g droid
9
9
  ```
10
10
 
11
+ If the `droid` command is not found after installing, your npm global bin directory may not be in your PATH. Run the following to fix it:
12
+
13
+ ```bash
14
+ # For zsh (macOS default)
15
+ echo 'export PATH="$(npm prefix -g)/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc
16
+
17
+ # For bash (Linux)
18
+ echo 'export PATH="$(npm prefix -g)/bin:$PATH"' >> ~/.bashrc && source ~/.bashrc
19
+
20
+ # For bash (macOS)
21
+ echo 'export PATH="$(npm prefix -g)/bin:$PATH"' >> ~/.bash_profile && source ~/.bash_profile
22
+
23
+ # For fish
24
+ echo 'fish_add_path "$(npm prefix -g)/bin"' >> ~/.config/fish/config.fish && source ~/.config/fish/config.fish
25
+ ```
26
+
27
+ On Windows, run in PowerShell:
28
+
29
+ ```powershell
30
+ [Environment]::SetEnvironmentVariable('Path', $env:PATH + ';' + (npm prefix -g), 'User')
31
+ ```
32
+
33
+ Then restart your terminal.
34
+
11
35
  Then navigate to your project and start the droid CLI:
12
36
 
13
37
  ```bash
package/install.js CHANGED
@@ -221,6 +221,122 @@ function extractFileFromTarball(tarballBuffer, filepath) {
221
221
  return null;
222
222
  }
223
223
 
224
+ /**
225
+ * Check if this is a global npm install by looking at the npm_config_global
226
+ * environment variable that npm sets during installation.
227
+ */
228
+ function isGlobalInstall() {
229
+ return (
230
+ process.env.npm_config_global === 'true' ||
231
+ process.env.npm_config_global === ''
232
+ );
233
+ }
234
+
235
+ /**
236
+ * Detect the npm global bin directory.
237
+ * Uses `npm prefix -g` and appends /bin on POSIX (Windows puts binaries
238
+ * directly in the prefix directory).
239
+ */
240
+ function getNpmGlobalBinDir() {
241
+ try {
242
+ const prefix = child_process
243
+ .execSync('npm prefix -g', { encoding: 'utf8', timeout: 10000 })
244
+ .trim();
245
+ if (!prefix) return null;
246
+ return process.platform === 'win32' ? prefix : path.join(prefix, 'bin');
247
+ } catch (e) {
248
+ return null;
249
+ }
250
+ }
251
+
252
+ /**
253
+ * Check if a directory is already present in the current PATH.
254
+ * Uses path.resolve() to normalize slashes and handles case-insensitive
255
+ * comparison on Windows.
256
+ */
257
+ function isDirInPath(dir) {
258
+ const envPath = process.env.PATH || '';
259
+ const sep = process.platform === 'win32' ? ';' : ':';
260
+ const normalize = (d) => path.resolve(d);
261
+ const normalizedDir = normalize(dir);
262
+ const dirs = envPath.split(sep).map(normalize);
263
+ if (process.platform === 'win32') {
264
+ return dirs.some((d) => d.toLowerCase() === normalizedDir.toLowerCase());
265
+ }
266
+ return dirs.includes(normalizedDir);
267
+ }
268
+
269
+ /**
270
+ * Detect the user's shell and suggest the appropriate profile file.
271
+ */
272
+ function getShellProfileHint() {
273
+ const shell = process.env.SHELL || '';
274
+ const shellName = path.basename(shell);
275
+ if (shellName === 'zsh') return '~/.zshrc';
276
+ if (shellName === 'bash') {
277
+ return process.platform === 'darwin' ? '~/.bash_profile' : '~/.bashrc';
278
+ }
279
+ if (shellName === 'fish') return '~/.config/fish/config.fish';
280
+ return null;
281
+ }
282
+
283
+ /**
284
+ * Print a warning if the npm global bin directory is not in the user's PATH.
285
+ * Only runs for global installs. Does NOT modify any files.
286
+ */
287
+ function warnIfNotInPath() {
288
+ try {
289
+ if (process.env.CI || process.env.CONTINUOUS_INTEGRATION) return;
290
+ if (!isGlobalInstall()) return;
291
+
292
+ const binDir = getNpmGlobalBinDir();
293
+ if (!binDir) return;
294
+ if (isDirInPath(binDir)) return;
295
+
296
+ const profileHint = getShellProfileHint();
297
+
298
+ if (process.platform === 'win32') {
299
+ console.log(
300
+ '\n' +
301
+ 'Note: The "droid" command may not be available in your terminal.\n' +
302
+ `The npm global bin directory is not in your PATH:\n` +
303
+ ` ${binDir}\n\n` +
304
+ 'To fix for this session, run:\n' +
305
+ ` set PATH=%PATH%;${binDir}\n\n` +
306
+ 'To fix permanently (PowerShell):\n' +
307
+ ` [Environment]::SetEnvironmentVariable('Path', $env:PATH + ';${binDir}', 'User')\n\n` +
308
+ 'Then restart your terminal.\n'
309
+ );
310
+ } else if (profileHint) {
311
+ const exportLine =
312
+ profileHint === '~/.config/fish/config.fish'
313
+ ? `fish_add_path "${binDir}"`
314
+ : `export PATH="${binDir}:$PATH"`;
315
+
316
+ console.log(
317
+ '\n' +
318
+ 'Note: The "droid" command may not be available in your terminal.\n' +
319
+ `The npm global bin directory is not in your PATH:\n` +
320
+ ` ${binDir}\n\n` +
321
+ `To fix, run:\n` +
322
+ ` echo '${exportLine}' >> ${profileHint} && source ${profileHint}\n`
323
+ );
324
+ } else {
325
+ console.log(
326
+ '\n' +
327
+ 'Note: The "droid" command may not be available in your terminal.\n' +
328
+ `The npm global bin directory is not in your PATH:\n` +
329
+ ` ${binDir}\n\n` +
330
+ 'To fix, add the following to your shell profile (~/.bashrc, ~/.zshrc, etc.):\n' +
331
+ ` export PATH="${binDir}:$PATH"\n\n` +
332
+ 'Then restart your terminal.\n'
333
+ );
334
+ }
335
+ } catch (e) {
336
+ // PATH check is best-effort; never fail the install
337
+ }
338
+ }
339
+
224
340
  async function main() {
225
341
  const shimPath = path.join(__dirname, 'bin', 'droid');
226
342
  let binaryPath = getBinaryPath();
@@ -308,7 +424,11 @@ async function main() {
308
424
  }
309
425
  }
310
426
 
311
- main().catch((e) => {
312
- console.error('postinstall error:', e.message);
313
- // Don't fail the install - the JS shim will still work
314
- });
427
+ main()
428
+ .then(() => {
429
+ warnIfNotInPath();
430
+ })
431
+ .catch((e) => {
432
+ console.error('postinstall error:', e.message);
433
+ // Don't fail the install - the JS shim will still work
434
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "droid",
3
- "version": "0.72.0",
3
+ "version": "0.74.0",
4
4
  "description": "Factory Droid CLI - AI-powered software engineering agent",
5
5
  "bin": {
6
6
  "droid": "bin/droid"
@@ -16,15 +16,15 @@
16
16
  "postinstall": "node install.js"
17
17
  },
18
18
  "optionalDependencies": {
19
- "@factory/cli-darwin-arm64": "0.72.0",
20
- "@factory/cli-darwin-x64": "0.72.0",
21
- "@factory/cli-darwin-x64-baseline": "0.72.0",
22
- "@factory/cli-linux-arm64": "0.72.0",
23
- "@factory/cli-linux-x64": "0.72.0",
24
- "@factory/cli-linux-x64-baseline": "0.72.0",
25
- "@factory/cli-win32-x64": "0.72.0",
26
- "@factory/cli-win32-x64-baseline": "0.72.0",
27
- "@factory/cli-win32-arm64": "0.72.0"
19
+ "@factory/cli-darwin-arm64": "0.74.0",
20
+ "@factory/cli-darwin-x64": "0.74.0",
21
+ "@factory/cli-darwin-x64-baseline": "0.74.0",
22
+ "@factory/cli-linux-arm64": "0.74.0",
23
+ "@factory/cli-linux-x64": "0.74.0",
24
+ "@factory/cli-linux-x64-baseline": "0.74.0",
25
+ "@factory/cli-win32-x64": "0.74.0",
26
+ "@factory/cli-win32-x64-baseline": "0.74.0",
27
+ "@factory/cli-win32-arm64": "0.74.0"
28
28
  },
29
29
  "engines": {
30
30
  "node": ">=20.0.0"