moflo 4.8.37 → 4.8.38

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.
@@ -35,8 +35,10 @@ function resolveBin(binName, localScript) {
35
35
 
36
36
  function getLocalCliPath() {
37
37
  const paths = [
38
+ resolve(projectRoot, 'node_modules/moflo/src/@claude-flow/cli/bin/cli.js'),
38
39
  resolve(projectRoot, 'node_modules/moflo/bin/cli.js'),
39
40
  resolve(projectRoot, 'node_modules/.bin/flo'),
41
+ resolve(projectRoot, 'src/@claude-flow/cli/bin/cli.js'),
40
42
  ];
41
43
  for (const p of paths) {
42
44
  if (existsSync(p)) return p;
@@ -92,8 +94,23 @@ async function main() {
92
94
  log('SKIP test-index (script not found)');
93
95
  }
94
96
 
95
- // 4. HNSW rebuild — MUST run last, after all writes are committed
97
+ // 4. Patterns indexer
98
+ const patternsScript = resolveBin('flo-patterns', 'index-patterns.mjs');
99
+ if (patternsScript) {
100
+ runStep('patterns-index', 'node', [patternsScript]);
101
+ } else {
102
+ log('SKIP patterns-index (script not found)');
103
+ }
104
+
105
+ // 5. Pretrain (extracts patterns from repository)
96
106
  const localCli = getLocalCliPath();
107
+ if (localCli) {
108
+ runStep('pretrain', 'node', [localCli, 'hooks', 'pretrain']);
109
+ } else {
110
+ log('SKIP pretrain (CLI not found)');
111
+ }
112
+
113
+ // 6. HNSW rebuild — MUST run last, after all writes are committed (#81)
97
114
  if (localCli) {
98
115
  runStep('hnsw-rebuild', 'node', [localCli, 'memory', 'rebuild', '--force']);
99
116
  } else {
@@ -106,5 +123,5 @@ async function main() {
106
123
 
107
124
  main().catch(err => {
108
125
  log(`FATAL: ${err.message}`);
109
- process.exit(0);
126
+ process.exit(1);
110
127
  });
package/bin/hooks.mjs CHANGED
@@ -258,24 +258,15 @@ async function main() {
258
258
  }
259
259
 
260
260
  case 'session-start': {
261
- // All startup tasks run in background (non-blocking)
262
- // Start daemon quietly in background
261
+ // Start daemon quietly in background (no DB writes)
263
262
  runDaemonStartBackground();
264
263
  // Initialize embeddings engine (must run before indexers that generate embeddings)
265
264
  runEmbeddingsInitBackground();
266
- // Index guidance files in background
267
- runIndexGuidanceBackground();
268
- // Generate structural code map in background
269
- runCodeMapBackground();
270
- // Index test files in background
271
- runTestIndexBackground();
272
- // Index code patterns into patterns namespace
273
- runPatternsIndexBackground();
274
- // Run pretrain in background to extract patterns from repository
275
- runBackgroundPretrain();
276
- // Force HNSW rebuild to ensure all processes use identical fresh index
277
- // This fixes agent search result mismatches (0.61 vs 0.81 similarity)
278
- runHNSWRebuildBackground();
265
+ // Run all DB-writing indexers SEQUENTIALLY in a single background process.
266
+ // This avoids sql.js last-write-wins concurrency (#78) and ensures
267
+ // HNSW rebuild runs after all indexers finish (#81).
268
+ // Chain: guidance → code-map → tests → patterns → pretrain → HNSW rebuild.
269
+ spawnWindowless('node', [resolve(__dirname, 'index-all.mjs')], 'sequential indexing chain');
279
270
  // Neural patterns now loaded by moflo core routing — no external patching.
280
271
  break;
281
272
  }
@@ -471,55 +462,6 @@ function runIndexGuidanceBackground(specificFile = null) {
471
462
  spawnWindowless('node', indexArgs, desc);
472
463
  }
473
464
 
474
- // Run structural code map generator in background (non-blocking)
475
- function runCodeMapBackground() {
476
- // Check auto_index.code_map flag in moflo.yaml (default: true)
477
- const yamlPath = resolve(projectRoot, 'moflo.yaml');
478
- if (existsSync(yamlPath)) {
479
- try {
480
- const content = readFileSync(yamlPath, 'utf-8');
481
- const match = content.match(/auto_index:\s*\n(?:.*\n)*?\s+code_map:\s*(true|false)/);
482
- if (match && match[1] === 'false') {
483
- log('info', 'Code map generation disabled (auto_index.code_map: false)');
484
- return;
485
- }
486
- } catch { /* ignore, proceed with indexing */ }
487
- }
488
-
489
- const codeMapScript = resolveBinOrLocal('flo-codemap', 'generate-code-map.mjs');
490
-
491
- if (!codeMapScript) {
492
- log('warn', 'Code map generator not found (checked npm bin + .claude/scripts/)');
493
- return;
494
- }
495
-
496
- spawnWindowless('node', [codeMapScript], 'background code map generation');
497
- }
498
-
499
- // Run test file indexer in background (non-blocking)
500
- function runTestIndexBackground() {
501
- // Check auto_index.tests flag in moflo.yaml (default: true)
502
- const yamlPath = resolve(projectRoot, 'moflo.yaml');
503
- if (existsSync(yamlPath)) {
504
- try {
505
- const content = readFileSync(yamlPath, 'utf-8');
506
- const match = content.match(/auto_index:\s*\n(?:.*\n)*?\s+tests:\s*(true|false)/);
507
- if (match && match[1] === 'false') {
508
- log('info', 'Test indexing disabled (auto_index.tests: false)');
509
- return;
510
- }
511
- } catch { /* ignore, proceed with indexing */ }
512
- }
513
-
514
- const testIndexScript = resolveBinOrLocal('flo-testmap', 'index-tests.mjs');
515
-
516
- if (!testIndexScript) {
517
- log('info', 'Test indexer not found (checked npm bin + .claude/scripts/)');
518
- return;
519
- }
520
-
521
- spawnWindowless('node', [testIndexScript], 'background test indexing');
522
- }
523
465
 
524
466
  // Run ReasoningBank + MicroLoRA training + EWC++ consolidation in background (non-blocking)
525
467
  function runBackgroundTraining() {
@@ -627,28 +569,6 @@ function runDaemonStartBackground() {
627
569
  spawnWindowless('node', [localCli, 'daemon', 'start', '--quiet'], 'daemon');
628
570
  }
629
571
 
630
- // Run pretrain in background on session start (non-blocking)
631
- function runBackgroundPretrain() {
632
- const localCli = getLocalCliPath();
633
- if (!localCli) {
634
- log('warn', 'Local CLI not found, skipping background pretrain');
635
- return;
636
- }
637
-
638
- spawnWindowless('node', [localCli, 'hooks', 'pretrain'], 'background pretrain');
639
- }
640
-
641
- // Force HNSW rebuild in background to ensure all processes use identical fresh index
642
- // This fixes the issue where spawned agents return different search results than CLI/MCP
643
- function runHNSWRebuildBackground() {
644
- const localCli = getLocalCliPath();
645
- if (!localCli) {
646
- log('warn', 'Local CLI not found, skipping HNSW rebuild');
647
- return;
648
- }
649
-
650
- spawnWindowless('node', [localCli, 'memory', 'rebuild', '--force'], 'HNSW rebuild');
651
- }
652
572
 
653
573
  // Initialize embeddings ONNX engine on session start (non-blocking)
654
574
  function runEmbeddingsInitBackground() {
@@ -661,30 +581,6 @@ function runEmbeddingsInitBackground() {
661
581
  spawnWindowless('node', [localCli, 'embeddings', 'init'], 'embeddings init');
662
582
  }
663
583
 
664
- // Index code patterns into the patterns namespace (non-blocking)
665
- // Extracts architectural patterns, idioms, and recurring structures from source
666
- function runPatternsIndexBackground() {
667
- // Check auto_index.patterns flag in moflo.yaml (default: true)
668
- const yamlPath = resolve(projectRoot, 'moflo.yaml');
669
- if (existsSync(yamlPath)) {
670
- try {
671
- const content = readFileSync(yamlPath, 'utf-8');
672
- const match = content.match(/auto_index:\s*\n(?:.*\n)*?\s+patterns:\s*(true|false)/);
673
- if (match && match[1] === 'false') {
674
- log('info', 'Patterns indexing disabled (auto_index.patterns: false)');
675
- return;
676
- }
677
- } catch { /* ignore, proceed with indexing */ }
678
- }
679
-
680
- const patternsScript = resolveBinOrLocal('flo-patterns', 'index-patterns.mjs');
681
- if (!patternsScript) {
682
- log('warn', 'Patterns indexer not found (checked npm bin + .claude/scripts/)');
683
- return;
684
- }
685
-
686
- spawnWindowless('node', [patternsScript], 'background patterns indexing');
687
- }
688
584
 
689
585
  // Neural pattern application — now handled by moflo core routing (learned patterns
690
586
  // loaded from routing-outcomes.json by hooks-tools.ts getSemanticRouter).
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Sequential indexer chain for session-start.
4
+ *
5
+ * Runs all DB-writing indexers one at a time to avoid sql.js last-write-wins
6
+ * concurrency issues (#78), then triggers HNSW rebuild once everything is
7
+ * committed (#81).
8
+ *
9
+ * Spawned as a single detached background process by hooks.mjs session-start.
10
+ */
11
+
12
+ import { existsSync, appendFileSync, readFileSync } from 'fs';
13
+ import { resolve, dirname } from 'path';
14
+ import { fileURLToPath } from 'url';
15
+ import { execFileSync } from 'child_process';
16
+
17
+ const __dirname = dirname(fileURLToPath(import.meta.url));
18
+ const projectRoot = resolve(__dirname, '..');
19
+ const LOG_PATH = resolve(projectRoot, '.swarm/hooks.log');
20
+
21
+ function log(msg) {
22
+ const ts = new Date().toISOString().replace('T', ' ').slice(0, 19);
23
+ const line = `[${ts}] [index-all] ${msg}\n`;
24
+ try { appendFileSync(LOG_PATH, line); } catch { /* ignore */ }
25
+ }
26
+
27
+ function resolveBin(binName, localScript) {
28
+ const mofloScript = resolve(projectRoot, 'node_modules/moflo/bin', localScript);
29
+ if (existsSync(mofloScript)) return mofloScript;
30
+ const npmBin = resolve(projectRoot, 'node_modules/.bin', binName);
31
+ if (existsSync(npmBin)) return npmBin;
32
+ const localPath = resolve(projectRoot, '.claude/scripts', localScript);
33
+ if (existsSync(localPath)) return localPath;
34
+ // Also check bin/ directory (for development use)
35
+ const binPath = resolve(projectRoot, 'bin', localScript);
36
+ if (existsSync(binPath)) return binPath;
37
+ return null;
38
+ }
39
+
40
+ function getLocalCliPath() {
41
+ const paths = [
42
+ resolve(projectRoot, 'node_modules/moflo/src/@claude-flow/cli/bin/cli.js'),
43
+ resolve(projectRoot, 'node_modules/moflo/bin/cli.js'),
44
+ resolve(projectRoot, 'node_modules/.bin/flo'),
45
+ // Development: local CLI
46
+ resolve(projectRoot, 'src/@claude-flow/cli/bin/cli.js'),
47
+ ];
48
+ for (const p of paths) {
49
+ if (existsSync(p)) return p;
50
+ }
51
+ return null;
52
+ }
53
+
54
+ /** Read moflo.yaml once and cache auto_index flags. */
55
+ let _autoIndexFlags = null;
56
+ function isIndexEnabled(key) {
57
+ if (_autoIndexFlags === null) {
58
+ _autoIndexFlags = {};
59
+ const yamlPath = resolve(projectRoot, 'moflo.yaml');
60
+ if (existsSync(yamlPath)) {
61
+ try {
62
+ const content = readFileSync(yamlPath, 'utf-8');
63
+ for (const k of ['guidance', 'code_map', 'tests', 'patterns']) {
64
+ const re = new RegExp(`auto_index:\\s*\\n(?:.*\\n)*?\\s+${k}:\\s*(true|false)`);
65
+ const match = content.match(re);
66
+ _autoIndexFlags[k] = match ? match[1] !== 'false' : true;
67
+ }
68
+ } catch { /* ignore, all default to true */ }
69
+ }
70
+ }
71
+ return _autoIndexFlags[key] !== false;
72
+ }
73
+
74
+ function runStep(label, cmd, args, timeoutMs = 120_000) {
75
+ const start = Date.now();
76
+ log(`START ${label}`);
77
+ try {
78
+ execFileSync(cmd, args, {
79
+ cwd: projectRoot,
80
+ timeout: timeoutMs,
81
+ stdio: 'ignore',
82
+ windowsHide: true,
83
+ });
84
+ const elapsed = ((Date.now() - start) / 1000).toFixed(1);
85
+ log(`DONE ${label} (${elapsed}s)`);
86
+ return true;
87
+ } catch (err) {
88
+ const elapsed = ((Date.now() - start) / 1000).toFixed(1);
89
+ log(`FAIL ${label} (${elapsed}s): ${err.message?.split('\n')[0] || 'unknown'}`);
90
+ return false;
91
+ }
92
+ }
93
+
94
+ async function main() {
95
+ const startTime = Date.now();
96
+ log('Sequential indexing chain started');
97
+
98
+ // 1. Guidance indexer
99
+ if (isIndexEnabled('guidance')) {
100
+ const guidanceScript = resolveBin('flo-index', 'index-guidance.mjs');
101
+ if (guidanceScript) {
102
+ runStep('guidance-index', 'node', [guidanceScript]);
103
+ } else {
104
+ log('SKIP guidance-index (script not found)');
105
+ }
106
+ } else {
107
+ log('SKIP guidance-index (disabled in moflo.yaml)');
108
+ }
109
+
110
+ // 2. Code map generator (the big one — ~22s)
111
+ if (isIndexEnabled('code_map')) {
112
+ const codeMapScript = resolveBin('flo-codemap', 'generate-code-map.mjs');
113
+ if (codeMapScript) {
114
+ runStep('code-map', 'node', [codeMapScript], 180_000);
115
+ } else {
116
+ log('SKIP code-map (script not found)');
117
+ }
118
+ } else {
119
+ log('SKIP code-map (disabled in moflo.yaml)');
120
+ }
121
+
122
+ // 3. Test indexer
123
+ if (isIndexEnabled('tests')) {
124
+ const testScript = resolveBin('flo-testmap', 'index-tests.mjs');
125
+ if (testScript) {
126
+ runStep('test-index', 'node', [testScript]);
127
+ } else {
128
+ log('SKIP test-index (script not found)');
129
+ }
130
+ } else {
131
+ log('SKIP test-index (disabled in moflo.yaml)');
132
+ }
133
+
134
+ // 4. Patterns indexer
135
+ if (isIndexEnabled('patterns')) {
136
+ const patternsScript = resolveBin('flo-patterns', 'index-patterns.mjs');
137
+ if (patternsScript) {
138
+ runStep('patterns-index', 'node', [patternsScript]);
139
+ } else {
140
+ log('SKIP patterns-index (script not found)');
141
+ }
142
+ } else {
143
+ log('SKIP patterns-index (disabled in moflo.yaml)');
144
+ }
145
+
146
+ // 5. Pretrain (extracts patterns from repository)
147
+ const localCli = getLocalCliPath();
148
+ if (localCli) {
149
+ runStep('pretrain', 'node', [localCli, 'hooks', 'pretrain']);
150
+ } else {
151
+ log('SKIP pretrain (CLI not found)');
152
+ }
153
+
154
+ // 6. HNSW rebuild — MUST run last, after all writes are committed (#81)
155
+ if (localCli) {
156
+ runStep('hnsw-rebuild', 'node', [localCli, 'memory', 'rebuild', '--force']);
157
+ } else {
158
+ log('SKIP hnsw-rebuild (CLI not found)');
159
+ }
160
+
161
+ const totalElapsed = ((Date.now() - startTime) / 1000).toFixed(1);
162
+ log(`Sequential indexing chain complete (${totalElapsed}s)`);
163
+ }
164
+
165
+ main().catch(err => {
166
+ log(`FATAL: ${err.message}`);
167
+ process.exit(1);
168
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moflo",
3
- "version": "4.8.37",
3
+ "version": "4.8.38",
4
4
  "description": "MoFlo — AI agent orchestration for Claude Code. Forked from ruflo/claude-flow with patches applied to source, plus feature-level orchestration.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -798,12 +798,19 @@ async function checkIntelligence() {
798
798
  trajectoryId: 'doctor-test',
799
799
  context: 'health check',
800
800
  domain: 'general',
801
- steps: [{ action: 'test', reward: 1, embedding: new Float32Array(64).fill(0.2), timestamp: Date.now() }],
801
+ steps: [{ action: 'test', reward: 1, stateAfter: new Float32Array(64).fill(0.2), timestamp: Date.now() }],
802
802
  startTime: Date.now(),
803
803
  endTime: Date.now(),
804
804
  qualityScore: 0.9,
805
805
  isComplete: true,
806
- verdict: { success: true, quality: 0.9, feedback: 'test' },
806
+ verdict: {
807
+ success: true,
808
+ confidence: 0.9,
809
+ strengths: ['health check passed'],
810
+ weaknesses: [],
811
+ improvements: [],
812
+ relevanceScore: 0.9,
813
+ },
807
814
  };
808
815
  rb.storeTrajectory(trajectory);
809
816
  // distill() populates memories (storeTrajectory alone does not)
@@ -2,5 +2,5 @@
2
2
  * Auto-generated by build. Do not edit manually.
3
3
  * Source of truth: root package.json → scripts/sync-version.mjs
4
4
  */
5
- export const VERSION = '4.8.37';
5
+ export const VERSION = '4.8.38';
6
6
  //# sourceMappingURL=version.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moflo/cli",
3
- "version": "4.8.37",
3
+ "version": "4.8.38",
4
4
  "type": "module",
5
5
  "description": "MoFlo CLI — AI agent orchestration with specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
6
6
  "main": "dist/src/index.js",