moflo 4.6.5 → 4.6.7
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/helpers/statusline.cjs +141 -121
- package/README.md +138 -52
- package/package.json +1 -1
- package/src/@claude-flow/cli/package.json +1 -1
|
@@ -31,6 +31,7 @@ function loadStatusLineConfig() {
|
|
|
31
31
|
const defaults = {
|
|
32
32
|
enabled: true,
|
|
33
33
|
branding: 'Moflo V4',
|
|
34
|
+
show_dir: true,
|
|
34
35
|
show_git: true,
|
|
35
36
|
show_model: true,
|
|
36
37
|
show_session: true,
|
|
@@ -42,7 +43,7 @@ function loadStatusLineConfig() {
|
|
|
42
43
|
show_adrs: true,
|
|
43
44
|
show_agentdb: true,
|
|
44
45
|
show_tests: true,
|
|
45
|
-
mode: '
|
|
46
|
+
mode: 'compact',
|
|
46
47
|
};
|
|
47
48
|
|
|
48
49
|
// Try moflo.yaml
|
|
@@ -159,38 +160,26 @@ function getGitInfo() {
|
|
|
159
160
|
staged: 0, ahead: 0, behind: 0,
|
|
160
161
|
};
|
|
161
162
|
|
|
162
|
-
//
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
'
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
const parts = raw.split('---SEP---').map(s => s.trim());
|
|
177
|
-
if (parts.length >= 4) {
|
|
178
|
-
result.name = parts[0] || 'user';
|
|
179
|
-
result.gitBranch = parts[1] || '';
|
|
180
|
-
|
|
181
|
-
// Parse porcelain status
|
|
182
|
-
if (parts[2]) {
|
|
183
|
-
for (const line of parts[2].split('\n')) {
|
|
184
|
-
if (!line || line.length < 2) continue;
|
|
185
|
-
const x = line[0], y = line[1];
|
|
186
|
-
if (x === '?' && y === '?') { result.untracked++; continue; }
|
|
187
|
-
if (x !== ' ' && x !== '?') result.staged++;
|
|
188
|
-
if (y !== ' ' && y !== '?') result.modified++;
|
|
189
|
-
}
|
|
163
|
+
// Individual git calls (cross-platform — sh -c fails on Windows)
|
|
164
|
+
result.name = safeExec('git config user.name', 2000) || 'user';
|
|
165
|
+
result.gitBranch = safeExec('git branch --show-current', 2000) || '';
|
|
166
|
+
|
|
167
|
+
// Parse porcelain status
|
|
168
|
+
const statusRaw = safeExec('git status --porcelain', 2000);
|
|
169
|
+
if (statusRaw) {
|
|
170
|
+
for (const line of statusRaw.split('\n')) {
|
|
171
|
+
if (!line || line.length < 2) continue;
|
|
172
|
+
const x = line[0], y = line[1];
|
|
173
|
+
if (x === '?' && y === '?') { result.untracked++; continue; }
|
|
174
|
+
if (x !== ' ' && x !== '?') result.staged++;
|
|
175
|
+
if (y !== ' ' && y !== '?') result.modified++;
|
|
190
176
|
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
{
|
|
191
180
|
|
|
192
181
|
// Parse ahead/behind
|
|
193
|
-
const ab = (
|
|
182
|
+
const ab = (safeExec('git rev-list --left-right --count HEAD...@{upstream}', 2000) || '0 0').split(/\s+/);
|
|
194
183
|
result.ahead = parseInt(ab[0]) || 0;
|
|
195
184
|
result.behind = parseInt(ab[1]) || 0;
|
|
196
185
|
}
|
|
@@ -669,26 +658,17 @@ function generateStatusline() {
|
|
|
669
658
|
}
|
|
670
659
|
|
|
671
660
|
// Multi-line dashboard (for --dashboard flag)
|
|
661
|
+
// Respects show_* toggles from moflo.yaml status_line config
|
|
672
662
|
function generateDashboard() {
|
|
673
663
|
const git = getGitInfo();
|
|
674
|
-
const modelName = getModelName();
|
|
675
|
-
const progress = getV3Progress();
|
|
676
|
-
const security = getSecurityStatus();
|
|
677
|
-
const swarm = getSwarmStatus();
|
|
678
|
-
const system = getSystemMetrics();
|
|
679
|
-
const adrs = getADRStatus();
|
|
680
|
-
const hooks = getHooksStatus();
|
|
681
|
-
const agentdb = getAgentDBStats();
|
|
682
|
-
const tests = getTestStats();
|
|
683
664
|
const session = getSessionStats();
|
|
684
|
-
const integration = getIntegrationStatus();
|
|
685
665
|
const lines = [];
|
|
686
666
|
|
|
687
|
-
// Header
|
|
667
|
+
// Header: branding + dir + git
|
|
688
668
|
let header = `${c.bold}${c.brightPurple}\u258A ${SL_CONFIG.branding}${c.reset}`;
|
|
689
|
-
|
|
690
|
-
if (git.gitBranch) {
|
|
691
|
-
header += ` ${c.
|
|
669
|
+
if (SL_CONFIG.show_dir) header += ` ${c.brightWhite}${path.basename(CWD)}${c.reset}`;
|
|
670
|
+
if (SL_CONFIG.show_git && git.gitBranch) {
|
|
671
|
+
header += ` ${c.brightBlue}\u23C7 ${git.gitBranch}${c.reset}`;
|
|
692
672
|
const changes = git.modified + git.staged + git.untracked;
|
|
693
673
|
if (changes > 0) {
|
|
694
674
|
let ind = '';
|
|
@@ -700,82 +680,112 @@ function generateDashboard() {
|
|
|
700
680
|
if (git.ahead > 0) header += ` ${c.brightGreen}\u2191${git.ahead}${c.reset}`;
|
|
701
681
|
if (git.behind > 0) header += ` ${c.brightRed}\u2193${git.behind}${c.reset}`;
|
|
702
682
|
}
|
|
703
|
-
|
|
704
|
-
|
|
683
|
+
if (SL_CONFIG.show_session && session.duration) {
|
|
684
|
+
header += ` ${c.dim}\u2502${c.reset} ${c.cyan}\u23F1 ${session.duration}${c.reset}`;
|
|
685
|
+
}
|
|
705
686
|
lines.push(header);
|
|
706
687
|
|
|
707
688
|
// Separator
|
|
708
|
-
lines.push(`${c.dim}
|
|
709
|
-
|
|
710
|
-
//
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
const
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
);
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
689
|
+
lines.push(`${c.dim}${'─'.repeat(53)}${c.reset}`);
|
|
690
|
+
|
|
691
|
+
// Swarm line (if enabled)
|
|
692
|
+
if (SL_CONFIG.show_swarm) {
|
|
693
|
+
const swarm = getSwarmStatus();
|
|
694
|
+
const system = getSystemMetrics();
|
|
695
|
+
const swarmInd = swarm.coordinationActive ? `${c.brightGreen}\u25C9${c.reset}` : `${c.dim}\u25CB${c.reset}`;
|
|
696
|
+
const agentsColor = swarm.activeAgents > 0 ? c.brightGreen : c.red;
|
|
697
|
+
lines.push(
|
|
698
|
+
`${c.brightYellow}\uD83E\uDD16 Swarm${c.reset} ${swarmInd} [${agentsColor}${String(swarm.activeAgents).padStart(2)}${c.reset}/${c.brightWhite}${swarm.maxAgents}${c.reset}] ` +
|
|
699
|
+
`${c.brightPurple}\uD83D\uDC65 ${system.subAgents}${c.reset} ` +
|
|
700
|
+
`${c.brightCyan}\uD83D\uDCBE ${system.memoryMB}MB${c.reset}`
|
|
701
|
+
);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
// AgentDB + MCP line (if either enabled)
|
|
705
|
+
if (SL_CONFIG.show_agentdb || SL_CONFIG.show_mcp) {
|
|
706
|
+
const parts = [];
|
|
707
|
+
if (SL_CONFIG.show_agentdb) {
|
|
708
|
+
const agentdb = getAgentDBStats();
|
|
709
|
+
const hnswInd = agentdb.hasHnsw ? `${c.brightGreen}\u26A1${c.reset}` : '';
|
|
710
|
+
const sizeDisp = agentdb.dbSizeKB >= 1024 ? `${(agentdb.dbSizeKB / 1024).toFixed(1)}MB` : `${agentdb.dbSizeKB}KB`;
|
|
711
|
+
const vectorColor = agentdb.vectorCount > 0 ? c.brightGreen : c.dim;
|
|
712
|
+
parts.push(`${c.cyan}Vectors${c.reset} ${vectorColor}\u25CF${agentdb.vectorCount}${hnswInd}${c.reset}`);
|
|
713
|
+
parts.push(`${c.cyan}Size${c.reset} ${c.brightWhite}${sizeDisp}${c.reset}`);
|
|
714
|
+
}
|
|
715
|
+
if (SL_CONFIG.show_mcp) {
|
|
716
|
+
const integration = getIntegrationStatus();
|
|
717
|
+
if (integration.mcpServers.total > 0) {
|
|
718
|
+
const mcpCol = integration.mcpServers.enabled === integration.mcpServers.total ? c.brightGreen :
|
|
719
|
+
integration.mcpServers.enabled > 0 ? c.brightYellow : c.red;
|
|
720
|
+
parts.push(`${c.cyan}MCP${c.reset} ${mcpCol}\u25CF${integration.mcpServers.enabled}/${integration.mcpServers.total}${c.reset}`);
|
|
721
|
+
}
|
|
722
|
+
if (integration.hasDatabase) parts.push(`${c.brightGreen}\u25C6${c.reset}DB`);
|
|
723
|
+
}
|
|
724
|
+
if (parts.length > 0) {
|
|
725
|
+
lines.push(`${c.brightCyan}\uD83D\uDCCA AgentDB${c.reset} ${parts.join(` ${c.dim}\u2502${c.reset} `)}`);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
return lines.join('\n');
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
// Compact dashboard: header + single combined line
|
|
733
|
+
function generateCompactDashboard() {
|
|
734
|
+
const git = getGitInfo();
|
|
735
|
+
const session = getSessionStats();
|
|
736
|
+
const lines = [];
|
|
737
|
+
|
|
738
|
+
// Header: branding + dir + git + session
|
|
739
|
+
let header = `${c.bold}${c.brightPurple}\u258A ${SL_CONFIG.branding}${c.reset}`;
|
|
740
|
+
if (SL_CONFIG.show_dir) header += ` ${c.brightWhite}${path.basename(CWD)}${c.reset}`;
|
|
741
|
+
if (SL_CONFIG.show_git && git.gitBranch) {
|
|
742
|
+
header += ` ${c.brightBlue}\u23C7 ${git.gitBranch}${c.reset}`;
|
|
743
|
+
const changes = git.modified + git.staged + git.untracked;
|
|
744
|
+
if (changes > 0) {
|
|
745
|
+
let ind = '';
|
|
746
|
+
if (git.staged > 0) ind += `${c.brightGreen}+${git.staged}${c.reset}`;
|
|
747
|
+
if (git.modified > 0) ind += `${c.brightYellow}~${git.modified}${c.reset}`;
|
|
748
|
+
if (git.untracked > 0) ind += `${c.dim}?${git.untracked}${c.reset}`;
|
|
749
|
+
header += ` ${ind}`;
|
|
750
|
+
}
|
|
751
|
+
if (git.ahead > 0) header += ` ${c.brightGreen}\u2191${git.ahead}${c.reset}`;
|
|
752
|
+
if (git.behind > 0) header += ` ${c.brightRed}\u2193${git.behind}${c.reset}`;
|
|
753
|
+
}
|
|
754
|
+
if (SL_CONFIG.show_session && session.duration) {
|
|
755
|
+
header += ` ${c.dim}\u2502${c.reset} ${c.cyan}\u23F1 ${session.duration}${c.reset}`;
|
|
756
|
+
}
|
|
757
|
+
lines.push(header);
|
|
758
|
+
|
|
759
|
+
// Combined swarm + agentdb + mcp line
|
|
760
|
+
const segments = [];
|
|
761
|
+
if (SL_CONFIG.show_swarm) {
|
|
762
|
+
const swarm = getSwarmStatus();
|
|
763
|
+
const swarmInd = swarm.coordinationActive ? `${c.brightGreen}\u25C9${c.reset}` : `${c.dim}\u25CB${c.reset}`;
|
|
764
|
+
const agentsColor = swarm.activeAgents > 0 ? c.brightGreen : c.red;
|
|
765
|
+
segments.push(
|
|
766
|
+
`${c.brightYellow}\uD83E\uDD16${c.reset} ${swarmInd}[${agentsColor}${swarm.activeAgents}${c.reset}/${c.brightWhite}${swarm.maxAgents}${c.reset}]`
|
|
767
|
+
);
|
|
768
|
+
}
|
|
769
|
+
if (SL_CONFIG.show_agentdb) {
|
|
770
|
+
const agentdb = getAgentDBStats();
|
|
771
|
+
const hnswInd = agentdb.hasHnsw ? `\u26A1` : '';
|
|
772
|
+
const sizeDisp = agentdb.dbSizeKB >= 1024 ? `${(agentdb.dbSizeKB / 1024).toFixed(1)}MB` : `${agentdb.dbSizeKB}KB`;
|
|
773
|
+
const vectorColor = agentdb.vectorCount > 0 ? c.brightGreen : c.dim;
|
|
774
|
+
segments.push(
|
|
775
|
+
`${c.brightCyan}\uD83D\uDCCA${c.reset} ${vectorColor}${agentdb.vectorCount}${hnswInd}${c.reset} ${c.dim}(${sizeDisp})${c.reset}`
|
|
776
|
+
);
|
|
777
|
+
}
|
|
778
|
+
if (SL_CONFIG.show_mcp) {
|
|
779
|
+
const integration = getIntegrationStatus();
|
|
780
|
+
if (integration.mcpServers.total > 0) {
|
|
781
|
+
const mcpCol = integration.mcpServers.enabled === integration.mcpServers.total ? c.brightGreen :
|
|
782
|
+
integration.mcpServers.enabled > 0 ? c.brightYellow : c.red;
|
|
783
|
+
segments.push(`${c.cyan}MCP${c.reset} ${mcpCol}\u25CF${integration.mcpServers.enabled}/${integration.mcpServers.total}${c.reset}`);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
if (segments.length > 0) {
|
|
787
|
+
lines.push(segments.join(` ${c.dim}\u2502${c.reset} `));
|
|
788
|
+
}
|
|
779
789
|
|
|
780
790
|
return lines.join('\n');
|
|
781
791
|
}
|
|
@@ -799,13 +809,23 @@ function generateJSON() {
|
|
|
799
809
|
}
|
|
800
810
|
|
|
801
811
|
// ─── Main ───────────────────────────────────────────────────────
|
|
802
|
-
|
|
812
|
+
// CLI flags take precedence over moflo.yaml mode
|
|
813
|
+
const cliMode = process.argv.includes('--json') ? 'json'
|
|
814
|
+
: process.argv.includes('--json-compact') ? 'json-compact'
|
|
815
|
+
: process.argv.includes('--dashboard') ? 'dashboard'
|
|
816
|
+
: process.argv.includes('--compact') ? 'compact'
|
|
817
|
+
: process.argv.includes('--single-line') ? 'single-line'
|
|
818
|
+
: null;
|
|
819
|
+
const mode = cliMode || SL_CONFIG.mode || 'compact';
|
|
820
|
+
|
|
821
|
+
if (mode === 'json') {
|
|
803
822
|
console.log(JSON.stringify(generateJSON(), null, 2));
|
|
804
|
-
} else if (
|
|
823
|
+
} else if (mode === 'json-compact') {
|
|
805
824
|
console.log(JSON.stringify(generateJSON()));
|
|
806
|
-
} else if (
|
|
825
|
+
} else if (mode === 'dashboard') {
|
|
807
826
|
console.log(generateDashboard());
|
|
827
|
+
} else if (mode === 'compact') {
|
|
828
|
+
console.log(generateCompactDashboard());
|
|
808
829
|
} else {
|
|
809
|
-
// Default: single-line statusline
|
|
810
830
|
console.log(generateStatusline());
|
|
811
831
|
}
|
package/README.md
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
# MoFlo
|
|
6
6
|
|
|
7
|
-
**An opinionated
|
|
7
|
+
**An opinionated fork of [Ruflo/Claude Flow](https://github.com/ruvnet/ruflo), optimized for local development.**
|
|
8
8
|
|
|
9
|
-
MoFlo adds automatic code and guidance cataloging along with memory gating on top of the original Claude Flow orchestration engine. Where the upstream project provides raw building blocks, MoFlo ships opinionated defaults — workflow gates that enforce memory-first patterns, semantic indexing that runs at session start, and learned routing that improves over time — so you get a productive setup from `flo init` without manual tuning.
|
|
9
|
+
MoFlo adds automatic code and guidance cataloging along with memory gating on top of the original Ruflo/Claude Flow orchestration engine. Where the upstream project provides raw building blocks, MoFlo ships opinionated defaults — workflow gates that enforce memory-first patterns, semantic indexing that runs at session start, and learned routing that improves over time — so you get a productive setup from `flo init` without manual tuning.
|
|
10
10
|
|
|
11
11
|
Install it as a dev dependency and run `flo init`.
|
|
12
12
|
|
|
@@ -23,29 +23,82 @@ Install it as a dev dependency and run `flo init`.
|
|
|
23
23
|
| **Context Tracking** | Monitors context window usage (FRESH → MODERATE → DEPLETED → CRITICAL) and advises accordingly. |
|
|
24
24
|
| **Cross-Platform** | Works on macOS, Linux, and Windows. |
|
|
25
25
|
|
|
26
|
-
##
|
|
26
|
+
## Getting Started
|
|
27
|
+
|
|
28
|
+
### 1. Install and init
|
|
27
29
|
|
|
28
30
|
```bash
|
|
29
|
-
# Install as a dev dependency
|
|
30
31
|
npm install --save-dev moflo
|
|
31
|
-
|
|
32
|
-
# Initialize your project (generates config, hooks, skill, CLAUDE.md section)
|
|
33
32
|
npx flo init
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`flo init` automatically scans your project to find where your guidance and code live, then writes the results into `moflo.yaml`. It looks for:
|
|
36
|
+
|
|
37
|
+
| What | Directories it checks | Default if none found |
|
|
38
|
+
|------|----------------------|----------------------|
|
|
39
|
+
| **Guidance** | `.claude/guidance`, `docs/guides`, `docs`, `architecture`, `adr`, `.cursor/rules` | `.claude/guidance` |
|
|
40
|
+
| **Source code** | `src`, `packages`, `lib`, `app`, `apps`, `services`, `server`, `client` | `src` |
|
|
41
|
+
| **Languages** | Scans detected source dirs for file extensions | `.ts`, `.tsx`, `.js`, `.jsx` |
|
|
42
|
+
|
|
43
|
+
It also generates:
|
|
34
44
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
45
|
+
| Generated File | Purpose |
|
|
46
|
+
|----------------|---------|
|
|
47
|
+
| `moflo.yaml` | Project config with detected guidance/code locations |
|
|
48
|
+
| `.claude/settings.json` | Workflow gate hooks for Claude Code |
|
|
49
|
+
| `.claude/skills/flo/` | The `/flo` issue execution skill (also `/fl`) |
|
|
50
|
+
| `CLAUDE.md` section | Teaches Claude how to use MoFlo |
|
|
51
|
+
| `.gitignore` entries | Excludes MoFlo state directories |
|
|
38
52
|
|
|
39
|
-
|
|
40
|
-
|
|
53
|
+
In interactive mode (`flo init` without `--yes`), it shows what it found and lets you confirm or adjust before writing.
|
|
54
|
+
|
|
55
|
+
### 2. Review your guidance and code settings
|
|
56
|
+
|
|
57
|
+
Open `moflo.yaml` to see what init detected. The two key sections:
|
|
58
|
+
|
|
59
|
+
**Guidance** — documentation that helps Claude understand your project (conventions, architecture, domain context):
|
|
60
|
+
|
|
61
|
+
```yaml
|
|
62
|
+
guidance:
|
|
63
|
+
directories:
|
|
64
|
+
- .claude/guidance # project rules, patterns, conventions
|
|
65
|
+
- docs # general documentation
|
|
41
66
|
```
|
|
42
67
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
-
|
|
68
|
+
**Code map** — source files to index for "where does X live?" navigation:
|
|
69
|
+
|
|
70
|
+
```yaml
|
|
71
|
+
code_map:
|
|
72
|
+
directories:
|
|
73
|
+
- src # your source code
|
|
74
|
+
- packages # shared packages (monorepo)
|
|
75
|
+
extensions: [".ts", ".tsx"]
|
|
76
|
+
exclude: [node_modules, dist, .next, coverage]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
MoFlo chunks your guidance files into semantic embeddings and indexes your code structure, so Claude searches your knowledge base before touching any files. Adjust these directories to match your project:
|
|
80
|
+
|
|
81
|
+
```yaml
|
|
82
|
+
# Monorepo with shared docs
|
|
83
|
+
guidance:
|
|
84
|
+
directories: [.claude/guidance, docs, packages/shared/docs]
|
|
85
|
+
code_map:
|
|
86
|
+
directories: [packages, apps, libs]
|
|
87
|
+
|
|
88
|
+
# Backend + frontend
|
|
89
|
+
code_map:
|
|
90
|
+
directories: [server/src, client/src]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 3. Index and verify
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
npx flo memory index-guidance # Index your guidance docs
|
|
97
|
+
npx flo memory code-map # Index your code structure
|
|
98
|
+
npx flo doctor # Verify everything works
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Both indexes run automatically at session start after this, so you only need to run them manually on first setup or after major structural changes.
|
|
49
102
|
|
|
50
103
|
## Commands
|
|
51
104
|
|
|
@@ -120,21 +173,22 @@ flo doctor # Health check
|
|
|
120
173
|
flo --version # Show version
|
|
121
174
|
```
|
|
122
175
|
|
|
123
|
-
## Configuration
|
|
124
176
|
|
|
125
|
-
|
|
177
|
+
## Full Configuration Reference
|
|
178
|
+
|
|
179
|
+
`flo init` generates a `moflo.yaml` at your project root. Here's the complete set of options:
|
|
126
180
|
|
|
127
181
|
```yaml
|
|
128
182
|
project:
|
|
129
183
|
name: "my-project"
|
|
130
184
|
|
|
131
185
|
guidance:
|
|
132
|
-
directories: [.claude/guidance]
|
|
186
|
+
directories: [.claude/guidance]
|
|
133
187
|
namespace: guidance
|
|
134
188
|
|
|
135
189
|
code_map:
|
|
136
|
-
directories: [src, packages]
|
|
137
|
-
extensions: [".ts", ".tsx"]
|
|
190
|
+
directories: [src, packages]
|
|
191
|
+
extensions: [".ts", ".tsx"]
|
|
138
192
|
exclude: [node_modules, dist]
|
|
139
193
|
namespace: code-map
|
|
140
194
|
|
|
@@ -147,42 +201,37 @@ auto_index:
|
|
|
147
201
|
guidance: true # Auto-index docs on session start
|
|
148
202
|
code_map: true # Auto-index code on session start
|
|
149
203
|
|
|
150
|
-
# Hook toggles (all on by default — disable to slim down)
|
|
151
204
|
hooks:
|
|
152
205
|
pre_edit: true # Track file edits for learning
|
|
153
|
-
post_edit: true # Record edit outcomes
|
|
154
|
-
pre_task: true #
|
|
206
|
+
post_edit: true # Record edit outcomes
|
|
207
|
+
pre_task: true # Agent routing before task spawn
|
|
155
208
|
post_task: true # Record task results for learning
|
|
156
209
|
gate: true # Workflow gate enforcement
|
|
157
|
-
route: true # Intelligent task routing
|
|
210
|
+
route: true # Intelligent task routing
|
|
158
211
|
stop_hook: true # Session-end persistence
|
|
159
212
|
session_restore: true # Restore session state on start
|
|
160
|
-
notification: true # Hook into Claude Code notifications
|
|
161
213
|
|
|
162
214
|
models:
|
|
163
|
-
default: opus
|
|
164
|
-
research: sonnet
|
|
165
|
-
review: opus
|
|
166
|
-
test: sonnet
|
|
215
|
+
default: opus
|
|
216
|
+
research: sonnet
|
|
217
|
+
review: opus
|
|
218
|
+
test: sonnet
|
|
167
219
|
|
|
168
|
-
# Optional: intelligent model routing (off by default)
|
|
169
220
|
model_routing:
|
|
170
|
-
enabled: false
|
|
221
|
+
enabled: false # Set to true for automatic model selection
|
|
171
222
|
confidence_threshold: 0.85
|
|
172
223
|
cost_optimization: true
|
|
173
224
|
circuit_breaker: true
|
|
174
225
|
|
|
175
|
-
# Status line display
|
|
176
226
|
status_line:
|
|
177
227
|
enabled: true
|
|
178
|
-
branding: "
|
|
179
|
-
mode:
|
|
228
|
+
branding: "MoFlo V4"
|
|
229
|
+
mode: compact # single-line, compact, or dashboard
|
|
230
|
+
show_dir: true # current directory name (compact/dashboard only)
|
|
180
231
|
show_git: true
|
|
181
|
-
show_model: true
|
|
182
232
|
show_session: true
|
|
183
|
-
show_intelligence: true
|
|
184
233
|
show_swarm: true
|
|
185
|
-
|
|
234
|
+
show_agentdb: true
|
|
186
235
|
show_mcp: true
|
|
187
236
|
```
|
|
188
237
|
|
|
@@ -228,13 +277,54 @@ MoFlo installs Claude Code hooks that run on every tool call. Together, these ga
|
|
|
228
277
|
|
|
229
278
|
All gates are configurable via `moflo.yaml` — you can disable any individual hook if it doesn't suit your workflow.
|
|
230
279
|
|
|
231
|
-
###
|
|
280
|
+
### Intelligent Agent Routing
|
|
281
|
+
|
|
282
|
+
MoFlo ships with 12 built-in task patterns that map common work to the right agent type:
|
|
283
|
+
|
|
284
|
+
| Pattern | Keywords | Primary Agent |
|
|
285
|
+
|---------|----------|---------------|
|
|
286
|
+
| security-task | auth, password, encryption, CVE | security-architect |
|
|
287
|
+
| testing-task | test, spec, coverage, e2e | tester |
|
|
288
|
+
| database-task | schema, migration, SQL, ORM | architect |
|
|
289
|
+
| feature-task | implement, add, create, build | architect → coder |
|
|
290
|
+
| bugfix-task | bug, fix, error, crash, debug | coder |
|
|
291
|
+
| api-task | endpoint, REST, route, handler | architect → coder |
|
|
292
|
+
| ... | | *(12 patterns total)* |
|
|
293
|
+
|
|
294
|
+
When you route a task (`flo hooks route --task "..."` or via MCP), MoFlo runs semantic similarity against these patterns using HNSW vector search and returns a ranked recommendation with confidence scores.
|
|
295
|
+
|
|
296
|
+
**The routing gets smarter over time.** Every time a task completes successfully, MoFlo's post-task hook records the outcome — the full task description, which agent handled it, and whether it succeeded. These learned patterns are combined with the built-in seeds on every future route call. Because learned patterns contain rich task descriptions (not just short keywords), they discriminate better as they accumulate.
|
|
232
297
|
|
|
233
|
-
|
|
298
|
+
Routing outcomes are stored in `.claude-flow/routing-outcomes.json` and persist across sessions. You can inspect them with `flo hooks patterns` or transfer them between projects with `flo hooks transfer`.
|
|
234
299
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
300
|
+
### The Two-Layer Task System
|
|
301
|
+
|
|
302
|
+
MoFlo doesn't replace your AI client's task system — it wraps it. Your client (Claude Code, Cursor, or any MCP-capable tool) handles spawning agents and running code. MoFlo adds a coordination layer on top that handles memory, routing, and learning.
|
|
303
|
+
|
|
304
|
+
```
|
|
305
|
+
┌──────────────────────────────────────────────────┐
|
|
306
|
+
│ YOUR AI CLIENT (Execution Layer) │
|
|
307
|
+
│ Spawns agents, runs code, streams output │
|
|
308
|
+
│ TaskCreate → Agent → TaskUpdate → results │
|
|
309
|
+
├──────────────────────────────────────────────────┤
|
|
310
|
+
│ MOFLO (Knowledge Layer) │
|
|
311
|
+
│ Routes tasks, gates agent spawns, stores │
|
|
312
|
+
│ patterns, learns from outcomes │
|
|
313
|
+
└──────────────────────────────────────────────────┘
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Here's how a typical task flows through both layers:
|
|
317
|
+
|
|
318
|
+
1. **MoFlo routes** — Before work starts, MoFlo analyzes the prompt and recommends an agent type and model tier via hook or MCP tool.
|
|
319
|
+
2. **MoFlo gates** — Before an agent can spawn, MoFlo verifies that memory was searched and a task was registered. This prevents blind exploration.
|
|
320
|
+
3. **Your client executes** — The actual agent runs through your client's native task system. MoFlo doesn't manage the agent — your client handles execution, output, and completion.
|
|
321
|
+
4. **MoFlo learns** — After the agent finishes, MoFlo records what worked (or didn't) in its memory database. Successful patterns feed into future routing.
|
|
322
|
+
|
|
323
|
+
The key insight: **your client handles execution, MoFlo handles knowledge.** Your client is good at spawning agents and running code. MoFlo is good at remembering what happened, routing to the right agent, and ensuring prior knowledge is checked before exploring from scratch.
|
|
324
|
+
|
|
325
|
+
For complex work, MoFlo structures tasks into waves — a research wave discovers context, then an implementation wave acts on it — with dependencies tracked through both the client's task system and MoFlo's coordination layer. The full integration pattern is documented in `.claude/guidance/task-swarm-integration.md`.
|
|
326
|
+
|
|
327
|
+
The `/flo` skill ties both systems together for GitHub issues — driving a full workflow (research → enhance → implement → test → simplify → PR) with your client's agents for execution and MoFlo's memory for continuity.
|
|
238
328
|
|
|
239
329
|
### Memory & Knowledge Storage
|
|
240
330
|
|
|
@@ -262,18 +352,14 @@ When `flo init` runs, it appends a workflow section to your CLAUDE.md that teach
|
|
|
262
352
|
|
|
263
353
|
## Architecture
|
|
264
354
|
|
|
265
|
-
MoFlo is a maintained fork of [ruflo 3.x](https://github.com/ruvnet/ruflo) with:
|
|
266
|
-
|
|
267
|
-
- **3 patches applied to TypeScript source** (no more monkey-patching node_modules):
|
|
268
|
-
- 384-dim domain-aware embeddings for consistent CLI ↔ MCP search
|
|
269
|
-
- `windowsHide: true` on all spawn/exec calls (Windows UX)
|
|
270
|
-
- Routing learned patterns (task outcomes feed back into routing)
|
|
271
355
|
- **7 standalone bin scripts** shipped with npm: `flo-search`, `flo-embeddings`, `flo-index`, `flo-codemap`, `flo-learn`, `flo-setup`, plus the main `flo` CLI
|
|
272
356
|
- **Project config system**: `moflo.yaml` for per-project settings
|
|
273
357
|
- **One-stop init**: `flo init` generates everything needed for OOTB operation
|
|
274
358
|
|
|
275
|
-
|
|
359
|
+
## Ruflo / Claude Flow
|
|
360
|
+
|
|
361
|
+
MoFlo builds on top of the full [Ruflo/Claude Flow](https://github.com/ruvnet/ruflo) engine. For detailed documentation on the underlying capabilities — swarm topologies, hive-mind consensus, HNSW vector search, neural routing, MCP server internals, and more — check out the [Ruflo repository](https://github.com/ruvnet/ruflo).
|
|
276
362
|
|
|
277
363
|
## License
|
|
278
364
|
|
|
279
|
-
MIT (inherited from [
|
|
365
|
+
MIT (inherited from [Ruflo/Claude Flow](https://github.com/ruvnet/ruflo))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "moflo",
|
|
3
|
-
"version": "4.6.
|
|
3
|
+
"version": "4.6.7",
|
|
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",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moflo/cli",
|
|
3
|
-
"version": "4.6.
|
|
3
|
+
"version": "4.6.6",
|
|
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",
|