@eskoubar95/spec 0.1.0 → 0.1.3
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/dist/commands/help.d.ts +5 -0
- package/dist/commands/help.d.ts.map +1 -0
- package/dist/commands/help.js +23 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +30 -14
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install.d.ts +5 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +88 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/update.d.ts +5 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +72 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/workspace.d.ts +5 -0
- package/dist/commands/workspace.d.ts.map +1 -0
- package/dist/commands/workspace.js +17 -0
- package/dist/commands/workspace.js.map +1 -0
- package/dist/index.js +42 -9
- package/dist/index.js.map +1 -1
- package/dist/lib/backup-cursor.d.ts +16 -0
- package/dist/lib/backup-cursor.d.ts.map +1 -0
- package/dist/lib/backup-cursor.js +50 -0
- package/dist/lib/backup-cursor.js.map +1 -0
- package/dist/lib/copy-template.d.ts +9 -1
- package/dist/lib/copy-template.d.ts.map +1 -1
- package/dist/lib/copy-template.js +94 -3
- package/dist/lib/copy-template.js.map +1 -1
- package/dist/lib/cursor-detection.d.ts +6 -0
- package/dist/lib/cursor-detection.d.ts.map +1 -0
- package/dist/lib/cursor-detection.js +31 -0
- package/dist/lib/cursor-detection.js.map +1 -0
- package/dist/lib/detection.d.ts +25 -0
- package/dist/lib/detection.d.ts.map +1 -0
- package/dist/lib/detection.js +186 -0
- package/dist/lib/detection.js.map +1 -0
- package/dist/lib/install-existing.d.ts +6 -0
- package/dist/lib/install-existing.d.ts.map +1 -0
- package/dist/lib/install-existing.js +63 -0
- package/dist/lib/install-existing.js.map +1 -0
- package/dist/lib/project-name.d.ts +7 -0
- package/dist/lib/project-name.d.ts.map +1 -0
- package/dist/lib/project-name.js +13 -0
- package/dist/lib/project-name.js.map +1 -0
- package/dist/lib/prompts.d.ts +6 -5
- package/dist/lib/prompts.d.ts.map +1 -1
- package/dist/lib/prompts.js +114 -0
- package/dist/lib/prompts.js.map +1 -1
- package/dist/lib/version-check.d.ts +21 -0
- package/dist/lib/version-check.d.ts.map +1 -0
- package/dist/lib/version-check.js +49 -0
- package/dist/lib/version-check.js.map +1 -0
- package/dist/lib/workspace.d.ts +7 -0
- package/dist/lib/workspace.d.ts.map +1 -0
- package/dist/lib/workspace.js +38 -0
- package/dist/lib/workspace.js.map +1 -0
- package/dist/types.d.ts +32 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +2 -2
- package/template/.cursor/commands/_shared/activation.md +220 -0
- package/template/.cursor/commands/_shared/coderabbit-integration.md +278 -0
- package/template/.cursor/commands/_shared/command-stacks.md +124 -0
- package/template/.cursor/commands/_shared/deployment-detection.md +294 -0
- package/template/.cursor/commands/_shared/detection.md +277 -0
- package/template/.cursor/commands/_shared/documentation-lookup.md +321 -0
- package/template/.cursor/commands/_shared/git-workflow.md +288 -0
- package/template/.cursor/commands/_shared/github-helpers.md +337 -0
- package/template/.cursor/commands/_shared/github-workflows.md +351 -0
- package/template/.cursor/commands/_shared/helper-metadata.md +481 -0
- package/template/.cursor/commands/_shared/linear-automation.md +388 -0
- package/template/.cursor/commands/_shared/linear-helpers.md +254 -0
- package/template/.cursor/commands/_shared/performance-monitoring.md +369 -0
- package/template/.cursor/commands/_shared/pr-description.md +279 -0
- package/template/.cursor/commands/_shared/retrospective-spec-creation.md +977 -0
- package/template/.cursor/commands/_shared/scaling.md +264 -0
- package/template/.cursor/commands/_shared/state-assertions.md +174 -0
- package/template/.cursor/commands/_shared/test-automation.md +388 -0
- package/template/.cursor/commands/_shared/verification-checkpoints.md +145 -0
- package/template/.cursor/commands/spec/audit.md +240 -0
- package/template/.cursor/commands/spec/evolve.md +163 -0
- package/template/.cursor/commands/spec/sync.md +196 -0
- package/template/.cursor/commands/tools/refactor.md +555 -0
- package/template/.cursor/rules/10-engineering.mdc +149 -0
- package/template/.cursor/rules/11-design.mdc +129 -0
- package/template/.cursor/rules/12-business.mdc +132 -0
- package/template/.cursor/rules/20-nextjs.mdc +146 -0
- package/template/.cursor/rules/21-api-design.mdc +176 -0
- package/template/.cursor/rules/30-database.mdc +183 -0
- package/template/.cursor/rules/31-testing.mdc +191 -0
- package/template/.cursor/scripts/validate-helpers.js +254 -0
- package/template/.sdd/detection-cache.json +1 -0
- package/template/.sdd/install-info.json +1 -0
- package/template/.sdd/version +1 -0
- package/template/spec/00-root-spec.md +8 -1
- package/template/work/backlog/tasks.local.md +92 -0
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
---
|
|
2
|
+
helper_id: linear-automation
|
|
3
|
+
load_when:
|
|
4
|
+
- linear_mode_enabled
|
|
5
|
+
- spec_init
|
|
6
|
+
- spec_refine
|
|
7
|
+
- spec_plan
|
|
8
|
+
- task_start
|
|
9
|
+
- task_validate
|
|
10
|
+
dependencies:
|
|
11
|
+
- linear-helpers
|
|
12
|
+
sections:
|
|
13
|
+
detection:
|
|
14
|
+
title: "Detection Logic"
|
|
15
|
+
lines: [9, 32]
|
|
16
|
+
documents:
|
|
17
|
+
title: "Documents"
|
|
18
|
+
lines: [35, 80]
|
|
19
|
+
issues:
|
|
20
|
+
title: "Issues"
|
|
21
|
+
lines: [82, 130]
|
|
22
|
+
projects:
|
|
23
|
+
title: "Projects"
|
|
24
|
+
lines: [132, 180]
|
|
25
|
+
labels:
|
|
26
|
+
title: "Labels"
|
|
27
|
+
lines: [182, 220]
|
|
28
|
+
statuses:
|
|
29
|
+
title: "Statuses"
|
|
30
|
+
lines: [222, 260]
|
|
31
|
+
always_load: false
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
# Linear MCP Automation Rules
|
|
35
|
+
|
|
36
|
+
This document defines when and how to automatically use Linear MCP functions within the SDD workflow.
|
|
37
|
+
|
|
38
|
+
## Purpose
|
|
39
|
+
|
|
40
|
+
Automate Linear operations based on SDD workflow events, ensuring seamless integration between spec-driven development and Linear project management, while remaining optional and lightweight.
|
|
41
|
+
|
|
42
|
+
## Detection Logic
|
|
43
|
+
|
|
44
|
+
**Before using Linear MCP, always check:**
|
|
45
|
+
|
|
46
|
+
1. **Check if Linear mode is enabled:**
|
|
47
|
+
- Check if `work/linear/sync-config.md` exists
|
|
48
|
+
- Verify `MODE=linear` in sync-config
|
|
49
|
+
- If not found or not set to linear → use local mode only
|
|
50
|
+
|
|
51
|
+
2. **Determine which MCP connection to use:**
|
|
52
|
+
- Read `MCP_CONNECTION_NAME` from sync-config.md
|
|
53
|
+
- If specified → use that specific MCP connection (e.g., "linear", "linear-huddle")
|
|
54
|
+
- If not specified → use default Linear MCP connection
|
|
55
|
+
- **Note:** Each workspace can have its own Linear workspace, so the connection name should match this project's Linear workspace
|
|
56
|
+
|
|
57
|
+
3. **Verify Linear MCP availability:**
|
|
58
|
+
- Test Linear MCP connection using the specified connection name (try a simple operation like `list_teams`)
|
|
59
|
+
- If MCP is unavailable → fallback to local mode automatically
|
|
60
|
+
- Report fallback to user but continue workflow normally
|
|
61
|
+
|
|
62
|
+
4. **Check configuration completeness:**
|
|
63
|
+
- If Linear mode is enabled but status mapping is missing → guide user to setup
|
|
64
|
+
- Reference `work/linear/SETUP.md` for setup instructions
|
|
65
|
+
|
|
66
|
+
## Linear MCP Functions and Automation Rules
|
|
67
|
+
|
|
68
|
+
### 1. Documents (`create_document`, `update_document`, `get_document`, `list_documents`)
|
|
69
|
+
|
|
70
|
+
**When to create/update Linear Documents:**
|
|
71
|
+
|
|
72
|
+
**A) During `/spec/init`:**
|
|
73
|
+
- **Create document:** If PRD is created (`spec/01-prd.md`) → create Linear document with PRD content
|
|
74
|
+
- **Document title:** `[Project Name] - PRD`
|
|
75
|
+
- **Document content:** Full PRD content from `spec/01-prd.md`
|
|
76
|
+
- **Link:** Add document link to Linear project (if project exists)
|
|
77
|
+
- **Only if:** `AUTO_CREATE_DOCUMENTS=true` in sync-config
|
|
78
|
+
|
|
79
|
+
**B) During `/spec/refine`:**
|
|
80
|
+
- **Update document:** If PRD document exists → update with refined PRD content
|
|
81
|
+
- **Create document:** If architecture is documented (`spec/02-architecture.md`) → create Linear document
|
|
82
|
+
- **Document title:** `[Project Name] - Architecture`
|
|
83
|
+
- **Document content:** Full architecture content from `spec/02-architecture.md`
|
|
84
|
+
|
|
85
|
+
**C) During `/spec/plan`:**
|
|
86
|
+
- **Create document:** If acceptance criteria are created (`spec/06-acceptance.md`) → create Linear document
|
|
87
|
+
- **Document title:** `[Project Name] - Acceptance Criteria`
|
|
88
|
+
- **Document content:** Full acceptance criteria from `spec/06-acceptance.md`
|
|
89
|
+
|
|
90
|
+
**D) During `/task/start` (complex tasks):**
|
|
91
|
+
- **Create document:** If task-level spec is created (`spec/tasks/[task-id]/spec.md`) → create Linear document
|
|
92
|
+
- **Document title:** `[Task ID] - [Task Name] - Specification`
|
|
93
|
+
- **Document content:** Task-level spec content
|
|
94
|
+
- **Link:** Link document to Linear issue (if issue exists)
|
|
95
|
+
|
|
96
|
+
**E) During `/task/validate`:**
|
|
97
|
+
- **Update document:** If task-level spec was updated during implementation → update Linear document
|
|
98
|
+
|
|
99
|
+
**Automation Logic:**
|
|
100
|
+
```markdown
|
|
101
|
+
IF Linear mode enabled AND AUTO_CREATE_DOCUMENTS=true AND spec file created/updated:
|
|
102
|
+
- Check if Linear document exists (search by title using list_documents)
|
|
103
|
+
- IF exists → update_document
|
|
104
|
+
- IF not exists → create_document
|
|
105
|
+
- Link document to Linear project/issue if applicable
|
|
106
|
+
- IF operation fails → log error, continue with local mode
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 2. Issues (`create_issue`, `update_issue`, `get_issue`, `list_issues`)
|
|
110
|
+
|
|
111
|
+
**When to create/update Linear Issues:**
|
|
112
|
+
|
|
113
|
+
**A) During `/spec/plan`:**
|
|
114
|
+
- **Create issues:** For each task in `work/backlog/tasks.local.md` → create Linear issue
|
|
115
|
+
- **Issue title:** Task description (first line)
|
|
116
|
+
- **Issue description:** Full task details (description, acceptance, dependencies, estimate)
|
|
117
|
+
- **Issue status:** Map to "Backlog" (or custom status from config)
|
|
118
|
+
- **Issue priority:** Map from task estimate (S=Low, M=Medium, L=High)
|
|
119
|
+
- **Issue labels:** Auto-assign labels based on task type (see Labels section)
|
|
120
|
+
- **Issue project:** Link to Linear project (if milestone project exists)
|
|
121
|
+
- **Issue team:** Assign to default team (if configured)
|
|
122
|
+
- **Ask before creating:** Always ask user: "Skal jeg oprette Linear issues for tasks?"
|
|
123
|
+
|
|
124
|
+
**B) During `/task/start`:**
|
|
125
|
+
- **Get issue:** Fetch Linear issue details (if Linear task ID provided)
|
|
126
|
+
- **Update issue:** Set status to "In Progress" (or custom status from config)
|
|
127
|
+
- **Update issue:** Add comment: "Task started via SDD workflow at [timestamp]"
|
|
128
|
+
- **If issue not found:** Error: "Linear issue [ID] ikke fundet"
|
|
129
|
+
|
|
130
|
+
**C) During `/task/validate`:**
|
|
131
|
+
- **Update issue:** Set status based on validation result:
|
|
132
|
+
- **Approved:** "Done" (or custom status from config)
|
|
133
|
+
- **Requires fixes:** "In Progress" (or custom status from config)
|
|
134
|
+
- **Requires spec refinement:** "Blocked" (or custom status from config)
|
|
135
|
+
- **Update issue:** Add comment with validation summary
|
|
136
|
+
|
|
137
|
+
**D) During `/spec/refine` or `/spec/evolve`:**
|
|
138
|
+
- **Update issues:** If spec changes affect tasks → update related Linear issues
|
|
139
|
+
- Add comment: "Spec updated: [summary of changes]"
|
|
140
|
+
- Update issue description if task scope changed
|
|
141
|
+
|
|
142
|
+
**Automation Logic:**
|
|
143
|
+
```markdown
|
|
144
|
+
IF Linear mode enabled AND task created/updated:
|
|
145
|
+
- Check if Linear issue exists (search by title or task ID in issue description)
|
|
146
|
+
- IF exists → update_issue
|
|
147
|
+
- IF not exists → create_issue (after user confirmation)
|
|
148
|
+
- Auto-assign status, labels, project, team based on rules
|
|
149
|
+
- IF operation fails → log error, continue with local mode
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### 3. Projects (`create_project`, `update_project`, `get_project`, `list_projects`)
|
|
153
|
+
|
|
154
|
+
**When to create/update Linear Projects:**
|
|
155
|
+
|
|
156
|
+
**A) During `/spec/plan`:**
|
|
157
|
+
- **Create projects:** For each milestone in `work/backlog/milestones.md` → create Linear project
|
|
158
|
+
- **Project name:** Milestone objective (first line)
|
|
159
|
+
- **Project description:** Full milestone details (objective, scope, exit criteria)
|
|
160
|
+
- **Project status:** Set to "Active" (or default status)
|
|
161
|
+
- **Project team:** Assign to default team (if configured)
|
|
162
|
+
- **Link issues:** Link all milestone tasks (issues) to project
|
|
163
|
+
- **Only if:** `AUTO_CREATE_PROJECTS=true` in sync-config
|
|
164
|
+
- **Ask before creating:** Always ask user: "Skal jeg oprette Linear projects for milestones?"
|
|
165
|
+
|
|
166
|
+
**B) During `/spec/evolve`:**
|
|
167
|
+
- **Update projects:** If milestone changes → update Linear project
|
|
168
|
+
- Update project description
|
|
169
|
+
- Update linked issues if task scope changed
|
|
170
|
+
|
|
171
|
+
**C) During `/task/start` or `/task/validate`:**
|
|
172
|
+
- **Get project:** Fetch Linear project for context (if issue is linked to project)
|
|
173
|
+
|
|
174
|
+
**Automation Logic:**
|
|
175
|
+
```markdown
|
|
176
|
+
IF Linear mode enabled AND AUTO_CREATE_PROJECTS=true AND milestone created/updated:
|
|
177
|
+
- Check if Linear project exists (search by name)
|
|
178
|
+
- IF exists → update_project
|
|
179
|
+
- IF not exists → create_project (after user confirmation)
|
|
180
|
+
- Link all milestone tasks (issues) to project
|
|
181
|
+
- IF operation fails → log error, continue with local mode
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 4. Teams (`get_team`, `list_teams`)
|
|
185
|
+
|
|
186
|
+
**When to use Teams:**
|
|
187
|
+
|
|
188
|
+
**A) During `/spec/plan`:**
|
|
189
|
+
- **Get team:** Fetch default team (if configured in sync-config)
|
|
190
|
+
- **Assign team:** Auto-assign Linear projects and issues to default team
|
|
191
|
+
|
|
192
|
+
**B) During `/task/start`:**
|
|
193
|
+
- **Get team:** Fetch team for context (if issue is assigned to team)
|
|
194
|
+
|
|
195
|
+
**Configuration:**
|
|
196
|
+
- Store default team ID in `work/linear/sync-config.md`:
|
|
197
|
+
```markdown
|
|
198
|
+
DEFAULT_TEAM_ID=[team-id]
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Automation Logic:**
|
|
202
|
+
```markdown
|
|
203
|
+
IF Linear mode enabled AND project/issue created:
|
|
204
|
+
- IF DEFAULT_TEAM_ID configured → assign to team
|
|
205
|
+
- IF not configured → skip team assignment (no error)
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### 5. Labels (`create_issue_label`, `list_issue_labels`)
|
|
209
|
+
|
|
210
|
+
**When to create/assign Labels:**
|
|
211
|
+
|
|
212
|
+
**A) During `/spec/plan`:**
|
|
213
|
+
- **Auto-assign labels:** For each task → assign labels based on task type:
|
|
214
|
+
- **Design tasks:** `design`, `ui`, `frontend`
|
|
215
|
+
- **Engineering tasks:** `engineering`, `backend`, `frontend`, `infrastructure`
|
|
216
|
+
- **Business tasks:** `business`, `requirements`
|
|
217
|
+
- **Infrastructure tasks:** `infrastructure`, `devops`, `deployment`
|
|
218
|
+
- **External service tasks:** `external-service`, `integration`
|
|
219
|
+
- **Risk mitigation tasks:** `risk`, `mitigation`
|
|
220
|
+
|
|
221
|
+
**B) During `/task/start`:**
|
|
222
|
+
- **Get labels:** Fetch issue labels for context
|
|
223
|
+
- **Auto-assign labels:** If task type detected → ensure labels are assigned
|
|
224
|
+
|
|
225
|
+
**C) During `/spec/refine`:**
|
|
226
|
+
- **Create labels:** If new task types emerge → create new labels (if they don't exist)
|
|
227
|
+
|
|
228
|
+
**Label Naming Convention:**
|
|
229
|
+
- Use lowercase, hyphenated names: `design`, `ui`, `frontend`, `backend`, `infrastructure`
|
|
230
|
+
- Use consistent prefixes: `type-*` for task types, `priority-*` for priorities
|
|
231
|
+
|
|
232
|
+
**Automation Logic:**
|
|
233
|
+
```markdown
|
|
234
|
+
IF Linear mode enabled AND AUTO_ASSIGN_LABELS=true AND issue created/updated:
|
|
235
|
+
- Detect task type from description/title
|
|
236
|
+
- Map task type to label names
|
|
237
|
+
- Check if labels exist (list_issue_labels)
|
|
238
|
+
- IF label doesn't exist → create_issue_label (try to create, if fails guide user)
|
|
239
|
+
- Assign labels to issue
|
|
240
|
+
- IF operation fails → log error, continue without labels
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### 6. Statuses (`get_issue_status`, `list_issue_statuses`)
|
|
244
|
+
|
|
245
|
+
**When to update Status:**
|
|
246
|
+
|
|
247
|
+
**A) During `/spec/plan`:**
|
|
248
|
+
- **Set status:** New issues → "Backlog" (or custom status from config)
|
|
249
|
+
|
|
250
|
+
**B) During `/task/start`:**
|
|
251
|
+
- **Set status:** Issue → "In Progress" (or custom status from config)
|
|
252
|
+
- **Get status:** Fetch current status for context
|
|
253
|
+
|
|
254
|
+
**C) During `/task/validate`:**
|
|
255
|
+
- **Set status:** Based on validation result:
|
|
256
|
+
- **Approved:** "Done" (or custom status from config)
|
|
257
|
+
- **Requires fixes:** "In Progress" (or custom status from config)
|
|
258
|
+
- **Requires spec refinement:** "Blocked" (or custom status from config)
|
|
259
|
+
|
|
260
|
+
**D) During `/spec/refine` or `/spec/evolve`:**
|
|
261
|
+
- **Set status:** If spec changes block tasks → set related issues to "Blocked"
|
|
262
|
+
|
|
263
|
+
**Status Mapping:**
|
|
264
|
+
- Map SDD workflow states to Linear statuses:
|
|
265
|
+
- **Planned:** "Backlog" (or `STATUS_BACKLOG` from config)
|
|
266
|
+
- **In Progress:** "In Progress" (or `STATUS_IN_PROGRESS` from config)
|
|
267
|
+
- **Validated/Approved:** "Done" (or `STATUS_DONE` from config)
|
|
268
|
+
- **Blocked:** "Blocked" (or `STATUS_BLOCKED` from config)
|
|
269
|
+
|
|
270
|
+
**Custom Status Support:**
|
|
271
|
+
- Status mapping supports both status IDs and status names
|
|
272
|
+
- If status name is provided in config → try to find by name
|
|
273
|
+
- If status ID is provided in config → use directly
|
|
274
|
+
- If status not found → guide user: "Status '[name]' ikke fundet i Linear. Opret den i Linear Settings → Statuses, eller opdater sync-config.md med status ID"
|
|
275
|
+
|
|
276
|
+
**Automation Logic:**
|
|
277
|
+
```markdown
|
|
278
|
+
IF Linear mode enabled AND task state changes:
|
|
279
|
+
- Map SDD state to Linear status (from config or default)
|
|
280
|
+
- Get available statuses (list_issue_statuses)
|
|
281
|
+
- Find matching status (by name or ID)
|
|
282
|
+
- Update issue status
|
|
283
|
+
- IF status not found → guide user to create custom status
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### 7. Comments (`create_comment`, `list_comments`)
|
|
287
|
+
|
|
288
|
+
**When to create Comments:**
|
|
289
|
+
|
|
290
|
+
**A) During `/task/start`:**
|
|
291
|
+
- **Create comment:** "Task started via SDD workflow at [timestamp]"
|
|
292
|
+
- **Create comment:** If task-level spec exists → add comment with spec summary
|
|
293
|
+
|
|
294
|
+
**B) During `/task/validate`:**
|
|
295
|
+
- **Create comment:** Validation summary:
|
|
296
|
+
- "Task validated: [result]"
|
|
297
|
+
- "Acceptance criteria: [summary]"
|
|
298
|
+
- "Issues found: [list]" (if any)
|
|
299
|
+
- "Next steps: [list]" (if any)
|
|
300
|
+
|
|
301
|
+
**C) During `/spec/refine` or `/spec/evolve`:**
|
|
302
|
+
- **Create comment:** On affected issues: "Spec updated: [summary of changes]"
|
|
303
|
+
|
|
304
|
+
**D) During implementation (if errors occur):**
|
|
305
|
+
- **Create comment:** "Error encountered: [error description]"
|
|
306
|
+
- **Create comment:** "Fix applied: [fix description]"
|
|
307
|
+
|
|
308
|
+
**Automation Logic:**
|
|
309
|
+
```markdown
|
|
310
|
+
IF Linear mode enabled AND workflow event occurs:
|
|
311
|
+
- Create comment on related Linear issue
|
|
312
|
+
- Include relevant context (spec changes, validation results, etc.)
|
|
313
|
+
- IF operation fails → log error, continue without comment
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### 8. Cycles (`list_cycles`, `get_cycle`)
|
|
317
|
+
|
|
318
|
+
**When to use Cycles:**
|
|
319
|
+
|
|
320
|
+
**A) During `/spec/plan`:**
|
|
321
|
+
- **Get active cycle:** Fetch current active cycle (if cycles are used)
|
|
322
|
+
- **Assign to cycle:** Link milestone projects to active cycle (if applicable)
|
|
323
|
+
|
|
324
|
+
**B) During `/task/start`:**
|
|
325
|
+
- **Get cycle:** Fetch cycle for context (if issue is in cycle)
|
|
326
|
+
|
|
327
|
+
**Configuration:**
|
|
328
|
+
- Store cycle preference in `work/linear/sync-config.md`:
|
|
329
|
+
```markdown
|
|
330
|
+
USE_CYCLES=true
|
|
331
|
+
ACTIVE_CYCLE_ID=[cycle-id] (optional, auto-detect if not set)
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
**Automation Logic:**
|
|
335
|
+
```markdown
|
|
336
|
+
IF Linear mode enabled AND USE_CYCLES=true:
|
|
337
|
+
- Get active cycle (list_cycles, filter by active)
|
|
338
|
+
- IF cycle exists → link projects/issues to cycle
|
|
339
|
+
- IF ACTIVE_CYCLE_ID set → use that cycle
|
|
340
|
+
- IF not set → auto-detect active cycle
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## Custom Setup Guidance
|
|
344
|
+
|
|
345
|
+
**Når systemet skal guide brugeren til custom setup:**
|
|
346
|
+
|
|
347
|
+
1. **Første gang Linear mode aktiveres:**
|
|
348
|
+
- Guide til at oprette `work/linear/sync-config.md`
|
|
349
|
+
- Guide til at oprette custom status/labels i Linear (hvis nødvendigt)
|
|
350
|
+
- Reference til `work/linear/SETUP.md`
|
|
351
|
+
|
|
352
|
+
2. **Hvis custom status mangler:**
|
|
353
|
+
- Systemet prøver at finde status ved name (hvis status name er i config)
|
|
354
|
+
- Hvis ikke fundet → guide: "Status '[name]' ikke fundet i Linear. Opret den i Linear Settings → Statuses, eller opdater sync-config.md med status ID"
|
|
355
|
+
|
|
356
|
+
3. **Hvis custom labels mangler:**
|
|
357
|
+
- Systemet prøver at oprette label automatisk
|
|
358
|
+
- Hvis fejler → guide: "Label '[name]' kunne ikke oprettes. Opret den manuelt i Linear Settings → Labels"
|
|
359
|
+
|
|
360
|
+
## Error Handling
|
|
361
|
+
|
|
362
|
+
**Hvis Linear MCP operation fejler:**
|
|
363
|
+
1. Log error tydeligt (inkluder operation type og error message)
|
|
364
|
+
2. Fortsæt med local mode (blokér ikke workflow)
|
|
365
|
+
3. Rapporter error til bruger
|
|
366
|
+
4. Tillad manuel retry eller skip Linear operation
|
|
367
|
+
|
|
368
|
+
**Hvis Linear MCP er utilgængelig:**
|
|
369
|
+
1. Detekter unavailability (connection test fejler)
|
|
370
|
+
2. Fallback til local mode automatisk
|
|
371
|
+
3. Rapporter fallback til bruger: "Linear MCP er utilgængelig. Fortsætter med local mode."
|
|
372
|
+
4. Fortsæt workflow normalt
|
|
373
|
+
|
|
374
|
+
**Idempotency:**
|
|
375
|
+
- Always check if Linear resource exists before creating
|
|
376
|
+
- Use `list_*` functions to check for existing resources
|
|
377
|
+
- If resource exists → update instead of create
|
|
378
|
+
- Prevent duplicate resources
|
|
379
|
+
|
|
380
|
+
## Best Practices
|
|
381
|
+
|
|
382
|
+
1. **Always ask before creating:** Ask user before creating Linear projects/issues/documents (except for status updates and comments)
|
|
383
|
+
2. **Batch operations:** Group related Linear operations when possible
|
|
384
|
+
3. **Idempotency:** Check if Linear resource exists before creating (prevent duplicates)
|
|
385
|
+
4. **Error recovery:** Always fall back to local mode if Linear fails
|
|
386
|
+
5. **Respect Linear workflow:** Don't override Linear-specific workflows (status transitions, etc.)
|
|
387
|
+
6. **Custom status support:** Support both status IDs and status names for flexibility
|
|
388
|
+
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
---
|
|
2
|
+
helper_id: linear-helpers
|
|
3
|
+
load_when:
|
|
4
|
+
- linear_mode_enabled
|
|
5
|
+
- linear_operation_needed
|
|
6
|
+
sections:
|
|
7
|
+
status_mapping:
|
|
8
|
+
title: "Status Mapping"
|
|
9
|
+
lines: [1, 50]
|
|
10
|
+
label_detection:
|
|
11
|
+
title: "Label Detection"
|
|
12
|
+
lines: [51, 100]
|
|
13
|
+
idempotency:
|
|
14
|
+
title: "Idempotency Checks"
|
|
15
|
+
lines: [101, 150]
|
|
16
|
+
always_load: false
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Linear Helper Functions
|
|
20
|
+
|
|
21
|
+
This document contains helper logic for Linear operations, including status mapping, label detection, idempotency checks, and error handling.
|
|
22
|
+
|
|
23
|
+
## Status Mapping
|
|
24
|
+
|
|
25
|
+
**Purpose:** Map SDD workflow states to Linear statuses with support for custom statuser.
|
|
26
|
+
|
|
27
|
+
**Logic:**
|
|
28
|
+
1. Read status mapping from `work/linear/sync-config.md`
|
|
29
|
+
2. If status name provided → try to find by name using `list_issue_statuses`
|
|
30
|
+
3. If status ID provided → use directly
|
|
31
|
+
4. If status not found → guide user to create custom status
|
|
32
|
+
|
|
33
|
+
**Function:**
|
|
34
|
+
```markdown
|
|
35
|
+
**Map SDD State to Linear Status:**
|
|
36
|
+
|
|
37
|
+
1. Read sync-config.md
|
|
38
|
+
2. Get status mapping for SDD state:
|
|
39
|
+
- Planned → STATUS_BACKLOG
|
|
40
|
+
- In Progress → STATUS_IN_PROGRESS
|
|
41
|
+
- Validated/Approved → STATUS_DONE
|
|
42
|
+
- Blocked → STATUS_BLOCKED
|
|
43
|
+
|
|
44
|
+
3. If status mapping is name (not UUID):
|
|
45
|
+
- Call list_issue_statuses to get all statuses
|
|
46
|
+
- Find status by name (case-insensitive)
|
|
47
|
+
- If found → use status ID
|
|
48
|
+
- If not found → guide user: "Status '[name]' ikke fundet i Linear. Opret den i Linear Settings → Statuses, eller opdater sync-config.md med status ID"
|
|
49
|
+
|
|
50
|
+
4. If status mapping is UUID:
|
|
51
|
+
- Use directly
|
|
52
|
+
|
|
53
|
+
5. Return status ID for Linear operations
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Usage in commands:**
|
|
57
|
+
- `/spec/plan`: Map "Planned" → STATUS_BACKLOG
|
|
58
|
+
- `/task/start`: Map "In Progress" → STATUS_IN_PROGRESS
|
|
59
|
+
- `/task/validate`: Map validation result → STATUS_DONE/STATUS_IN_PROGRESS/STATUS_BLOCKED
|
|
60
|
+
|
|
61
|
+
## Label Detection
|
|
62
|
+
|
|
63
|
+
**Purpose:** Auto-detect task type and map to Linear labels.
|
|
64
|
+
|
|
65
|
+
**Logic:**
|
|
66
|
+
1. Analyze task description and title
|
|
67
|
+
2. Detect task type based on keywords
|
|
68
|
+
3. Map task type to label names
|
|
69
|
+
4. Check if labels exist, create if missing
|
|
70
|
+
|
|
71
|
+
**Task Type Detection:**
|
|
72
|
+
```markdown
|
|
73
|
+
**Detect Task Type:**
|
|
74
|
+
|
|
75
|
+
Keywords for task type detection:
|
|
76
|
+
- Design: "design", "ui", "ux", "visual", "styling", "component", "layout"
|
|
77
|
+
- Engineering: "implement", "code", "api", "endpoint", "function", "service", "module"
|
|
78
|
+
- Business: "requirement", "business", "user story", "feature", "product"
|
|
79
|
+
- Infrastructure: "infrastructure", "deployment", "devops", "ci/cd", "hosting", "database", "server"
|
|
80
|
+
- External Service: "integration", "api", "service", "third-party", "external"
|
|
81
|
+
- Risk Mitigation: "risk", "mitigation", "security", "backup", "recovery"
|
|
82
|
+
|
|
83
|
+
Task type priority (if multiple matches):
|
|
84
|
+
1. Infrastructure
|
|
85
|
+
2. External Service
|
|
86
|
+
3. Risk Mitigation
|
|
87
|
+
4. Design
|
|
88
|
+
5. Engineering
|
|
89
|
+
6. Business
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Label Mapping:**
|
|
93
|
+
```markdown
|
|
94
|
+
**Map Task Type to Labels:**
|
|
95
|
+
|
|
96
|
+
- Design tasks → ["design", "ui", "frontend"]
|
|
97
|
+
- Engineering tasks → ["engineering", "backend" or "frontend", "infrastructure" (if applicable)]
|
|
98
|
+
- Business tasks → ["business", "requirements"]
|
|
99
|
+
- Infrastructure tasks → ["infrastructure", "devops", "deployment"]
|
|
100
|
+
- External service tasks → ["external-service", "integration"]
|
|
101
|
+
- Risk mitigation tasks → ["risk", "mitigation"]
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Function:**
|
|
105
|
+
```markdown
|
|
106
|
+
**Auto-Assign Labels:**
|
|
107
|
+
|
|
108
|
+
1. Detect task type from description/title
|
|
109
|
+
2. Map task type to label names
|
|
110
|
+
3. For each label name:
|
|
111
|
+
- Call list_issue_labels to check if label exists
|
|
112
|
+
- IF exists → use label ID
|
|
113
|
+
- IF not exists → try create_issue_label
|
|
114
|
+
- IF succeeds → use new label ID
|
|
115
|
+
- IF fails → guide user: "Label '[name]' kunne ikke oprettes. Opret den manuelt i Linear Settings → Labels"
|
|
116
|
+
4. Assign labels to issue
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Idempotency Check
|
|
120
|
+
|
|
121
|
+
**Purpose:** Check if Linear resource exists before creating to prevent duplicates.
|
|
122
|
+
|
|
123
|
+
**Logic:**
|
|
124
|
+
1. Search for existing resource by name/title
|
|
125
|
+
2. If found → update instead of create
|
|
126
|
+
3. If not found → create new
|
|
127
|
+
|
|
128
|
+
**Functions:**
|
|
129
|
+
|
|
130
|
+
**Check if Project Exists:**
|
|
131
|
+
```markdown
|
|
132
|
+
**Check Project Exists:**
|
|
133
|
+
|
|
134
|
+
1. Call list_projects
|
|
135
|
+
2. Search for project by name (exact match or case-insensitive)
|
|
136
|
+
3. IF found → return project ID
|
|
137
|
+
4. IF not found → return null
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Check if Issue Exists:**
|
|
141
|
+
```markdown
|
|
142
|
+
**Check Issue Exists:**
|
|
143
|
+
|
|
144
|
+
1. Call list_issues with query for title or description
|
|
145
|
+
2. Search for issue by title (exact match or case-insensitive)
|
|
146
|
+
3. IF found → return issue ID
|
|
147
|
+
4. IF not found → return null
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Check if Document Exists:**
|
|
151
|
+
```markdown
|
|
152
|
+
**Check Document Exists:**
|
|
153
|
+
|
|
154
|
+
1. Call list_documents
|
|
155
|
+
2. Search for document by title (exact match or case-insensitive)
|
|
156
|
+
3. IF found → return document ID
|
|
157
|
+
4. IF not found → return null
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Usage:**
|
|
161
|
+
- Before creating Linear project → check if exists, update if found
|
|
162
|
+
- Before creating Linear issue → check if exists, update if found
|
|
163
|
+
- Before creating Linear document → check if exists, update if found
|
|
164
|
+
|
|
165
|
+
## Error Handling
|
|
166
|
+
|
|
167
|
+
**Purpose:** Handle Linear MCP errors gracefully with fallback to local mode.
|
|
168
|
+
|
|
169
|
+
**Error Types:**
|
|
170
|
+
|
|
171
|
+
**1. Linear MCP Unavailable:**
|
|
172
|
+
```markdown
|
|
173
|
+
**Handle MCP Unavailability:**
|
|
174
|
+
|
|
175
|
+
1. Read MCP_CONNECTION_NAME from sync-config.md (if specified)
|
|
176
|
+
2. Test connection using specified connection name (try list_teams)
|
|
177
|
+
3. IF fails → detect unavailability
|
|
178
|
+
4. Report to user: "Linear MCP connection '[connection-name]' er utilgængelig. Fortsætter med local mode."
|
|
179
|
+
5. Continue workflow with local mode only
|
|
180
|
+
6. Do not block workflow
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**2. Linear Operation Failed:**
|
|
184
|
+
```markdown
|
|
185
|
+
**Handle Operation Failure:**
|
|
186
|
+
|
|
187
|
+
1. Catch error from Linear MCP operation
|
|
188
|
+
2. Log error clearly (include operation type and error message)
|
|
189
|
+
3. Report to user: "Linear operation '[operation]' fejlede: [error]. Fortsætter med local mode."
|
|
190
|
+
4. Continue workflow with local mode
|
|
191
|
+
5. Allow user to retry or skip Linear operation
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**3. Resource Not Found:**
|
|
195
|
+
```markdown
|
|
196
|
+
**Handle Resource Not Found:**
|
|
197
|
+
|
|
198
|
+
1. IF status not found → guide user to create custom status
|
|
199
|
+
2. IF label not found → try to create, if fails guide user
|
|
200
|
+
3. IF issue not found → error: "Linear issue [ID] ikke fundet"
|
|
201
|
+
4. IF project not found → error: "Linear project [name] ikke fundet"
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**4. Configuration Error:**
|
|
205
|
+
```markdown
|
|
206
|
+
**Handle Configuration Error:**
|
|
207
|
+
|
|
208
|
+
1. IF sync-config.md missing → guide user to create it
|
|
209
|
+
2. IF MODE=linear but status mapping missing → guide user to setup
|
|
210
|
+
3. IF team ID invalid → guide user to update sync-config.md
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Error Recovery:**
|
|
214
|
+
- Always fallback to local mode
|
|
215
|
+
- Never block workflow
|
|
216
|
+
- Always report errors to user
|
|
217
|
+
- Allow manual retry or skip
|
|
218
|
+
|
|
219
|
+
## Helper Function Usage
|
|
220
|
+
|
|
221
|
+
**In Commands:**
|
|
222
|
+
|
|
223
|
+
Commands should use these helpers via reference to this document:
|
|
224
|
+
|
|
225
|
+
```markdown
|
|
226
|
+
**Linear Operations:**
|
|
227
|
+
|
|
228
|
+
1. Check Linear mode (see linear-automation.md Detection Logic)
|
|
229
|
+
2. Use status mapping (see Status Mapping above)
|
|
230
|
+
3. Use label detection (see Label Detection above)
|
|
231
|
+
4. Use idempotency check (see Idempotency Check above)
|
|
232
|
+
5. Handle errors (see Error Handling above)
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**Example Integration:**
|
|
236
|
+
|
|
237
|
+
```markdown
|
|
238
|
+
**During /spec/plan:**
|
|
239
|
+
|
|
240
|
+
1. Check if Linear mode enabled
|
|
241
|
+
2. For each milestone:
|
|
242
|
+
- Check if project exists (idempotency check)
|
|
243
|
+
- IF exists → update_project
|
|
244
|
+
- IF not exists → create_project (after user confirmation)
|
|
245
|
+
3. For each task:
|
|
246
|
+
- Detect task type (label detection)
|
|
247
|
+
- Map to labels
|
|
248
|
+
- Check if issue exists (idempotency check)
|
|
249
|
+
- Map status (status mapping)
|
|
250
|
+
- IF exists → update_issue
|
|
251
|
+
- IF not exists → create_issue (after user confirmation)
|
|
252
|
+
4. Handle any errors (error handling)
|
|
253
|
+
```
|
|
254
|
+
|