@claude-flow/cli 3.27.0 → 3.27.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.
@@ -1 +1 @@
1
- 3.25.6
1
+ 3.23.0
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "manifest": {
3
- "version": "3.27.0",
3
+ "version": "3.27.1",
4
4
  "files": {
5
5
  "auto-memory-hook.mjs": "68be7e9a9eba7bf9c4e8a230db7bf61a243b965639f8504842799d6c6ca28762",
6
- "hook-handler.cjs": "2a18a761f0dc4839df8b6eeadf8f0ceb6badcc5bf14414c91555711a5e9d4bdc",
6
+ "hook-handler.cjs": "2e4927ff158c0079a67a6f0ef0b99ac748d600d33798b0a5fbd5a6a82225ec03",
7
7
  "intelligence.cjs": "bd1f8e4b034944aee1df0391dc47ac2e8cc4b3aa542c65407a59d49620bbf76b",
8
- "statusline.cjs": "8abc67b7512e66fe5f8fe6cc5f099f827de6f7e2023a493f920090248d326e01"
8
+ "statusline.cjs": "44882bcda49ff6dc1d3738e25b6ec23e07bdc0177321b8cd15dd966ff1c7090f"
9
9
  }
10
10
  },
11
- "signature": "f0oa4b6TIdjXxPc8TFjFEXODgr4+gNsdQXc54NszbvhpR066pXyaCgxrYTsN9iRwFFY1dp6RtaUCuaMpN4NqDg==",
11
+ "signature": "roS3Sgyq3yDDiQvm0pyB3ZzdGMUoQnRYJjFdbTSW5HZqPRirjf72qgkzQu+Yw+fNfVBrS9ljS/kWpnJKt/6DAw==",
12
12
  "algorithm": "ed25519"
13
13
  }
@@ -23,6 +23,18 @@ const helpersDir = __dirname;
23
23
  // statusline-generator.ts's resolveCliBin() candidate list. Used only to
24
24
  // spawn the detached funnel-refresh helper below; failures are silent (no
25
25
  // candidate found just means the refresh never fires this session).
