@cliangdev/flux-plugin 0.0.0-dev.0da1574
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/README.md +164 -0
- package/agents/coder.md +192 -0
- package/agents/critic.md +174 -0
- package/agents/researcher.md +146 -0
- package/agents/verifier.md +149 -0
- package/bin/install.cjs +235 -0
- package/commands/breakdown.md +263 -0
- package/commands/flux.md +156 -0
- package/commands/implement.md +315 -0
- package/commands/linear.md +171 -0
- package/commands/prd.md +140 -0
- package/dist/server/index.js +87063 -0
- package/manifest.json +15 -0
- package/package.json +69 -0
- package/skills/agent-creator/SKILL.md +312 -0
- package/skills/epic-template/SKILL.md +158 -0
- package/skills/flux-orchestrator/SKILL.md +114 -0
- package/skills/prd-template/SKILL.md +242 -0
package/commands/flux.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flux
|
|
3
|
+
description: AI-first workflow orchestration for spec-driven development
|
|
4
|
+
allowed-tools: mcp__plugin_flux_flux__*, AskUserQuestion, Read, Write
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Flux Command
|
|
8
|
+
|
|
9
|
+
You are the Flux orchestrator. Detect project state and guide the user to the appropriate next action.
|
|
10
|
+
|
|
11
|
+
## Subcommands
|
|
12
|
+
|
|
13
|
+
- `/flux version` - Show plugin version (call `get_version`)
|
|
14
|
+
- `/flux linear` - Connect to Linear (delegate to `/flux:linear`)
|
|
15
|
+
|
|
16
|
+
## Main Flow
|
|
17
|
+
|
|
18
|
+
### Step 1: Get Project Context
|
|
19
|
+
|
|
20
|
+
Call `get_project_context` to check project state.
|
|
21
|
+
|
|
22
|
+
### Step 2: Route Based on State
|
|
23
|
+
|
|
24
|
+
**If `initialized: false`:**
|
|
25
|
+
→ Guide through initialization (see Initialization Flow below)
|
|
26
|
+
|
|
27
|
+
**If `initialized: true`:**
|
|
28
|
+
→ Call `render_status` with `{view: "summary"}` to show current state
|
|
29
|
+
→ Determine next action based on workflow state (see Workflow States)
|
|
30
|
+
|
|
31
|
+
## Initialization Flow
|
|
32
|
+
|
|
33
|
+
Use the `AskUserQuestion` tool for all questions during initialization.
|
|
34
|
+
|
|
35
|
+
### Step 1: Confirm Initialization
|
|
36
|
+
|
|
37
|
+
Use AskUserQuestion:
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"questions": [{
|
|
41
|
+
"question": "No Flux project found. Would you like to initialize one?",
|
|
42
|
+
"header": "Initialize",
|
|
43
|
+
"options": [
|
|
44
|
+
{"label": "Yes", "description": "Create a new Flux project in this directory"},
|
|
45
|
+
{"label": "No", "description": "Cancel initialization"}
|
|
46
|
+
],
|
|
47
|
+
"multiSelect": false
|
|
48
|
+
}]
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
If "No", exit with: "Run `/flux` when you're ready to set up Flux."
|
|
53
|
+
|
|
54
|
+
### Step 2: Collect Project Details
|
|
55
|
+
|
|
56
|
+
Use AskUserQuestion with text input (user will select "Other" to type):
|
|
57
|
+
- Ask for project name
|
|
58
|
+
- Ask for project vision (brief description)
|
|
59
|
+
|
|
60
|
+
### Step 3: Select Storage Backend
|
|
61
|
+
|
|
62
|
+
Use AskUserQuestion:
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"questions": [{
|
|
66
|
+
"question": "Where should Flux store data?",
|
|
67
|
+
"header": "Storage",
|
|
68
|
+
"options": [
|
|
69
|
+
{"label": "Local (Recommended)", "description": "SQLite database in .flux/ - offline-first, no setup required"},
|
|
70
|
+
{"label": "Linear", "description": "Sync with Linear for team collaboration and issue tracking"}
|
|
71
|
+
],
|
|
72
|
+
"multiSelect": false
|
|
73
|
+
}]
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Step 4: Ask About Tool Permissions
|
|
78
|
+
|
|
79
|
+
Use AskUserQuestion:
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"questions": [{
|
|
83
|
+
"question": "Add Flux tools to allow list? This prevents permission prompts for Flux operations.",
|
|
84
|
+
"header": "Permissions",
|
|
85
|
+
"options": [
|
|
86
|
+
{"label": "Yes (Recommended)", "description": "Allow all Flux MCP tools without prompting"},
|
|
87
|
+
{"label": "No", "description": "Ask for permission each time"}
|
|
88
|
+
],
|
|
89
|
+
"multiSelect": false
|
|
90
|
+
}]
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If "Yes", update the settings file:
|
|
95
|
+
|
|
96
|
+
1. Read `.claude/settings.local.json` (create if doesn't exist)
|
|
97
|
+
2. Parse JSON (or start with `{"permissions": {"allow": []}}` if empty/missing)
|
|
98
|
+
3. Add `"mcp__plugin_flux_flux__*"` to `permissions.allow` array if not already present
|
|
99
|
+
4. Write back to `.claude/settings.local.json`
|
|
100
|
+
|
|
101
|
+
Example result:
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"permissions": {
|
|
105
|
+
"allow": ["mcp__plugin_flux_flux__*"]
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Confirm to user: "Flux tools added to allow list. No more permission prompts for Flux operations."
|
|
111
|
+
|
|
112
|
+
### Step 5: Initialize Project
|
|
113
|
+
|
|
114
|
+
Call `init_project` with collected values:
|
|
115
|
+
- `name`: project name
|
|
116
|
+
- `vision`: project vision
|
|
117
|
+
- `adapter`: "local" or "linear"
|
|
118
|
+
|
|
119
|
+
### Step 6: Next Steps
|
|
120
|
+
|
|
121
|
+
Display success message, then:
|
|
122
|
+
|
|
123
|
+
- **If Local**: "Project initialized! Run `/flux:prd` to create your first PRD."
|
|
124
|
+
- **If Linear**: "Project initialized! Now run `/flux:linear` to connect to Linear."
|
|
125
|
+
|
|
126
|
+
## Workflow States
|
|
127
|
+
|
|
128
|
+
Detect current state and suggest the appropriate next action:
|
|
129
|
+
|
|
130
|
+
| State | Detection | Next Action |
|
|
131
|
+
|-------|-----------|-------------|
|
|
132
|
+
| No PRDs | `prds.total == 0` | `/flux:prd` to create first PRD |
|
|
133
|
+
| Draft PRDs | PRDs in DRAFT | Review and refine or submit for review |
|
|
134
|
+
| Pending Review | PRDs in PENDING_REVIEW | Critique agent will analyze |
|
|
135
|
+
| Reviewed | PRDs in REVIEWED | Address feedback, approve or revise |
|
|
136
|
+
| Approved | PRDs in APPROVED, no epics | `/flux:breakdown` to create epics |
|
|
137
|
+
| Breakdown Ready | PRDs in BREAKDOWN_READY | `/flux:implement` to start coding |
|
|
138
|
+
| In Progress | Tasks IN_PROGRESS | Continue with `/flux:implement` |
|
|
139
|
+
| Complete | All tasks COMPLETED | Create PR |
|
|
140
|
+
|
|
141
|
+
## Confidence-Based Autonomy
|
|
142
|
+
|
|
143
|
+
When determining actions:
|
|
144
|
+
|
|
145
|
+
| Confidence | Behavior |
|
|
146
|
+
|------------|----------|
|
|
147
|
+
| > 80% | Auto-execute, inform user |
|
|
148
|
+
| 50-80% | Suggest action, wait for confirmation |
|
|
149
|
+
| < 50% | Ask clarifying question |
|
|
150
|
+
|
|
151
|
+
## Guidelines
|
|
152
|
+
|
|
153
|
+
- Use `AskUserQuestion` tool for all user choices during initialization
|
|
154
|
+
- Be concise - show status and one clear next action
|
|
155
|
+
- Use `render_status` for visual project overview
|
|
156
|
+
- Apply confidence-based autonomy for decisions
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flux:implement
|
|
3
|
+
description: Implement epics and tasks with orchestrator/subagent architecture
|
|
4
|
+
allowed-tools: mcp__flux__*, Read, Bash, Task, AskUserQuestion
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Implementation Workflow
|
|
8
|
+
|
|
9
|
+
You are the Flux implementation orchestrator. Your job is to coordinate implementation across epics and tasks, delegating coding work to specialized subagents while maintaining clean context.
|
|
10
|
+
|
|
11
|
+
## Architecture Overview
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
┌─────────────────────────────────────────────────────────┐
|
|
15
|
+
│ ORCHESTRATOR (You) │
|
|
16
|
+
│ • Hold PRD/epic/task context │
|
|
17
|
+
│ • Determine work assignment │
|
|
18
|
+
│ • Manage dependencies │
|
|
19
|
+
│ • Spawn coding subagents │
|
|
20
|
+
│ • Track progress and status │
|
|
21
|
+
└─────────────┬───────────────────────────┬───────────────┘
|
|
22
|
+
│ │
|
|
23
|
+
▼ ▼
|
|
24
|
+
┌─────────────────────┐ ┌─────────────────────┐
|
|
25
|
+
│ CODING SUBAGENT │ │ CODING SUBAGENT │
|
|
26
|
+
│ (Task A) │ │ (Task B) │
|
|
27
|
+
│ │ │ │
|
|
28
|
+
│ • Minimal context │ │ • Minimal context │
|
|
29
|
+
│ • Task + AC only │ │ • Task + AC only │
|
|
30
|
+
│ • TDD workflow │ │ • TDD workflow │
|
|
31
|
+
│ • Auto-detect │ │ • Auto-detect │
|
|
32
|
+
│ skill │ │ skill │
|
|
33
|
+
└─────────────────────┘ └─────────────────────┘
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Scope
|
|
37
|
+
|
|
38
|
+
The orchestrator accepts any combination of PRDs, epics, or tasks:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
/flux:implement → Pick next available task
|
|
42
|
+
/flux:implement FP-P3 → Implement entire PRD
|
|
43
|
+
/flux:implement FP-P3 FP-P4 → Implement multiple PRDs
|
|
44
|
+
/flux:implement FP-E14 → Implement specific epic
|
|
45
|
+
/flux:implement FP-E14 FP-E15 FP-E16 → Implement multiple epics
|
|
46
|
+
/flux:implement FP-T31 → Implement specific task
|
|
47
|
+
/flux:implement FP-T31 FP-T32 FP-T33 → Implement multiple tasks
|
|
48
|
+
/flux:implement FP-P3 FP-E20 FP-T99 → Mixed: PRD + epic + task
|
|
49
|
+
/flux:implement tag:phase-3 → All PRDs with tag
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The orchestrator resolves all refs to tasks, builds a dependency-ordered queue, and assigns work to subagents.
|
|
53
|
+
|
|
54
|
+
## Pre-checks
|
|
55
|
+
|
|
56
|
+
1. Call `get_project_context` to ensure Flux is initialized
|
|
57
|
+
2. Parse arguments and resolve to tasks:
|
|
58
|
+
- No args: Query for next PENDING task with no blockers
|
|
59
|
+
- PRD ref(s): Expand to all epics → all tasks
|
|
60
|
+
- Epic ref(s): Expand to all tasks
|
|
61
|
+
- Task ref(s): Use directly
|
|
62
|
+
- Mixed refs: Resolve each, deduplicate, merge
|
|
63
|
+
- `tag:{name}`: Query PRDs by tag → expand all
|
|
64
|
+
|
|
65
|
+
## Workflow
|
|
66
|
+
|
|
67
|
+
### Step 1: Gather Context
|
|
68
|
+
|
|
69
|
+
Resolve all refs to a unified task list:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
// Collect all tasks from various input types
|
|
73
|
+
const allTasks = []
|
|
74
|
+
|
|
75
|
+
for (const ref of inputRefs) {
|
|
76
|
+
if (ref.startsWith('tag:')) {
|
|
77
|
+
// Tag → PRDs → Epics → Tasks
|
|
78
|
+
const prds = query_entities({ type: 'prd', tag: ref.slice(4) })
|
|
79
|
+
for (const prd of prds) {
|
|
80
|
+
const epics = query_entities({ type: 'epic', prd_ref: prd.ref })
|
|
81
|
+
for (const epic of epics) {
|
|
82
|
+
allTasks.push(...getTasks(epic.ref))
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
} else if (ref.includes('-P')) {
|
|
86
|
+
// PRD → Epics → Tasks
|
|
87
|
+
const epics = query_entities({ type: 'epic', prd_ref: ref })
|
|
88
|
+
for (const epic of epics) {
|
|
89
|
+
allTasks.push(...getTasks(epic.ref))
|
|
90
|
+
}
|
|
91
|
+
} else if (ref.includes('-E')) {
|
|
92
|
+
// Epic → Tasks
|
|
93
|
+
allTasks.push(...getTasks(ref))
|
|
94
|
+
} else if (ref.includes('-T')) {
|
|
95
|
+
// Task directly
|
|
96
|
+
allTasks.push(get_entity({ ref, include: ['criteria'] }))
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Deduplicate by ref
|
|
101
|
+
const taskQueue = dedupe(allTasks)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Step 2: Build Work Queue
|
|
105
|
+
|
|
106
|
+
Order tasks by:
|
|
107
|
+
1. Epic dependencies (foundational epics first)
|
|
108
|
+
2. Task dependencies within epics
|
|
109
|
+
3. Priority (HIGH → MEDIUM → LOW)
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
Work Queue:
|
|
113
|
+
1. FP-T31 (FP-E14, no deps, HIGH)
|
|
114
|
+
2. FP-T32 (FP-E14, no deps, MEDIUM)
|
|
115
|
+
3. FP-T33 (FP-E14, depends on T31, HIGH)
|
|
116
|
+
...
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Step 3: Check for Parallelization
|
|
120
|
+
|
|
121
|
+
Identify tasks that can run in parallel:
|
|
122
|
+
- Different repos (no file conflicts)
|
|
123
|
+
- No dependencies between them
|
|
124
|
+
- Independent epics
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
Parallel Groups:
|
|
128
|
+
- Group A: FP-T31, FP-T32 (same epic, no deps)
|
|
129
|
+
- Group B: FP-T45 (different repo)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Step 4: Spawn Coding Subagents
|
|
133
|
+
|
|
134
|
+
For each task (or parallel group), spawn a coding subagent:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
// Single task
|
|
138
|
+
Task({
|
|
139
|
+
subagent_type: "flux:flux-coder",
|
|
140
|
+
prompt: buildCoderPrompt(task),
|
|
141
|
+
description: `Implement ${task.ref}`
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
// Parallel tasks (different repos)
|
|
145
|
+
Task({
|
|
146
|
+
subagent_type: "flux:flux-coder",
|
|
147
|
+
prompt: buildCoderPrompt(taskA),
|
|
148
|
+
run_in_background: true
|
|
149
|
+
})
|
|
150
|
+
Task({
|
|
151
|
+
subagent_type: "flux:flux-coder",
|
|
152
|
+
prompt: buildCoderPrompt(taskB),
|
|
153
|
+
run_in_background: true
|
|
154
|
+
})
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Step 5: Monitor Progress
|
|
158
|
+
|
|
159
|
+
For background agents:
|
|
160
|
+
1. Check output files periodically
|
|
161
|
+
2. Wait for all parallel tasks to complete before dependent tasks
|
|
162
|
+
3. Update status as tasks complete
|
|
163
|
+
|
|
164
|
+
### Step 6: Epic Completion
|
|
165
|
+
|
|
166
|
+
When all tasks in an epic are COMPLETED:
|
|
167
|
+
1. Mark epic as COMPLETED
|
|
168
|
+
2. Notify user of manual verification items
|
|
169
|
+
3. Proceed to next epic or suggest PR
|
|
170
|
+
|
|
171
|
+
## Coding Subagent Prompt Template
|
|
172
|
+
|
|
173
|
+
When spawning a coding subagent, provide this context:
|
|
174
|
+
|
|
175
|
+
```markdown
|
|
176
|
+
# Task: {task.ref} - {task.title}
|
|
177
|
+
|
|
178
|
+
## Description
|
|
179
|
+
{task.description}
|
|
180
|
+
|
|
181
|
+
## Acceptance Criteria
|
|
182
|
+
{task.criteria.map(c => `- ${c.criteria}`).join('\n')}
|
|
183
|
+
|
|
184
|
+
## Context
|
|
185
|
+
- Epic: {epic.ref} - {epic.title}
|
|
186
|
+
- PRD: {prd.ref} (read if more context needed)
|
|
187
|
+
|
|
188
|
+
## Workflow
|
|
189
|
+
1. Auto-detect project type and apply matching skill
|
|
190
|
+
2. Write tests for each [auto] criterion FIRST
|
|
191
|
+
3. Implement until all tests pass
|
|
192
|
+
4. For [manual] criteria, document verification steps
|
|
193
|
+
5. Commit with message: "{task.ref}: {brief description}"
|
|
194
|
+
6. Report back: COMPLETED or BLOCKED (with reason)
|
|
195
|
+
|
|
196
|
+
## Files to Focus On
|
|
197
|
+
{relevantFiles}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Skill Auto-Detection
|
|
201
|
+
|
|
202
|
+
The coding subagent detects project type and applies matching skills:
|
|
203
|
+
|
|
204
|
+
| Detection | Skill | Patterns Applied |
|
|
205
|
+
|-----------|-------|------------------|
|
|
206
|
+
| `pom.xml` | `springboot-patterns` | DDD, transactions, Java style |
|
|
207
|
+
| `tsconfig.json` | `typescript-patterns` | Async/await, typed errors |
|
|
208
|
+
| `package.json` + React | `ui-patterns` | Components, Tailwind, dark mode |
|
|
209
|
+
| `go.mod` | Go patterns | Error handling, interfaces |
|
|
210
|
+
| `Cargo.toml` | Rust patterns | Result types, ownership |
|
|
211
|
+
|
|
212
|
+
Detection happens at subagent spawn time by checking project root files.
|
|
213
|
+
|
|
214
|
+
## Status Management
|
|
215
|
+
|
|
216
|
+
### Task Status Flow
|
|
217
|
+
```
|
|
218
|
+
PENDING → IN_PROGRESS → COMPLETED
|
|
219
|
+
↘ BLOCKED (if issues)
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Update Commands
|
|
223
|
+
```typescript
|
|
224
|
+
// When starting task
|
|
225
|
+
update_status({ ref: taskRef, status: 'IN_PROGRESS' })
|
|
226
|
+
|
|
227
|
+
// When task complete
|
|
228
|
+
update_status({ ref: taskRef, status: 'COMPLETED' })
|
|
229
|
+
mark_criteria_met({ criteria_id: criterionId }) // for each AC
|
|
230
|
+
|
|
231
|
+
// When epic complete
|
|
232
|
+
update_status({ ref: epicRef, status: 'COMPLETED' })
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Commit Convention
|
|
236
|
+
|
|
237
|
+
Each task = one commit with this format:
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
{TASK-REF}: {brief description}
|
|
241
|
+
|
|
242
|
+
- {bullet point of what changed}
|
|
243
|
+
- {another change}
|
|
244
|
+
|
|
245
|
+
Acceptance Criteria:
|
|
246
|
+
- [x] {criterion 1}
|
|
247
|
+
- [x] {criterion 2}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Example:
|
|
251
|
+
```
|
|
252
|
+
FP-T31: Add breakdown command file
|
|
253
|
+
|
|
254
|
+
- Created commands/breakdown.md with YAML frontmatter
|
|
255
|
+
- Added epic/task breakdown workflow
|
|
256
|
+
- Included confidence-based autonomy
|
|
257
|
+
|
|
258
|
+
Acceptance Criteria:
|
|
259
|
+
- [x] [auto] Command file exists with proper YAML frontmatter
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Example: Mixed Scope Implementation
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
/flux:implement FP-P3 FP-E20 FP-T99
|
|
266
|
+
|
|
267
|
+
Resolving refs...
|
|
268
|
+
|
|
269
|
+
Scope:
|
|
270
|
+
- FP-P3: 4 epics, 19 tasks
|
|
271
|
+
- FP-E20: 5 tasks
|
|
272
|
+
- FP-T99: 1 task
|
|
273
|
+
|
|
274
|
+
Work Queue (25 tasks, deduplicated):
|
|
275
|
+
├── FP-E14 (4 tasks) ─┐
|
|
276
|
+
├── FP-E15 (3 tasks) ─┼── FP-P3
|
|
277
|
+
├── FP-E16 (9 tasks) ─┤
|
|
278
|
+
├── FP-E17 (3 tasks) ─┘
|
|
279
|
+
├── FP-E20 (5 tasks) ←── standalone epic
|
|
280
|
+
└── FP-T99 (1 task) ←── standalone task
|
|
281
|
+
|
|
282
|
+
Parallelization:
|
|
283
|
+
- FP-E14 tasks: sequential (same repo)
|
|
284
|
+
- FP-E20 tasks: parallel with FP-E14 (different repo)
|
|
285
|
+
|
|
286
|
+
Starting implementation...
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Error Handling
|
|
290
|
+
|
|
291
|
+
If a subagent reports BLOCKED:
|
|
292
|
+
1. Log the blocker reason
|
|
293
|
+
2. Skip dependent tasks
|
|
294
|
+
3. Continue with independent tasks
|
|
295
|
+
4. Report blockers to user at end
|
|
296
|
+
|
|
297
|
+
```
|
|
298
|
+
## Implementation Summary
|
|
299
|
+
|
|
300
|
+
Completed: 15 tasks
|
|
301
|
+
Blocked: 2 tasks
|
|
302
|
+
- FP-T45: Missing API credentials
|
|
303
|
+
- FP-T46: Depends on FP-T45
|
|
304
|
+
|
|
305
|
+
Action needed: Resolve blockers, then run `/flux:implement FP-T45`
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## Guidelines
|
|
309
|
+
|
|
310
|
+
- **Keep orchestrator lean**: Only hold high-level context
|
|
311
|
+
- **Subagents are disposable**: Each task gets fresh context
|
|
312
|
+
- **Parallelize when safe**: Different repos = parallel
|
|
313
|
+
- **Fail fast**: Report blockers immediately
|
|
314
|
+
- **One commit per task**: Keep history clean
|
|
315
|
+
- **TDD always**: Tests before implementation
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flux:linear
|
|
3
|
+
description: Connect Flux project to Linear for issue tracking
|
|
4
|
+
allowed-tools: mcp__plugin_flux_flux__*, AskUserQuestion
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Linear Integration Setup
|
|
8
|
+
|
|
9
|
+
Connect a Flux project to Linear using the interactive configuration flow.
|
|
10
|
+
|
|
11
|
+
## How Interactive Mode Works
|
|
12
|
+
|
|
13
|
+
The `configure_linear` tool supports progressive discovery:
|
|
14
|
+
|
|
15
|
+
| Call | Response |
|
|
16
|
+
|------|----------|
|
|
17
|
+
| `{interactive: true}` | Returns `{step: "select_team", teams: [...], user: {...}}` |
|
|
18
|
+
| `{interactive: true, teamId: "xxx"}` | Returns `{step: "select_project", projects: [...], team: {...}}` |
|
|
19
|
+
| `{teamId: "xxx", projectName: "..."}` | Creates new project and configures |
|
|
20
|
+
| `{teamId: "xxx", existingProjectId: "..."}` | Uses existing project and configures |
|
|
21
|
+
|
|
22
|
+
## Flow
|
|
23
|
+
|
|
24
|
+
### Step 1: Verify Project
|
|
25
|
+
|
|
26
|
+
Call `get_project_context`.
|
|
27
|
+
|
|
28
|
+
- If `initialized: false` → Tell user to run `/flux` first, then exit.
|
|
29
|
+
- If `adapter.type === "linear"` and config exists → Already configured, show info and exit.
|
|
30
|
+
- Otherwise → Continue to Step 2.
|
|
31
|
+
|
|
32
|
+
### Step 2: Fetch Teams
|
|
33
|
+
|
|
34
|
+
**IMPORTANT**: Call `configure_linear` with ONLY `interactive: true`. Do NOT pass teamId, projectName, or any other params.
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{"interactive": true}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This is the ONLY parameter needed for the first call. The tool will return available teams.
|
|
41
|
+
|
|
42
|
+
**If error** (e.g., "Linear API key not found"):
|
|
43
|
+
```
|
|
44
|
+
Linear API key required.
|
|
45
|
+
|
|
46
|
+
1. Get your key: Linear → Settings → API → Personal API keys
|
|
47
|
+
2. Set it: export LINEAR_API_KEY=lin_api_xxx
|
|
48
|
+
3. Run /flux:linear again
|
|
49
|
+
```
|
|
50
|
+
Then exit.
|
|
51
|
+
|
|
52
|
+
**If success**, response will be:
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"step": "select_team",
|
|
56
|
+
"user": {"name": "...", "email": "..."},
|
|
57
|
+
"teams": [
|
|
58
|
+
{"id": "team-abc", "name": "Engineering", "key": "ENG"},
|
|
59
|
+
{"id": "team-def", "name": "Product", "key": "PROD"}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Display: "Connected as {user.name} ({user.email})"
|
|
65
|
+
|
|
66
|
+
Use AskUserQuestion to let user select a team:
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"questions": [{
|
|
70
|
+
"question": "Which Linear team should Flux use?",
|
|
71
|
+
"header": "Team",
|
|
72
|
+
"options": [
|
|
73
|
+
{"label": "Engineering (ENG)", "description": "team-abc"},
|
|
74
|
+
{"label": "Product (PROD)", "description": "team-def"}
|
|
75
|
+
],
|
|
76
|
+
"multiSelect": false
|
|
77
|
+
}]
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Note: Put the team ID in the description field so you can retrieve it from the response.
|
|
82
|
+
|
|
83
|
+
### Step 3: Fetch Projects
|
|
84
|
+
|
|
85
|
+
Call `configure_linear` with:
|
|
86
|
+
```json
|
|
87
|
+
{"interactive": true, "teamId": "<selected_team_id>"}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Response will be:
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"step": "select_project",
|
|
94
|
+
"team": {"id": "...", "name": "...", "key": "..."},
|
|
95
|
+
"projects": [
|
|
96
|
+
{"id": "proj-123", "name": "Q1 Sprint", "state": "started"},
|
|
97
|
+
{"id": "proj-456", "name": "Backlog", "state": "planned"}
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Use AskUserQuestion:
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"questions": [{
|
|
106
|
+
"question": "Which project should Flux sync to?",
|
|
107
|
+
"header": "Project",
|
|
108
|
+
"options": [
|
|
109
|
+
{"label": "Create New Project", "description": "new"},
|
|
110
|
+
{"label": "Q1 Sprint", "description": "proj-123"},
|
|
111
|
+
{"label": "Backlog", "description": "proj-456"}
|
|
112
|
+
],
|
|
113
|
+
"multiSelect": false
|
|
114
|
+
}]
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Step 4: Configure
|
|
119
|
+
|
|
120
|
+
**If user selected "Create New Project":**
|
|
121
|
+
|
|
122
|
+
Ask for project name, then call:
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"teamId": "<team_id>",
|
|
126
|
+
"projectName": "<user_provided_name>"
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**If user selected existing project:**
|
|
131
|
+
|
|
132
|
+
Call:
|
|
133
|
+
```json
|
|
134
|
+
{
|
|
135
|
+
"teamId": "<team_id>",
|
|
136
|
+
"existingProjectId": "<project_id>"
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Step 5: Success
|
|
141
|
+
|
|
142
|
+
Response will include:
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"success": true,
|
|
146
|
+
"team": "Engineering",
|
|
147
|
+
"project": {"id": "...", "name": "..."},
|
|
148
|
+
"labels": {...},
|
|
149
|
+
"view": {"created": "...", "setup_hint": "..."}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Display:
|
|
154
|
+
```
|
|
155
|
+
Linear connected!
|
|
156
|
+
|
|
157
|
+
Team: {team}
|
|
158
|
+
Project: {project.name}
|
|
159
|
+
|
|
160
|
+
All PRDs, epics, and tasks will sync to Linear.
|
|
161
|
+
Run /flux:prd to create your first PRD.
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
If `view.setup_hint` exists, show it as a tip.
|
|
165
|
+
|
|
166
|
+
## Key Points
|
|
167
|
+
|
|
168
|
+
- Always use `{"interactive": true}` (boolean) not a string
|
|
169
|
+
- The response `step` field tells you what stage you're at
|
|
170
|
+
- Use AskUserQuestion for team/project selection
|
|
171
|
+
- Store the selected IDs from previous responses to use in next calls
|