claude-flow 3.30.2 → 3.30.3
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.
|
@@ -89,6 +89,10 @@ function spawnDetachedHookRefresh(subcommand) {
|
|
|
89
89
|
detached: true,
|
|
90
90
|
stdio: 'ignore',
|
|
91
91
|
env: process.env,
|
|
92
|
+
// Windows: without this, npx.cmd's cmd.exe wrapper flashes a visible
|
|
93
|
+
// console window every time a hook fires a background refresh. Runs
|
|
94
|
+
// hidden instead. No-op on POSIX.
|
|
95
|
+
windowsHide: true,
|
|
92
96
|
});
|
|
93
97
|
child.unref();
|
|
94
98
|
} catch (e) { /* best-effort only */ }
|
|
@@ -98,105 +102,6 @@ function spawnDetachedFunnelRefresh() {
|
|
|
98
102
|
spawnDetachedHookRefresh('refresh-funnel');
|
|
99
103
|
}
|
|
100
104
|
|
|
101
|
-
// ADR-318/319: first-run auto-enable of spinner verbs (default ON) +
|
|
102
|
-
// announcements (default OFF, explicit opt-in). Fires ONCE per install
|
|
103
|
-
// (marker at ~/.ruflo/first-run-enabled.json), then never again —
|
|
104
|
-
// subsequent sessions see the marker and skip.
|
|
105
|
-
//
|
|
106
|
-
// Split posture rationale:
|
|
107
|
-
// - Spinner verbs = low-intrusion (per-spin flash, append-mode mix
|
|
108
|
-
// with Claude Code defaults, moderate visibility over time). Default ON.
|
|
109
|
-
// Disclosure notification + one-command disable satisfies the ethical bar.
|
|
110
|
-
// - Announcements = higher-intrusion (prominent line at every Claude Code
|
|
111
|
-
// startup, more attention per view). Default OFF; opt-in via
|
|
112
|
-
// RUFLO_AUTO_ENABLE_ANNOUNCEMENTS=1 or explicit `ruflo announcements enable`.
|
|
113
|
-
//
|
|
114
|
-
// Gates (spinner is default-on unless any is TRUE):
|
|
115
|
-
// - RUFLO_NO_AUTO_ENABLE truthy (master opt-out — kills both)
|
|
116
|
-
// - RUFLO_NO_AUTO_ENABLE_SPINNER truthy (spinner-only opt-out)
|
|
117
|
-
// - CI / GITHUB_ACTIONS truthy
|
|
118
|
-
// - stdout is not a TTY (piped, non-interactive)
|
|
119
|
-
// - Marker file already exists
|
|
120
|
-
//
|
|
121
|
-
// Announcements needs the same gates PLUS RUFLO_AUTO_ENABLE_ANNOUNCEMENTS=1.
|
|
122
|
-
//
|
|
123
|
-
// Marker is written even if the spawns fail — auto-enable is a "we tried once"
|
|
124
|
-
// contract, not "keep trying until success." Users can run enable manually.
|
|
125
|
-
function firstRunAutoEnableIfEligible() {
|
|
126
|
-
try {
|
|
127
|
-
const path = require('path');
|
|
128
|
-
const fs = require('fs');
|
|
129
|
-
const os = require('os');
|
|
130
|
-
const truthy = (v) => v && !/^(0|false|off|no)$/i.test(String(v));
|
|
131
|
-
if (truthy(process.env.RUFLO_NO_AUTO_ENABLE)) return;
|
|
132
|
-
if (process.env.CI || process.env.GITHUB_ACTIONS) return;
|
|
133
|
-
if (process.stdout && process.stdout.isTTY === false) return;
|
|
134
|
-
const markerPath = path.join(os.homedir(), '.ruflo', 'first-run-enabled.json');
|
|
135
|
-
if (fs.existsSync(markerPath)) return;
|
|
136
|
-
|
|
137
|
-
const enableSpinner = !truthy(process.env.RUFLO_NO_AUTO_ENABLE_SPINNER);
|
|
138
|
-
const enableAnnouncements = truthy(process.env.RUFLO_AUTO_ENABLE_ANNOUNCEMENTS);
|
|
139
|
-
|
|
140
|
-
// Nothing to do — user opted out of both. Skip marker write so if they
|
|
141
|
-
// change their mind and re-enable env vars later, first-run still fires.
|
|
142
|
-
if (!enableSpinner && !enableAnnouncements) return;
|
|
143
|
-
|
|
144
|
-
// Spawn the enable commands detached + non-blocking. Any failure
|
|
145
|
-
// (missing CLI, refused state, etc.) is silent — auto-enable is
|
|
146
|
-
// best-effort and MUST NOT block session-restore. Uses execPath +
|
|
147
|
-
// resolved cli.js directly rather than spawnDetachedHookRefresh
|
|
148
|
-
// because that helper hardcodes 'hooks' as the top-level command.
|
|
149
|
-
const { spawn } = require('child_process');
|
|
150
|
-
const cliBin = resolveCliBinForHook();
|
|
151
|
-
const runDetached = (args) => {
|
|
152
|
-
try {
|
|
153
|
-
const spawnArgs = cliBin
|
|
154
|
-
? [process.execPath, [cliBin, ...args]]
|
|
155
|
-
: [process.platform === 'win32' ? 'npx.cmd' : 'npx',
|
|
156
|
-
['--prefer-offline', '@claude-flow/cli', ...args]];
|
|
157
|
-
const child = spawn(spawnArgs[0], spawnArgs[1], {
|
|
158
|
-
detached: true, stdio: 'ignore', env: process.env, windowsHide: true,
|
|
159
|
-
});
|
|
160
|
-
child.unref();
|
|
161
|
-
} catch { /* best-effort */ }
|
|
162
|
-
};
|
|
163
|
-
if (enableSpinner) runDetached(['spinner', 'enable', '--yes']);
|
|
164
|
-
if (enableAnnouncements) runDetached(['announcements', 'enable', '--yes']);
|
|
165
|
-
|
|
166
|
-
try {
|
|
167
|
-
fs.mkdirSync(path.dirname(markerPath), { recursive: true, mode: 0o700 });
|
|
168
|
-
fs.writeFileSync(
|
|
169
|
-
markerPath,
|
|
170
|
-
JSON.stringify({
|
|
171
|
-
_ts: Date.now(),
|
|
172
|
-
source: 'session-restore-hook',
|
|
173
|
-
enabled: { spinner: enableSpinner, announcements: enableAnnouncements },
|
|
174
|
-
}, null, 2),
|
|
175
|
-
{ encoding: 'utf-8', mode: 0o600 }
|
|
176
|
-
);
|
|
177
|
-
} catch { /* ignore — best effort */ }
|
|
178
|
-
|
|
179
|
-
// Notification tells user exactly what happened. stderr so it doesn't
|
|
180
|
-
// corrupt any downstream JSON stdout consumer.
|
|
181
|
-
try {
|
|
182
|
-
const parts = [];
|
|
183
|
-
if (enableSpinner) parts.push('spinner verbs');
|
|
184
|
-
if (enableAnnouncements) parts.push('startup announcements');
|
|
185
|
-
const disableCmds = [];
|
|
186
|
-
if (enableSpinner) disableCmds.push('`ruflo spinner disable`');
|
|
187
|
-
if (enableAnnouncements) disableCmds.push('`ruflo announcements disable`');
|
|
188
|
-
process.stderr.write(
|
|
189
|
-
'[ruflo] First-run: enabled ' + parts.join(' + ') + '. ' +
|
|
190
|
-
'Disable anytime with ' + disableCmds.join(' / ') + '. ' +
|
|
191
|
-
(enableSpinner && !enableAnnouncements
|
|
192
|
-
? 'Announcements stay opt-in — set RUFLO_AUTO_ENABLE_ANNOUNCEMENTS=1 to enable those too. '
|
|
193
|
-
: '') +
|
|
194
|
-
'Restart Claude Code once to see the changes take effect.\n'
|
|
195
|
-
);
|
|
196
|
-
} catch { /* ignore */ }
|
|
197
|
-
} catch { /* auto-enable must never break session-restore */ }
|
|
198
|
-
}
|
|
199
|
-
|
|
200
105
|
// Same fallback-aware pattern as spawnDetachedFunnelRefresh() above, for
|
|
201
106
|
// ADR-316's co-pilot advisor tip. Safe to call on EVERY session-restore:
|
|
202
107
|
// refresh-advisor's own action checks consent + a 24h TTL BEFORE spending
|
|
@@ -444,11 +349,6 @@ const handlers = {
|
|
|
444
349
|
},
|
|
445
350
|
|
|
446
351
|
'session-restore': async () => {
|
|
447
|
-
// ADR-318/319 first-run auto-enable — fire once per install, never
|
|
448
|
-
// re-fires after user disables. Respects RUFLO_NO_AUTO_ENABLE + CI.
|
|
449
|
-
// Fully non-blocking (detached spawn) so session-restore latency
|
|
450
|
-
// is unchanged.
|
|
451
|
-
firstRunAutoEnableIfEligible();
|
|
452
352
|
if (session) {
|
|
453
353
|
// Try restore first, fall back to start
|
|
454
354
|
const existing = session.restore && session.restore();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-flow",
|
|
3
|
-
"version": "3.30.
|
|
3
|
+
"version": "3.30.3",
|
|
4
4
|
"description": "Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-flow/cli",
|
|
3
|
-
"version": "3.30.
|
|
3
|
+
"version": "3.30.3",
|
|
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",
|