26
+ //
27
+ // Verifies dist/src/index.js exists alongside bin/cli.js, not just the bin
28
+ // itself — Claude Code's own plugin marketplace mechanism installs by
29
+ // `git clone`/`git pull` with no build step, so `~/.claude/plugins/
30
+ // marketplaces/ruflo` is a SOURCE-ONLY checkout by construction: bin/cli.js
31
+ // is present on disk but importing dist/src/index.js throws
32
+ // ERR_MODULE_NOT_FOUND on every real command (confirmed live — only
33
+ // `--version` happens to survive it, since it reads package.json directly).
34
+ // Without this check, resolveCliBinForHook() picked that doomed candidate
35
+ // first every time and spawnDetachedFunnelRefresh() below had no fallback,
36
+ // so the promo/disclosure row could never populate for any marketplace
37
+ // install, on any OS.
26
38
  function resolveCliBinForHook() {
27
39
  try {
28
40
  const home = os.homedir();
@@ -38,7 +50,11 @@ function resolveCliBinForHook() {
38
50
  path.join(helpersDir, '..', '..', 'bin', 'cli.js'),
39
51
  ];
40
52
  for (const p of candidates) {
41
- if (fs.existsSync(p)) return p;
53
+ try {
54
+ if (fs.existsSync(p) && fs.existsSync(path.join(path.dirname(p), '..', 'dist', 'src', 'index.js'))) {
55
+ return p;
56
+ }
57
+ } catch (e) { /* try next candidate */ }
42
58
  }
43
59
  } catch (e) { /* ignore */ }
44
60
  return null;
@@ -54,12 +70,22 @@ function resolveCliBinForHook() {
54
70
  // session-restore's own process has already exited, so it actually gets a
55
71
  // chance to write the cache. Never awaited here — must not add to
56
72
  // SessionStart's own timeout budget.
57
- function spawnDetachedFunnelRefresh() {
73
+ //
74
+ // No usable local candidate (resolveCliBinForHook() returned null) falls
75
+ // back to npx: this call is detached/unref'd, so a slower npx cold-start
76
+ // costs nothing perceptible — unlike the statusline's own synchronous
77
+ // render path, where local-first exists purely for per-render latency.
78
+ // `--prefer-offline` avoids a registry round trip for the tarball when
79
+ // already cached while still resolving the current `@latest` version.
80
+ function spawnDetachedHookRefresh(subcommand) {
58
81
  try {
59
- const cliBin = resolveCliBinForHook();
60
- if (!cliBin) return;
61
82
  const { spawn } = require('child_process');
62
- const child = spawn(process.execPath, [cliBin, 'hooks', 'refresh-funnel', '--quiet'], {
83
+ const cliBin = resolveCliBinForHook();
84
+ const cmd = process.platform === 'win32' ? 'npx.cmd' : 'npx';
85
+ const spawnArgs = cliBin
86
+ ? [process.execPath, [cliBin, 'hooks', subcommand, '--quiet']]
87
+ : [cmd, ['--prefer-offline', '@claude-flow/cli', 'hooks', subcommand, '--quiet']];
88
+ const child = spawn(spawnArgs[0], spawnArgs[1], {
63
89
  detached: true,
64
90
  stdio: 'ignore',
65
91
  env: process.env,
@@ -68,24 +94,18 @@ function spawnDetachedFunnelRefresh() {
68
94
  } catch (e) { /* best-effort only */ }
69
95
  }
70
96
 
71
- // Same detached/unref'd pattern as spawnDetachedFunnelRefresh() above, for
97
+ function spawnDetachedFunnelRefresh() {
98
+ spawnDetachedHookRefresh('refresh-funnel');
99
+ }
100
+
101
+ // Same fallback-aware pattern as spawnDetachedFunnelRefresh() above, for
72
102
  // ADR-316's co-pilot advisor tip. Safe to call on EVERY session-restore:
73
103
  // refresh-advisor's own action checks consent + a 24h TTL BEFORE spending
74
104
  // anything, so an unconsented or already-fresh install is a fast no-op file
75
105
  // read, never a network call. Never awaited here — must not add to
76
106
  // SessionStart's own timeout budget.
77
107
  function spawnDetachedAdvisorRefresh() {
78
- try {
79
- const cliBin = resolveCliBinForHook();
80
- if (!cliBin) return;
81
- const { spawn } = require('child_process');
82
- const child = spawn(process.execPath, [cliBin, 'hooks', 'refresh-advisor', '--quiet'], {
83
- detached: true,
84
- stdio: 'ignore',
85
- env: process.env,
86
- });
87
- child.unref();
88
- } catch (e) { /* best-effort only */ }
108
+ spawnDetachedHookRefresh('refresh-advisor');
89
109
  }
90
110
 
91
111
  // Safe require with stdout suppression - the helper modules have CLI
@@ -116,7 +116,20 @@ function resolveCliBinCandidates() {
116
116
  }
117
117
  } catch { /* ignore */ }
118
118
  } catch { /* ignore */ }
119
- return candidates.filter((p) => { try { return fs.existsSync(p); } catch { return false; } });
119
+ return candidates.filter((p) => {
120
+ try {
121
+ if (!fs.existsSync(p)) return false;
122
+ // A candidate's bin/cli.js can exist on disk while its compiled
123
+ // dist/ never got built (Claude Code's own plugin marketplace just
124
+ // git-clones the repo — no install/build step — so every marketplace
125
+ // install is a source-only checkout by construction). Importing
126
+ // dist/src/index.js from bin/cli.js then throws MODULE_NOT_FOUND on
127
+ // every real command; only --version happens to survive it. Check
128
+ // for the compiled entrypoint too so a doomed candidate is skipped
129
+ // up front instead of wasting a spawn-and-fail on every render.
130
+ return fs.existsSync(path.join(path.dirname(p), '..', 'dist', 'src', 'index.js'));
131
+ } catch { return false; }
132
+ });
120
133
  }
121
134
 
122
135
  // Return { fresh, promoFresh, data }. 'fresh' is true only if within the TTL
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "generation": 1,
4
- "generatedAt": "2026-07-14T03:21:11.654Z",
5
- "gitSha": "87212ddb",
4
+ "generatedAt": "2026-07-14T03:48:36.860Z",
5
+ "gitSha": "5ca9ce1b",
6
6
  "catalog": {
7
7
  "agents": 164,
8
8
  "tools": 387,
@@ -139,7 +139,20 @@ function resolveCliBinCandidates() {
139
139
  }
140
140
  } catch { /* ignore */ }
141
141
  } catch { /* ignore */ }
142
- return candidates.filter((p) => { try { return fs.existsSync(p); } catch { return false; } });
142
+ return candidates.filter((p) => {
143
+ try {
144
+ if (!fs.existsSync(p)) return false;
145
+ // A candidate's bin/cli.js can exist on disk while its compiled
146
+ // dist/ never got built (Claude Code's own plugin marketplace just
147
+ // git-clones the repo — no install/build step — so every marketplace
148
+ // install is a source-only checkout by construction). Importing
149
+ // dist/src/index.js from bin/cli.js then throws MODULE_NOT_FOUND on
150
+ // every real command; only --version happens to survive it. Check
151
+ // for the compiled entrypoint too so a doomed candidate is skipped
152
+ // up front instead of wasting a spawn-and-fail on every render.
153
+ return fs.existsSync(path.join(path.dirname(p), '..', 'dist', 'src', 'index.js'));
154
+ } catch { return false; }
155
+ });
143
156
  }
144
157
 
145
158
  // Return { fresh, promoFresh, data }. 'fresh' is true only if within the TTL
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-flow/cli",
3
- "version": "3.27.0",
3
+ "version": "3.27.1",
4
4
  "type": "module",
5
5
  "description": "Ruflo CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
6
6
  "main": "dist/src/index.js",