moflo 4.7.3 → 4.7.4
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.
|
@@ -0,0 +1,577 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flo
|
|
3
|
+
description: MoFlo ticket workflow - analyze and execute GitHub issues
|
|
4
|
+
arguments: "[options] <issue-number | title>"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /flo - MoFlo Ticket Workflow
|
|
8
|
+
|
|
9
|
+
Research, create tickets for, 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 -t <issue-number> # Ticket only: research and update ticket, then STOP
|
|
18
|
+
/flo -t <title> # Create a NEW ticket with description, acceptance criteria, test cases
|
|
19
|
+
/flo --ticket <issue-number|title> # Same as -t
|
|
20
|
+
/flo -r <issue-number> # Research only: analyze issue, output findings
|
|
21
|
+
/flo --research <issue-number> # Same as -r
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Also available as `/fl` (shorthand alias).
|
|
25
|
+
|
|
26
|
+
### Execution Mode (how work is done)
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
/flo 123 # SWARM mode (default) - multi-agent coordination
|
|
30
|
+
/flo -s 123 # SWARM mode (explicit)
|
|
31
|
+
/flo --swarm 123 # Same as -s
|
|
32
|
+
/flo -h 123 # HIVE-MIND mode - consensus-based coordination
|
|
33
|
+
/flo --hive 123 # Same as -h
|
|
34
|
+
/flo -n 123 # NORMAL mode - single Claude, no agents
|
|
35
|
+
/flo --normal 123 # Same as -n
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Epic Handling
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
/flo 42 # If #42 is an epic, processes all stories sequentially
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Epic Detection:** An issue is automatically detected as an epic if ANY of these are true:
|
|
45
|
+
- Has a label matching: `epic`, `tracking`, `parent`, or `umbrella` (case-insensitive)
|
|
46
|
+
- Body contains `## Stories` or `## Tasks` sections
|
|
47
|
+
- Body has checklist-linked issues: `- [ ] #123`
|
|
48
|
+
- Body has numbered issue references: `1. #123`
|
|
49
|
+
- The issue has GitHub sub-issues (via `subIssues` API field)
|
|
50
|
+
|
|
51
|
+
**Sequential Processing:** When an epic is selected:
|
|
52
|
+
1. List all child stories/tasks (from checklist or linked issues)
|
|
53
|
+
2. Process each story **one at a time** in order
|
|
54
|
+
3. Each story goes through the full workflow (research -> ticket -> implement -> test -> PR)
|
|
55
|
+
4. After each story's PR is created, move to the next story
|
|
56
|
+
5. Continue until all stories are complete
|
|
57
|
+
|
|
58
|
+
### Combined Examples
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
/flo 123 # Swarm + full workflow (default) - includes ALL tests
|
|
62
|
+
/flo 42 # If #42 is epic, processes stories sequentially
|
|
63
|
+
/flo -t 123 # Swarm + ticket only (no implementation)
|
|
64
|
+
/flo -h -t 123 # Hive-mind + ticket only
|
|
65
|
+
/flo -n -r 123 # Normal + research only
|
|
66
|
+
/flo --swarm --ticket 123 # Explicit swarm + ticket only
|
|
67
|
+
/flo -n 123 # Normal + full workflow (still runs all tests)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## SWARM IS MANDATORY BY DEFAULT
|
|
71
|
+
|
|
72
|
+
Even if a task "looks simple", you MUST use swarm coordination unless
|
|
73
|
+
the user explicitly passes -n/--normal. "Simple" is a trap. Tasks have
|
|
74
|
+
hidden complexity. Swarm catches it.
|
|
75
|
+
|
|
76
|
+
THE ONLY WAY TO SKIP SWARM: User passes -n or --normal explicitly.
|
|
77
|
+
|
|
78
|
+
## COMPREHENSIVE TESTING REQUIREMENT
|
|
79
|
+
|
|
80
|
+
ALL tests MUST pass BEFORE PR creation - NO EXCEPTIONS.
|
|
81
|
+
- Unit Tests: MANDATORY for all new/modified code
|
|
82
|
+
- Integration Tests: MANDATORY for API endpoints and services
|
|
83
|
+
- E2E Tests: MANDATORY for user-facing features
|
|
84
|
+
PR CANNOT BE CREATED until all relevant tests pass.
|
|
85
|
+
|
|
86
|
+
## Workflow Overview
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
Research -> Ticket -> Execute -> Testing -> Simplify -> PR+Done
|
|
90
|
+
|
|
91
|
+
Research: Fetch issue, search memory, read guidance, find files
|
|
92
|
+
Ticket: Create or update GitHub issue with description, acceptance criteria, test cases
|
|
93
|
+
Execute: Assign self, create branch, implement changes
|
|
94
|
+
Testing: Unit + Integration + E2E tests (ALL MUST PASS - gate)
|
|
95
|
+
Simplify: Run /simplify on changed code (gate - must run before PR)
|
|
96
|
+
PR+Done: Create PR, update issue status, store learnings
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Workflow Gates
|
|
100
|
+
|
|
101
|
+
| Gate | Requirement | Blocked Action |
|
|
102
|
+
|------|-------------|----------------|
|
|
103
|
+
| **Testing Gate** | Unit + Integration + E2E must pass | PR creation |
|
|
104
|
+
| **Simplification Gate** | /simplify must run on changed files | PR creation |
|
|
105
|
+
|
|
106
|
+
### Execution Mode (applies to all phases)
|
|
107
|
+
|
|
108
|
+
| Mode | Description |
|
|
109
|
+
|------|-------------|
|
|
110
|
+
| **SWARM** (default) | Multi-agent via Task tool: researcher, coder, tester, reviewer |
|
|
111
|
+
| **HIVE-MIND** (-h) | Consensus-based coordination for architecture decisions |
|
|
112
|
+
| **NORMAL** (-n) | Single Claude, no agent spawning. Only when user explicitly requests. |
|
|
113
|
+
|
|
114
|
+
## Phase 1: Research (-r or default first step)
|
|
115
|
+
|
|
116
|
+
### 1.1 Fetch Issue Details
|
|
117
|
+
```bash
|
|
118
|
+
gh issue view <issue-number> --json number,title,body,labels,state,assignees,comments,milestone
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 1.2 Check Ticket Status
|
|
122
|
+
Look for `## Acceptance Criteria` marker in issue body.
|
|
123
|
+
- **If present**: Ticket already enhanced, skip to execute or confirm
|
|
124
|
+
- **If absent**: Proceed with research and ticket update
|
|
125
|
+
|
|
126
|
+
### 1.3 Search Memory FIRST
|
|
127
|
+
ALWAYS search memory BEFORE reading guidance or docs files.
|
|
128
|
+
Memory has file paths, context, and patterns - often all you need.
|
|
129
|
+
Only read guidance files if memory search returns zero relevant results.
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
npx flo memory search --query "<issue title keywords>" --namespace patterns
|
|
133
|
+
npx flo memory search --query "<domain keywords>" --namespace guidance
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Or via MCP: `mcp__claude-flow__memory_search`
|
|
137
|
+
|
|
138
|
+
### 1.4 Read Guidance Docs (ONLY if memory insufficient)
|
|
139
|
+
**Only if memory search returned < 3 relevant results**, read guidance files:
|
|
140
|
+
- Bug -> testing patterns, error handling
|
|
141
|
+
- Feature -> domain model, architecture
|
|
142
|
+
- UI -> frontend patterns, components
|
|
143
|
+
|
|
144
|
+
### 1.5 Research Codebase
|
|
145
|
+
Use Task tool with Explore agent to find:
|
|
146
|
+
- Affected files and their current state
|
|
147
|
+
- Related code and dependencies
|
|
148
|
+
- Existing patterns to follow
|
|
149
|
+
- Test coverage gaps
|
|
150
|
+
|
|
151
|
+
## Phase 2: Ticket (-t creates or updates a ticket)
|
|
152
|
+
|
|
153
|
+
When given an issue number, `-t` enhances the existing ticket. When given a title (non-numeric argument), `-t` creates a new GitHub issue. Either way, the ticket MUST include all three of the following sections.
|
|
154
|
+
|
|
155
|
+
### 2.0 Complexity Assessment (MANDATORY before building ticket)
|
|
156
|
+
|
|
157
|
+
After research, assess the complexity of the work. This determines whether the issue stays as a single ticket or gets promoted to an epic with sub-issues.
|
|
158
|
+
|
|
159
|
+
**Complexity Signals — count how many apply:**
|
|
160
|
+
|
|
161
|
+
| Signal | Weight | Example |
|
|
162
|
+
|--------|--------|---------|
|
|
163
|
+
| Multiple files changed (5+) | +2 | Touches models, API, tests, docs, config |
|
|
164
|
+
| New module or package | +2 | Requires new directory structure |
|
|
165
|
+
| Cross-cutting concern | +2 | Auth, logging, error handling across layers |
|
|
166
|
+
| Database/schema changes | +2 | Migrations, new tables, index changes |
|
|
167
|
+
| Multiple independent work streams | +3 | Frontend + backend + infra changes |
|
|
168
|
+
| External API integration | +1 | Third-party service, webhook, OAuth |
|
|
169
|
+
| Breaking change / migration | +2 | Requires deprecation, data migration |
|
|
170
|
+
| Significant test surface | +1 | Needs 10+ new test cases across categories |
|
|
171
|
+
| Security implications | +1 | Authentication, authorization, input validation |
|
|
172
|
+
| UI + backend changes together | +2 | Full-stack feature spanning layers |
|
|
173
|
+
|
|
174
|
+
**Complexity Thresholds:**
|
|
175
|
+
|
|
176
|
+
| Score | Classification | Action |
|
|
177
|
+
|-------|---------------|--------|
|
|
178
|
+
| 0–3 | **Simple** | Single ticket — proceed normally |
|
|
179
|
+
| 4–6 | **Moderate** | Single ticket — flag in description that it may benefit from splitting |
|
|
180
|
+
| 7+ | **Complex** | **PROMOTE TO EPIC** — decompose into sub-issues |
|
|
181
|
+
|
|
182
|
+
**When promoting to epic:**
|
|
183
|
+
|
|
184
|
+
1. Decompose the work into 2–6 independent, shippable stories
|
|
185
|
+
2. Each story should be completable in a single PR
|
|
186
|
+
3. Stories should have clear boundaries (one concern per story)
|
|
187
|
+
4. Order stories by dependency (independent ones first)
|
|
188
|
+
5. Create each story as a GitHub issue with its own Description, Acceptance Criteria, and Test Cases
|
|
189
|
+
6. Create or convert the parent issue into an epic with a `## Stories` checklist
|
|
190
|
+
|
|
191
|
+
```javascript
|
|
192
|
+
// Complexity assessment pseudocode
|
|
193
|
+
function assessComplexity(research) {
|
|
194
|
+
let score = 0;
|
|
195
|
+
if (research.affectedFiles.length >= 5) score += 2;
|
|
196
|
+
if (research.requiresNewModule) score += 2;
|
|
197
|
+
if (research.crossCutting) score += 2;
|
|
198
|
+
if (research.schemaChanges) score += 2;
|
|
199
|
+
if (research.independentWorkStreams >= 2) score += 3;
|
|
200
|
+
if (research.externalAPIs) score += 1;
|
|
201
|
+
if (research.breakingChanges) score += 2;
|
|
202
|
+
if (research.estimatedTestCases >= 10) score += 1;
|
|
203
|
+
if (research.securityImplications) score += 1;
|
|
204
|
+
if (research.fullStack) score += 2;
|
|
205
|
+
return score;
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### 2.0.1 Epic Decomposition (when score >= 7)
|
|
210
|
+
|
|
211
|
+
When complexity warrants an epic, decompose into stories:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# Step 1: Create each sub-issue
|
|
215
|
+
gh issue create --title "Story: <story-title>" --body "<## Description + ## Acceptance Criteria + ## Suggested Test Cases>" --label "story"
|
|
216
|
+
# Capture the new issue number from output
|
|
217
|
+
|
|
218
|
+
# Step 2: Repeat for all stories (2-6 stories typically)
|
|
219
|
+
|
|
220
|
+
# Step 3: Build the epic body with checklist referencing ALL story issue numbers
|
|
221
|
+
# Step 4: If updating an existing issue, convert it to epic:
|
|
222
|
+
gh issue edit <parent-number> --add-label "epic" --body "<epic body with ## Stories checklist>"
|
|
223
|
+
|
|
224
|
+
# Step 5: If creating new, create the epic:
|
|
225
|
+
gh issue create --title "Epic: <title>" --label "epic" --body "<epic body>"
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Epic body format (MANDATORY — this is how tracking works):**
|
|
229
|
+
|
|
230
|
+
```markdown
|
|
231
|
+
## Overview
|
|
232
|
+
<High-level description of the epic goal>
|
|
233
|
+
|
|
234
|
+
## Stories
|
|
235
|
+
|
|
236
|
+
- [ ] #<story-1-number> <story-1-title>
|
|
237
|
+
- [ ] #<story-2-number> <story-2-title>
|
|
238
|
+
- [ ] #<story-3-number> <story-3-title>
|
|
239
|
+
|
|
240
|
+
## Complexity Assessment
|
|
241
|
+
Score: <N>/20 — <Simple|Moderate|Complex>
|
|
242
|
+
Signals: <list of signals that triggered>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
The `## Stories` checklist with `- [ ] #<number>` format is **mandatory** — this is what enables:
|
|
246
|
+
- Epic detection by the `/flo` skill
|
|
247
|
+
- Story extraction for sequential processing
|
|
248
|
+
- Progress tracking via checked/unchecked items
|
|
249
|
+
|
|
250
|
+
### 2.1 Build Ticket Content
|
|
251
|
+
Compile research into a well-structured ticket. The issue MUST include all three of the following sections:
|
|
252
|
+
|
|
253
|
+
**Detailed Description** — Clear, thorough explanation of what needs to be done and why. Include:
|
|
254
|
+
- Root cause analysis (bugs) or approach rationale (features)
|
|
255
|
+
- Impact and risk factors
|
|
256
|
+
- Affected files (with line numbers), new files, deletions
|
|
257
|
+
- Implementation plan: numbered steps with clear actions, dependencies, decision points
|
|
258
|
+
|
|
259
|
+
**Acceptance Criteria** — Specific, testable conditions that must be true for this issue to be considered complete. Write as a checklist:
|
|
260
|
+
- [ ] Criterion 1 (e.g., "API returns 200 with valid token")
|
|
261
|
+
- [ ] Criterion 2 (e.g., "Error message shown when input exceeds 255 chars")
|
|
262
|
+
- [ ] ...each criterion must be independently verifiable
|
|
263
|
+
|
|
264
|
+
**Suggested Test Cases** — Concrete test scenarios covering happy path, edge cases, and error conditions:
|
|
265
|
+
- Test case 1: description, input, expected output
|
|
266
|
+
- Test case 2: description, input, expected output
|
|
267
|
+
- Include unit, integration, and E2E test suggestions as appropriate
|
|
268
|
+
|
|
269
|
+
### 2.2 Create or Update GitHub Issue
|
|
270
|
+
|
|
271
|
+
**If issue number was given** (update existing):
|
|
272
|
+
```bash
|
|
273
|
+
gh issue edit <issue-number> --body "<original body + ## Description + ## Acceptance Criteria + ## Suggested Test Cases>"
|
|
274
|
+
gh issue comment <issue-number> --body "Ticket enhanced with description, acceptance criteria, and test cases. Ready for execution."
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**If title was given** (create new):
|
|
278
|
+
```bash
|
|
279
|
+
gh issue create --title "<title>" --body "<## Description + ## Acceptance Criteria + ## Suggested Test Cases>"
|
|
280
|
+
```
|
|
281
|
+
Print the new issue URL so the user can see it.
|
|
282
|
+
|
|
283
|
+
## Phase 3: Execute (default, runs automatically after ticket)
|
|
284
|
+
|
|
285
|
+
### 3.1 Assign Issue and Update Status
|
|
286
|
+
```bash
|
|
287
|
+
gh issue edit <issue-number> --add-assignee @me
|
|
288
|
+
gh issue edit <issue-number> --add-label "in-progress"
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### 3.2 Create Branch
|
|
292
|
+
```bash
|
|
293
|
+
git checkout main && git pull origin main
|
|
294
|
+
git checkout -b <type>/<issue-number>-<short-desc>
|
|
295
|
+
```
|
|
296
|
+
Types: `feature/`, `fix/`, `refactor/`, `docs/`
|
|
297
|
+
|
|
298
|
+
### 3.3 Implement
|
|
299
|
+
Follow the implementation plan from the ticket. No prompts - execute all steps.
|
|
300
|
+
|
|
301
|
+
## Phase 4: Testing (MANDATORY GATE)
|
|
302
|
+
|
|
303
|
+
This is NOT optional. ALL applicable test types must pass for the change type.
|
|
304
|
+
WORKFLOW STOPS HERE until tests pass. No shortcuts. No exceptions.
|
|
305
|
+
|
|
306
|
+
### 4.1 Write and Run Tests
|
|
307
|
+
Write unit, integration, and E2E tests as appropriate for the change type.
|
|
308
|
+
Use the project's existing test runner and patterns.
|
|
309
|
+
|
|
310
|
+
### 4.2 Test Auto-Fix Loop
|
|
311
|
+
If any tests fail, enter the auto-fix loop (max 3 retries OR 10 minutes):
|
|
312
|
+
1. Run all tests
|
|
313
|
+
2. If ALL pass -> proceed to simplification
|
|
314
|
+
3. If ANY fail: analyze failure, fix test or implementation code, retry
|
|
315
|
+
4. If retries exhausted -> STOP and report to user
|
|
316
|
+
|
|
317
|
+
## Phase 4.5: Code Simplification (MANDATORY)
|
|
318
|
+
|
|
319
|
+
The built-in /simplify command reviews ALL changed code for:
|
|
320
|
+
- Reuse opportunities and code quality
|
|
321
|
+
- Efficiency improvements
|
|
322
|
+
- Consistency with existing codebase patterns
|
|
323
|
+
- Preserves ALL functionality - no behavior changes
|
|
324
|
+
|
|
325
|
+
If /simplify makes changes -> re-run tests to confirm nothing broke.
|
|
326
|
+
If re-tests fail -> revert changes, proceed with original code.
|
|
327
|
+
|
|
328
|
+
## Phase 5: Commit and PR (only after tests pass)
|
|
329
|
+
|
|
330
|
+
### 5.1 Commit
|
|
331
|
+
```bash
|
|
332
|
+
git add <specific files>
|
|
333
|
+
git commit -m "type(scope): description
|
|
334
|
+
|
|
335
|
+
Closes #<issue-number>
|
|
336
|
+
|
|
337
|
+
Co-Authored-By: Claude <noreply@anthropic.com>"
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### 5.2 Create PR
|
|
341
|
+
```bash
|
|
342
|
+
git push -u origin <branch-name>
|
|
343
|
+
gh pr create --title "type(scope): description" --body "## Summary
|
|
344
|
+
<brief description>
|
|
345
|
+
|
|
346
|
+
## Changes
|
|
347
|
+
<bullet list>
|
|
348
|
+
|
|
349
|
+
## Testing
|
|
350
|
+
- [x] Unit tests pass
|
|
351
|
+
- [x] Integration tests pass
|
|
352
|
+
- [x] E2E tests pass
|
|
353
|
+
- [ ] Manual testing done
|
|
354
|
+
|
|
355
|
+
Closes #<issue-number>"
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### 5.3 Update Issue Status
|
|
359
|
+
```bash
|
|
360
|
+
gh issue edit <issue-number> --remove-label "in-progress" --add-label "ready-for-review"
|
|
361
|
+
gh issue comment <issue-number> --body "PR created: <pr-url>"
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Epic Handling
|
|
365
|
+
|
|
366
|
+
### Detecting Epics
|
|
367
|
+
|
|
368
|
+
An issue is an **epic** if:
|
|
369
|
+
1. It has the `epic` label, OR
|
|
370
|
+
2. Its body contains `## Stories` or `## Tasks` sections, OR
|
|
371
|
+
3. It has linked child issues (via `- [ ] #123` checklist format)
|
|
372
|
+
|
|
373
|
+
### Epic Processing Flow
|
|
374
|
+
|
|
375
|
+
1. DETECT EPIC - Check labels, parse body for ## Stories / ## Tasks, extract issue references
|
|
376
|
+
2. LIST ALL STORIES - Extract from checklist, order top-to-bottom as listed
|
|
377
|
+
3. SEQUENTIAL PROCESSING - For each story:
|
|
378
|
+
a. Run full /flo workflow (research -> ticket -> implement -> test -> PR)
|
|
379
|
+
b. After PR is created, **check off the story** in the epic body
|
|
380
|
+
c. Move to the next unchecked story
|
|
381
|
+
4. COMPLETION - All stories checked off, epic marked as ready-for-review
|
|
382
|
+
|
|
383
|
+
ONE STORY AT A TIME - NO PARALLEL STORY EXECUTION.
|
|
384
|
+
Each story must complete (PR created) before starting next.
|
|
385
|
+
|
|
386
|
+
### Epic Checklist Tracking (MANDATORY)
|
|
387
|
+
|
|
388
|
+
After each story's PR is created, update the epic body to check off that story:
|
|
389
|
+
|
|
390
|
+
```bash
|
|
391
|
+
# 1. Fetch current epic body
|
|
392
|
+
EPIC_BODY=$(gh issue view <epic-number> --json body -q '.body')
|
|
393
|
+
|
|
394
|
+
# 2. Replace "- [ ] #<story-number>" with "- [x] #<story-number>"
|
|
395
|
+
UPDATED_BODY=$(echo "$EPIC_BODY" | sed 's/- \[ \] #<story-number>/- [x] #<story-number>/')
|
|
396
|
+
|
|
397
|
+
# 3. Update the epic
|
|
398
|
+
gh issue edit <epic-number> --body "$UPDATED_BODY"
|
|
399
|
+
|
|
400
|
+
# 4. Comment on the epic with progress
|
|
401
|
+
gh issue comment <epic-number> --body "✅ Story #<story-number> completed — PR: <pr-url>"
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
This applies to ALL epics, regardless of how they were created:
|
|
405
|
+
- Epics created by `/flo -t` complexity promotion
|
|
406
|
+
- Epics created manually by users
|
|
407
|
+
- Epics detected from existing issues
|
|
408
|
+
|
|
409
|
+
The checklist state (`[ ]` vs `[x]`) is the **single source of truth** for epic progress.
|
|
410
|
+
|
|
411
|
+
### Epic Detection Code
|
|
412
|
+
|
|
413
|
+
```javascript
|
|
414
|
+
function isEpic(issue) {
|
|
415
|
+
// Label-based detection (case-insensitive)
|
|
416
|
+
const epicLabels = ['epic', 'tracking', 'parent', 'umbrella'];
|
|
417
|
+
if (issue.labels?.some(l => epicLabels.includes(l.name.toLowerCase()))) return true;
|
|
418
|
+
// Section-based detection
|
|
419
|
+
if (issue.body?.includes('## Stories') || issue.body?.includes('## Tasks')) return true;
|
|
420
|
+
// Checklist-linked issues: - [ ] #123 or - [x] #123
|
|
421
|
+
if (/- \[[ x]\] #\d+/.test(issue.body)) return true;
|
|
422
|
+
// Numbered issue references: 1. #123
|
|
423
|
+
if (/\d+\.\s+#\d+/.test(issue.body)) return true;
|
|
424
|
+
// GitHub sub-issues API
|
|
425
|
+
if (issue.subIssues?.length > 0) return true;
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
function extractStories(epicBody) {
|
|
430
|
+
const stories = [];
|
|
431
|
+
// Checklist format: - [ ] #123
|
|
432
|
+
const checklistPattern = /- \[[ ]\] #(\d+)/g;
|
|
433
|
+
let match;
|
|
434
|
+
while ((match = checklistPattern.exec(epicBody)) !== null) {
|
|
435
|
+
stories.push(parseInt(match[1]));
|
|
436
|
+
}
|
|
437
|
+
// Numbered format: 1. #123
|
|
438
|
+
if (stories.length === 0) {
|
|
439
|
+
const numberedPattern = /\d+\.\s+#(\d+)/g;
|
|
440
|
+
while ((match = numberedPattern.exec(epicBody)) !== null) {
|
|
441
|
+
stories.push(parseInt(match[1]));
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return stories;
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
## Parse Arguments
|
|
449
|
+
|
|
450
|
+
```javascript
|
|
451
|
+
const args = "$ARGUMENTS".trim().split(/\s+/);
|
|
452
|
+
let workflowMode = "full"; // full, ticket, research
|
|
453
|
+
let execMode = "swarm"; // swarm (default), hive, normal
|
|
454
|
+
let issueNumber = null;
|
|
455
|
+
let titleWords = [];
|
|
456
|
+
|
|
457
|
+
for (let i = 0; i < args.length; i++) {
|
|
458
|
+
const arg = args[i];
|
|
459
|
+
|
|
460
|
+
// Workflow mode (what to do)
|
|
461
|
+
if (arg === "-t" || arg === "--ticket") {
|
|
462
|
+
workflowMode = "ticket";
|
|
463
|
+
} else if (arg === "-r" || arg === "--research") {
|
|
464
|
+
workflowMode = "research";
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// Execution mode (how to do it)
|
|
468
|
+
else if (arg === "-s" || arg === "--swarm") {
|
|
469
|
+
execMode = "swarm";
|
|
470
|
+
} else if (arg === "-h" || arg === "--hive") {
|
|
471
|
+
execMode = "hive";
|
|
472
|
+
} else if (arg === "-n" || arg === "--normal") {
|
|
473
|
+
execMode = "normal";
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// Issue number or title text
|
|
477
|
+
else if (/^\d+$/.test(arg)) {
|
|
478
|
+
issueNumber = arg;
|
|
479
|
+
} else {
|
|
480
|
+
// Non-flag, non-numeric argument — collect as title words
|
|
481
|
+
titleWords.push(arg);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// In ticket mode, a title can be given instead of an issue number
|
|
486
|
+
let ticketTitle = titleWords.join(" ");
|
|
487
|
+
if (!issueNumber && !ticketTitle) {
|
|
488
|
+
throw new Error("Issue number or title required. Usage: /flo <issue-number | title>");
|
|
489
|
+
}
|
|
490
|
+
if (!issueNumber && workflowMode !== "ticket") {
|
|
491
|
+
throw new Error("Issue number required for full/research mode. Use -t for new tickets.");
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// Log execution mode to prevent silent skipping
|
|
495
|
+
console.log("Execution mode: " + execMode.toUpperCase());
|
|
496
|
+
if (execMode === "swarm") {
|
|
497
|
+
console.log("SWARM MODE: Will spawn agents via Task tool. Do NOT skip this.");
|
|
498
|
+
}
|
|
499
|
+
console.log("TESTING: Unit + Integration + E2E tests REQUIRED before PR.");
|
|
500
|
+
console.log("SIMPLIFY: /simplify command runs on changed code before PR.");
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
## Execution Flow
|
|
504
|
+
|
|
505
|
+
### Workflow Modes (what to do)
|
|
506
|
+
|
|
507
|
+
| Mode | Command | Steps | Stops After |
|
|
508
|
+
|------|---------|-------|-------------|
|
|
509
|
+
| **Full** (default) | `/flo 123` | Research -> Ticket -> Implement -> Test -> Simplify -> PR | PR created |
|
|
510
|
+
| **Epic** | `/flo 42` (epic) | For each story: Full workflow sequentially | All story PRs created |
|
|
511
|
+
| **Ticket** | `/flo -t 123` | Research -> Ticket | Issue updated |
|
|
512
|
+
| **Research** | `/flo -r 123` | Research | Findings output |
|
|
513
|
+
|
|
514
|
+
### Execution Modes (how to do it)
|
|
515
|
+
|
|
516
|
+
| Mode | Flag | Description | When to Use |
|
|
517
|
+
|------|------|-------------|-------------|
|
|
518
|
+
| **Swarm** (DEFAULT) | `-s`, `--swarm` | Multi-agent via Task tool | Always, unless explicitly overridden |
|
|
519
|
+
| **Hive-Mind** | `-h`, `--hive` | Consensus-based coordination | Architecture decisions, tradeoffs |
|
|
520
|
+
| **Normal** | `-n`, `--normal` | Single Claude, no agents | User explicitly wants simple mode |
|
|
521
|
+
|
|
522
|
+
## Execution Mode Details
|
|
523
|
+
|
|
524
|
+
### SWARM Mode (Default) - ALWAYS USE UNLESS TOLD OTHERWISE
|
|
525
|
+
|
|
526
|
+
You MUST use the Task tool to spawn agents. No exceptions.
|
|
527
|
+
|
|
528
|
+
**Swarm spawns these agents via Task tool:**
|
|
529
|
+
- `researcher` - Analyzes issue, searches memory, finds patterns
|
|
530
|
+
- `coder` - Implements changes following plan
|
|
531
|
+
- `tester` - Writes and runs tests
|
|
532
|
+
- `/simplify` - Built-in command that reviews changed code before PR
|
|
533
|
+
- `reviewer` - Reviews code before PR
|
|
534
|
+
|
|
535
|
+
**Swarm execution pattern:**
|
|
536
|
+
```javascript
|
|
537
|
+
// 1. Create task list FIRST
|
|
538
|
+
TaskCreate({ subject: "Research issue #123", ... })
|
|
539
|
+
TaskCreate({ subject: "Implement changes", ... })
|
|
540
|
+
TaskCreate({ subject: "Test implementation", ... })
|
|
541
|
+
TaskCreate({ subject: "Run /simplify on changed files", ... })
|
|
542
|
+
TaskCreate({ subject: "Review and PR", ... })
|
|
543
|
+
|
|
544
|
+
// 2. Init swarm
|
|
545
|
+
Bash("npx flo swarm init --topology hierarchical --max-agents 8 --strategy specialized")
|
|
546
|
+
|
|
547
|
+
// 3. Spawn agents with Task tool (run_in_background: true)
|
|
548
|
+
Task({ prompt: "...", subagent_type: "researcher", run_in_background: true })
|
|
549
|
+
Task({ prompt: "...", subagent_type: "coder", run_in_background: true })
|
|
550
|
+
|
|
551
|
+
// 4. Wait for results, synthesize, continue
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
### HIVE-MIND Mode (-h, --hive)
|
|
555
|
+
|
|
556
|
+
Use for consensus-based decisions:
|
|
557
|
+
- Architecture choices
|
|
558
|
+
- Approach tradeoffs
|
|
559
|
+
- Design decisions with multiple valid options
|
|
560
|
+
|
|
561
|
+
### NORMAL Mode (-n, --normal)
|
|
562
|
+
|
|
563
|
+
**Only when user explicitly requests.** Single Claude execution without agents.
|
|
564
|
+
- Still uses Task tool for tracking
|
|
565
|
+
- Still creates tasks for visibility
|
|
566
|
+
- Just doesn't spawn multiple agents
|
|
567
|
+
|
|
568
|
+
---
|
|
569
|
+
|
|
570
|
+
**Full mode executes without prompts.** It will:
|
|
571
|
+
1. Research the issue and codebase
|
|
572
|
+
2. Enhance the GitHub issue with implementation plan
|
|
573
|
+
3. Assign issue to self, add "in-progress" label
|
|
574
|
+
4. Create branch, implement, test
|
|
575
|
+
5. Run /simplify on changed code, re-test if changes made
|
|
576
|
+
6. Commit, create PR, update issue status
|
|
577
|
+
7. Store learnings
|
|
@@ -150,7 +150,102 @@ Use Task tool with Explore agent to find:
|
|
|
150
150
|
|
|
151
151
|
## Phase 2: Ticket (-t creates or updates a ticket)
|
|
152
152
|
|
|
153
|
-
When given an issue number, `-t` enhances the existing ticket. When given a title (non-numeric argument), `-t` creates a new GitHub issue. Either way, the ticket MUST include all three of the following sections
|
|
153
|
+
When given an issue number, `-t` enhances the existing ticket. When given a title (non-numeric argument), `-t` creates a new GitHub issue. Either way, the ticket MUST include all three of the following sections.
|
|
154
|
+
|
|
155
|
+
### 2.0 Complexity Assessment (MANDATORY before building ticket)
|
|
156
|
+
|
|
157
|
+
After research, assess the complexity of the work. This determines whether the issue stays as a single ticket or gets promoted to an epic with sub-issues.
|
|
158
|
+
|
|
159
|
+
**Complexity Signals — count how many apply:**
|
|
160
|
+
|
|
161
|
+
| Signal | Weight | Example |
|
|
162
|
+
|--------|--------|---------|
|
|
163
|
+
| Multiple files changed (5+) | +2 | Touches models, API, tests, docs, config |
|
|
164
|
+
| New module or package | +2 | Requires new directory structure |
|
|
165
|
+
| Cross-cutting concern | +2 | Auth, logging, error handling across layers |
|
|
166
|
+
| Database/schema changes | +2 | Migrations, new tables, index changes |
|
|
167
|
+
| Multiple independent work streams | +3 | Frontend + backend + infra changes |
|
|
168
|
+
| External API integration | +1 | Third-party service, webhook, OAuth |
|
|
169
|
+
| Breaking change / migration | +2 | Requires deprecation, data migration |
|
|
170
|
+
| Significant test surface | +1 | Needs 10+ new test cases across categories |
|
|
171
|
+
| Security implications | +1 | Authentication, authorization, input validation |
|
|
172
|
+
| UI + backend changes together | +2 | Full-stack feature spanning layers |
|
|
173
|
+
|
|
174
|
+
**Complexity Thresholds:**
|
|
175
|
+
|
|
176
|
+
| Score | Classification | Action |
|
|
177
|
+
|-------|---------------|--------|
|
|
178
|
+
| 0–3 | **Simple** | Single ticket — proceed normally |
|
|
179
|
+
| 4–6 | **Moderate** | Single ticket — flag in description that it may benefit from splitting |
|
|
180
|
+
| 7+ | **Complex** | **PROMOTE TO EPIC** — decompose into sub-issues |
|
|
181
|
+
|
|
182
|
+
**When promoting to epic:**
|
|
183
|
+
|
|
184
|
+
1. Decompose the work into 2–6 independent, shippable stories
|
|
185
|
+
2. Each story should be completable in a single PR
|
|
186
|
+
3. Stories should have clear boundaries (one concern per story)
|
|
187
|
+
4. Order stories by dependency (independent ones first)
|
|
188
|
+
5. Create each story as a GitHub issue with its own Description, Acceptance Criteria, and Test Cases
|
|
189
|
+
6. Create or convert the parent issue into an epic with a `## Stories` checklist
|
|
190
|
+
|
|
191
|
+
```javascript
|
|
192
|
+
// Complexity assessment pseudocode
|
|
193
|
+
function assessComplexity(research) {
|
|
194
|
+
let score = 0;
|
|
195
|
+
if (research.affectedFiles.length >= 5) score += 2;
|
|
196
|
+
if (research.requiresNewModule) score += 2;
|
|
197
|
+
if (research.crossCutting) score += 2;
|
|
198
|
+
if (research.schemaChanges) score += 2;
|
|
199
|
+
if (research.independentWorkStreams >= 2) score += 3;
|
|
200
|
+
if (research.externalAPIs) score += 1;
|
|
201
|
+
if (research.breakingChanges) score += 2;
|
|
202
|
+
if (research.estimatedTestCases >= 10) score += 1;
|
|
203
|
+
if (research.securityImplications) score += 1;
|
|
204
|
+
if (research.fullStack) score += 2;
|
|
205
|
+
return score;
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### 2.0.1 Epic Decomposition (when score >= 7)
|
|
210
|
+
|
|
211
|
+
When complexity warrants an epic, decompose into stories:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# Step 1: Create each sub-issue
|
|
215
|
+
gh issue create --title "Story: <story-title>" --body "<## Description + ## Acceptance Criteria + ## Suggested Test Cases>" --label "story"
|
|
216
|
+
# Capture the new issue number from output
|
|
217
|
+
|
|
218
|
+
# Step 2: Repeat for all stories (2-6 stories typically)
|
|
219
|
+
|
|
220
|
+
# Step 3: Build the epic body with checklist referencing ALL story issue numbers
|
|
221
|
+
# Step 4: If updating an existing issue, convert it to epic:
|
|
222
|
+
gh issue edit <parent-number> --add-label "epic" --body "<epic body with ## Stories checklist>"
|
|
223
|
+
|
|
224
|
+
# Step 5: If creating new, create the epic:
|
|
225
|
+
gh issue create --title "Epic: <title>" --label "epic" --body "<epic body>"
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Epic body format (MANDATORY — this is how tracking works):**
|
|
229
|
+
|
|
230
|
+
```markdown
|
|
231
|
+
## Overview
|
|
232
|
+
<High-level description of the epic goal>
|
|
233
|
+
|
|
234
|
+
## Stories
|
|
235
|
+
|
|
236
|
+
- [ ] #<story-1-number> <story-1-title>
|
|
237
|
+
- [ ] #<story-2-number> <story-2-title>
|
|
238
|
+
- [ ] #<story-3-number> <story-3-title>
|
|
239
|
+
|
|
240
|
+
## Complexity Assessment
|
|
241
|
+
Score: <N>/20 — <Simple|Moderate|Complex>
|
|
242
|
+
Signals: <list of signals that triggered>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
The `## Stories` checklist with `- [ ] #<number>` format is **mandatory** — this is what enables:
|
|
246
|
+
- Epic detection by the `/flo` skill
|
|
247
|
+
- Story extraction for sequential processing
|
|
248
|
+
- Progress tracking via checked/unchecked items
|
|
154
249
|
|
|
155
250
|
### 2.1 Build Ticket Content
|
|
156
251
|
Compile research into a well-structured ticket. The issue MUST include all three of the following sections:
|
|
@@ -279,12 +374,40 @@ An issue is an **epic** if:
|
|
|
279
374
|
|
|
280
375
|
1. DETECT EPIC - Check labels, parse body for ## Stories / ## Tasks, extract issue references
|
|
281
376
|
2. LIST ALL STORIES - Extract from checklist, order top-to-bottom as listed
|
|
282
|
-
3. SEQUENTIAL PROCESSING - For each story:
|
|
283
|
-
|
|
377
|
+
3. SEQUENTIAL PROCESSING - For each story:
|
|
378
|
+
a. Run full /flo workflow (research -> ticket -> implement -> test -> PR)
|
|
379
|
+
b. After PR is created, **check off the story** in the epic body
|
|
380
|
+
c. Move to the next unchecked story
|
|
381
|
+
4. COMPLETION - All stories checked off, epic marked as ready-for-review
|
|
284
382
|
|
|
285
383
|
ONE STORY AT A TIME - NO PARALLEL STORY EXECUTION.
|
|
286
384
|
Each story must complete (PR created) before starting next.
|
|
287
385
|
|
|
386
|
+
### Epic Checklist Tracking (MANDATORY)
|
|
387
|
+
|
|
388
|
+
After each story's PR is created, update the epic body to check off that story:
|
|
389
|
+
|
|
390
|
+
```bash
|
|
391
|
+
# 1. Fetch current epic body
|
|
392
|
+
EPIC_BODY=$(gh issue view <epic-number> --json body -q '.body')
|
|
393
|
+
|
|
394
|
+
# 2. Replace "- [ ] #<story-number>" with "- [x] #<story-number>"
|
|
395
|
+
UPDATED_BODY=$(echo "$EPIC_BODY" | sed 's/- \[ \] #<story-number>/- [x] #<story-number>/')
|
|
396
|
+
|
|
397
|
+
# 3. Update the epic
|
|
398
|
+
gh issue edit <epic-number> --body "$UPDATED_BODY"
|
|
399
|
+
|
|
400
|
+
# 4. Comment on the epic with progress
|
|
401
|
+
gh issue comment <epic-number> --body "✅ Story #<story-number> completed — PR: <pr-url>"
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
This applies to ALL epics, regardless of how they were created:
|
|
405
|
+
- Epics created by `/flo -t` complexity promotion
|
|
406
|
+
- Epics created manually by users
|
|
407
|
+
- Epics detected from existing issues
|
|
408
|
+
|
|
409
|
+
The checklist state (`[ ]` vs `[x]`) is the **single source of truth** for epic progress.
|
|
410
|
+
|
|
288
411
|
### Epic Detection Code
|
|
289
412
|
|
|
290
413
|
```javascript
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "moflo",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.4",
|
|
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",
|
|
@@ -229,7 +229,7 @@ const listCommand = {
|
|
|
229
229
|
}
|
|
230
230
|
// Format for display
|
|
231
231
|
const displayAgents = result.agents.map(agent => ({
|
|
232
|
-
id: agent.
|
|
232
|
+
id: agent.agentId,
|
|
233
233
|
type: agent.agentType,
|
|
234
234
|
status: agent.status,
|
|
235
235
|
created: new Date(agent.createdAt).toLocaleTimeString(),
|
|
@@ -540,7 +540,11 @@ const poolCommand = {
|
|
|
540
540
|
`Auto-Scale: ${result.autoScale ? 'Yes' : 'No'}`,
|
|
541
541
|
`Utilization: ${(utilization * 100).toFixed(1)}%`
|
|
542
542
|
].join('\n'), 'Agent Pool');
|
|
543
|
-
const agents = result.agents ?? []
|
|
543
|
+
const agents = (result.agents ?? []).map((a) => ({
|
|
544
|
+
id: a.agentId || a.id,
|
|
545
|
+
type: a.agentType || a.type,
|
|
546
|
+
status: a.status,
|
|
547
|
+
}));
|
|
544
548
|
if (agents.length > 0) {
|
|
545
549
|
output.writeln();
|
|
546
550
|
output.writeln(output.bold('Pool Agents'));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moflo/cli",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.4",
|
|
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",
|