@cliangdev/flux-plugin 0.0.0-dev.1db9c6c → 0.0.0-dev.2cf4bc2
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 +9 -4
- 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 +47 -34
- package/commands/flux.md +127 -84
- package/commands/linear.md +171 -0
- package/dist/server/index.js +116 -11
- package/manifest.json +15 -0
- package/package.json +9 -4
- package/skills/flux-orchestrator/SKILL.md +58 -76
package/bin/install.cjs
CHANGED
|
@@ -99,47 +99,42 @@ ${cyan} ███████╗██╗ ██╗ ██╗██╗
|
|
|
99
99
|
const claudeDir = isGlobal
|
|
100
100
|
? path.join(os.homedir(), ".claude")
|
|
101
101
|
: path.join(process.cwd(), ".claude");
|
|
102
|
-
const pluginDir = path.join(claudeDir, "plugins", "marketplaces", "npm", "flux-plugin");
|
|
103
102
|
const locationLabel = isGlobal ? "~/.claude" : "./.claude";
|
|
104
103
|
|
|
105
|
-
console.log(` Installing to ${cyan}${locationLabel}
|
|
104
|
+
console.log(` Installing to ${cyan}${locationLabel}${reset}\n`);
|
|
106
105
|
|
|
107
|
-
fs.mkdirSync(
|
|
108
|
-
|
|
109
|
-
const pluginConfigDir = path.join(pluginDir, ".claude-plugin");
|
|
110
|
-
fs.mkdirSync(pluginConfigDir, { recursive: true });
|
|
111
|
-
writeJson(path.join(pluginConfigDir, "plugin.json"), {
|
|
112
|
-
name: "flux-plugin",
|
|
113
|
-
description: "AI-first workflow orchestration for spec-driven development",
|
|
114
|
-
version: pkg.version,
|
|
115
|
-
author: {
|
|
116
|
-
name: "cliangdev",
|
|
117
|
-
url: "https://github.com/cliangdev/flux-plugin"
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
console.log(` ${green}✓${reset} Created plugin config`);
|
|
106
|
+
fs.mkdirSync(claudeDir, { recursive: true });
|
|
121
107
|
|
|
122
108
|
const commandsSrc = path.join(src, "commands");
|
|
123
109
|
if (fs.existsSync(commandsSrc)) {
|
|
124
|
-
const commandsDest = path.join(
|
|
125
|
-
|
|
110
|
+
const commandsDest = path.join(claudeDir, "commands");
|
|
111
|
+
const fluxSubDir = path.join(commandsDest, "flux");
|
|
112
|
+
fs.mkdirSync(fluxSubDir, { recursive: true });
|
|
126
113
|
|
|
127
114
|
const commandFiles = fs.readdirSync(commandsSrc);
|
|
128
115
|
for (const file of commandFiles) {
|
|
129
116
|
if (file.endsWith(".md")) {
|
|
130
|
-
fs.copyFileSync(
|
|
131
|
-
path.join(commandsSrc, file),
|
|
132
|
-
path.join(commandsDest, file)
|
|
133
|
-
);
|
|
134
117
|
const name = file.replace(".md", "");
|
|
135
|
-
|
|
118
|
+
if (name === "flux") {
|
|
119
|
+
fs.copyFileSync(
|
|
120
|
+
path.join(commandsSrc, file),
|
|
121
|
+
path.join(commandsDest, file)
|
|
122
|
+
);
|
|
123
|
+
console.log(` ${green}✓${reset} Installed command: /flux`);
|
|
124
|
+
} else {
|
|
125
|
+
fs.copyFileSync(
|
|
126
|
+
path.join(commandsSrc, file),
|
|
127
|
+
path.join(fluxSubDir, file)
|
|
128
|
+
);
|
|
129
|
+
console.log(` ${green}✓${reset} Installed command: /flux:${name}`);
|
|
130
|
+
}
|
|
136
131
|
}
|
|
137
132
|
}
|
|
138
133
|
}
|
|
139
134
|
|
|
140
135
|
const skillsSrc = path.join(src, "skills");
|
|
141
136
|
if (fs.existsSync(skillsSrc)) {
|
|
142
|
-
const skillsDest = path.join(
|
|
137
|
+
const skillsDest = path.join(claudeDir, "skills");
|
|
143
138
|
fs.mkdirSync(skillsDest, { recursive: true });
|
|
144
139
|
|
|
145
140
|
const skillDirs = fs.readdirSync(skillsSrc, { withFileTypes: true });
|
|
@@ -154,27 +149,45 @@ ${cyan} ███████╗██╗ ██╗ ██╗██╗
|
|
|
154
149
|
}
|
|
155
150
|
}
|
|
156
151
|
|
|
157
|
-
const
|
|
152
|
+
const agentsSrc = path.join(src, "agents");
|
|
153
|
+
if (fs.existsSync(agentsSrc)) {
|
|
154
|
+
const agentsDest = path.join(claudeDir, "agents");
|
|
155
|
+
fs.mkdirSync(agentsDest, { recursive: true });
|
|
156
|
+
|
|
157
|
+
const agentFiles = fs.readdirSync(agentsSrc);
|
|
158
|
+
for (const file of agentFiles) {
|
|
159
|
+
if (file.endsWith(".md")) {
|
|
160
|
+
fs.copyFileSync(
|
|
161
|
+
path.join(agentsSrc, file),
|
|
162
|
+
path.join(agentsDest, file)
|
|
163
|
+
);
|
|
164
|
+
const name = file.replace(".md", "");
|
|
165
|
+
console.log(` ${green}✓${reset} Installed agent: ${name}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const mcpConfigPath = isGlobal
|
|
158
171
|
? path.join(os.homedir(), ".claude.json")
|
|
159
|
-
: path.join(process.cwd(), ".
|
|
172
|
+
: path.join(process.cwd(), ".mcp.json");
|
|
160
173
|
|
|
161
|
-
const
|
|
174
|
+
const mcpConfig = readJson(mcpConfigPath);
|
|
162
175
|
|
|
163
|
-
if (!
|
|
164
|
-
|
|
176
|
+
if (!mcpConfig.mcpServers) {
|
|
177
|
+
mcpConfig.mcpServers = {};
|
|
165
178
|
}
|
|
166
179
|
|
|
167
|
-
|
|
180
|
+
mcpConfig.mcpServers.flux = {
|
|
168
181
|
command: "npx",
|
|
169
|
-
args: ["-y",
|
|
182
|
+
args: ["-y", `@cliangdev/flux-plugin@${pkg.version}`, "serve"],
|
|
170
183
|
};
|
|
171
184
|
|
|
172
|
-
writeJson(
|
|
185
|
+
writeJson(mcpConfigPath, mcpConfig);
|
|
173
186
|
console.log(
|
|
174
|
-
` ${green}✓${reset} Configured MCP server in ${isGlobal ? "~/.claude.json" : "./.
|
|
187
|
+
` ${green}✓${reset} Configured MCP server in ${isGlobal ? "~/.claude.json" : "./.mcp.json"}`
|
|
175
188
|
);
|
|
176
189
|
|
|
177
|
-
const versionFile = path.join(
|
|
190
|
+
const versionFile = path.join(claudeDir, "flux-version");
|
|
178
191
|
fs.writeFileSync(versionFile, pkg.version);
|
|
179
192
|
|
|
180
193
|
console.log(`
|
package/commands/flux.md
CHANGED
|
@@ -1,113 +1,156 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: flux
|
|
3
3
|
description: AI-first workflow orchestration for spec-driven development
|
|
4
|
-
allowed-tools:
|
|
4
|
+
allowed-tools: mcp__plugin_flux_flux__*, AskUserQuestion, Read, Write
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
# Flux
|
|
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
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
- `/flux version` - Show plugin version (call `get_version`)
|
|
14
|
+
- `/flux linear` - Connect to Linear (delegate to `/flux:linear`)
|
|
10
15
|
|
|
11
|
-
##
|
|
16
|
+
## Main Flow
|
|
17
|
+
|
|
18
|
+
### Step 1: Get Project Context
|
|
12
19
|
|
|
13
|
-
|
|
14
|
-
- `/flux version` - Show version information
|
|
20
|
+
Call `get_project_context` to check project state.
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
### Step 2: Route Based on State
|
|
17
23
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
```
|
|
21
|
-
Flux Plugin v{version}
|
|
22
|
-
Package: @cliangdev/{name}
|
|
23
|
-
```
|
|
24
|
-
3. Exit (do not proceed to project state check)
|
|
24
|
+
**If `initialized: false`:**
|
|
25
|
+
→ Guide through initialization (see Initialization Flow below)
|
|
25
26
|
|
|
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)
|
|
27
30
|
|
|
28
|
-
|
|
31
|
+
## Initialization Flow
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
Use the `AskUserQuestion` tool for all questions during initialization.
|
|
31
34
|
|
|
32
|
-
###
|
|
35
|
+
### Step 1: Confirm Initialization
|
|
33
36
|
|
|
34
|
-
|
|
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
|
+
```
|
|
35
51
|
|
|
36
|
-
|
|
37
|
-
- If no, end with: "Run `/flux` when you're ready to set up Flux."
|
|
52
|
+
If "No", exit with: "Run `/flux` when you're ready to set up Flux."
|
|
38
53
|
|
|
39
|
-
2
|
|
40
|
-
- Wait for response
|
|
54
|
+
### Step 2: Collect Project Details
|
|
41
55
|
|
|
42
|
-
|
|
43
|
-
|
|
56
|
+
Use AskUserQuestion with text input (user will select "Other" to type):
|
|
57
|
+
- Ask for project name
|
|
58
|
+
- Ask for project vision (brief description)
|
|
44
59
|
|
|
45
|
-
|
|
60
|
+
### Step 3: Select Storage Backend
|
|
46
61
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
+
```
|
|
50
76
|
|
|
51
|
-
|
|
52
|
-
Vision: {vision}
|
|
53
|
-
Reference prefix: {ref_prefix}
|
|
77
|
+
### Step 4: Ask About Tool Permissions
|
|
54
78
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
+
```
|
|
58
93
|
|
|
59
|
-
|
|
60
|
-
```
|
|
94
|
+
If "Yes", update the settings file:
|
|
61
95
|
|
|
62
|
-
|
|
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`
|
|
63
100
|
|
|
64
|
-
|
|
101
|
+
Example result:
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"permissions": {
|
|
105
|
+
"allow": ["mcp__plugin_flux_flux__*"]
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
65
109
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
> "All tasks complete! Review your work and create a PR."
|
|
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 |
|
|
107
150
|
|
|
108
151
|
## Guidelines
|
|
109
152
|
|
|
110
|
-
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
-
|
|
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,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
|