moflo 4.8.44 → 4.8.45
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/guidance/shipped/moflo-claude-swarm-cohesion.md +3 -3
- package/.claude/guidance/shipped/{memory-strategy.md → moflo-memory-strategy.md} +3 -3
- package/.claude/guidance/shipped/{subagents.md → moflo-subagents.md} +1 -1
- package/.claude/guidance/shipped/moflo.md +3 -3
- package/.claude/scripts/index-all.mjs +193 -193
- package/.claude/scripts/index-guidance.mjs +1 -1
- package/.claude/scripts/session-start-launcher.mjs +3 -3
- package/bin/session-start-launcher.mjs +3 -3
- package/bin/setup-project.mjs +7 -7
- package/package.json +2 -2
- package/src/@claude-flow/cli/dist/src/init/claudemd-generator.js +46 -46
- package/src/@claude-flow/cli/dist/src/init/moflo-init.js +764 -764
- package/src/@claude-flow/cli/dist/src/version.js +1 -1
- package/src/@claude-flow/cli/package.json +106 -106
- /package/.claude/guidance/shipped/{memorydb-maintenance.md → moflo-memorydb-maintenance.md} +0 -0
- /package/.claude/guidance/shipped/{task-icons.md → moflo-task-icons.md} +0 -0
|
@@ -144,7 +144,7 @@ TaskCreate was already called in Step 1 — tasks are visible before agents spaw
|
|
|
144
144
|
```javascript
|
|
145
145
|
// TaskCreate already done in Step 1 above
|
|
146
146
|
Task({
|
|
147
|
-
prompt: `FIRST: Search memory, then read .claude/guidance/subagents.md
|
|
147
|
+
prompt: `FIRST: Search memory, then read .claude/guidance/moflo-subagents.md
|
|
148
148
|
|
|
149
149
|
YOUR TASK (ID: 1): Research requirements and codebase patterns
|
|
150
150
|
- Analyze feature requirements
|
|
@@ -436,6 +436,6 @@ npx flo swarm init --topology hierarchical-mesh --max-agents 15 --strategy speci
|
|
|
436
436
|
|
|
437
437
|
## See Also
|
|
438
438
|
|
|
439
|
-
- `.claude/guidance/subagents.md` - Subagents guide
|
|
440
|
-
- `.claude/guidance/memory-strategy.md` - Memory architecture and search
|
|
439
|
+
- `.claude/guidance/moflo-subagents.md` - Subagents guide
|
|
440
|
+
- `.claude/guidance/moflo-memory-strategy.md` - Memory architecture and search
|
|
441
441
|
- `.claude/guidance/moflo.md` - Full CLI/MCP reference
|
|
@@ -265,13 +265,13 @@ npx flo memory search --query "your domain query" --namespace guidance # Verify
|
|
|
265
265
|
| "Vector: No" in list | Entry lacks embedding | Run `node bin/build-embeddings.mjs` |
|
|
266
266
|
| Entries not found after adding file | Indexer hasn't run yet | Run `node bin/index-all.mjs` or restart session |
|
|
267
267
|
| Bundled moflo guidance not indexed | Not installed as dependency | Only indexes when `node_modules/moflo/.claude/guidance/` exists |
|
|
268
|
-
| Empty namespace | Indexer never ran or DB was purged | See `memorydb-maintenance.md` for reindex/purge procedures |
|
|
268
|
+
| Empty namespace | Indexer never ran or DB was purged | See `moflo-memorydb-maintenance.md` for reindex/purge procedures |
|
|
269
269
|
|
|
270
270
|
---
|
|
271
271
|
|
|
272
272
|
## See Also
|
|
273
273
|
|
|
274
|
-
- `memorydb-maintenance.md` — Database location, schema, purge/reindex procedures
|
|
275
|
-
- `subagents.md` — Subagents guide
|
|
274
|
+
- `moflo-memorydb-maintenance.md` — Database location, schema, purge/reindex procedures
|
|
275
|
+
- `moflo-subagents.md` — Subagents guide
|
|
276
276
|
- `moflo-claude-swarm-cohesion.md` — Task & swarm coordination
|
|
277
277
|
- `moflo.md` — Full CLI/MCP reference
|
|
@@ -100,7 +100,7 @@ This applies to ALL `gh` commands that target a repo: `pr create`, `pr merge`, `
|
|
|
100
100
|
|
|
101
101
|
### Task Icons (MANDATORY)
|
|
102
102
|
- `TaskCreate` MUST use **ICON + [Role]** in `subject` and `activeForm`
|
|
103
|
-
- Full icon map: `.claude/guidance/shipped/task-icons.md`
|
|
103
|
+
- Full icon map: `.claude/guidance/shipped/moflo-task-icons.md`
|
|
104
104
|
- Example: `🧪 [Tester] Run unit tests` / activeForm: `🧪 Running unit tests`
|
|
105
105
|
|
|
106
106
|
---
|
|
@@ -634,13 +634,13 @@ All code changes MUST work on Windows, macOS, and Linux. Follow these rules:
|
|
|
634
634
|
| `flo` command not found | Not in PATH | Use `npx flo` or `node node_modules/moflo/bin/index-guidance.mjs` |
|
|
635
635
|
| Bundled guidance not indexed | Running inside moflo repo (same dir) | Bundled guidance only indexes when installed as a dependency in a different project |
|
|
636
636
|
|
|
637
|
-
See `memory-strategy.md` for memory-specific troubleshooting.
|
|
637
|
+
See `moflo-memory-strategy.md` for memory-specific troubleshooting.
|
|
638
638
|
|
|
639
639
|
---
|
|
640
640
|
|
|
641
641
|
## See Also
|
|
642
642
|
|
|
643
|
-
- `.claude/guidance/subagents.md` - Subagents memory-first protocol and store patterns
|
|
643
|
+
- `.claude/guidance/moflo-subagents.md` - Subagents memory-first protocol and store patterns
|
|
644
644
|
- `.claude/guidance/moflo-claude-swarm-cohesion.md` - Task & swarm coordination with TaskCreate/TaskUpdate
|
|
645
|
-
- `.claude/guidance/memory-strategy.md` - Database schema, namespaces, search commands, RAG linking
|
|
645
|
+
- `.claude/guidance/moflo-memory-strategy.md` - Database schema, namespaces, search commands, RAG linking
|
|
646
646
|
- `.claude/guidance/guidance-memory-strategy.md` - How to write guidance docs that index well for RAG
|
|
@@ -1,193 +1,193 @@
|
|
|
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
|
-
|
|
19
|
-
// Detect project root by walking up from cwd to find package.json.
|
|
20
|
-
// IMPORTANT: Do NOT use resolve(__dirname, '..') — this script lives in bin/
|
|
21
|
-
// during development but gets synced to .claude/scripts/ in consumer projects,
|
|
22
|
-
// so __dirname-relative paths break. findProjectRoot() works in both locations.
|
|
23
|
-
function findProjectRoot() {
|
|
24
|
-
let dir = process.cwd();
|
|
25
|
-
const root = resolve(dir, '/');
|
|
26
|
-
while (dir !== root) {
|
|
27
|
-
if (existsSync(resolve(dir, 'package.json'))) return dir;
|
|
28
|
-
dir = dirname(dir);
|
|
29
|
-
}
|
|
30
|
-
return process.cwd();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const projectRoot = findProjectRoot();
|
|
34
|
-
const LOG_PATH = resolve(projectRoot, '.swarm/hooks.log');
|
|
35
|
-
|
|
36
|
-
function log(msg) {
|
|
37
|
-
const ts = new Date().toISOString().replace('T', ' ').slice(0, 19);
|
|
38
|
-
const line = `[${ts}] [index-all] ${msg}\n`;
|
|
39
|
-
try { appendFileSync(LOG_PATH, line); } catch { /* ignore */ }
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function resolveBin(binName, localScript) {
|
|
43
|
-
const mofloScript = resolve(projectRoot, 'node_modules/moflo/bin', localScript);
|
|
44
|
-
if (existsSync(mofloScript)) return mofloScript;
|
|
45
|
-
const npmBin = resolve(projectRoot, 'node_modules/.bin', binName);
|
|
46
|
-
if (existsSync(npmBin)) return npmBin;
|
|
47
|
-
const localPath = resolve(projectRoot, '.claude/scripts', localScript);
|
|
48
|
-
if (existsSync(localPath)) return localPath;
|
|
49
|
-
// Also check bin/ directory (for development use)
|
|
50
|
-
const binPath = resolve(projectRoot, 'bin', localScript);
|
|
51
|
-
if (existsSync(binPath)) return binPath;
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function getLocalCliPath() {
|
|
56
|
-
const paths = [
|
|
57
|
-
resolve(projectRoot, 'node_modules/moflo/src/@claude-flow/cli/bin/cli.js'),
|
|
58
|
-
resolve(projectRoot, 'node_modules/moflo/bin/cli.js'),
|
|
59
|
-
resolve(projectRoot, 'node_modules/.bin/flo'),
|
|
60
|
-
// Development: local CLI
|
|
61
|
-
resolve(projectRoot, 'src/@claude-flow/cli/bin/cli.js'),
|
|
62
|
-
];
|
|
63
|
-
for (const p of paths) {
|
|
64
|
-
if (existsSync(p)) return p;
|
|
65
|
-
}
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/** Read moflo.yaml once and cache auto_index flags. */
|
|
70
|
-
let _autoIndexFlags = null;
|
|
71
|
-
function isIndexEnabled(key) {
|
|
72
|
-
if (_autoIndexFlags === null) {
|
|
73
|
-
_autoIndexFlags = {};
|
|
74
|
-
const yamlPath = resolve(projectRoot, 'moflo.yaml');
|
|
75
|
-
if (existsSync(yamlPath)) {
|
|
76
|
-
try {
|
|
77
|
-
const content = readFileSync(yamlPath, 'utf-8');
|
|
78
|
-
for (const k of ['guidance', 'code_map', 'tests', 'patterns']) {
|
|
79
|
-
const re = new RegExp(`auto_index:\\s*\\n(?:.*\\n)*?\\s+${k}:\\s*(true|false)`);
|
|
80
|
-
const match = content.match(re);
|
|
81
|
-
_autoIndexFlags[k] = match ? match[1] !== 'false' : true;
|
|
82
|
-
}
|
|
83
|
-
} catch { /* ignore, all default to true */ }
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return _autoIndexFlags[key] !== false;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function runStep(label, cmd, args, timeoutMs = 120_000) {
|
|
90
|
-
const start = Date.now();
|
|
91
|
-
log(`START ${label}`);
|
|
92
|
-
try {
|
|
93
|
-
execFileSync(cmd, args, {
|
|
94
|
-
cwd: projectRoot,
|
|
95
|
-
timeout: timeoutMs,
|
|
96
|
-
stdio: 'ignore',
|
|
97
|
-
windowsHide: true,
|
|
98
|
-
});
|
|
99
|
-
const elapsed = ((Date.now() - start) / 1000).toFixed(1);
|
|
100
|
-
log(`DONE ${label} (${elapsed}s)`);
|
|
101
|
-
return true;
|
|
102
|
-
} catch (err) {
|
|
103
|
-
const elapsed = ((Date.now() - start) / 1000).toFixed(1);
|
|
104
|
-
log(`FAIL ${label} (${elapsed}s): ${err.message?.split('\n')[0] || 'unknown'}`);
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
async function main() {
|
|
110
|
-
const startTime = Date.now();
|
|
111
|
-
log('Sequential indexing chain started');
|
|
112
|
-
|
|
113
|
-
// 1. Guidance indexer
|
|
114
|
-
if (isIndexEnabled('guidance')) {
|
|
115
|
-
const guidanceScript = resolveBin('flo-index', 'index-guidance.mjs');
|
|
116
|
-
if (guidanceScript) {
|
|
117
|
-
runStep('guidance-index', 'node', [guidanceScript, '--no-embeddings']);
|
|
118
|
-
} else {
|
|
119
|
-
log('SKIP guidance-index (script not found)');
|
|
120
|
-
}
|
|
121
|
-
} else {
|
|
122
|
-
log('SKIP guidance-index (disabled in moflo.yaml)');
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// 2. Code map generator (the big one — ~22s)
|
|
126
|
-
if (isIndexEnabled('code_map')) {
|
|
127
|
-
const codeMapScript = resolveBin('flo-codemap', 'generate-code-map.mjs');
|
|
128
|
-
if (codeMapScript) {
|
|
129
|
-
runStep('code-map', 'node', [codeMapScript, '--no-embeddings'], 180_000);
|
|
130
|
-
} else {
|
|
131
|
-
log('SKIP code-map (script not found)');
|
|
132
|
-
}
|
|
133
|
-
} else {
|
|
134
|
-
log('SKIP code-map (disabled in moflo.yaml)');
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// 3. Test indexer
|
|
138
|
-
if (isIndexEnabled('tests')) {
|
|
139
|
-
const testScript = resolveBin('flo-testmap', 'index-tests.mjs');
|
|
140
|
-
if (testScript) {
|
|
141
|
-
runStep('test-index', 'node', [testScript, '--no-embeddings']);
|
|
142
|
-
} else {
|
|
143
|
-
log('SKIP test-index (script not found)');
|
|
144
|
-
}
|
|
145
|
-
} else {
|
|
146
|
-
log('SKIP test-index (disabled in moflo.yaml)');
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// 4. Patterns indexer
|
|
150
|
-
if (isIndexEnabled('patterns')) {
|
|
151
|
-
const patternsScript = resolveBin('flo-patterns', 'index-patterns.mjs');
|
|
152
|
-
if (patternsScript) {
|
|
153
|
-
runStep('patterns-index', 'node', [patternsScript]);
|
|
154
|
-
} else {
|
|
155
|
-
log('SKIP patterns-index (script not found)');
|
|
156
|
-
}
|
|
157
|
-
} else {
|
|
158
|
-
log('SKIP patterns-index (disabled in moflo.yaml)');
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// 5. Pretrain (extracts patterns from repository)
|
|
162
|
-
const localCli = getLocalCliPath();
|
|
163
|
-
if (localCli) {
|
|
164
|
-
runStep('pretrain', 'node', [localCli, 'hooks', 'pretrain']);
|
|
165
|
-
} else {
|
|
166
|
-
log('SKIP pretrain (CLI not found)');
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// 6. Build embeddings — single pass for ALL namespaces, after all indexers finish.
|
|
170
|
-
// Individual indexers are called with --no-embeddings to prevent background
|
|
171
|
-
// embedding spawns that race with this chain (sql.js last-write-wins).
|
|
172
|
-
const embeddingsScript = resolveBin('flo-embeddings', 'build-embeddings.mjs');
|
|
173
|
-
if (embeddingsScript) {
|
|
174
|
-
runStep('build-embeddings', 'node', [embeddingsScript], 300_000);
|
|
175
|
-
} else {
|
|
176
|
-
log('SKIP build-embeddings (script not found)');
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// 7. HNSW rebuild — MUST run last, after all writes are committed (#81)
|
|
180
|
-
if (localCli) {
|
|
181
|
-
runStep('hnsw-rebuild', 'node', [localCli, 'memory', 'rebuild', '--force']);
|
|
182
|
-
} else {
|
|
183
|
-
log('SKIP hnsw-rebuild (CLI not found)');
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const totalElapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
187
|
-
log(`Sequential indexing chain complete (${totalElapsed}s)`);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
main().catch(err => {
|
|
191
|
-
log(`FATAL: ${err.message}`);
|
|
192
|
-
process.exit(1);
|
|
193
|
-
});
|
|
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
|
+
|
|
19
|
+
// Detect project root by walking up from cwd to find package.json.
|
|
20
|
+
// IMPORTANT: Do NOT use resolve(__dirname, '..') — this script lives in bin/
|
|
21
|
+
// during development but gets synced to .claude/scripts/ in consumer projects,
|
|
22
|
+
// so __dirname-relative paths break. findProjectRoot() works in both locations.
|
|
23
|
+
function findProjectRoot() {
|
|
24
|
+
let dir = process.cwd();
|
|
25
|
+
const root = resolve(dir, '/');
|
|
26
|
+
while (dir !== root) {
|
|
27
|
+
if (existsSync(resolve(dir, 'package.json'))) return dir;
|
|
28
|
+
dir = dirname(dir);
|
|
29
|
+
}
|
|
30
|
+
return process.cwd();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const projectRoot = findProjectRoot();
|
|
34
|
+
const LOG_PATH = resolve(projectRoot, '.swarm/hooks.log');
|
|
35
|
+
|
|
36
|
+
function log(msg) {
|
|
37
|
+
const ts = new Date().toISOString().replace('T', ' ').slice(0, 19);
|
|
38
|
+
const line = `[${ts}] [index-all] ${msg}\n`;
|
|
39
|
+
try { appendFileSync(LOG_PATH, line); } catch { /* ignore */ }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function resolveBin(binName, localScript) {
|
|
43
|
+
const mofloScript = resolve(projectRoot, 'node_modules/moflo/bin', localScript);
|
|
44
|
+
if (existsSync(mofloScript)) return mofloScript;
|
|
45
|
+
const npmBin = resolve(projectRoot, 'node_modules/.bin', binName);
|
|
46
|
+
if (existsSync(npmBin)) return npmBin;
|
|
47
|
+
const localPath = resolve(projectRoot, '.claude/scripts', localScript);
|
|
48
|
+
if (existsSync(localPath)) return localPath;
|
|
49
|
+
// Also check bin/ directory (for development use)
|
|
50
|
+
const binPath = resolve(projectRoot, 'bin', localScript);
|
|
51
|
+
if (existsSync(binPath)) return binPath;
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function getLocalCliPath() {
|
|
56
|
+
const paths = [
|
|
57
|
+
resolve(projectRoot, 'node_modules/moflo/src/@claude-flow/cli/bin/cli.js'),
|
|
58
|
+
resolve(projectRoot, 'node_modules/moflo/bin/cli.js'),
|
|
59
|
+
resolve(projectRoot, 'node_modules/.bin/flo'),
|
|
60
|
+
// Development: local CLI
|
|
61
|
+
resolve(projectRoot, 'src/@claude-flow/cli/bin/cli.js'),
|
|
62
|
+
];
|
|
63
|
+
for (const p of paths) {
|
|
64
|
+
if (existsSync(p)) return p;
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Read moflo.yaml once and cache auto_index flags. */
|
|
70
|
+
let _autoIndexFlags = null;
|
|
71
|
+
function isIndexEnabled(key) {
|
|
72
|
+
if (_autoIndexFlags === null) {
|
|
73
|
+
_autoIndexFlags = {};
|
|
74
|
+
const yamlPath = resolve(projectRoot, 'moflo.yaml');
|
|
75
|
+
if (existsSync(yamlPath)) {
|
|
76
|
+
try {
|
|
77
|
+
const content = readFileSync(yamlPath, 'utf-8');
|
|
78
|
+
for (const k of ['guidance', 'code_map', 'tests', 'patterns']) {
|
|
79
|
+
const re = new RegExp(`auto_index:\\s*\\n(?:.*\\n)*?\\s+${k}:\\s*(true|false)`);
|
|
80
|
+
const match = content.match(re);
|
|
81
|
+
_autoIndexFlags[k] = match ? match[1] !== 'false' : true;
|
|
82
|
+
}
|
|
83
|
+
} catch { /* ignore, all default to true */ }
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return _autoIndexFlags[key] !== false;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function runStep(label, cmd, args, timeoutMs = 120_000) {
|
|
90
|
+
const start = Date.now();
|
|
91
|
+
log(`START ${label}`);
|
|
92
|
+
try {
|
|
93
|
+
execFileSync(cmd, args, {
|
|
94
|
+
cwd: projectRoot,
|
|
95
|
+
timeout: timeoutMs,
|
|
96
|
+
stdio: 'ignore',
|
|
97
|
+
windowsHide: true,
|
|
98
|
+
});
|
|
99
|
+
const elapsed = ((Date.now() - start) / 1000).toFixed(1);
|
|
100
|
+
log(`DONE ${label} (${elapsed}s)`);
|
|
101
|
+
return true;
|
|
102
|
+
} catch (err) {
|
|
103
|
+
const elapsed = ((Date.now() - start) / 1000).toFixed(1);
|
|
104
|
+
log(`FAIL ${label} (${elapsed}s): ${err.message?.split('\n')[0] || 'unknown'}`);
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function main() {
|
|
110
|
+
const startTime = Date.now();
|
|
111
|
+
log('Sequential indexing chain started');
|
|
112
|
+
|
|
113
|
+
// 1. Guidance indexer
|
|
114
|
+
if (isIndexEnabled('guidance')) {
|
|
115
|
+
const guidanceScript = resolveBin('flo-index', 'index-guidance.mjs');
|
|
116
|
+
if (guidanceScript) {
|
|
117
|
+
runStep('guidance-index', 'node', [guidanceScript, '--no-embeddings']);
|
|
118
|
+
} else {
|
|
119
|
+
log('SKIP guidance-index (script not found)');
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
log('SKIP guidance-index (disabled in moflo.yaml)');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 2. Code map generator (the big one — ~22s)
|
|
126
|
+
if (isIndexEnabled('code_map')) {
|
|
127
|
+
const codeMapScript = resolveBin('flo-codemap', 'generate-code-map.mjs');
|
|
128
|
+
if (codeMapScript) {
|
|
129
|
+
runStep('code-map', 'node', [codeMapScript, '--no-embeddings'], 180_000);
|
|
130
|
+
} else {
|
|
131
|
+
log('SKIP code-map (script not found)');
|
|
132
|
+
}
|
|
133
|
+
} else {
|
|
134
|
+
log('SKIP code-map (disabled in moflo.yaml)');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// 3. Test indexer
|
|
138
|
+
if (isIndexEnabled('tests')) {
|
|
139
|
+
const testScript = resolveBin('flo-testmap', 'index-tests.mjs');
|
|
140
|
+
if (testScript) {
|
|
141
|
+
runStep('test-index', 'node', [testScript, '--no-embeddings']);
|
|
142
|
+
} else {
|
|
143
|
+
log('SKIP test-index (script not found)');
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
log('SKIP test-index (disabled in moflo.yaml)');
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 4. Patterns indexer
|
|
150
|
+
if (isIndexEnabled('patterns')) {
|
|
151
|
+
const patternsScript = resolveBin('flo-patterns', 'index-patterns.mjs');
|
|
152
|
+
if (patternsScript) {
|
|
153
|
+
runStep('patterns-index', 'node', [patternsScript]);
|
|
154
|
+
} else {
|
|
155
|
+
log('SKIP patterns-index (script not found)');
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
log('SKIP patterns-index (disabled in moflo.yaml)');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// 5. Pretrain (extracts patterns from repository)
|
|
162
|
+
const localCli = getLocalCliPath();
|
|
163
|
+
if (localCli) {
|
|
164
|
+
runStep('pretrain', 'node', [localCli, 'hooks', 'pretrain']);
|
|
165
|
+
} else {
|
|
166
|
+
log('SKIP pretrain (CLI not found)');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// 6. Build embeddings — single pass for ALL namespaces, after all indexers finish.
|
|
170
|
+
// Individual indexers are called with --no-embeddings to prevent background
|
|
171
|
+
// embedding spawns that race with this chain (sql.js last-write-wins).
|
|
172
|
+
const embeddingsScript = resolveBin('flo-embeddings', 'build-embeddings.mjs');
|
|
173
|
+
if (embeddingsScript) {
|
|
174
|
+
runStep('build-embeddings', 'node', [embeddingsScript], 300_000);
|
|
175
|
+
} else {
|
|
176
|
+
log('SKIP build-embeddings (script not found)');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// 7. HNSW rebuild — MUST run last, after all writes are committed (#81)
|
|
180
|
+
if (localCli) {
|
|
181
|
+
runStep('hnsw-rebuild', 'node', [localCli, 'memory', 'rebuild', '--force']);
|
|
182
|
+
} else {
|
|
183
|
+
log('SKIP hnsw-rebuild (CLI not found)');
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const totalElapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
187
|
+
log(`Sequential indexing chain complete (${totalElapsed}s)`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
main().catch(err => {
|
|
191
|
+
log(`FATAL: ${err.message}`);
|
|
192
|
+
process.exit(1);
|
|
193
|
+
});
|
|
@@ -187,11 +187,11 @@ try {
|
|
|
187
187
|
const shippedFiles = readdirSync(shippedDir).filter(f => f.endsWith('.md'));
|
|
188
188
|
for (const file of shippedFiles) {
|
|
189
189
|
const src = resolve(shippedDir, file);
|
|
190
|
-
const dest = resolve(guidanceDir,
|
|
190
|
+
const dest = resolve(guidanceDir, file);
|
|
191
191
|
const header = `<!-- AUTO-GENERATED by moflo session-start. Do not edit — changes will be overwritten. -->\n<!-- Source: node_modules/moflo/.claude/guidance/shipped/${file} -->\n\n`;
|
|
192
192
|
const content = readFileSync(src, 'utf-8');
|
|
193
193
|
writeFileSync(dest, header + content);
|
|
194
|
-
currentManifest.push(`.claude/guidance
|
|
194
|
+
currentManifest.push(`.claude/guidance/${file}`);
|
|
195
195
|
}
|
|
196
196
|
} catch { /* non-fatal */ }
|
|
197
197
|
}
|
|
@@ -230,7 +230,7 @@ try {
|
|
|
230
230
|
if (existsSync(shippedDir)) {
|
|
231
231
|
const shippedFiles = readdirSync(shippedDir).filter(f => f.endsWith('.md'));
|
|
232
232
|
for (const file of shippedFiles) {
|
|
233
|
-
const dest = resolve(guidanceDir,
|
|
233
|
+
const dest = resolve(guidanceDir, file);
|
|
234
234
|
if (!existsSync(dest)) {
|
|
235
235
|
if (!existsSync(guidanceDir)) mkdirSync(guidanceDir, { recursive: true });
|
|
236
236
|
const header = `<!-- AUTO-GENERATED by moflo session-start. Do not edit — changes will be overwritten. -->\n<!-- Source: node_modules/moflo/.claude/guidance/shipped/${file} -->\n\n`;
|
|
@@ -187,11 +187,11 @@ try {
|
|
|
187
187
|
const shippedFiles = readdirSync(shippedDir).filter(f => f.endsWith('.md'));
|
|
188
188
|
for (const file of shippedFiles) {
|
|
189
189
|
const src = resolve(shippedDir, file);
|
|
190
|
-
const dest = resolve(guidanceDir,
|
|
190
|
+
const dest = resolve(guidanceDir, file);
|
|
191
191
|
const header = `<!-- AUTO-GENERATED by moflo session-start. Do not edit — changes will be overwritten. -->\n<!-- Source: node_modules/moflo/.claude/guidance/shipped/${file} -->\n\n`;
|
|
192
192
|
const content = readFileSync(src, 'utf-8');
|
|
193
193
|
writeFileSync(dest, header + content);
|
|
194
|
-
currentManifest.push(`.claude/guidance
|
|
194
|
+
currentManifest.push(`.claude/guidance/${file}`);
|
|
195
195
|
}
|
|
196
196
|
} catch { /* non-fatal */ }
|
|
197
197
|
}
|
|
@@ -230,7 +230,7 @@ try {
|
|
|
230
230
|
if (existsSync(shippedDir)) {
|
|
231
231
|
const shippedFiles = readdirSync(shippedDir).filter(f => f.endsWith('.md'));
|
|
232
232
|
for (const file of shippedFiles) {
|
|
233
|
-
const dest = resolve(guidanceDir,
|
|
233
|
+
const dest = resolve(guidanceDir, file);
|
|
234
234
|
if (!existsSync(dest)) {
|
|
235
235
|
if (!existsSync(guidanceDir)) mkdirSync(guidanceDir, { recursive: true });
|
|
236
236
|
const header = `<!-- AUTO-GENERATED by moflo session-start. Do not edit — changes will be overwritten. -->\n<!-- Source: node_modules/moflo/.claude/guidance/shipped/${file} -->\n\n`;
|
package/bin/setup-project.mjs
CHANGED
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
* npx flo-setup --check # Check if setup is current
|
|
12
12
|
*
|
|
13
13
|
* What it does:
|
|
14
|
-
* 1. Copies .claude/guidance/subagents.md → project's .claude/guidance/moflo-bootstrap.md
|
|
14
|
+
* 1. Copies .claude/guidance/shipped/moflo-subagents.md → project's .claude/guidance/moflo-bootstrap.md
|
|
15
15
|
* 2. Appends a subagent protocol section to CLAUDE.md (idempotent, with markers)
|
|
16
16
|
*
|
|
17
|
-
* The project can layer its own
|
|
17
|
+
* The project can layer its own guidance files on top for
|
|
18
18
|
* project-specific rules (companyId, entity templates, etc.).
|
|
19
19
|
*/
|
|
20
20
|
|
|
@@ -59,7 +59,7 @@ When the user asks you to remember something: \`mcp__moflo__memory_store\` with
|
|
|
59
59
|
- **Memory-first**: Must search memory before Glob/Grep/Read
|
|
60
60
|
- **TaskCreate-first**: Must call TaskCreate before spawning Agent tool
|
|
61
61
|
|
|
62
|
-
- **Task Icons**: \`TaskCreate\` MUST use ICON+[Role] format — see \`.claude/guidance/task-icons.md\`
|
|
62
|
+
- **Task Icons**: \`TaskCreate\` MUST use ICON+[Role] format — see \`.claude/guidance/moflo-task-icons.md\`
|
|
63
63
|
|
|
64
64
|
### MCP Tools (preferred over CLI)
|
|
65
65
|
|
|
@@ -116,10 +116,10 @@ function findProjectRoot() {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
function copyBootstrap(projectRoot) {
|
|
119
|
-
const shippedSource = join(mofloRoot, '.claude', 'guidance', 'shipped', 'subagents.md');
|
|
119
|
+
const shippedSource = join(mofloRoot, '.claude', 'guidance', 'shipped', 'moflo-subagents.md');
|
|
120
120
|
const source = existsSync(shippedSource)
|
|
121
121
|
? shippedSource
|
|
122
|
-
: join(mofloRoot, '.claude', 'guidance', 'subagents.md');
|
|
122
|
+
: join(mofloRoot, '.claude', 'guidance', 'moflo-subagents.md');
|
|
123
123
|
const targetDir = join(projectRoot, '.claude', 'guidance');
|
|
124
124
|
const target = join(targetDir, 'moflo-bootstrap.md');
|
|
125
125
|
|
|
@@ -131,8 +131,8 @@ function copyBootstrap(projectRoot) {
|
|
|
131
131
|
// Read source content and prepend auto-generated notice
|
|
132
132
|
const content = readFileSync(source, 'utf-8');
|
|
133
133
|
const header = `<!-- AUTO-GENERATED by flo-setup. Do not edit — changes will be overwritten. -->
|
|
134
|
-
<!-- Source: node_modules/moflo/.claude/guidance/subagents.md -->
|
|
135
|
-
<!-- To customize,
|
|
134
|
+
<!-- Source: node_modules/moflo/.claude/guidance/shipped/moflo-subagents.md -->
|
|
135
|
+
<!-- To customize, add project-specific guidance in .claude/guidance/. -->
|
|
136
136
|
|
|
137
137
|
`;
|
|
138
138
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "moflo",
|
|
3
|
-
"version": "4.8.
|
|
3
|
+
"version": "4.8.45",
|
|
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",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"@types/bcrypt": "^5.0.2",
|
|
90
90
|
"@types/node": "^20.19.37",
|
|
91
91
|
"eslint": "^8.0.0",
|
|
92
|
-
"moflo": "^4.8.
|
|
92
|
+
"moflo": "^4.8.44",
|
|
93
93
|
"tsx": "^4.21.0",
|
|
94
94
|
"typescript": "^5.9.3",
|
|
95
95
|
"vitest": "^4.0.0"
|