moflo 4.6.12 → 4.7.2
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.
- package/.claude/settings.json +4 -4
- package/.claude/skills/flo/SKILL.md +80 -58
- package/.claude/workflow-state.json +1 -5
- package/README.md +467 -452
- package/bin/hooks.mjs +7 -3
- package/bin/setup-project.mjs +251 -251
- package/package.json +121 -121
- package/src/@claude-flow/cli/README.md +307 -7391
- package/src/@claude-flow/cli/dist/src/commands/doctor.js +1 -1
- package/src/@claude-flow/cli/dist/src/commands/embeddings.js +4 -4
- package/src/@claude-flow/cli/dist/src/commands/init.js +35 -8
- package/src/@claude-flow/cli/dist/src/commands/orc.d.ts +8 -4
- package/src/@claude-flow/cli/dist/src/commands/orc.js +152 -15
- package/src/@claude-flow/cli/dist/src/commands/swarm.js +2 -2
- package/src/@claude-flow/cli/dist/src/init/claudemd-generator.js +55 -33
- package/src/@claude-flow/cli/dist/src/init/executor.js +34 -38
- package/src/@claude-flow/cli/dist/src/init/helpers-generator.d.ts +0 -36
- package/src/@claude-flow/cli/dist/src/init/helpers-generator.js +6 -984
- package/src/@claude-flow/cli/dist/src/init/index.d.ts +1 -1
- package/src/@claude-flow/cli/dist/src/init/index.js +1 -1
- package/src/@claude-flow/cli/dist/src/init/moflo-init.js +78 -5
- package/src/@claude-flow/cli/dist/src/init/settings-generator.js +50 -120
- package/src/@claude-flow/cli/dist/src/mcp-tools/hooks-tools.js +275 -32
- package/src/@claude-flow/cli/dist/src/plugins/store/discovery.js +4 -204
- package/src/@claude-flow/cli/dist/src/plugins/tests/standalone-test.js +4 -4
- package/src/@claude-flow/cli/dist/src/runtime/headless.d.ts +3 -3
- package/src/@claude-flow/cli/dist/src/runtime/headless.js +3 -3
- package/src/@claude-flow/cli/dist/src/services/agentic-flow-bridge.d.ts +3 -3
- package/src/@claude-flow/cli/dist/src/services/agentic-flow-bridge.js +3 -1
- package/src/@claude-flow/cli/dist/src/services/headless-worker-executor.js +98 -84
- package/src/@claude-flow/cli/dist/src/services/workflow-gate.js +21 -1
- package/src/@claude-flow/cli/dist/src/transfer/store/tests/standalone-test.js +4 -4
- package/src/@claude-flow/cli/package.json +110 -110
|
@@ -6,7 +6,7 @@ export { type InitOptions, type InitComponents, type InitResult, type HooksConfi
|
|
|
6
6
|
export { generateSettings, generateSettingsJson, } from './settings-generator.js';
|
|
7
7
|
export { generateMCPConfig, generateMCPJson, generateMCPCommands, } from './mcp-generator.js';
|
|
8
8
|
export { generateStatuslineScript, generateStatuslineHook, } from './statusline-generator.js';
|
|
9
|
-
export { generatePreCommitHook, generatePostCommitHook,
|
|
9
|
+
export { generatePreCommitHook, generatePostCommitHook, generateAutoMemoryHook, generateHelpers, } from './helpers-generator.js';
|
|
10
10
|
export { generateClaudeMd, generateMinimalClaudeMd, CLAUDE_MD_TEMPLATES, } from './claudemd-generator.js';
|
|
11
11
|
export { executeInit, executeUpgrade, executeUpgradeWithMissing, default } from './executor.js';
|
|
12
12
|
export type { UpgradeResult } from './executor.js';
|
|
@@ -8,7 +8,7 @@ export { DEFAULT_INIT_OPTIONS, MINIMAL_INIT_OPTIONS, FULL_INIT_OPTIONS, detectPl
|
|
|
8
8
|
export { generateSettings, generateSettingsJson, } from './settings-generator.js';
|
|
9
9
|
export { generateMCPConfig, generateMCPJson, generateMCPCommands, } from './mcp-generator.js';
|
|
10
10
|
export { generateStatuslineScript, generateStatuslineHook, } from './statusline-generator.js';
|
|
11
|
-
export { generatePreCommitHook, generatePostCommitHook,
|
|
11
|
+
export { generatePreCommitHook, generatePostCommitHook, generateAutoMemoryHook, generateHelpers, } from './helpers-generator.js';
|
|
12
12
|
export { generateClaudeMd, generateMinimalClaudeMd, CLAUDE_MD_TEMPLATES, } from './claudemd-generator.js';
|
|
13
13
|
// Main executor
|
|
14
14
|
export { executeInit, executeUpgrade, executeUpgradeWithMissing, default } from './executor.js';
|
|
@@ -100,7 +100,9 @@ export async function initMoflo(options) {
|
|
|
100
100
|
steps.push(generateSkill(projectRoot, force));
|
|
101
101
|
// Step 4: CLAUDE.md MoFlo section
|
|
102
102
|
steps.push(generateClaudeMd(projectRoot, force));
|
|
103
|
-
// Step 5: .
|
|
103
|
+
// Step 5: .claude/scripts/ from moflo bin/
|
|
104
|
+
steps.push(syncScripts(projectRoot, force));
|
|
105
|
+
// Step 6: .gitignore entries
|
|
104
106
|
steps.push(updateGitignore(projectRoot));
|
|
105
107
|
return { steps };
|
|
106
108
|
}
|
|
@@ -299,6 +301,14 @@ function generateHooks(root, force, answers) {
|
|
|
299
301
|
"timeout": 5000
|
|
300
302
|
}
|
|
301
303
|
]
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
"matcher": "^Bash$",
|
|
307
|
+
"hooks": [{
|
|
308
|
+
"type": "command",
|
|
309
|
+
"command": "npx flo gate check-dangerous-command",
|
|
310
|
+
"timeout": 2000
|
|
311
|
+
}]
|
|
302
312
|
}
|
|
303
313
|
],
|
|
304
314
|
"PostToolUse": [
|
|
@@ -379,6 +389,15 @@ function generateHooks(root, force, answers) {
|
|
|
379
389
|
}]
|
|
380
390
|
}
|
|
381
391
|
],
|
|
392
|
+
"PreCompact": [
|
|
393
|
+
{
|
|
394
|
+
"hooks": [{
|
|
395
|
+
"type": "command",
|
|
396
|
+
"command": "npx flo gate compact-guidance",
|
|
397
|
+
"timeout": 3000
|
|
398
|
+
}]
|
|
399
|
+
}
|
|
400
|
+
],
|
|
382
401
|
"Notification": [
|
|
383
402
|
{
|
|
384
403
|
"hooks": [{
|
|
@@ -423,7 +442,7 @@ function generateSkill(root, force) {
|
|
|
423
442
|
}
|
|
424
443
|
}
|
|
425
444
|
if (!skillContent) {
|
|
426
|
-
return { name: '.claude/skills/flo/', status: '
|
|
445
|
+
return { name: '.claude/skills/flo/', status: 'error', detail: 'Could not find SKILL.md in moflo package' };
|
|
427
446
|
}
|
|
428
447
|
fs.writeFileSync(skillFile, skillContent, 'utf-8');
|
|
429
448
|
// Create /fl alias (same content)
|
|
@@ -472,10 +491,11 @@ This project uses [MoFlo](https://github.com/eric-cielo/moflo) for AI-assisted d
|
|
|
472
491
|
Your first tool call for every new user prompt MUST be a memory search. Do this BEFORE Glob, Grep, Read, or any file exploration.
|
|
473
492
|
|
|
474
493
|
\`\`\`
|
|
475
|
-
mcp__claude-flow__memory_search — query: "<task description>", namespace: "guidance" or "patterns" or "code-map"
|
|
494
|
+
mcp__claude-flow__memory_search — query: "<task description>", namespace: "guidance" or "patterns" or "knowledge" or "code-map"
|
|
476
495
|
\`\`\`
|
|
477
496
|
|
|
478
|
-
For codebase navigation, search the \`code-map\` namespace first. For patterns and domain knowledge, search \`patterns\` and \`guidance\`.
|
|
497
|
+
For codebase navigation, search the \`code-map\` namespace first. For patterns and domain knowledge, search \`patterns\`, \`knowledge\`, and \`guidance\`.
|
|
498
|
+
When the user asks you to remember something, store it: \`memory store --namespace knowledge --key "[topic]" --value "[what to remember]"\`
|
|
479
499
|
|
|
480
500
|
### Workflow Gates (enforced automatically)
|
|
481
501
|
|
|
@@ -529,7 +549,60 @@ ${MOFLO_MARKER_END}
|
|
|
529
549
|
};
|
|
530
550
|
}
|
|
531
551
|
// ============================================================================
|
|
532
|
-
// Step 5: .
|
|
552
|
+
// Step 5: .claude/scripts/ — sync from moflo bin/
|
|
553
|
+
// These scripts are used by session-start hooks for indexing, code map, etc.
|
|
554
|
+
// Always overwrite to keep them in sync with the installed moflo version.
|
|
555
|
+
// ============================================================================
|
|
556
|
+
const SCRIPT_MAP = {
|
|
557
|
+
'hooks.mjs': 'hooks.mjs',
|
|
558
|
+
'session-start-launcher.mjs': 'session-start-launcher.mjs',
|
|
559
|
+
'index-guidance.mjs': 'index-guidance.mjs',
|
|
560
|
+
'build-embeddings.mjs': 'build-embeddings.mjs',
|
|
561
|
+
'generate-code-map.mjs': 'generate-code-map.mjs',
|
|
562
|
+
'semantic-search.mjs': 'semantic-search.mjs',
|
|
563
|
+
};
|
|
564
|
+
function syncScripts(root, force) {
|
|
565
|
+
const scriptsDir = path.join(root, '.claude', 'scripts');
|
|
566
|
+
if (!fs.existsSync(scriptsDir)) {
|
|
567
|
+
fs.mkdirSync(scriptsDir, { recursive: true });
|
|
568
|
+
}
|
|
569
|
+
// Find moflo bin/ directory
|
|
570
|
+
const candidates = [
|
|
571
|
+
path.join(root, 'node_modules', 'moflo', 'bin'),
|
|
572
|
+
// When running from moflo repo itself
|
|
573
|
+
path.join(path.dirname(path.dirname(path.dirname(path.dirname(path.dirname(__dirname))))), 'bin'),
|
|
574
|
+
];
|
|
575
|
+
const binDir = candidates.find(d => fs.existsSync(d));
|
|
576
|
+
if (!binDir) {
|
|
577
|
+
return { name: '.claude/scripts/', status: 'skipped', detail: 'moflo bin/ not found' };
|
|
578
|
+
}
|
|
579
|
+
let copied = 0;
|
|
580
|
+
for (const [dest, src] of Object.entries(SCRIPT_MAP)) {
|
|
581
|
+
const srcPath = path.join(binDir, src);
|
|
582
|
+
const destPath = path.join(scriptsDir, dest);
|
|
583
|
+
if (!fs.existsSync(srcPath))
|
|
584
|
+
continue;
|
|
585
|
+
// Always overwrite scripts to keep in sync (they're derived, not user-edited)
|
|
586
|
+
if (!fs.existsSync(destPath) || force || isStale(srcPath, destPath)) {
|
|
587
|
+
fs.copyFileSync(srcPath, destPath);
|
|
588
|
+
copied++;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
if (copied === 0) {
|
|
592
|
+
return { name: '.claude/scripts/', status: 'skipped', detail: 'Scripts already up to date' };
|
|
593
|
+
}
|
|
594
|
+
return { name: '.claude/scripts/', status: 'updated', detail: `${copied} scripts synced from moflo` };
|
|
595
|
+
}
|
|
596
|
+
function isStale(srcPath, destPath) {
|
|
597
|
+
try {
|
|
598
|
+
return fs.statSync(srcPath).mtimeMs > fs.statSync(destPath).mtimeMs;
|
|
599
|
+
}
|
|
600
|
+
catch {
|
|
601
|
+
return true;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
// ============================================================================
|
|
605
|
+
// Step 6: .gitignore
|
|
533
606
|
// ============================================================================
|
|
534
607
|
function updateGitignore(root) {
|
|
535
608
|
const gitignorePath = path.join(root, '.gitignore');
|
|
@@ -189,87 +189,84 @@ function generateStatusLineConfig(_options) {
|
|
|
189
189
|
}
|
|
190
190
|
/**
|
|
191
191
|
* Generate hooks configuration
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
* working identically on Windows, macOS, and Linux.
|
|
192
|
+
* All hooks route through the npx flo CLI for consistent behavior.
|
|
193
|
+
* The CLI handles routing, gates, learning, and session management.
|
|
195
194
|
*/
|
|
196
195
|
function generateHooksConfig(config) {
|
|
197
196
|
const hooks = {};
|
|
198
|
-
//
|
|
199
|
-
// No shell-level error suppression needed (2>/dev/null || true breaks Windows).
|
|
200
|
-
// PreToolUse — validate commands and edits before execution
|
|
197
|
+
// PreToolUse — gates and validation before tool execution
|
|
201
198
|
if (config.preToolUse) {
|
|
202
199
|
hooks.PreToolUse = [
|
|
203
200
|
{
|
|
204
|
-
matcher: '
|
|
205
|
-
hooks: [
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
201
|
+
matcher: '^(Write|Edit|MultiEdit)$',
|
|
202
|
+
hooks: [{ type: 'command', command: 'npx flo hooks pre-edit', timeout: 5000 }],
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
matcher: '^(Glob|Grep)$',
|
|
206
|
+
hooks: [{ type: 'command', command: 'npx flo gate check-before-scan', timeout: 3000 }],
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
matcher: '^Read$',
|
|
210
|
+
hooks: [{ type: 'command', command: 'npx flo gate check-before-read', timeout: 3000 }],
|
|
212
211
|
},
|
|
213
212
|
{
|
|
214
|
-
matcher: '
|
|
213
|
+
matcher: '^Task$',
|
|
215
214
|
hooks: [
|
|
216
|
-
{
|
|
217
|
-
|
|
218
|
-
command: hookHandlerCmd('pre-edit'),
|
|
219
|
-
timeout: config.timeout,
|
|
220
|
-
},
|
|
215
|
+
{ type: 'command', command: 'npx flo gate check-before-agent', timeout: 3000 },
|
|
216
|
+
{ type: 'command', command: 'npx flo hooks pre-task', timeout: 5000 },
|
|
221
217
|
],
|
|
222
218
|
},
|
|
219
|
+
{
|
|
220
|
+
matcher: '^Bash$',
|
|
221
|
+
hooks: [{ type: 'command', command: 'npx flo gate check-dangerous-command', timeout: 2000 }],
|
|
222
|
+
},
|
|
223
223
|
];
|
|
224
224
|
}
|
|
225
|
-
// PostToolUse — record
|
|
225
|
+
// PostToolUse — record outcomes for learning
|
|
226
226
|
if (config.postToolUse) {
|
|
227
227
|
hooks.PostToolUse = [
|
|
228
228
|
{
|
|
229
|
-
matcher: 'Write|Edit|MultiEdit',
|
|
230
|
-
hooks: [
|
|
231
|
-
{
|
|
232
|
-
type: 'command',
|
|
233
|
-
command: hookHandlerCmd('post-edit'),
|
|
234
|
-
timeout: 10000,
|
|
235
|
-
},
|
|
236
|
-
],
|
|
229
|
+
matcher: '^(Write|Edit|MultiEdit)$',
|
|
230
|
+
hooks: [{ type: 'command', command: 'npx flo hooks post-edit', timeout: 5000 }],
|
|
237
231
|
},
|
|
238
232
|
{
|
|
239
|
-
matcher: '
|
|
240
|
-
hooks: [
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
233
|
+
matcher: '^Task$',
|
|
234
|
+
hooks: [{ type: 'command', command: 'npx flo hooks post-task', timeout: 5000 }],
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
matcher: '^TaskCreate$',
|
|
238
|
+
hooks: [{ type: 'command', command: 'npx flo gate record-task-created', timeout: 2000 }],
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
matcher: '^Bash$',
|
|
242
|
+
hooks: [{ type: 'command', command: 'npx flo gate check-bash-memory', timeout: 2000 }],
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
matcher: '^mcp__claude-flow__memory_(search|retrieve)$',
|
|
246
|
+
hooks: [{ type: 'command', command: 'npx flo gate record-memory-searched', timeout: 2000 }],
|
|
247
247
|
},
|
|
248
248
|
];
|
|
249
249
|
}
|
|
250
|
-
// UserPromptSubmit — intelligent task routing
|
|
250
|
+
// UserPromptSubmit — gate reminders + intelligent task routing
|
|
251
251
|
if (config.userPromptSubmit) {
|
|
252
252
|
hooks.UserPromptSubmit = [
|
|
253
253
|
{
|
|
254
254
|
hooks: [
|
|
255
|
-
{
|
|
256
|
-
|
|
257
|
-
command: hookHandlerCmd('route'),
|
|
258
|
-
timeout: 10000,
|
|
259
|
-
},
|
|
255
|
+
{ type: 'command', command: 'npx flo gate prompt-reminder', timeout: 2000 },
|
|
256
|
+
{ type: 'command', command: 'npx flo hooks route', timeout: 5000 },
|
|
260
257
|
],
|
|
261
258
|
},
|
|
262
259
|
];
|
|
263
260
|
}
|
|
264
|
-
// SessionStart —
|
|
261
|
+
// SessionStart — launch daemon, indexers, pretrain via session-start-launcher
|
|
265
262
|
if (config.sessionStart) {
|
|
266
263
|
hooks.SessionStart = [
|
|
267
264
|
{
|
|
268
265
|
hooks: [
|
|
269
266
|
{
|
|
270
267
|
type: 'command',
|
|
271
|
-
command:
|
|
272
|
-
timeout:
|
|
268
|
+
command: 'node "$CLAUDE_PROJECT_DIR/.claude/scripts/session-start-launcher.mjs"',
|
|
269
|
+
timeout: 3000,
|
|
273
270
|
},
|
|
274
271
|
{
|
|
275
272
|
type: 'command',
|
|
@@ -280,100 +277,33 @@ function generateHooksConfig(config) {
|
|
|
280
277
|
},
|
|
281
278
|
];
|
|
282
279
|
}
|
|
283
|
-
//
|
|
284
|
-
if (config.sessionStart) {
|
|
285
|
-
hooks.SessionEnd = [
|
|
286
|
-
{
|
|
287
|
-
hooks: [
|
|
288
|
-
{
|
|
289
|
-
type: 'command',
|
|
290
|
-
command: hookHandlerCmd('session-end'),
|
|
291
|
-
timeout: 10000,
|
|
292
|
-
},
|
|
293
|
-
],
|
|
294
|
-
},
|
|
295
|
-
];
|
|
296
|
-
}
|
|
297
|
-
// Stop — sync auto memory on exit
|
|
280
|
+
// Stop — persist session + sync auto memory
|
|
298
281
|
if (config.stop) {
|
|
299
282
|
hooks.Stop = [
|
|
300
283
|
{
|
|
301
284
|
hooks: [
|
|
302
|
-
{
|
|
303
|
-
|
|
304
|
-
command: autoMemoryCmd('sync'),
|
|
305
|
-
timeout: 10000,
|
|
306
|
-
},
|
|
285
|
+
{ type: 'command', command: 'npx flo hooks session-end', timeout: 5000 },
|
|
286
|
+
{ type: 'command', command: autoMemoryCmd('sync'), timeout: 10000 },
|
|
307
287
|
],
|
|
308
288
|
},
|
|
309
289
|
];
|
|
310
290
|
}
|
|
311
|
-
// PreCompact —
|
|
291
|
+
// PreCompact — guidance before context window compaction
|
|
312
292
|
if (config.preCompact) {
|
|
313
293
|
hooks.PreCompact = [
|
|
314
294
|
{
|
|
315
|
-
|
|
316
|
-
hooks: [
|
|
317
|
-
{
|
|
318
|
-
type: 'command',
|
|
319
|
-
command: hookHandlerCmd('compact-manual'),
|
|
320
|
-
},
|
|
321
|
-
{
|
|
322
|
-
type: 'command',
|
|
323
|
-
command: hookHandlerCmd('session-end'),
|
|
324
|
-
timeout: 5000,
|
|
325
|
-
},
|
|
326
|
-
],
|
|
327
|
-
},
|
|
328
|
-
{
|
|
329
|
-
matcher: 'auto',
|
|
330
|
-
hooks: [
|
|
331
|
-
{
|
|
332
|
-
type: 'command',
|
|
333
|
-
command: hookHandlerCmd('compact-auto'),
|
|
334
|
-
},
|
|
335
|
-
{
|
|
336
|
-
type: 'command',
|
|
337
|
-
command: hookHandlerCmd('session-end'),
|
|
338
|
-
timeout: 6000,
|
|
339
|
-
},
|
|
340
|
-
],
|
|
295
|
+
hooks: [{ type: 'command', command: 'npx flo gate compact-guidance', timeout: 3000 }],
|
|
341
296
|
},
|
|
342
297
|
];
|
|
343
298
|
}
|
|
344
|
-
//
|
|
345
|
-
hooks.SubagentStart = [
|
|
346
|
-
{
|
|
347
|
-
hooks: [
|
|
348
|
-
{
|
|
349
|
-
type: 'command',
|
|
350
|
-
command: hookHandlerCmd('status'),
|
|
351
|
-
timeout: 3000,
|
|
352
|
-
},
|
|
353
|
-
],
|
|
354
|
-
},
|
|
355
|
-
];
|
|
356
|
-
// SubagentStop — track agent completion for metrics
|
|
357
|
-
// NOTE: The valid event is "SubagentStop" (not "SubagentEnd")
|
|
358
|
-
hooks.SubagentStop = [
|
|
359
|
-
{
|
|
360
|
-
hooks: [
|
|
361
|
-
{
|
|
362
|
-
type: 'command',
|
|
363
|
-
command: hookHandlerCmd('post-task'),
|
|
364
|
-
timeout: 5000,
|
|
365
|
-
},
|
|
366
|
-
],
|
|
367
|
-
},
|
|
368
|
-
];
|
|
369
|
-
// Notification — capture Claude Code notifications for logging
|
|
299
|
+
// Notification — capture notifications for logging
|
|
370
300
|
if (config.notification) {
|
|
371
301
|
hooks.Notification = [
|
|
372
302
|
{
|
|
373
303
|
hooks: [
|
|
374
304
|
{
|
|
375
305
|
type: 'command',
|
|
376
|
-
command:
|
|
306
|
+
command: 'npx flo hooks notification',
|
|
377
307
|
timeout: 3000,
|
|
378
308
|
},
|
|
379
309
|
],
|