moflo 4.6.6 → 4.6.8
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/auto-memory-hook.mjs +6 -0
- package/.claude/helpers/hook-handler.cjs +7 -2
- package/.claude/helpers/intelligence.cjs +14 -4
- package/.claude/helpers/statusline.cjs +36 -9
- package/.claude/skills/flo/SKILL.md +432 -0
- package/README.md +83 -1
- package/bin/index-guidance.mjs +11 -1
- package/package.json +2 -1
|
@@ -348,6 +348,10 @@ async function doStatus() {
|
|
|
348
348
|
|
|
349
349
|
const command = process.argv[2] || 'status';
|
|
350
350
|
|
|
351
|
+
// Suppress unhandled rejection warnings from dynamic import() failures
|
|
352
|
+
// which can cause non-zero exit codes even when caught
|
|
353
|
+
process.on('unhandledRejection', () => {});
|
|
354
|
+
|
|
351
355
|
try {
|
|
352
356
|
switch (command) {
|
|
353
357
|
case 'import': await doImport(); break;
|
|
@@ -361,3 +365,5 @@ try {
|
|
|
361
365
|
// Hooks must never crash Claude Code - fail silently
|
|
362
366
|
dim(`Error (non-critical): ${err.message}`);
|
|
363
367
|
}
|
|
368
|
+
// Ensure clean exit for Claude Code hooks
|
|
369
|
+
process.exit(0);
|
|
@@ -66,9 +66,11 @@ async function main() {
|
|
|
66
66
|
try { hookInput = JSON.parse(stdinData); } catch (e) { /* ignore parse errors */ }
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
// Merge stdin data into prompt resolution: prefer stdin fields, then env
|
|
69
|
+
// Merge stdin data into prompt resolution: prefer stdin fields, then env vars.
|
|
70
|
+
// NEVER fall back to argv args — shell glob expansion of braces in bash output
|
|
71
|
+
// creates junk files (#1342). Use env vars or stdin only.
|
|
70
72
|
const prompt = hookInput.prompt || hookInput.command || hookInput.toolInput
|
|
71
|
-
|| process.env.PROMPT || process.env.TOOL_INPUT_command ||
|
|
73
|
+
|| process.env.PROMPT || process.env.TOOL_INPUT_command || '';
|
|
72
74
|
|
|
73
75
|
const handlers = {
|
|
74
76
|
'route': () => {
|
|
@@ -308,4 +310,7 @@ if (command && handlers[command]) {
|
|
|
308
310
|
|
|
309
311
|
main().catch(function(e) {
|
|
310
312
|
console.log('[WARN] Hook handler error: ' + e.message);
|
|
313
|
+
}).finally(function() {
|
|
314
|
+
// Ensure clean exit for Claude Code hooks
|
|
315
|
+
process.exit(0);
|
|
311
316
|
});
|
|
@@ -65,7 +65,8 @@ function bootstrapFromMemoryFiles() {
|
|
|
65
65
|
var items = fs.readdirSync(candidates[i], { withFileTypes: true, recursive: true });
|
|
66
66
|
for (var j = 0; j < items.length; j++) {
|
|
67
67
|
if (items[j].name === "MEMORY.md") {
|
|
68
|
-
var
|
|
68
|
+
var parentDir = items[j].parentPath || items[j].path || candidates[i];
|
|
69
|
+
var fp = path.join(parentDir, items[j].name);
|
|
69
70
|
files.push(fp);
|
|
70
71
|
}
|
|
71
72
|
}
|
|
@@ -96,15 +97,24 @@ function bootstrapFromMemoryFiles() {
|
|
|
96
97
|
|
|
97
98
|
function loadEntries() {
|
|
98
99
|
var store = readJSON(STORE_PATH);
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
// Support both formats: flat array or { entries: [...] }
|
|
101
|
+
var entries = null;
|
|
102
|
+
if (store) {
|
|
103
|
+
if (Array.isArray(store) && store.length > 0) {
|
|
104
|
+
entries = store;
|
|
105
|
+
} else if (store.entries && store.entries.length > 0) {
|
|
106
|
+
entries = store.entries;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (entries) {
|
|
110
|
+
return entries.map(function(e, i) {
|
|
101
111
|
return {
|
|
102
112
|
id: e.id || ("entry-" + i),
|
|
103
113
|
content: e.content || e.value || "",
|
|
104
114
|
summary: e.summary || e.key || "",
|
|
105
115
|
category: e.category || e.namespace || "default",
|
|
106
116
|
confidence: e.confidence || 0.5,
|
|
107
|
-
sourceFile: e.sourceFile || "",
|
|
117
|
+
sourceFile: e.sourceFile || (e.metadata && e.metadata.sourceFile) || "",
|
|
108
118
|
words: tokenize((e.content || e.value || "") + " " + (e.summary || e.key || "")),
|
|
109
119
|
};
|
|
110
120
|
});
|
|
@@ -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,
|
|
@@ -108,10 +109,24 @@ const c = {
|
|
|
108
109
|
brightWhite: '\x1b[1;37m',
|
|
109
110
|
};
|
|
110
111
|
|
|
112
|
+
// Abbreviate path: ~ for home, shorten intermediate dirs
|
|
113
|
+
function abbreviatePath(fullPath) {
|
|
114
|
+
const home = os.homedir();
|
|
115
|
+
let p = fullPath;
|
|
116
|
+
// Replace home dir with ~
|
|
117
|
+
if (p.startsWith(home)) {
|
|
118
|
+
p = '~' + p.slice(home.length);
|
|
119
|
+
}
|
|
120
|
+
// Normalize separators
|
|
121
|
+
p = p.replace(/\\/g, '/');
|
|
122
|
+
return p;
|
|
123
|
+
}
|
|
124
|
+
|
|
111
125
|
// Safe execSync with strict timeout (returns empty string on failure)
|
|
112
126
|
function safeExec(cmd, timeoutMs = 2000) {
|
|
113
127
|
try {
|
|
114
128
|
return execSync(cmd, {
|
|
129
|
+
cwd: CWD,
|
|
115
130
|
encoding: 'utf-8',
|
|
116
131
|
timeout: timeoutMs,
|
|
117
132
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
@@ -192,7 +207,9 @@ function getModelName() {
|
|
|
192
207
|
const claudeConfig = readJSON(path.join(os.homedir(), '.claude.json'));
|
|
193
208
|
if (claudeConfig?.projects) {
|
|
194
209
|
for (const [projectPath, projectConfig] of Object.entries(claudeConfig.projects)) {
|
|
195
|
-
|
|
210
|
+
const normCwd = CWD.replace(/\\/g, '/');
|
|
211
|
+
const normProject = projectPath.replace(/\\/g, '/');
|
|
212
|
+
if (normCwd === normProject || normCwd.startsWith(normProject + '/')) {
|
|
196
213
|
const usage = projectConfig.lastModelUsage;
|
|
197
214
|
if (usage) {
|
|
198
215
|
const ids = Object.keys(usage);
|
|
@@ -663,8 +680,9 @@ function generateDashboard() {
|
|
|
663
680
|
const session = getSessionStats();
|
|
664
681
|
const lines = [];
|
|
665
682
|
|
|
666
|
-
// Header: branding + git
|
|
683
|
+
// Header: branding + dir + git
|
|
667
684
|
let header = `${c.bold}${c.brightPurple}\u258A ${SL_CONFIG.branding}${c.reset}`;
|
|
685
|
+
if (SL_CONFIG.show_dir) header += ` ${c.brightWhite}${abbreviatePath(CWD)}${c.reset}`;
|
|
668
686
|
if (SL_CONFIG.show_git && git.gitBranch) {
|
|
669
687
|
header += ` ${c.brightBlue}\u23C7 ${git.gitBranch}${c.reset}`;
|
|
670
688
|
const changes = git.modified + git.staged + git.untracked;
|
|
@@ -733,8 +751,9 @@ function generateCompactDashboard() {
|
|
|
733
751
|
const session = getSessionStats();
|
|
734
752
|
const lines = [];
|
|
735
753
|
|
|
736
|
-
// Header: branding + git + session
|
|
754
|
+
// Header: branding + dir + git + session
|
|
737
755
|
let header = `${c.bold}${c.brightPurple}\u258A ${SL_CONFIG.branding}${c.reset}`;
|
|
756
|
+
if (SL_CONFIG.show_dir) header += ` ${c.brightWhite}${abbreviatePath(CWD)}${c.reset}`;
|
|
738
757
|
if (SL_CONFIG.show_git && git.gitBranch) {
|
|
739
758
|
header += ` ${c.brightBlue}\u23C7 ${git.gitBranch}${c.reset}`;
|
|
740
759
|
const changes = git.modified + git.staged + git.untracked;
|
|
@@ -806,15 +825,23 @@ function generateJSON() {
|
|
|
806
825
|
}
|
|
807
826
|
|
|
808
827
|
// ─── Main ───────────────────────────────────────────────────────
|
|
809
|
-
|
|
828
|
+
// CLI flags take precedence over moflo.yaml mode
|
|
829
|
+
const cliMode = process.argv.includes('--json') ? 'json'
|
|
830
|
+
: process.argv.includes('--json-compact') ? 'json-compact'
|
|
831
|
+
: process.argv.includes('--dashboard') ? 'dashboard'
|
|
832
|
+
: process.argv.includes('--compact') ? 'compact'
|
|
833
|
+
: process.argv.includes('--single-line') ? 'single-line'
|
|
834
|
+
: null;
|
|
835
|
+
const mode = cliMode || SL_CONFIG.mode || 'compact';
|
|
836
|
+
|
|
837
|
+
if (mode === 'json') {
|
|
810
838
|
console.log(JSON.stringify(generateJSON(), null, 2));
|
|
811
|
-
} else if (
|
|
839
|
+
} else if (mode === 'json-compact') {
|
|
812
840
|
console.log(JSON.stringify(generateJSON()));
|
|
813
|
-
} else if (
|
|
814
|
-
console.log(generateCompactDashboard());
|
|
815
|
-
} else if (process.argv.includes('--dashboard') || SL_CONFIG.mode === 'dashboard') {
|
|
841
|
+
} else if (mode === 'dashboard') {
|
|
816
842
|
console.log(generateDashboard());
|
|
843
|
+
} else if (mode === 'compact') {
|
|
844
|
+
console.log(generateCompactDashboard());
|
|
817
845
|
} else {
|
|
818
|
-
// Default: single-line statusline
|
|
819
846
|
console.log(generateStatusline());
|
|
820
847
|
}
|
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flo
|
|
3
|
+
description: MoFlo ticket workflow - analyze and execute GitHub issues
|
|
4
|
+
arguments: "[options] <issue-number>"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /flo - MoFlo Ticket Workflow
|
|
8
|
+
|
|
9
|
+
Research, enhance, and execute GitHub issues automatically.
|
|
10
|
+
|
|
11
|
+
**Arguments:** $ARGUMENTS
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
/flo <issue-number> # Full workflow with SWARM (default)
|
|
17
|
+
/flo -e <issue-number> # Enhance only: research and update ticket, then STOP
|
|
18
|
+
/flo --enhance <issue-number> # Same as -e
|
|
19
|
+
/flo -r <issue-number> # Research only: analyze issue, output findings
|
|
20
|
+
/flo --research <issue-number> # Same as -r
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Also available as `/fl` (shorthand alias).
|
|
24
|
+
|
|
25
|
+
### Execution Mode (how work is done)
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
/flo 123 # SWARM mode (default) - multi-agent coordination
|
|
29
|
+
/flo -sw 123 # SWARM mode (explicit)
|
|
30
|
+
/flo --swarm 123 # Same as -sw
|
|
31
|
+
/flo -hv 123 # HIVE-MIND mode - consensus-based coordination
|
|
32
|
+
/flo --hive 123 # Same as -hv
|
|
33
|
+
/flo -n 123 # NAKED mode - single Claude, no agents
|
|
34
|
+
/flo --naked 123 # Same as -n
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Epic Handling
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
/flo 42 # If #42 is an epic, processes all stories sequentially
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Epic Detection:** An issue is automatically detected as an epic if ANY of these are true:
|
|
44
|
+
- Has a label matching: `epic`, `tracking`, `parent`, or `umbrella` (case-insensitive)
|
|
45
|
+
- Body contains `## Stories` or `## Tasks` sections
|
|
46
|
+
- Body has checklist-linked issues: `- [ ] #123`
|
|
47
|
+
- Body has numbered issue references: `1. #123`
|
|
48
|
+
- The issue has GitHub sub-issues (via `subIssues` API field)
|
|
49
|
+
|
|
50
|
+
**Sequential Processing:** When an epic is selected:
|
|
51
|
+
1. List all child stories/tasks (from checklist or linked issues)
|
|
52
|
+
2. Process each story **one at a time** in order
|
|
53
|
+
3. Each story goes through the full workflow (research -> enhance -> implement -> test -> PR)
|
|
54
|
+
4. After each story's PR is created, move to the next story
|
|
55
|
+
5. Continue until all stories are complete
|
|
56
|
+
|
|
57
|
+
### Combined Examples
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
/flo 123 # Swarm + full workflow (default) - includes ALL tests
|
|
61
|
+
/flo 42 # If #42 is epic, processes stories sequentially
|
|
62
|
+
/flo -e 123 # Swarm + enhance only (no implementation)
|
|
63
|
+
/flo -hv -e 123 # Hive-mind + enhance only
|
|
64
|
+
/flo -n -r 123 # Naked + research only
|
|
65
|
+
/flo --swarm --enhance 123 # Explicit swarm + enhance only
|
|
66
|
+
/flo -n 123 # Naked + full workflow (still runs all tests)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## SWARM IS MANDATORY BY DEFAULT
|
|
70
|
+
|
|
71
|
+
Even if a task "looks simple", you MUST use swarm coordination unless
|
|
72
|
+
the user explicitly passes -n/--naked. "Simple" is a trap. Tasks have
|
|
73
|
+
hidden complexity. Swarm catches it.
|
|
74
|
+
|
|
75
|
+
THE ONLY WAY TO SKIP SWARM: User passes -n or --naked explicitly.
|
|
76
|
+
|
|
77
|
+
## COMPREHENSIVE TESTING REQUIREMENT
|
|
78
|
+
|
|
79
|
+
ALL tests MUST pass BEFORE PR creation - NO EXCEPTIONS.
|
|
80
|
+
- Unit Tests: MANDATORY for all new/modified code
|
|
81
|
+
- Integration Tests: MANDATORY for API endpoints and services
|
|
82
|
+
- E2E Tests: MANDATORY for user-facing features
|
|
83
|
+
PR CANNOT BE CREATED until all relevant tests pass.
|
|
84
|
+
|
|
85
|
+
## Workflow Overview
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
Research -> Enhance -> Execute -> Testing -> Simplify -> PR+Done
|
|
89
|
+
|
|
90
|
+
Research: Fetch issue, search memory, read guidance, find files
|
|
91
|
+
Enhance: Update GitHub issue with tech analysis, affected files, impl plan
|
|
92
|
+
Execute: Assign self, create branch, implement changes
|
|
93
|
+
Testing: Unit + Integration + E2E tests (ALL MUST PASS - gate)
|
|
94
|
+
Simplify: Run /simplify on changed code (gate - must run before PR)
|
|
95
|
+
PR+Done: Create PR, update issue status, store learnings
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Workflow Gates
|
|
99
|
+
|
|
100
|
+
| Gate | Requirement | Blocked Action |
|
|
101
|
+
|------|-------------|----------------|
|
|
102
|
+
| **Testing Gate** | Unit + Integration + E2E must pass | PR creation |
|
|
103
|
+
| **Simplification Gate** | /simplify must run on changed files | PR creation |
|
|
104
|
+
|
|
105
|
+
### Execution Mode (applies to all phases)
|
|
106
|
+
|
|
107
|
+
| Mode | Description |
|
|
108
|
+
|------|-------------|
|
|
109
|
+
| **SWARM** (default) | Multi-agent via Task tool: researcher, coder, tester, reviewer |
|
|
110
|
+
| **HIVE-MIND** (-hv) | Consensus-based coordination for architecture decisions |
|
|
111
|
+
| **NAKED** (-n) | Single Claude, no agent spawning. Only when user explicitly requests. |
|
|
112
|
+
|
|
113
|
+
## Phase 1: Research (-r or default first step)
|
|
114
|
+
|
|
115
|
+
### 1.1 Fetch Issue Details
|
|
116
|
+
```bash
|
|
117
|
+
gh issue view <issue-number> --json number,title,body,labels,state,assignees,comments,milestone
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 1.2 Check Enhancement Status
|
|
121
|
+
Look for `## Implementation Plan` marker in issue body.
|
|
122
|
+
- **If present**: Issue already enhanced, skip to execute or confirm
|
|
123
|
+
- **If absent**: Proceed with research and enhancement
|
|
124
|
+
|
|
125
|
+
### 1.3 Search Memory FIRST
|
|
126
|
+
ALWAYS search memory BEFORE reading guidance or docs files.
|
|
127
|
+
Memory has file paths, context, and patterns - often all you need.
|
|
128
|
+
Only read guidance files if memory search returns zero relevant results.
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx flo memory search --query "<issue title keywords>" --namespace patterns
|
|
132
|
+
npx flo memory search --query "<domain keywords>" --namespace guidance
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Or via MCP: `mcp__claude-flow__memory_search`
|
|
136
|
+
|
|
137
|
+
### 1.4 Read Guidance Docs (ONLY if memory insufficient)
|
|
138
|
+
**Only if memory search returned < 3 relevant results**, read guidance files:
|
|
139
|
+
- Bug -> testing patterns, error handling
|
|
140
|
+
- Feature -> domain model, architecture
|
|
141
|
+
- UI -> frontend patterns, components
|
|
142
|
+
|
|
143
|
+
### 1.5 Research Codebase
|
|
144
|
+
Use Task tool with Explore agent to find:
|
|
145
|
+
- Affected files and their current state
|
|
146
|
+
- Related code and dependencies
|
|
147
|
+
- Existing patterns to follow
|
|
148
|
+
- Test coverage gaps
|
|
149
|
+
|
|
150
|
+
## Phase 2: Enhance (-e includes research + enhancement)
|
|
151
|
+
|
|
152
|
+
### 2.1 Build Enhancement
|
|
153
|
+
Compile research into structured enhancement:
|
|
154
|
+
|
|
155
|
+
**Technical Analysis** - Root cause (bugs) or approach (features), impact, risk factors
|
|
156
|
+
|
|
157
|
+
**Affected Files** - Files to modify (with line numbers), new files, deletions
|
|
158
|
+
|
|
159
|
+
**Implementation Plan** - Numbered steps with clear actions, dependencies, decision points
|
|
160
|
+
|
|
161
|
+
**Test Plan** - Unit tests to add/update, integration tests needed, manual testing checklist
|
|
162
|
+
|
|
163
|
+
**Estimates** - Complexity (Low/Medium/High), scope (# files, # new tests)
|
|
164
|
+
|
|
165
|
+
### 2.2 Update GitHub Issue
|
|
166
|
+
```bash
|
|
167
|
+
gh issue edit <issue-number> --body "<original body + Technical Analysis + Affected Files + Implementation Plan + Test Plan + Estimates>"
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### 2.3 Add Enhancement Comment
|
|
171
|
+
```bash
|
|
172
|
+
gh issue comment <issue-number> --body "Issue enhanced with implementation plan. Ready for execution."
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Phase 3: Execute (default, runs automatically after enhance)
|
|
176
|
+
|
|
177
|
+
### 3.1 Assign Issue and Update Status
|
|
178
|
+
```bash
|
|
179
|
+
gh issue edit <issue-number> --add-assignee @me
|
|
180
|
+
gh issue edit <issue-number> --add-label "in-progress"
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### 3.2 Create Branch
|
|
184
|
+
```bash
|
|
185
|
+
git checkout main && git pull origin main
|
|
186
|
+
git checkout -b <type>/<issue-number>-<short-desc>
|
|
187
|
+
```
|
|
188
|
+
Types: `feature/`, `fix/`, `refactor/`, `docs/`
|
|
189
|
+
|
|
190
|
+
### 3.3 Implement
|
|
191
|
+
Follow the implementation plan from the enhanced issue. No prompts - execute all steps.
|
|
192
|
+
|
|
193
|
+
## Phase 4: Testing (MANDATORY GATE)
|
|
194
|
+
|
|
195
|
+
This is NOT optional. ALL applicable test types must pass for the change type.
|
|
196
|
+
WORKFLOW STOPS HERE until tests pass. No shortcuts. No exceptions.
|
|
197
|
+
|
|
198
|
+
### 4.1 Write and Run Tests
|
|
199
|
+
Write unit, integration, and E2E tests as appropriate for the change type.
|
|
200
|
+
Use the project's existing test runner and patterns.
|
|
201
|
+
|
|
202
|
+
### 4.2 Test Auto-Fix Loop
|
|
203
|
+
If any tests fail, enter the auto-fix loop (max 3 retries OR 10 minutes):
|
|
204
|
+
1. Run all tests
|
|
205
|
+
2. If ALL pass -> proceed to simplification
|
|
206
|
+
3. If ANY fail: analyze failure, fix test or implementation code, retry
|
|
207
|
+
4. If retries exhausted -> STOP and report to user
|
|
208
|
+
|
|
209
|
+
## Phase 4.5: Code Simplification (MANDATORY)
|
|
210
|
+
|
|
211
|
+
The built-in /simplify command reviews ALL changed code for:
|
|
212
|
+
- Reuse opportunities and code quality
|
|
213
|
+
- Efficiency improvements
|
|
214
|
+
- Consistency with existing codebase patterns
|
|
215
|
+
- Preserves ALL functionality - no behavior changes
|
|
216
|
+
|
|
217
|
+
If /simplify makes changes -> re-run tests to confirm nothing broke.
|
|
218
|
+
If re-tests fail -> revert changes, proceed with original code.
|
|
219
|
+
|
|
220
|
+
## Phase 5: Commit and PR (only after tests pass)
|
|
221
|
+
|
|
222
|
+
### 5.1 Commit
|
|
223
|
+
```bash
|
|
224
|
+
git add <specific files>
|
|
225
|
+
git commit -m "type(scope): description
|
|
226
|
+
|
|
227
|
+
Closes #<issue-number>
|
|
228
|
+
|
|
229
|
+
Co-Authored-By: Claude <noreply@anthropic.com>"
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### 5.2 Create PR
|
|
233
|
+
```bash
|
|
234
|
+
git push -u origin <branch-name>
|
|
235
|
+
gh pr create --title "type(scope): description" --body "## Summary
|
|
236
|
+
<brief description>
|
|
237
|
+
|
|
238
|
+
## Changes
|
|
239
|
+
<bullet list>
|
|
240
|
+
|
|
241
|
+
## Testing
|
|
242
|
+
- [x] Unit tests pass
|
|
243
|
+
- [x] Integration tests pass
|
|
244
|
+
- [x] E2E tests pass
|
|
245
|
+
- [ ] Manual testing done
|
|
246
|
+
|
|
247
|
+
Closes #<issue-number>"
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### 5.3 Update Issue Status
|
|
251
|
+
```bash
|
|
252
|
+
gh issue edit <issue-number> --remove-label "in-progress" --add-label "ready-for-review"
|
|
253
|
+
gh issue comment <issue-number> --body "PR created: <pr-url>"
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Epic Handling
|
|
257
|
+
|
|
258
|
+
### Detecting Epics
|
|
259
|
+
|
|
260
|
+
An issue is an **epic** if:
|
|
261
|
+
1. It has the `epic` label, OR
|
|
262
|
+
2. Its body contains `## Stories` or `## Tasks` sections, OR
|
|
263
|
+
3. It has linked child issues (via `- [ ] #123` checklist format)
|
|
264
|
+
|
|
265
|
+
### Epic Processing Flow
|
|
266
|
+
|
|
267
|
+
1. DETECT EPIC - Check labels, parse body for ## Stories / ## Tasks, extract issue references
|
|
268
|
+
2. LIST ALL STORIES - Extract from checklist, order top-to-bottom as listed
|
|
269
|
+
3. SEQUENTIAL PROCESSING - For each story: run full /flo workflow, wait for PR, update checklist
|
|
270
|
+
4. COMPLETION - All stories have PRs, epic marked as ready-for-review
|
|
271
|
+
|
|
272
|
+
ONE STORY AT A TIME - NO PARALLEL STORY EXECUTION.
|
|
273
|
+
Each story must complete (PR created) before starting next.
|
|
274
|
+
|
|
275
|
+
### Epic Detection Code
|
|
276
|
+
|
|
277
|
+
```javascript
|
|
278
|
+
function isEpic(issue) {
|
|
279
|
+
// Label-based detection (case-insensitive)
|
|
280
|
+
const epicLabels = ['epic', 'tracking', 'parent', 'umbrella'];
|
|
281
|
+
if (issue.labels?.some(l => epicLabels.includes(l.name.toLowerCase()))) return true;
|
|
282
|
+
// Section-based detection
|
|
283
|
+
if (issue.body?.includes('## Stories') || issue.body?.includes('## Tasks')) return true;
|
|
284
|
+
// Checklist-linked issues: - [ ] #123 or - [x] #123
|
|
285
|
+
if (/- \[[ x]\] #\d+/.test(issue.body)) return true;
|
|
286
|
+
// Numbered issue references: 1. #123
|
|
287
|
+
if (/\d+\.\s+#\d+/.test(issue.body)) return true;
|
|
288
|
+
// GitHub sub-issues API
|
|
289
|
+
if (issue.subIssues?.length > 0) return true;
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function extractStories(epicBody) {
|
|
294
|
+
const stories = [];
|
|
295
|
+
// Checklist format: - [ ] #123
|
|
296
|
+
const checklistPattern = /- \[[ ]\] #(\d+)/g;
|
|
297
|
+
let match;
|
|
298
|
+
while ((match = checklistPattern.exec(epicBody)) !== null) {
|
|
299
|
+
stories.push(parseInt(match[1]));
|
|
300
|
+
}
|
|
301
|
+
// Numbered format: 1. #123
|
|
302
|
+
if (stories.length === 0) {
|
|
303
|
+
const numberedPattern = /\d+\.\s+#(\d+)/g;
|
|
304
|
+
while ((match = numberedPattern.exec(epicBody)) !== null) {
|
|
305
|
+
stories.push(parseInt(match[1]));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return stories;
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Parse Arguments
|
|
313
|
+
|
|
314
|
+
```javascript
|
|
315
|
+
const args = "$ARGUMENTS".trim().split(/\s+/);
|
|
316
|
+
let workflowMode = "full"; // full, enhance, research
|
|
317
|
+
let execMode = "swarm"; // swarm (default), hive, naked
|
|
318
|
+
let issueNumber = null;
|
|
319
|
+
|
|
320
|
+
for (let i = 0; i < args.length; i++) {
|
|
321
|
+
const arg = args[i];
|
|
322
|
+
|
|
323
|
+
// Workflow mode (what to do)
|
|
324
|
+
if (arg === "-e" || arg === "--enhance") {
|
|
325
|
+
workflowMode = "enhance";
|
|
326
|
+
} else if (arg === "-r" || arg === "--research") {
|
|
327
|
+
workflowMode = "research";
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Execution mode (how to do it)
|
|
331
|
+
else if (arg === "-sw" || arg === "--swarm") {
|
|
332
|
+
execMode = "swarm";
|
|
333
|
+
} else if (arg === "-hv" || arg === "--hive") {
|
|
334
|
+
execMode = "hive";
|
|
335
|
+
} else if (arg === "-n" || arg === "--naked") {
|
|
336
|
+
execMode = "naked";
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Issue number
|
|
340
|
+
else if (/^\d+$/.test(arg)) {
|
|
341
|
+
issueNumber = arg;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (!issueNumber) {
|
|
346
|
+
throw new Error("Issue number required. Usage: /flo <issue-number>");
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Log execution mode to prevent silent skipping
|
|
350
|
+
console.log("Execution mode: " + execMode.toUpperCase());
|
|
351
|
+
if (execMode === "swarm") {
|
|
352
|
+
console.log("SWARM MODE: Will spawn agents via Task tool. Do NOT skip this.");
|
|
353
|
+
}
|
|
354
|
+
console.log("TESTING: Unit + Integration + E2E tests REQUIRED before PR.");
|
|
355
|
+
console.log("SIMPLIFY: /simplify command runs on changed code before PR.");
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Execution Flow
|
|
359
|
+
|
|
360
|
+
### Workflow Modes (what to do)
|
|
361
|
+
|
|
362
|
+
| Mode | Command | Steps | Stops After |
|
|
363
|
+
|------|---------|-------|-------------|
|
|
364
|
+
| **Full** (default) | `/flo 123` | Research -> Enhance -> Implement -> Test -> Simplify -> PR | PR created |
|
|
365
|
+
| **Epic** | `/flo 42` (epic) | For each story: Full workflow sequentially | All story PRs created |
|
|
366
|
+
| **Enhance** | `/flo -e 123` | Research -> Enhance | Issue updated |
|
|
367
|
+
| **Research** | `/flo -r 123` | Research | Findings output |
|
|
368
|
+
|
|
369
|
+
### Execution Modes (how to do it)
|
|
370
|
+
|
|
371
|
+
| Mode | Flag | Description | When to Use |
|
|
372
|
+
|------|------|-------------|-------------|
|
|
373
|
+
| **Swarm** (DEFAULT) | `-sw`, `--swarm` | Multi-agent via Task tool | Always, unless explicitly overridden |
|
|
374
|
+
| **Hive-Mind** | `-hv`, `--hive` | Consensus-based coordination | Architecture decisions, tradeoffs |
|
|
375
|
+
| **Naked** | `-n`, `--naked` | Single Claude, no agents | User explicitly wants simple mode |
|
|
376
|
+
|
|
377
|
+
## Execution Mode Details
|
|
378
|
+
|
|
379
|
+
### SWARM Mode (Default) - ALWAYS USE UNLESS TOLD OTHERWISE
|
|
380
|
+
|
|
381
|
+
You MUST use the Task tool to spawn agents. No exceptions.
|
|
382
|
+
|
|
383
|
+
**Swarm spawns these agents via Task tool:**
|
|
384
|
+
- `researcher` - Analyzes issue, searches memory, finds patterns
|
|
385
|
+
- `coder` - Implements changes following plan
|
|
386
|
+
- `tester` - Writes and runs tests
|
|
387
|
+
- `/simplify` - Built-in command that reviews changed code before PR
|
|
388
|
+
- `reviewer` - Reviews code before PR
|
|
389
|
+
|
|
390
|
+
**Swarm execution pattern:**
|
|
391
|
+
```javascript
|
|
392
|
+
// 1. Create task list FIRST
|
|
393
|
+
TaskCreate({ subject: "Research issue #123", ... })
|
|
394
|
+
TaskCreate({ subject: "Implement changes", ... })
|
|
395
|
+
TaskCreate({ subject: "Test implementation", ... })
|
|
396
|
+
TaskCreate({ subject: "Run /simplify on changed files", ... })
|
|
397
|
+
TaskCreate({ subject: "Review and PR", ... })
|
|
398
|
+
|
|
399
|
+
// 2. Init swarm
|
|
400
|
+
Bash("npx flo swarm init --topology hierarchical --max-agents 8 --strategy specialized")
|
|
401
|
+
|
|
402
|
+
// 3. Spawn agents with Task tool (run_in_background: true)
|
|
403
|
+
Task({ prompt: "...", subagent_type: "researcher", run_in_background: true })
|
|
404
|
+
Task({ prompt: "...", subagent_type: "coder", run_in_background: true })
|
|
405
|
+
|
|
406
|
+
// 4. Wait for results, synthesize, continue
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### HIVE-MIND Mode (-hv, --hive)
|
|
410
|
+
|
|
411
|
+
Use for consensus-based decisions:
|
|
412
|
+
- Architecture choices
|
|
413
|
+
- Approach tradeoffs
|
|
414
|
+
- Design decisions with multiple valid options
|
|
415
|
+
|
|
416
|
+
### NAKED Mode (-n, --naked)
|
|
417
|
+
|
|
418
|
+
**Only when user explicitly requests.** Single Claude execution without agents.
|
|
419
|
+
- Still uses Task tool for tracking
|
|
420
|
+
- Still creates tasks for visibility
|
|
421
|
+
- Just doesn't spawn multiple agents
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
**Full mode executes without prompts.** It will:
|
|
426
|
+
1. Research the issue and codebase
|
|
427
|
+
2. Enhance the GitHub issue with implementation plan
|
|
428
|
+
3. Assign issue to self, add "in-progress" label
|
|
429
|
+
4. Create branch, implement, test
|
|
430
|
+
5. Run /simplify on changed code, re-test if changes made
|
|
431
|
+
6. Commit, create PR, update issue status
|
|
432
|
+
7. Store learnings
|
package/README.md
CHANGED
|
@@ -10,6 +10,30 @@ MoFlo adds automatic code and guidance cataloging along with memory gating on to
|
|
|
10
10
|
|
|
11
11
|
Install it as a dev dependency and run `flo init`.
|
|
12
12
|
|
|
13
|
+
## Opinionated Defaults
|
|
14
|
+
|
|
15
|
+
MoFlo makes deliberate choices so you don't have to:
|
|
16
|
+
|
|
17
|
+
- **Fully self-contained** — No external services, no cloud dependencies, no API keys. Everything runs locally on your machine.
|
|
18
|
+
- **Node.js runtime** — Targets Node.js specifically. All scripts, hooks, and tooling are JavaScript/TypeScript. No Python, no Rust binaries, no native compilation.
|
|
19
|
+
- **sql.js (WASM)** — The memory database uses sql.js, a pure WebAssembly build of SQLite. No native `better-sqlite3` bindings to compile, no platform-specific build steps. Works identically on Windows, macOS, and Linux.
|
|
20
|
+
- **Simplified embeddings pipeline** — 384-dimensional neural embeddings via Transformers.js (MiniLM-L6-v2, WASM). Same model and precision as the upstream multi-provider pipeline, but simpler — two scripts instead of an abstraction layer. Runs locally, no API calls.
|
|
21
|
+
- **Full learning stack wired up OOTB** — The following are all configured and functional from `flo init`, no manual setup:
|
|
22
|
+
- **SONA** (Self-Optimizing Neural Architecture) — learns from task trajectories via `@ruvector/sona` (Rust/NAPI)
|
|
23
|
+
- **MicroLoRA** — rank-2 LoRA weight adaptations at ~1µs per adapt via `@ruvector/learning-wasm` (WASM)
|
|
24
|
+
- **EWC++** (Elastic Weight Consolidation) — prevents catastrophic forgetting across sessions
|
|
25
|
+
- **HNSW Vector Search** — fast nearest-neighbor search via `@ruvector/core` VectorDb
|
|
26
|
+
- **Semantic Routing** — maps tasks to agents via `@ruvector/router` SemanticRouter
|
|
27
|
+
- **Trajectory Persistence** — outcomes stored in `routing-outcomes.json`, survive across sessions
|
|
28
|
+
- All WASM/NAPI-based, no GPU, no API keys, no external services.
|
|
29
|
+
- **Memory-first workflow** — Claude must search what it already knows before exploring files. Enforced by hooks, not just instructions.
|
|
30
|
+
- **Task registration before agents** — Sub-agents can't spawn until work is tracked. Prevents runaway agent proliferation.
|
|
31
|
+
- **Learned routing** — Task outcomes feed back into the routing system automatically. No manual configuration needed — it gets smarter with use.
|
|
32
|
+
- **Incremental indexing** — Guidance and code map indexes run on every session start but skip unchanged files. Fast after the first run.
|
|
33
|
+
- **AI client agnostic** — Works with any MCP-capable AI client. We develop and test with Claude Code, but the MCP tools, memory system, and hooks are client-independent.
|
|
34
|
+
- **GitHub-oriented** — The `/flo` skill, PR workflows, and issue tracking are built around GitHub. With Claude's help, you can adapt them to your own issue tracker and source control system.
|
|
35
|
+
- **Cross-platform** — Forward-slash path normalization, no `sh -c` shell commands, `windowsHide` on all spawn calls.
|
|
36
|
+
|
|
13
37
|
## Features
|
|
14
38
|
|
|
15
39
|
| Feature | What It Does |
|
|
@@ -102,6 +126,8 @@ Both indexes run automatically at session start after this, so you only need to
|
|
|
102
126
|
|
|
103
127
|
## Commands
|
|
104
128
|
|
|
129
|
+
You don't need to run these for normal use — `flo init` sets everything up, and the hooks handle memory, routing, and learning automatically. These commands are here for manual setup, debugging, and tweaking.
|
|
130
|
+
|
|
105
131
|
### Memory
|
|
106
132
|
|
|
107
133
|
```bash
|
|
@@ -165,6 +191,36 @@ feature:
|
|
|
165
191
|
|
|
166
192
|
Stories are resolved via topological sort (respecting `depends_on`), then executed sequentially by spawning `claude -p "/flo <issue>"`.
|
|
167
193
|
|
|
194
|
+
### The `/flo` Skill
|
|
195
|
+
|
|
196
|
+
Inside your AI client, the `/flo` (or `/fl`) slash command drives GitHub issue workflows. Quick reference:
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
/flo <issue> # Full workflow (research → implement → test → PR)
|
|
200
|
+
/flo -e <issue> # Enhance only (research and update ticket, then stop)
|
|
201
|
+
/flo -r <issue> # Research only (analyze issue, output findings)
|
|
202
|
+
/flo -sw <issue> # Swarm mode (default, multi-agent coordination)
|
|
203
|
+
/flo -hv <issue> # Hive-mind mode (consensus-based coordination)
|
|
204
|
+
/flo -n <issue> # Naked mode (single agent, no swarm)
|
|
205
|
+
/flo <epic-issue> # Detects epics, processes stories sequentially
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
For full options and details, type `/flo` with no arguments — your AI client will display the complete skill documentation. Also available as `/fl`.
|
|
209
|
+
|
|
210
|
+
#### Epic handling
|
|
211
|
+
|
|
212
|
+
When you pass an issue number, `/flo` automatically checks if it's an epic — no extra flag needed. An issue is treated as an epic if any of these are true:
|
|
213
|
+
|
|
214
|
+
- It has a label matching `epic`, `tracking`, `parent`, or `umbrella` (case-insensitive)
|
|
215
|
+
- Its body contains a `## Stories` or `## Tasks` section
|
|
216
|
+
- Its body has checklist-linked issues: `- [ ] #101`
|
|
217
|
+
- Its body has numbered issue references: `1. #101`
|
|
218
|
+
- The issue has GitHub sub-issues (via the API)
|
|
219
|
+
|
|
220
|
+
When an epic is detected, `/flo` processes each child story sequentially — full workflow per story (research → implement → test → PR), one at a time, in the order listed. The `-e`, `-r`, `-n`, `-sw`, and `-hv` flags still apply and get passed through to each story.
|
|
221
|
+
|
|
222
|
+
Stories are extracted from markdown checklists (`- [ ] #101`) or numbered lists (`1. #101`), processed top-to-bottom.
|
|
223
|
+
|
|
168
224
|
### System
|
|
169
225
|
|
|
170
226
|
```bash
|
|
@@ -227,6 +283,7 @@ status_line:
|
|
|
227
283
|
enabled: true
|
|
228
284
|
branding: "MoFlo V4"
|
|
229
285
|
mode: compact # single-line, compact, or dashboard
|
|
286
|
+
show_dir: true # current directory name (compact/dashboard only)
|
|
230
287
|
show_git: true
|
|
231
288
|
show_session: true
|
|
232
289
|
show_swarm: true
|
|
@@ -296,6 +353,27 @@ When you route a task (`flo hooks route --task "..."` or via MCP), MoFlo runs se
|
|
|
296
353
|
|
|
297
354
|
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`.
|
|
298
355
|
|
|
356
|
+
### What Ships Out of the Box
|
|
357
|
+
|
|
358
|
+
`flo init` wires up the following systems automatically — no configuration needed:
|
|
359
|
+
|
|
360
|
+
| System | What It Does | Technology |
|
|
361
|
+
|--------|-------------|------------|
|
|
362
|
+
| **Semantic Memory** | Store and search knowledge with 384-dim embeddings | sql.js (WASM SQLite) + Transformers.js (MiniLM-L6-v2) |
|
|
363
|
+
| **HNSW Vector Search** | Fast nearest-neighbor search across all stored knowledge | `@ruvector/core` VectorDb |
|
|
364
|
+
| **Semantic Routing** | Match tasks to agent types using vector similarity | `@ruvector/router` SemanticRouter |
|
|
365
|
+
| **SONA Learning** | Learn from task trajectories — what agent handled what, and whether it succeeded | `@ruvector/sona` SonaEngine (Rust/NAPI) |
|
|
366
|
+
| **MicroLoRA Adaptation** | Rank-2 LoRA weight updates from successful patterns (~1µs per adapt) | `@ruvector/learning-wasm` |
|
|
367
|
+
| **EWC++ Consolidation** | Prevent catastrophic forgetting — new learning doesn't overwrite old patterns | Built into hooks-tools |
|
|
368
|
+
| **Workflow Gates** | Memory-first and task-registration enforcement via Claude Code hooks | `.claude/settings.json` hooks |
|
|
369
|
+
| **Context Tracking** | Monitor context window depletion (FRESH → CRITICAL) | Session interaction counter |
|
|
370
|
+
| **Guidance Indexing** | Chunk and embed your project docs on session start | `flo-index` bin script |
|
|
371
|
+
| **Code Map** | Index source file structure (types, exports, functions) on session start | `flo-codemap` bin script |
|
|
372
|
+
| **Learned Routing** | Task outcomes feed back into routing — gets smarter over time | `routing-outcomes.json` persistence |
|
|
373
|
+
| **Status Line** | Live dashboard showing git, swarm, memory, and MCP status | `statusline.cjs` hook |
|
|
374
|
+
|
|
375
|
+
All of these run locally with zero external dependencies. The SONA, MicroLoRA, and HNSW components are WASM/NAPI binaries that ship with the npm package — no compilation, no GPU, no API keys.
|
|
376
|
+
|
|
299
377
|
### The Two-Layer Task System
|
|
300
378
|
|
|
301
379
|
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.
|
|
@@ -355,6 +433,10 @@ When `flo init` runs, it appends a workflow section to your CLAUDE.md that teach
|
|
|
355
433
|
- **Project config system**: `moflo.yaml` for per-project settings
|
|
356
434
|
- **One-stop init**: `flo init` generates everything needed for OOTB operation
|
|
357
435
|
|
|
436
|
+
## Ruflo / Claude Flow
|
|
437
|
+
|
|
438
|
+
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).
|
|
439
|
+
|
|
358
440
|
## License
|
|
359
441
|
|
|
360
|
-
MIT (inherited from [
|
|
442
|
+
MIT (inherited from [Ruflo/Claude Flow](https://github.com/ruvnet/ruflo))
|
package/bin/index-guidance.mjs
CHANGED
|
@@ -98,6 +98,13 @@ function loadGuidanceDirs() {
|
|
|
98
98
|
dirs.push({ path: bundledGuidanceDir, prefix: 'moflo-bundled', absolute: true });
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
// 3. Include CLAUDE.md from project root if it exists
|
|
102
|
+
// This is the primary project instruction file for Claude-enabled projects
|
|
103
|
+
const claudeMdPath = resolve(projectRoot, 'CLAUDE.md');
|
|
104
|
+
if (existsSync(claudeMdPath)) {
|
|
105
|
+
dirs.push({ path: projectRoot, prefix: 'project-root', absolute: true, fileFilter: ['CLAUDE.md'] });
|
|
106
|
+
}
|
|
107
|
+
|
|
101
108
|
return dirs;
|
|
102
109
|
}
|
|
103
110
|
|
|
@@ -635,7 +642,10 @@ function indexDirectory(db, dirConfig) {
|
|
|
635
642
|
return results;
|
|
636
643
|
}
|
|
637
644
|
|
|
638
|
-
const
|
|
645
|
+
const allMdFiles = readdirSync(dirPath).filter(f => f.endsWith('.md'));
|
|
646
|
+
const files = dirConfig.fileFilter
|
|
647
|
+
? allMdFiles.filter(f => dirConfig.fileFilter.includes(f))
|
|
648
|
+
: allMdFiles;
|
|
639
649
|
|
|
640
650
|
for (const file of files) {
|
|
641
651
|
const filePath = resolve(dirPath, file);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "moflo",
|
|
3
|
-
"version": "4.6.
|
|
3
|
+
"version": "4.6.8",
|
|
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",
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"moflo:security": "npm run security:audit && npm run security:test"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
+
"@ruvector/learning-wasm": "^0.1.29",
|
|
62
63
|
"semver": "^7.6.0",
|
|
63
64
|
"sql.js": "^1.12.0",
|
|
64
65
|
"zod": "^3.22.4"
|