@dabble/linear-cli 1.0.0
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 +169 -0
- package/bin/linear.mjs +2068 -0
- package/claude/commands/done.md +65 -0
- package/claude/commands/next.md +94 -0
- package/claude/commands/standup.md +63 -0
- package/claude/skills/linear-cli.md +193 -0
- package/claude/skills/product-planning.md +136 -0
- package/package.json +35 -0
- package/postinstall.mjs +54 -0
- package/preuninstall.mjs +52 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# /done - Complete work on an issue
|
|
2
|
+
|
|
3
|
+
Help the developer wrap up their work on the current Linear issue.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
/done # Complete the issue detected from branch name
|
|
9
|
+
/done ISSUE-12 # Complete a specific issue
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Steps
|
|
13
|
+
|
|
14
|
+
1. **Detect the issue** from the branch name or use the provided ID
|
|
15
|
+
2. **Summarize the work** by checking:
|
|
16
|
+
- `git log --oneline <base>..HEAD` to see commits
|
|
17
|
+
- `git diff --stat <base>..HEAD` to see files changed
|
|
18
|
+
3. **Ask what they want to do** using AskUserQuestion:
|
|
19
|
+
- Close the issue in Linear
|
|
20
|
+
- Create a PR first
|
|
21
|
+
- Add final notes to the issue
|
|
22
|
+
- Just clean up (worktree only)
|
|
23
|
+
|
|
24
|
+
## After Selection
|
|
25
|
+
|
|
26
|
+
### If they want to create a PR:
|
|
27
|
+
1. Run `gh pr create --title "ISSUE-12: Issue title" --body "..."` with a summary
|
|
28
|
+
2. Then proceed to closing if requested
|
|
29
|
+
|
|
30
|
+
### If they want to add notes:
|
|
31
|
+
1. Ask what notes to add
|
|
32
|
+
2. Run `linear issue update ISSUE-12 --append "..."` with the notes
|
|
33
|
+
|
|
34
|
+
### If they want to close:
|
|
35
|
+
1. Run `linear done ISSUE-12` to close the issue
|
|
36
|
+
|
|
37
|
+
### Worktree cleanup:
|
|
38
|
+
If in a worktree, `linear done` will output commands to clean up. Let the user know they can copy those commands or run them manually.
|
|
39
|
+
|
|
40
|
+
## Example Flow
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
User: /done
|
|
44
|
+
|
|
45
|
+
Claude: Let me check what you've been working on...
|
|
46
|
+
|
|
47
|
+
[Runs git log and git diff]
|
|
48
|
+
|
|
49
|
+
You've made 3 commits on ISSUE-12: Add caching layer
|
|
50
|
+
- src/cache.ts (new file, 45 lines)
|
|
51
|
+
- src/api.ts (modified, +12 -3)
|
|
52
|
+
|
|
53
|
+
What would you like to do?
|
|
54
|
+
1. Create PR and close issue
|
|
55
|
+
2. Close issue (no PR)
|
|
56
|
+
3. Add notes and close
|
|
57
|
+
4. Just clean up worktree (don't close)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Notes
|
|
61
|
+
|
|
62
|
+
- Always show a summary of the work done before asking
|
|
63
|
+
- If there are no commits, skip the PR option
|
|
64
|
+
- The `linear done` command handles the mechanical parts (closing, worktree detection)
|
|
65
|
+
- Don't auto-close - always confirm with the user first
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# /next - Find the next issue to work on
|
|
2
|
+
|
|
3
|
+
Help the developer find and start working on their next Linear issue, or do product planning.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
/next # Show unblocked issues to choose from
|
|
9
|
+
/next ISSUE-12 # Skip selection, start working on ISSUE-12 directly
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## If an issue ID is provided
|
|
13
|
+
|
|
14
|
+
Skip straight to starting work on that issue (see "Starting Work on an Issue" below).
|
|
15
|
+
|
|
16
|
+
## If no issue ID is provided
|
|
17
|
+
|
|
18
|
+
1. Run `linear issues --unblocked` to get issues ready to work on
|
|
19
|
+
2. Parse the output and count the issues
|
|
20
|
+
3. Present options using the format below
|
|
21
|
+
|
|
22
|
+
### Presenting Options
|
|
23
|
+
|
|
24
|
+
Always present a numbered list with these rules:
|
|
25
|
+
- Show up to **5 issues maximum** (yours are already sorted first by the CLI)
|
|
26
|
+
- If more than 5 issues exist, note how many more after the list
|
|
27
|
+
- **Always** include "Product planning" as the final option
|
|
28
|
+
|
|
29
|
+
### Format
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
Here's what's ready to work on:
|
|
33
|
+
|
|
34
|
+
1. ISSUE-5: Add caching layer [Backlog] (assigned to you)
|
|
35
|
+
2. ISSUE-8: Fix login timeout [Backlog]
|
|
36
|
+
3. ISSUE-12: Update API docs [Backlog]
|
|
37
|
+
4. ISSUE-18: Do Something Else [Backlog]
|
|
38
|
+
5. ISSUE-29: Another thing [Backlog]
|
|
39
|
+
... and 7 more unblocked issues
|
|
40
|
+
6. Product planning - brainstorm features, review backlog, plan next phase
|
|
41
|
+
|
|
42
|
+
Which would you like to work on?
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### If NO unblocked issues:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
No unblocked issues at the moment.
|
|
49
|
+
|
|
50
|
+
1. Product planning - brainstorm features, review backlog, plan next phase
|
|
51
|
+
|
|
52
|
+
Would you like to work on product planning?
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### If exactly ONE issue:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
There's one issue ready to work on:
|
|
59
|
+
|
|
60
|
+
1. ISSUE-5: Add caching layer [Backlog] (assigned to you)
|
|
61
|
+
2. Product planning - brainstorm features, review backlog, plan next phase
|
|
62
|
+
|
|
63
|
+
Which would you like?
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Starting Work on an Issue
|
|
67
|
+
|
|
68
|
+
When the user selects an issue (or provides one directly via `/next ISSUE-12`):
|
|
69
|
+
|
|
70
|
+
1. Run `linear issue start <id>` to assign and set In Progress
|
|
71
|
+
2. Run `linear branch <id>` to create a git branch
|
|
72
|
+
3. Run `linear issue show <id>` to display full context
|
|
73
|
+
4. **Enter plan mode** using the EnterPlanMode tool
|
|
74
|
+
|
|
75
|
+
This ensures every issue starts with a proper implementation plan before writing code.
|
|
76
|
+
|
|
77
|
+
## If they choose "Product planning"
|
|
78
|
+
|
|
79
|
+
Start a planning session by asking:
|
|
80
|
+
|
|
81
|
+
"What would you like to focus on?"
|
|
82
|
+
- Review and prioritize the backlog
|
|
83
|
+
- Brainstorm new features
|
|
84
|
+
- Plan the next phase
|
|
85
|
+
- Something specific
|
|
86
|
+
|
|
87
|
+
Then follow the product-planning skill guidelines to facilitate the session.
|
|
88
|
+
|
|
89
|
+
## Notes
|
|
90
|
+
|
|
91
|
+
- Always use long flags (--unblocked, not -u) for clarity
|
|
92
|
+
- The CLI already sorts your assigned issues first
|
|
93
|
+
- If presenting options, use the AskUserQuestion tool for a clean interface
|
|
94
|
+
- The "Product planning" option ensures there's always something productive to do
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# /standup - Daily standup summary
|
|
2
|
+
|
|
3
|
+
Generate a summary of your work for standup meetings.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
/standup # Show standup summary from Linear + GitHub
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## What It Shows
|
|
12
|
+
|
|
13
|
+
Run `linear standup` to get:
|
|
14
|
+
|
|
15
|
+
**From Linear:**
|
|
16
|
+
- Issues you completed yesterday
|
|
17
|
+
- Issues currently in progress
|
|
18
|
+
- Issues that are blocked
|
|
19
|
+
|
|
20
|
+
**From GitHub (if in a repo):**
|
|
21
|
+
- Commits you made yesterday
|
|
22
|
+
- PRs you opened or merged yesterday
|
|
23
|
+
|
|
24
|
+
## After Running
|
|
25
|
+
|
|
26
|
+
1. Present the output from `linear standup` to the user
|
|
27
|
+
2. Offer to help with:
|
|
28
|
+
- Drafting a standup message for Slack/Teams
|
|
29
|
+
- Identifying what to work on next (suggest `/next`)
|
|
30
|
+
- Resolving any blockers
|
|
31
|
+
|
|
32
|
+
## Example Flow
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
User: /standup
|
|
36
|
+
|
|
37
|
+
Claude: [Runs linear standup]
|
|
38
|
+
|
|
39
|
+
Here's your standup summary:
|
|
40
|
+
|
|
41
|
+
**Yesterday:**
|
|
42
|
+
✓ ISSUE-5: Add caching layer
|
|
43
|
+
✓ ISSUE-6: Fix login timeout
|
|
44
|
+
|
|
45
|
+
**Today:**
|
|
46
|
+
→ ISSUE-8: Implement worktree support
|
|
47
|
+
|
|
48
|
+
**Blocked:**
|
|
49
|
+
⊘ ISSUE-12: Waiting on API credentials
|
|
50
|
+
|
|
51
|
+
**GitHub:**
|
|
52
|
+
- 4 commits on beautiful-tech
|
|
53
|
+
- PR #42 merged: ISSUE-5: Add caching layer
|
|
54
|
+
|
|
55
|
+
Would you like me to help draft a standup message, or shall we look at what to work on next?
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Notes
|
|
59
|
+
|
|
60
|
+
- The `linear standup` command handles all the data fetching
|
|
61
|
+
- GitHub info requires the `gh` CLI to be installed and authenticated
|
|
62
|
+
- If not in a git repo, GitHub section will be skipped
|
|
63
|
+
- Use `--no-github` flag to skip GitHub even if available
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: linear-cli
|
|
3
|
+
description: Manage Linear issues and projects from the command line. This skill allows automating Linear project management.
|
|
4
|
+
allowed-tools: Bash(linear:*), Bash(curl:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Linear CLI
|
|
8
|
+
|
|
9
|
+
A cross-platform CLI for Linear's GraphQL API, with unblocked issue filtering.
|
|
10
|
+
|
|
11
|
+
Install: `npm install -g @dabble/linear-cli`
|
|
12
|
+
|
|
13
|
+
## First-Time Setup
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
linear login
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
This will:
|
|
20
|
+
1. Open Linear API settings in your browser
|
|
21
|
+
2. Prompt you to paste your API key
|
|
22
|
+
3. Show available teams and let you pick one (or create a new team)
|
|
23
|
+
4. Save config to `./.linear`
|
|
24
|
+
|
|
25
|
+
Use `--global` to save to `~/.linear` instead.
|
|
26
|
+
|
|
27
|
+
## Configuration
|
|
28
|
+
|
|
29
|
+
Config is loaded in order: `./.linear` → `~/.linear` → env vars
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
# .linear file format
|
|
33
|
+
api_key=lin_api_xxx
|
|
34
|
+
team=ISSUE
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick Reference
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Auth
|
|
41
|
+
linear login # Interactive setup
|
|
42
|
+
linear login --global # Save to ~/.linear
|
|
43
|
+
linear logout # Remove config
|
|
44
|
+
linear whoami # Show current user/team
|
|
45
|
+
|
|
46
|
+
# Issues
|
|
47
|
+
linear issues --unblocked # Ready to work on (no blockers)
|
|
48
|
+
linear issues --open # All non-completed issues
|
|
49
|
+
linear issues --in-progress # Issues currently in progress
|
|
50
|
+
linear issues --mine # Only your assigned issues
|
|
51
|
+
linear issues --label bug # Filter by label
|
|
52
|
+
# Flags can be combined: linear issues --in-progress --mine
|
|
53
|
+
linear issue show ISSUE-1 # Full details with parent context
|
|
54
|
+
linear issue start ISSUE-1 # Assign to you + set In Progress
|
|
55
|
+
linear issue create --title "Fix bug" --project "Phase 1" --assign --estimate M
|
|
56
|
+
linear issue create --title "Blocked task" --blocked-by ISSUE-1
|
|
57
|
+
linear issue update ISSUE-1 --state "In Progress"
|
|
58
|
+
linear issue update ISSUE-1 --append "Notes..."
|
|
59
|
+
linear issue update ISSUE-1 --blocks ISSUE-2 # Add blocking relation
|
|
60
|
+
linear issue close ISSUE-1
|
|
61
|
+
linear issue comment ISSUE-1 "Comment text"
|
|
62
|
+
|
|
63
|
+
# Projects
|
|
64
|
+
linear projects # Active projects
|
|
65
|
+
linear projects --all # Include completed
|
|
66
|
+
linear project show "Phase 1" # Details with issues
|
|
67
|
+
linear project create "Name" --description "..."
|
|
68
|
+
linear project complete "Phase 1"
|
|
69
|
+
|
|
70
|
+
# Labels
|
|
71
|
+
linear labels # List all labels
|
|
72
|
+
linear label create "bug" --color "#FF0000"
|
|
73
|
+
|
|
74
|
+
# Git
|
|
75
|
+
linear branch ISSUE-1 # Create branch: ISSUE-1-issue-title
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Estimation
|
|
79
|
+
|
|
80
|
+
Use t-shirt sizes for estimates. Always use `--estimate` (not `-e`) for clarity.
|
|
81
|
+
|
|
82
|
+
| Size | Meaning |
|
|
83
|
+
|------|---------|
|
|
84
|
+
| XS | Trivial, < 1 hour |
|
|
85
|
+
| S | Small, couple hours |
|
|
86
|
+
| M | Medium, a day or so |
|
|
87
|
+
| L | Large, multi-day - consider breaking down |
|
|
88
|
+
| XL | Very large - should definitely break down |
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# Create with estimate (use long flags for clarity)
|
|
92
|
+
linear issue create --title "Add caching" --estimate M --assign
|
|
93
|
+
|
|
94
|
+
# L/XL issues should be broken into sub-issues
|
|
95
|
+
linear issue create --title "Implement auth" --estimate L
|
|
96
|
+
linear issue create --title "Add login endpoint" --parent ISSUE-5 --estimate S
|
|
97
|
+
linear issue create --title "Add JWT validation" --parent ISSUE-5 --estimate S
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Git Conventions
|
|
101
|
+
|
|
102
|
+
Always link git work to Linear issues:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Create branch from issue (recommended)
|
|
106
|
+
linear branch ISSUE-5 # Creates: ISSUE-5-add-caching-layer
|
|
107
|
+
|
|
108
|
+
# Commit message format
|
|
109
|
+
git commit -m "ISSUE-5: Add cache invalidation on logout"
|
|
110
|
+
|
|
111
|
+
# Include issue ID in PR title
|
|
112
|
+
gh pr create --title "ISSUE-5: Add caching layer"
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Workflow Guidelines
|
|
116
|
+
|
|
117
|
+
### Starting work on an issue
|
|
118
|
+
```bash
|
|
119
|
+
linear issues --unblocked # Find what's ready
|
|
120
|
+
linear issue show ISSUE-2 # Review it (shows parent context)
|
|
121
|
+
linear issue start ISSUE-2 # Assign + set In Progress
|
|
122
|
+
linear branch ISSUE-2 # Create git branch
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### When you hit a blocker
|
|
126
|
+
If work cannot continue due to a dependency or external factor:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Create the blocking issue
|
|
130
|
+
linear issue create --title "Need API credentials" --blocks ISSUE-5
|
|
131
|
+
|
|
132
|
+
# Or mark existing issue as blocking
|
|
133
|
+
linear issue update ISSUE-3 --blocks ISSUE-5
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
This removes ISSUE-5 from `--unblocked` results until the blocker is resolved.
|
|
137
|
+
|
|
138
|
+
### When a task is larger than expected
|
|
139
|
+
If you discover an M issue is actually L/XL, break it down:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Create sub-issues
|
|
143
|
+
linear issue create --title "Step 1: Research approach" --parent ISSUE-5 --estimate S
|
|
144
|
+
linear issue create --title "Step 2: Implement core logic" --parent ISSUE-5 --estimate M
|
|
145
|
+
linear issue create --title "Step 3: Add tests" --parent ISSUE-5 --estimate S
|
|
146
|
+
|
|
147
|
+
# Start working on the first sub-issue
|
|
148
|
+
linear issue start ISSUE-6
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Completing work
|
|
152
|
+
After finishing implementation, ask the developer if they want to close the issue:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
# Suggest closing
|
|
156
|
+
linear issue close ISSUE-5
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Do not auto-close issues. Let the developer review the work first.
|
|
160
|
+
|
|
161
|
+
### Adding notes while working
|
|
162
|
+
```bash
|
|
163
|
+
linear issue update ISSUE-2 --append "## Notes\n\nDiscovered X, trying Y approach..."
|
|
164
|
+
# or for quick updates
|
|
165
|
+
linear issue comment ISSUE-2 "Found the root cause in auth.ts:142"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Completing a phase
|
|
169
|
+
```bash
|
|
170
|
+
linear issue close ISSUE-7 # Close remaining issues
|
|
171
|
+
linear project complete "Phase 1"
|
|
172
|
+
# Then update CLAUDE.md status table
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Parent Context
|
|
176
|
+
|
|
177
|
+
When viewing an issue with `linear issue show`, you'll see where it fits in the larger work:
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
# ISSUE-6: Add JWT validation
|
|
181
|
+
|
|
182
|
+
State: In Progress
|
|
183
|
+
...
|
|
184
|
+
|
|
185
|
+
## Context
|
|
186
|
+
|
|
187
|
+
ISSUE-3: Implement authentication system
|
|
188
|
+
- [Done] ISSUE-4: Add login endpoint
|
|
189
|
+
→ [In Progress] ISSUE-6: Add JWT validation ← you are here
|
|
190
|
+
- [Backlog] ISSUE-7: Add refresh tokens
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
This helps understand the scope and what comes before/after the current task.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: product-planning
|
|
3
|
+
description: Help with product planning, feature brainstorming, and backlog management using Linear.
|
|
4
|
+
allowed-tools: Bash(linear:*), Bash(curl:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Product Planning Skill
|
|
8
|
+
|
|
9
|
+
Help the developer think through product direction, brainstorm features, and manage their Linear backlog.
|
|
10
|
+
|
|
11
|
+
## When to Use This Skill
|
|
12
|
+
|
|
13
|
+
Use this skill when the developer wants to:
|
|
14
|
+
- Brainstorm new features or improvements
|
|
15
|
+
- Review and prioritize the backlog
|
|
16
|
+
- Break down large ideas into actionable issues
|
|
17
|
+
- Plan a new phase or milestone
|
|
18
|
+
- Think through product strategy
|
|
19
|
+
|
|
20
|
+
## Approach
|
|
21
|
+
|
|
22
|
+
### 1. Understand Current State
|
|
23
|
+
|
|
24
|
+
First, gather context:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# See all open issues (backlog + in progress, excludes completed)
|
|
28
|
+
linear issues --open
|
|
29
|
+
|
|
30
|
+
# See active projects/phases
|
|
31
|
+
linear projects
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 2. Facilitate Discussion
|
|
35
|
+
|
|
36
|
+
Ask good questions to help clarify thinking:
|
|
37
|
+
|
|
38
|
+
- "What problem are we trying to solve?"
|
|
39
|
+
- "Who benefits from this feature?"
|
|
40
|
+
- "What's the simplest version that would be valuable?"
|
|
41
|
+
- "What are the dependencies or blockers?"
|
|
42
|
+
- "How does this fit with the current phase?"
|
|
43
|
+
|
|
44
|
+
### 3. Break Down Ideas
|
|
45
|
+
|
|
46
|
+
When a feature is identified, help break it into Linear issues:
|
|
47
|
+
|
|
48
|
+
**For small features (S/M):**
|
|
49
|
+
- Create a single issue with clear acceptance criteria
|
|
50
|
+
- Assign appropriate estimate
|
|
51
|
+
|
|
52
|
+
**For large features (L/XL):**
|
|
53
|
+
- Create a parent issue describing the overall goal
|
|
54
|
+
- Break into sub-issues, each S or M sized
|
|
55
|
+
- Identify dependencies between sub-issues
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Create parent issue
|
|
59
|
+
linear issue create --title "User authentication system" --estimate L --project "Phase 2"
|
|
60
|
+
|
|
61
|
+
# Create sub-issues
|
|
62
|
+
linear issue create --title "Design auth flow" --parent ISSUE-10 --estimate S
|
|
63
|
+
linear issue create --title "Implement login endpoint" --parent ISSUE-10 --estimate M
|
|
64
|
+
linear issue create --title "Add session management" --parent ISSUE-10 --estimate M --blocked-by ISSUE-12
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 4. Organize Into Phases
|
|
68
|
+
|
|
69
|
+
If planning a new phase:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Create the phase
|
|
73
|
+
linear project create "Phase 3: User Dashboard" --description "Build the main user-facing dashboard with key metrics"
|
|
74
|
+
|
|
75
|
+
# Add issues to it
|
|
76
|
+
linear issue create --title "Dashboard layout" --project "Phase 3" --estimate M
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Brainstorming Prompts
|
|
80
|
+
|
|
81
|
+
When the developer is stuck, try these prompts:
|
|
82
|
+
|
|
83
|
+
**For new features:**
|
|
84
|
+
- "What do users complain about most?"
|
|
85
|
+
- "What manual process could we automate?"
|
|
86
|
+
- "What would make you excited to use this product?"
|
|
87
|
+
|
|
88
|
+
**For improvements:**
|
|
89
|
+
- "Where do users get confused?"
|
|
90
|
+
- "What takes too long?"
|
|
91
|
+
- "What breaks most often?"
|
|
92
|
+
|
|
93
|
+
**For prioritization:**
|
|
94
|
+
- "What would have the biggest impact with the least effort?"
|
|
95
|
+
- "What's blocking other work?"
|
|
96
|
+
- "What do users ask for most?"
|
|
97
|
+
|
|
98
|
+
## Output Format
|
|
99
|
+
|
|
100
|
+
After a planning session, summarize:
|
|
101
|
+
|
|
102
|
+
1. **New issues created** - List with IDs and estimates
|
|
103
|
+
2. **Backlog changes** - Any reprioritization or updates
|
|
104
|
+
3. **Next steps** - What to work on next
|
|
105
|
+
4. **Open questions** - Things that need more thought
|
|
106
|
+
|
|
107
|
+
## Example Session
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
Developer: "I want to add user notifications"
|
|
111
|
+
|
|
112
|
+
Claude: Let me check the current state...
|
|
113
|
+
[runs linear issues --all]
|
|
114
|
+
|
|
115
|
+
Good context. A few questions:
|
|
116
|
+
1. What triggers notifications? (events, mentions, etc.)
|
|
117
|
+
2. Where do they appear? (in-app, email, push?)
|
|
118
|
+
3. Is this blocking other work?
|
|
119
|
+
|
|
120
|
+
Developer: "Just in-app for now, triggered by comments on their issues"
|
|
121
|
+
|
|
122
|
+
That's a nicely scoped M-sized feature. Let me create it:
|
|
123
|
+
[runs linear issue create --title "In-app notifications for issue comments" --estimate M --project "Phase 2"]
|
|
124
|
+
|
|
125
|
+
Created ISSUE-15. Should I break this down further, or is it small enough to tackle as one unit?
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Integration with /next
|
|
129
|
+
|
|
130
|
+
When invoked from the `/next` command (user chose "product planning"), start by asking:
|
|
131
|
+
|
|
132
|
+
"What would you like to focus on today?"
|
|
133
|
+
- Review and prioritize the backlog
|
|
134
|
+
- Brainstorm new features
|
|
135
|
+
- Plan the next phase
|
|
136
|
+
- Something specific (let them describe)
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dabble/linear-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Linear CLI with unblocked issue filtering, built for AI-assisted development",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"linear": "./bin/linear.mjs"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"postinstall": "node postinstall.mjs",
|
|
11
|
+
"preuninstall": "node preuninstall.mjs"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"bin/",
|
|
15
|
+
"claude/",
|
|
16
|
+
"postinstall.mjs",
|
|
17
|
+
"preuninstall.mjs"
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"linear",
|
|
21
|
+
"cli",
|
|
22
|
+
"project-management",
|
|
23
|
+
"issues",
|
|
24
|
+
"claude"
|
|
25
|
+
],
|
|
26
|
+
"author": "Dabble",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/dabblewriter/linear-cli"
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18.0.0"
|
|
34
|
+
}
|
|
35
|
+
}
|
package/postinstall.mjs
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { cpSync, mkdirSync, existsSync, readdirSync, readFileSync, writeFileSync } from 'fs';
|
|
2
|
+
import { join, dirname, relative } from 'path';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const src = join(__dirname, 'claude');
|
|
8
|
+
const dest = join(homedir(), '.claude');
|
|
9
|
+
|
|
10
|
+
// Copy skill and command files
|
|
11
|
+
try {
|
|
12
|
+
if (!existsSync(dest)) {
|
|
13
|
+
mkdirSync(dest, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Recursively copy claude/ to ~/.claude/
|
|
17
|
+
cpSync(src, dest, { recursive: true });
|
|
18
|
+
|
|
19
|
+
const files = readdirSync(src, { recursive: true, withFileTypes: true })
|
|
20
|
+
.filter((e) => e.isFile())
|
|
21
|
+
.map((e) => relative(src, join(e.parentPath, e.name)));
|
|
22
|
+
|
|
23
|
+
console.log(`\x1b[32m✓\x1b[0m Installed Claude files to ~/.claude/`);
|
|
24
|
+
for (const file of files) {
|
|
25
|
+
console.log(` - ${file}`);
|
|
26
|
+
}
|
|
27
|
+
} catch (err) {
|
|
28
|
+
console.log(`\x1b[33m⚠\x1b[0m Could not install Claude files: ${err.message}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Add linear permission to settings.json
|
|
32
|
+
const PERMISSION = 'Bash(linear:*)';
|
|
33
|
+
const settingsPath = join(dest, 'settings.json');
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
let settings = { permissions: { allow: [], deny: [] } };
|
|
37
|
+
|
|
38
|
+
if (existsSync(settingsPath)) {
|
|
39
|
+
settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Ensure structure exists
|
|
43
|
+
settings.permissions = settings.permissions || {};
|
|
44
|
+
settings.permissions.allow = settings.permissions.allow || [];
|
|
45
|
+
|
|
46
|
+
// Add permission if not already present
|
|
47
|
+
if (!settings.permissions.allow.includes(PERMISSION)) {
|
|
48
|
+
settings.permissions.allow.push(PERMISSION);
|
|
49
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
|
|
50
|
+
console.log(`\x1b[32m✓\x1b[0m Added ${PERMISSION} to ~/.claude/settings.json`);
|
|
51
|
+
}
|
|
52
|
+
} catch (err) {
|
|
53
|
+
console.log(`\x1b[33m⚠\x1b[0m Could not update settings: ${err.message}`);
|
|
54
|
+
}
|
package/preuninstall.mjs
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { unlinkSync, existsSync, readFileSync, writeFileSync, readdirSync } from 'fs';
|
|
2
|
+
import { join, dirname, relative } from 'path';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const src = join(__dirname, 'claude');
|
|
8
|
+
const dest = join(homedir(), '.claude');
|
|
9
|
+
|
|
10
|
+
// Remove files that were installed from claude/
|
|
11
|
+
let removedCount = 0;
|
|
12
|
+
try {
|
|
13
|
+
const files = readdirSync(src, { recursive: true, withFileTypes: true })
|
|
14
|
+
.filter((e) => e.isFile())
|
|
15
|
+
.map((e) => relative(src, join(e.parentPath, e.name)));
|
|
16
|
+
|
|
17
|
+
for (const file of files) {
|
|
18
|
+
const filePath = join(dest, file);
|
|
19
|
+
try {
|
|
20
|
+
if (existsSync(filePath)) {
|
|
21
|
+
unlinkSync(filePath);
|
|
22
|
+
removedCount++;
|
|
23
|
+
}
|
|
24
|
+
} catch (err) {
|
|
25
|
+
// Silently ignore removal errors
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
} catch (err) {
|
|
29
|
+
// Silently ignore if claude/ dir doesn't exist
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (removedCount > 0) {
|
|
33
|
+
console.log(`\x1b[32m✓\x1b[0m Removed ${removedCount} Claude file(s) from ~/.claude/`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Remove linear permission from settings.json
|
|
37
|
+
const PERMISSION = 'Bash(linear:*)';
|
|
38
|
+
const settingsPath = join(dest, 'settings.json');
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
if (existsSync(settingsPath)) {
|
|
42
|
+
const settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
|
|
43
|
+
|
|
44
|
+
if (settings.permissions?.allow?.includes(PERMISSION)) {
|
|
45
|
+
settings.permissions.allow = settings.permissions.allow.filter(p => p !== PERMISSION);
|
|
46
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
|
|
47
|
+
console.log(`\x1b[32m✓\x1b[0m Removed ${PERMISSION} from ~/.claude/settings.json`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
} catch (err) {
|
|
51
|
+
// Silently ignore settings errors
|
|
52
|
+
}
|