@axiomatic-labs/claudeflow 2.13.25 → 2.13.27

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/install.js +102 -9
  2. package/package.json +1 -1
package/lib/install.js CHANGED
@@ -334,6 +334,7 @@ function ensureGlobalCli(version) {
334
334
  autoInstalled: !needsUpgrade,
335
335
  upgraded: needsUpgrade,
336
336
  fromVersion: installedVersion || undefined,
337
+ shellPath: verifyShellCanFindCli(),
337
338
  };
338
339
  }
339
340
  return {
@@ -368,6 +369,67 @@ function readGlobalCliVersion() {
368
369
  }
369
370
  }
370
371
 
372
+ // Returns { ok: boolean | null, binPath?: string, shellRcFile?: string,
373
+ // nvmDetected?: boolean, suggestedFix?: string }
374
+ //
375
+ // Distinguishes "package installed globally" from "package findable from
376
+ // the user's interactive shell". Catches the common nvm-lazy-load setup
377
+ // where `npm install -g` writes a binary the shell can't see until nvm
378
+ // is sourced — typically discovered only when the user opens a fresh
379
+ // terminal and types `claudeflow` and gets "command not found".
380
+ function verifyShellCanFindCli() {
381
+ // Skip on Windows; lazy-load + nvm-windows behave differently and the
382
+ // login-shell trick below is brittle there.
383
+ if (process.platform === 'win32') return { ok: null };
384
+
385
+ const shellPath = process.env.SHELL;
386
+ if (!shellPath || !fs.existsSync(shellPath)) return { ok: null };
387
+
388
+ // Run a non-inherited interactive login shell — that's the closest
389
+ // simulation of "user opens a new terminal" without polluting the
390
+ // current process.
391
+ let foundOnUserPath = null;
392
+ try {
393
+ const out = execSync(`${shellPath} -lic 'command -v claudeflow 2>/dev/null'`, {
394
+ encoding: 'utf8',
395
+ timeout: 6000,
396
+ stdio: ['ignore', 'pipe', 'ignore'],
397
+ }).trim();
398
+ foundOnUserPath = out.length > 0;
399
+ } catch {
400
+ // Some shells exit non-zero when `command -v` finds nothing — treat
401
+ // that as "not found" rather than as an inconclusive check.
402
+ foundOnUserPath = false;
403
+ }
404
+
405
+ if (foundOnUserPath) return { ok: true };
406
+
407
+ // Resolve where the binary actually lives so the warning is concrete.
408
+ let binPath = null;
409
+ try {
410
+ const prefix = execSync('npm config get prefix', { encoding: 'utf8', timeout: 5000 }).trim();
411
+ binPath = path.join(prefix, 'bin', 'claudeflow');
412
+ } catch {}
413
+
414
+ const home = process.env.HOME || '';
415
+ const nvmDetected = !!process.env.NVM_DIR
416
+ || fs.existsSync(path.join(home, '.nvm', 'nvm.sh'));
417
+ const isZsh = shellPath.endsWith('/zsh');
418
+ const shellRcFile = isZsh ? '~/.zshrc' : (shellPath.endsWith('/bash') ? '~/.bashrc' : '~/.profile');
419
+
420
+ // Wrapper-function fix that mirrors the user's existing nvm lazy-load
421
+ // pattern (e.g., npx, node, npm). Single line, paste into rcFile, done.
422
+ const wrapperFix = `claudeflow() { unset -f claudeflow; [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"; claudeflow "$@"; }`;
423
+
424
+ return {
425
+ ok: false,
426
+ binPath,
427
+ shellRcFile,
428
+ nvmDetected,
429
+ suggestedFix: wrapperFix,
430
+ };
431
+ }
432
+
371
433
  function showGettingStarted(cwd, cliStatus = { available: false, autoInstalled: false }) {
372
434
  const MANIFESTS = ['package.json', 'pyproject.toml', 'Gemfile', 'go.mod', 'Cargo.toml', 'composer.json'];
373
435
  const SKIP_DIRS = new Set(['node_modules', 'vendor', '__pycache__', 'dist', 'build', '.next', '.nuxt', '.output', '.claude']);
@@ -401,7 +463,27 @@ function showGettingStarted(cwd, cliStatus = { available: false, autoInstalled:
401
463
  ` ${ui.DIM}✓ Upgraded global ${ui.CYAN}claudeflow${ui.RESET}${ui.DIM} CLI${cliStatus.fromVersion ? ` from ${cliStatus.fromVersion}` : ''}.${ui.RESET}`
402
464
  );
403
465
  console.log('');
404
- } else if (!cliStatus.available) {
466
+ }
467
+
468
+ // Shell PATH warning — if the global package was installed but the
469
+ // user's interactive shell can't find the binary (typical with
470
+ // nvm lazy-load), emit a concrete fix.
471
+ if (cliStatus.shellPath && cliStatus.shellPath.ok === false) {
472
+ const sp = cliStatus.shellPath;
473
+ console.log(` ${ui.YELLOW}⚠ ${ui.BOLD}claudeflow${ui.RESET}${ui.YELLOW} CLI installed but NOT on your shell PATH.${ui.RESET}`);
474
+ if (sp.binPath) {
475
+ console.log(` ${ui.DIM}Binary lives at: ${sp.binPath}${ui.RESET}`);
476
+ }
477
+ if (sp.nvmDetected) {
478
+ console.log(` ${ui.DIM}Likely cause: nvm lazy-load. Add this to ${sp.shellRcFile}, then reopen terminal:${ui.RESET}`);
479
+ console.log(` ${ui.CYAN}${sp.suggestedFix}${ui.RESET}`);
480
+ } else {
481
+ console.log(` ${ui.DIM}Add the npm prefix bin directory to your PATH in ${sp.shellRcFile}.${ui.RESET}`);
482
+ }
483
+ console.log('');
484
+ }
485
+
486
+ if (!cliStatus.available) {
405
487
  console.log(` ${ui.DIM}To get the ${ui.CYAN}claudeflow${ui.RESET}${ui.DIM} shell command, run:${ui.RESET}`);
406
488
  console.log(` ${ui.CYAN}npm i -g @axiomatic-labs/claudeflow${ui.RESET}`);
407
489
  if (cliStatus.error && cliStatus.error !== 'skipped') {
@@ -434,14 +516,23 @@ function showGettingStarted(cwd, cliStatus = { available: false, autoInstalled:
434
516
  }
435
517
 
436
518
  console.log('');
437
- console.log(` ${ui.BOLD}Commands:${ui.RESET}`);
438
- console.log(` ${ui.CYAN}/claudeflow-install${ui.RESET} ${ui.DIM}Route setup automatically for new or existing projects${ui.RESET}`);
439
- console.log(` ${ui.CYAN}/claudeflow-build${ui.RESET} ${ui.DIM}Execute an approved spec for larger or higher-risk changes${ui.RESET}`);
440
- console.log(` ${ui.CYAN}/claudeflow-design-tokens${ui.RESET} ${ui.DIM}Create design reference from a site or screenshot${ui.RESET}`);
441
- console.log(` ${ui.CYAN}/claudeflow-create-ui${ui.RESET} ${ui.DIM}Build pages from visual references${ui.RESET}`);
442
- console.log(` ${ui.CYAN}/claudeflow-checkpoints${ui.RESET} ${ui.DIM}Auto-save work with git checkpoints${ui.RESET}`);
443
- console.log(` ${ui.CYAN}/claudeflow-add-skill${ui.RESET} ${ui.DIM}Add new technology skills (e.g. /claudeflow-add-skill stripe)${ui.RESET}`);
444
- console.log(` ${ui.CYAN}/claudeflow-add-tools${ui.RESET} ${ui.DIM}Discover and install MCP servers + CLI tools${ui.RESET}`);
519
+ console.log(` ${ui.BOLD}Slash commands (inside Claude Code):${ui.RESET}`);
520
+ console.log(` ${ui.CYAN}/claudeflow-install${ui.RESET} ${ui.DIM}Smart router scaffold a new project or update an existing one${ui.RESET}`);
521
+ console.log(` ${ui.CYAN}/claudeflow-build${ui.RESET} ${ui.DIM}Execute multi-file implementation requests with explicit verification${ui.RESET}`);
522
+ console.log(` ${ui.CYAN}/claudeflow-review${ui.RESET} ${ui.DIM}Senior review of a spec, request, or whole project${ui.RESET}`);
523
+ console.log(` ${ui.CYAN}/claudeflow-test${ui.RESET} ${ui.DIM}Run applicable test types with anti-falsification enforcement${ui.RESET}`);
524
+ console.log(` ${ui.CYAN}/claudeflow-ship${ui.RESET} ${ui.DIM}Release gate classify blockers and deploy when ready${ui.RESET}`);
525
+ console.log(` ${ui.CYAN}/claudeflow-design-init${ui.RESET} ${ui.DIM}Initialize design direction from reference sites or screenshots${ui.RESET}`);
526
+ console.log(` ${ui.CYAN}/claudeflow-prototype${ui.RESET} ${ui.DIM}Generate three UI direction prototypes via anchor-screen workflow${ui.RESET}`);
527
+ console.log(` ${ui.CYAN}/claudeflow-create-ui${ui.RESET} ${ui.DIM}Build pages or components from text, URLs, or plan files${ui.RESET}`);
528
+ console.log(` ${ui.CYAN}/claudeflow-regen-claudemd${ui.RESET} ${ui.DIM}Regenerate CLAUDE.md from the latest template + setup-context${ui.RESET}`);
529
+ console.log('');
530
+ console.log(` ${ui.BOLD}Shell commands (outside Claude Code):${ui.RESET}`);
531
+ console.log(` ${ui.CYAN}claudeflow${ui.RESET} ${ui.DIM}Start Claude Code with this project's claudeflow context${ui.RESET}`);
532
+ console.log(` ${ui.CYAN}claudeflow panel${ui.RESET} ${ui.DIM}Open the local web dashboard — toggle hooks, reminders, enforcement${ui.RESET}`);
533
+ console.log(` ${ui.CYAN}claudeflow doctor${ui.RESET} ${ui.DIM}Diagnose CDP-port and lockfile issues; ${ui.CYAN}--fix${ui.RESET}${ui.DIM} to auto-repair${ui.RESET}`);
534
+ console.log(` ${ui.CYAN}claudeflow install${ui.RESET} ${ui.DIM}Refresh the template + global CLI in this project${ui.RESET}`);
535
+ console.log(` ${ui.CYAN}claudeflow version${ui.RESET} ${ui.DIM}Show installed framework + CLI versions${ui.RESET}`);
445
536
  console.log('');
446
537
  console.log(` ${ui.DIM}Docs: https://claudeflow.dev${ui.RESET}`);
447
538
  console.log('');
@@ -1107,4 +1198,6 @@ module.exports = Object.assign(run, {
1107
1198
  mergeClaudeSettings,
1108
1199
  commandExists,
1109
1200
  readGlobalCliVersion,
1201
+ verifyShellCanFindCli,
1202
+ showGettingStarted,
1110
1203
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiomatic-labs/claudeflow",
3
- "version": "2.13.25",
3
+ "version": "2.13.27",
4
4
  "description": "Claudeflow — AI-powered development toolkit for Claude Code. Skills, agents, hooks, and quality gates that ship production apps.",
5
5
  "bin": {
6
6
  "claudeflow": "./bin/cli.js"