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.
Files changed (33) hide show
  1. package/.claude/settings.json +4 -4
  2. package/.claude/skills/flo/SKILL.md +80 -58
  3. package/.claude/workflow-state.json +1 -5
  4. package/README.md +467 -452
  5. package/bin/hooks.mjs +7 -3
  6. package/bin/setup-project.mjs +251 -251
  7. package/package.json +121 -121
  8. package/src/@claude-flow/cli/README.md +307 -7391
  9. package/src/@claude-flow/cli/dist/src/commands/doctor.js +1 -1
  10. package/src/@claude-flow/cli/dist/src/commands/embeddings.js +4 -4
  11. package/src/@claude-flow/cli/dist/src/commands/init.js +35 -8
  12. package/src/@claude-flow/cli/dist/src/commands/orc.d.ts +8 -4
  13. package/src/@claude-flow/cli/dist/src/commands/orc.js +152 -15
  14. package/src/@claude-flow/cli/dist/src/commands/swarm.js +2 -2
  15. package/src/@claude-flow/cli/dist/src/init/claudemd-generator.js +55 -33
  16. package/src/@claude-flow/cli/dist/src/init/executor.js +34 -38
  17. package/src/@claude-flow/cli/dist/src/init/helpers-generator.d.ts +0 -36
  18. package/src/@claude-flow/cli/dist/src/init/helpers-generator.js +6 -984
  19. package/src/@claude-flow/cli/dist/src/init/index.d.ts +1 -1
  20. package/src/@claude-flow/cli/dist/src/init/index.js +1 -1
  21. package/src/@claude-flow/cli/dist/src/init/moflo-init.js +78 -5
  22. package/src/@claude-flow/cli/dist/src/init/settings-generator.js +50 -120
  23. package/src/@claude-flow/cli/dist/src/mcp-tools/hooks-tools.js +275 -32
  24. package/src/@claude-flow/cli/dist/src/plugins/store/discovery.js +4 -204
  25. package/src/@claude-flow/cli/dist/src/plugins/tests/standalone-test.js +4 -4
  26. package/src/@claude-flow/cli/dist/src/runtime/headless.d.ts +3 -3
  27. package/src/@claude-flow/cli/dist/src/runtime/headless.js +3 -3
  28. package/src/@claude-flow/cli/dist/src/services/agentic-flow-bridge.d.ts +3 -3
  29. package/src/@claude-flow/cli/dist/src/services/agentic-flow-bridge.js +3 -1
  30. package/src/@claude-flow/cli/dist/src/services/headless-worker-executor.js +98 -84
  31. package/src/@claude-flow/cli/dist/src/services/workflow-gate.js +21 -1
  32. package/src/@claude-flow/cli/dist/src/transfer/store/tests/standalone-test.js +4 -4
  33. 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, generateSessionManager, generateAgentRouter, generateMemoryHelper, generateHelpers, generateWindowsDaemonManager, generateWindowsBatchWrapper, generateCrossPlatformSessionManager, } from './helpers-generator.js';
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, generateSessionManager, generateAgentRouter, generateMemoryHelper, generateHelpers, generateWindowsDaemonManager, generateWindowsBatchWrapper, generateCrossPlatformSessionManager, } from './helpers-generator.js';
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: .gitignore entries
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: 'failed', detail: 'Could not find SKILL.md in moflo package' };
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: .gitignore
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
- * Uses local hook-handler.cjs for cross-platform compatibility.
193
- * All hooks invoke scripts directly via `node <script> <subcommand>`,
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
- // Node.js scripts handle errors internally via try/catch.
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: 'Bash',
205
- hooks: [
206
- {
207
- type: 'command',
208
- command: hookHandlerCmd('pre-bash'),
209
- timeout: config.timeout,
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: 'Write|Edit|MultiEdit',
213
+ matcher: '^Task$',
215
214
  hooks: [
216
- {
217
- type: 'command',
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 edits and commands for session metrics / learning
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: 'Bash',
240
- hooks: [
241
- {
242
- type: 'command',
243
- command: hookHandlerCmd('post-bash'),
244
- timeout: config.timeout,
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
- type: 'command',
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 — restore session state + import auto memory
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: hookHandlerCmd('session-restore'),
272
- timeout: 15000,
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
- // SessionEnd — persist session state
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
- type: 'command',
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 — preserve context before compaction
291
+ // PreCompact — guidance before context window compaction
312
292
  if (config.preCompact) {
313
293
  hooks.PreCompact = [
314
294
  {
315
- matcher: 'manual',
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
- // SubagentStartstatus update when a sub-agent is spawned
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
+ // Notificationcapture 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: hookHandlerCmd('notify'),
306
+ command: 'npx flo hooks notification',
377
307
  timeout: 3000,
378
308
  },
379
309
  ],