prjct-cli 0.40.0 → 0.42.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.
@@ -1,51 +1,44 @@
1
1
  ---
2
2
  allowed-tools: [Read, Write, Bash, AskUserQuestion]
3
- description: 'Linear issue tracker integration via MCP'
3
+ description: 'Linear issue tracker integration via SDK'
4
4
  extends: '_bases/tracker-base.md'
5
5
  ---
6
6
 
7
7
  # p. linear - Linear Integration
8
8
 
9
- **EXTENDS**: `_bases/tracker-base.md` - See base template for common flows.
10
-
11
9
  **ARGUMENTS**: $ARGUMENTS
12
10
 
13
- Manage Linear issues directly from prjct using MCP (no SDK needed).
14
-
15
- ## Tracker-Specific Config
11
+ Manage Linear issues directly from prjct using natural language.
16
12
 
17
- - `{mcpServerName}`: "linear"
18
- - `{mcpPrefix}`: "mcp__linear__"
19
- - `{projectKey}`: "teamId"
13
+ ## How This Works
20
14
 
21
- ## Context Variables
15
+ User types natural commands → Claude interprets → Executes SDK → Shows formatted result
22
16
 
23
- - `{projectId}`: From `.prjct/prjct.config.json`
24
- - `{globalPath}`: `~/.prjct-cli/projects/{projectId}`
25
- - `{agentName}`: Name of the AI agent (Claude Code, Gemini CLI)
26
- - `{agentSettingsPath}`: Path to agent settings (settings.json)
27
- - `{args}`: User-provided arguments (subcommand)
17
+ **Examples**:
18
+ - `p. linear` → List my assigned issues
19
+ - `p. linear 123` or `p. linear PRJ-123` Get issue details
20
+ - `p. linear start 123` Start working on issue
21
+ - `p. linear done 123` → Mark issue as done
22
+ - `p. linear setup` → Configure API key
23
+ - `p. linear "add auth feature"` → Create new issue
28
24
 
29
25
  ---
30
26
 
31
- ## Subcommands
27
+ ## CRITICAL - Execution Pattern
32
28
 
33
- | Command | Description |
34
- |---------|-------------|
35
- | `p. linear` | Show your assigned issues |
36
- | `p. linear setup` | Configure Linear (first time) |
37
- | `p. linear start <ID>` | Start working on issue (e.g., PRJ-59) |
38
- | `p. linear comment <ID> <text>` | Add comment to issue |
29
+ **NEVER use MCP tools** (`mcp__linear__*`, `mcp__claude_ai_Linear__*`).
30
+ **ALWAYS use SDK via CLI helper** (much faster, per-project credentials).
39
31
 
40
- ---
32
+ ### CLI Helper (Internal Use)
41
33
 
42
- ## Authentication
34
+ ```bash
35
+ # Setup paths first
36
+ PRJCT_CLI=$(npm root -g)/prjct-cli
37
+ PROJECT_ID=$(cat .prjct/prjct.config.json | jq -r '.projectId')
43
38
 
44
- Linear uses MCP with OAuth - **no API key needed**.
45
-
46
- **MCP Server**: `https://mcp.linear.app/mcp`
47
- **Auth**: Browser-based OAuth (first use opens browser)
48
- **Tools prefix**: `mcp__linear__*`
39
+ # Then run commands with --project flag
40
+ bun $PRJCT_CLI/core/cli/linear.ts --project $PROJECT_ID <command> [args...]
41
+ ```
49
42
 
50
43
  ---
51
44
 
@@ -63,98 +56,52 @@ IF file not found:
63
56
 
64
57
  ---
65
58
 
66
- ## Step 2: Install MCP Server (if needed)
67
-
68
- ```
69
- READ: {agentSettingsPath} (create {} if not exists)
70
- CHECK: Does mcpServers.linear exist?
71
-
72
- IF not exists:
73
- READ: templates/mcp-config.json
74
- EXTRACT: mcpServers.linear
75
-
76
- MERGE into {agentSettingsPath}:
77
- {
78
- "mcpServers": {
79
- "linear": {
80
- "command": "npx",
81
- "args": ["-y", "mcp-remote", "https://mcp.linear.app/mcp"]
82
- }
83
- }
84
- }
85
-
86
- WRITE: {agentSettingsPath}
87
-
88
- OUTPUT: "✅ Installed Linear MCP server"
89
- OUTPUT: ""
90
- OUTPUT: "⚠️ Restart {agentName} to activate the MCP server."
91
- OUTPUT: "Then run `p. linear setup` again to complete configuration."
92
- STOP
93
- ```
94
-
95
- ---
59
+ ## Step 2: Parse User Intent
96
60
 
97
- ## Step 3: Check MCP Tools Available
61
+ Analyze $ARGUMENTS to determine what user wants:
98
62
 
99
- ```
100
- CHECK: Are mcp__linear__* tools available?
63
+ | User Input | Intent | CLI Command |
64
+ |------------|--------|-------------|
65
+ | (empty) | List my issues | `list` |
66
+ | `setup` | Configure API key | `setup <apiKey>` |
67
+ | `123` or `PRJ-123` | Get issue details | `get PRJ-123` |
68
+ | `start 123` | Start working | `start PRJ-123` |
69
+ | `done 123` | Mark complete | `done PRJ-123` |
70
+ | `comment 123 text...` | Add comment | `comment PRJ-123 "text"` |
71
+ | `"create something"` | Create issue | `create '{"title":"..."}'` |
72
+ | `teams` | List teams | `teams` |
73
+ | `status` | Check connection | `status` |
101
74
 
102
- IF not available:
103
- OUTPUT: "Linear MCP is installed but not yet active."
104
- OUTPUT: "Restart {agentName}, then run `p. linear setup` again."
105
- STOP
106
- ```
75
+ **Identifier normalization**: If user types `123`, check project config for team key and expand to `PRJ-123`.
107
76
 
108
77
  ---
109
78
 
110
79
  ## Subcommand: setup
111
80
 
112
- ### Flow
81
+ **Trigger**: `p. linear setup`
113
82
 
114
- 1. **Install MCP + Verify tools available**
115
- ```
116
- Execute Step 2 (auto-install if needed)
117
- Execute Step 3 (verify tools active)
118
- IF not available: Prompt restart and STOP
119
- ```
83
+ ### Flow
120
84
 
121
- 2. **Test connection (triggers OAuth if needed)**
85
+ 1. **Ask for API key**
122
86
  ```
123
- USE TOOL: mcp__linear__list_issues
124
- PARAMS: { "limit": 1 }
125
-
126
- # First use will open browser for OAuth
87
+ ASK: "Enter your Linear API key"
88
+ HINT: "Get it from https://linear.app/settings/api"
127
89
  ```
128
90
 
129
- 3. **Get user info and teams**
91
+ 2. **Store and test via CLI**
92
+ ```bash
93
+ RESULT=$(bun $PRJCT_CLI/core/cli/linear.ts --project $PROJECT_ID setup "$API_KEY")
130
94
  ```
131
- USE TOOL: mcp__linear__get_viewer
132
- EXTRACT: userId, name, email
133
95
 
134
- USE TOOL: mcp__linear__list_teams
135
- ```
96
+ 3. **Parse result** - Contains `{ success, teams, defaultTeam }`
136
97
 
137
- 4. **Ask user to select team**
98
+ 4. **If multiple teams, ask user to select**
138
99
  ```
139
100
  ASK: "Select your default team"
140
- OPTIONS: List of teams
141
- ```
101
+ OPTIONS: teams from result
142
102
 
143
- 5. **Save config to project.json**
144
- ```json
145
- {
146
- "integrations": {
147
- "linear": {
148
- "enabled": true,
149
- "authMode": "mcp",
150
- "teamId": "{teamId}",
151
- "teamName": "{teamName}",
152
- "teamKey": "{teamKey}",
153
- "userId": "{userId}",
154
- "setupAt": "{timestamp}"
155
- }
156
- }
157
- }
103
+ # Re-run setup with team selection
104
+ bun $PRJCT_CLI/core/cli/linear.ts --project $PROJECT_ID setup "$API_KEY" "$TEAM_ID"
158
105
  ```
159
106
 
160
107
  ### Output
@@ -162,151 +109,189 @@ IF not available:
162
109
  ```
163
110
  ✅ Linear configured
164
111
 
165
- Connected as: {name} ({email})
166
112
  Team: {teamName} ({teamKey})
167
- Auth: MCP (OAuth)
113
+ Credentials: Stored per-project
168
114
 
169
115
  Next: `p. linear` to see your issues
170
116
  ```
171
117
 
172
118
  ---
173
119
 
174
- ## Subcommand: status (default, no args)
120
+ ## Subcommand: list (default)
175
121
 
122
+ **Trigger**: `p. linear` (no arguments)
123
+
124
+ ```bash
125
+ RESULT=$(bun $PRJCT_CLI/core/cli/linear.ts --project $PROJECT_ID list)
176
126
  ```
177
- USE TOOL: mcp__linear__list_issues
178
- PARAMS:
179
- assignedToMe: true
180
- limit: 10
181
127
 
182
- OUTPUT:
183
- Linear: Connected ✓
184
- Team: {teamName} ({teamKey})
128
+ ### Output
129
+
130
+ ```
131
+ Linear: Connected
185
132
 
186
- Your issues ({count}):
187
- • {PRJ-123} {title} ({status})
188
- • {PRJ-124} {title} ({status})
189
- ...
133
+ Your issues (5):
134
+ PRJ-123 Add user authentication In Progress
135
+ PRJ-124 Fix login redirect Todo
136
+ PRJ-125 Update dependencies Backlog
137
+ ...
190
138
 
191
- Next: `p. linear start PRJ-123` to begin work
139
+ Next: `p. linear 123` for details, `p. linear start 123` to begin
192
140
  ```
193
141
 
194
142
  ---
195
143
 
196
- ## Subcommand: start <ID>
144
+ ## Subcommand: get <ID>
197
145
 
146
+ **Trigger**: `p. linear 123` or `p. linear PRJ-123`
147
+
148
+ ```bash
149
+ RESULT=$(bun $PRJCT_CLI/core/cli/linear.ts --project $PROJECT_ID get "PRJ-123")
198
150
  ```
199
- 1. Get issue
200
- USE TOOL: mcp__linear__get_issue
201
- PARAMS: { "issueId": "{ID}" }
202
151
 
203
- 2. Update status to In Progress
204
- USE TOOL: mcp__linear__update_issue
205
- PARAMS:
206
- issueId: "{uuid}"
207
- stateId: "{in_progress_state_id}"
152
+ ### Output
208
153
 
209
- 3. Create prjct task from issue
154
+ ```
155
+ PRJ-123: Add user authentication
210
156
 
211
- 4. Create git branch: feature/{ID}-{slug}
157
+ Status: In Progress
158
+ Priority: High
159
+ Assignee: @user
212
160
 
213
- OUTPUT:
214
- Started: {ID} - {title}
161
+ Description:
162
+ {description text}
215
163
 
216
- Branch: feature/PRJ-59-add-user-auth
217
- Linear: In Progress ✓
164
+ URL: https://linear.app/team/issue/PRJ-123
165
+
166
+ Next: `p. linear start 123` to begin, `p. task "PRJ-123"` to track in prjct
167
+ ```
168
+
169
+ ---
170
+
171
+ ## Subcommand: start <ID>
172
+
173
+ **Trigger**: `p. linear start 123`
174
+
175
+ ```bash
176
+ # 1. Get issue info
177
+ ISSUE=$(bun $PRJCT_CLI/core/cli/linear.ts --project $PROJECT_ID get "PRJ-123")
178
+
179
+ # 2. Mark in progress
180
+ bun $PRJCT_CLI/core/cli/linear.ts --project $PROJECT_ID start "PRJ-123"
181
+
182
+ # 3. Create git branch
183
+ git checkout -b "feature/PRJ-123-{slug}"
184
+ ```
185
+
186
+ ### Output
187
+
188
+ ```
189
+ Started: PRJ-123 - {title}
190
+
191
+ Branch: feature/PRJ-123-add-user-auth
192
+ Linear: In Progress
218
193
 
219
194
  Next: Work on the task, then `p. done`
220
195
  ```
221
196
 
222
197
  ---
223
198
 
224
- ## Subcommand: comment <ID> <text>
199
+ ## Subcommand: done <ID>
200
+
201
+ **Trigger**: `p. linear done 123`
225
202
 
203
+ ```bash
204
+ bun $PRJCT_CLI/core/cli/linear.ts --project $PROJECT_ID done "PRJ-123"
226
205
  ```
227
- 1. Get issue UUID
228
- USE TOOL: mcp__linear__get_issue
229
- PARAMS: { "issueId": "{ID}" }
230
-
231
- 2. Add comment
232
- USE TOOL: mcp__linear__create_comment
233
- PARAMS:
234
- issueId: "{uuid}"
235
- body: "{text}"
236
-
237
- OUTPUT:
238
- Comment added to {ID}
206
+
207
+ ### Output
208
+
209
+ ```
210
+ Completed: PRJ-123 - {title}
211
+
212
+ Linear: Done
239
213
  ```
240
214
 
241
215
  ---
242
216
 
243
- ## MCP Tool Reference
217
+ ## Subcommand: create
244
218
 
245
- | Operation | MCP Tool |
246
- |-----------|----------|
247
- | List issues | `mcp__linear__list_issues` |
248
- | Get issue | `mcp__linear__get_issue` |
249
- | Update issue | `mcp__linear__update_issue` |
250
- | Create issue | `mcp__linear__create_issue` |
251
- | Add comment | `mcp__linear__create_comment` |
252
- | Get viewer | `mcp__linear__get_viewer` |
253
- | List teams | `mcp__linear__list_teams` |
219
+ **Trigger**: `p. linear "add feature X"` or `p. linear create "title"`
254
220
 
255
- ### Example: List My Issues
221
+ ```bash
222
+ # Get default team from credentials
223
+ TEAMS=$(bun $PRJCT_CLI/core/cli/linear.ts --project $PROJECT_ID teams)
256
224
 
225
+ # Create issue
226
+ RESULT=$(bun $PRJCT_CLI/core/cli/linear.ts --project $PROJECT_ID create '{"title":"...","teamId":"..."}')
257
227
  ```
258
- USE TOOL: mcp__linear__list_issues
259
- PARAMS:
260
- assignedToMe: true
261
- includeArchived: false
262
- limit: 20
228
+
229
+ ### Output
230
+
263
231
  ```
232
+ ✅ Created: PRJ-126 - {title}
264
233
 
265
- ### Example: Get Issue by ID
234
+ URL: https://linear.app/...
266
235
 
236
+ Next: `p. linear start 126` to begin
267
237
  ```
268
- USE TOOL: mcp__linear__get_issue
269
- PARAMS:
270
- issueId: "PRJ-59"
238
+
239
+ ---
240
+
241
+ ## Subcommand: comment <ID> <text>
242
+
243
+ **Trigger**: `p. linear comment 123 "Progress update..."`
244
+
245
+ ```bash
246
+ bun $PRJCT_CLI/core/cli/linear.ts --project $PROJECT_ID comment "PRJ-123" "Progress update..."
271
247
  ```
272
248
 
273
- ### Example: Add Comment
249
+ ### Output
274
250
 
275
251
  ```
276
- USE TOOL: mcp__linear__create_comment
277
- PARAMS:
278
- issueId: "{uuid}"
279
- body: "Implementation complete. Used MCP instead of SDK."
252
+ Comment added to PRJ-123
280
253
  ```
281
254
 
282
255
  ---
283
256
 
284
- ## Config Storage
257
+ ## Subcommand: update <ID>
285
258
 
286
- | What | Where |
287
- |------|-------|
288
- | Auth | MCP OAuth (managed by Linear) |
289
- | Config | `{globalPath}/project.json` `integrations.linear` |
290
- | Issue cache | `{globalPath}/storage/issues.json` |
259
+ **Trigger**: `p. linear update 123` (then ask what to update)
260
+
261
+ ```bash
262
+ bun $PRJCT_CLI/core/cli/linear.ts --project $PROJECT_ID update "PRJ-123" '{"description":"..."}'
263
+ ```
291
264
 
292
265
  ---
293
266
 
294
267
  ## Error Handling
295
268
 
296
- | Error | Action |
297
- |-------|--------|
298
- | MCP tools not found | "Add Linear MCP to settings, restart {agentName}" |
299
- | OAuth failed | "Re-authenticate via browser" |
300
- | Issue not found | "Issue {ID} not found in Linear" |
269
+ | Error | Response |
270
+ |-------|----------|
271
+ | Not configured | "Run `p. linear setup` to configure your API key" |
272
+ | Invalid API key | "Invalid API key. Get a new one at https://linear.app/settings/api" |
273
+ | Issue not found | "Issue PRJ-123 not found" |
274
+ | No project | "Run `p. init` first" |
301
275
 
302
276
  ---
303
277
 
304
- ## Output Format
278
+ ## Credential Storage
305
279
 
306
- ```
307
- {action}: {result}
280
+ Credentials are stored **per-project** to support multiple Linear workspaces:
308
281
 
309
- {details}
282
+ **Location**: `~/.prjct-cli/projects/{projectId}/config/credentials.json`
310
283
 
311
- Next: {suggested action}
312
- ```
284
+ **Fallback chain**:
285
+ 1. Project credentials (per-project)
286
+ 2. Global keychain (macOS)
287
+ 3. Environment variable (`LINEAR_API_KEY`)
288
+
289
+ ---
290
+
291
+ ## Performance
292
+
293
+ | Operation | SDK | MCP (deprecated) |
294
+ |-----------|-----|------------------|
295
+ | Fetch issue | ~150ms | ~600ms |
296
+ | List issues | ~300ms | ~1200ms |
297
+ | Create issue | ~200ms | ~800ms |
@@ -8,6 +8,56 @@ allowed-tools: [Read, Write, Bash, Task, Glob, Grep, AskUserQuestion]
8
8
  prjct context task $ARGUMENTS
9
9
  ```
10
10
 
11
+ ## Step 0: Detect Issue Tracker Reference
12
+
13
+ IF `$ARGUMENTS` matches pattern `/^[A-Z]+-\d+$/` (e.g., PRJ-123, PROJ-456):
14
+
15
+ ```
16
+ READ: {globalPath}/project.json
17
+ CHECK: integrations.linear OR integrations.jira
18
+
19
+ IF integrations.linear.enabled:
20
+ # Linear issue detected
21
+ IMPORT: linearService from core/integrations/linear
22
+ CALL: linearService.fetchIssue("$ARGUMENTS")
23
+
24
+ IF issue found:
25
+ SET: task.externalId = issue.externalId
26
+ SET: task.externalProvider = "linear"
27
+ SET: task.description = issue.title
28
+ SET: $ARGUMENTS = issue.title # Use title for task
29
+
30
+ # Mark issue as In Progress in Linear
31
+ CALL: linearService.markInProgress(issue.id)
32
+
33
+ OUTPUT: "Linked to Linear: {issue.externalId} - {issue.title}"
34
+ OUTPUT: "Linear: In Progress"
35
+
36
+ ELSE IF integrations.jira.enabled:
37
+ # JIRA issue detected
38
+ IMPORT: jiraService from core/integrations/jira
39
+ CALL: jiraService.fetchIssue("$ARGUMENTS")
40
+
41
+ IF issue found:
42
+ SET: task.externalId = issue.externalId
43
+ SET: task.externalProvider = "jira"
44
+ SET: task.description = issue.title
45
+ SET: $ARGUMENTS = issue.title # Use title for task
46
+
47
+ # Mark issue as In Progress in JIRA
48
+ CALL: jiraService.markInProgress(issue.externalId)
49
+
50
+ OUTPUT: "Linked to JIRA: {issue.externalId} - {issue.title}"
51
+ OUTPUT: "JIRA: In Progress"
52
+
53
+ ELSE:
54
+ OUTPUT: "Issue tracker not configured. Run `p. linear setup` or `p. jira setup`"
55
+ ```
56
+
57
+ ---
58
+
59
+ ## Main Flow
60
+
11
61
  IF `currentTask` active → Ask: complete, pause, or cancel?
12
62
 
13
63
  USE Task(Explore) → find similar code, affected files
@@ -23,14 +73,28 @@ prjct work "$ARGUMENTS"
23
73
 
24
74
  WRITE `{globalPath}/storage/state.json`:
25
75
  ```json
26
- {"currentTask":{"id":"{uuid}","description":"{subtask}","type":"{type}","status":"active","startedAt":"{now}","subtasks":[...],"currentSubtaskIndex":0,"parentDescription":"$ARGUMENTS"}}
76
+ {
77
+ "currentTask": {
78
+ "id": "{uuid}",
79
+ "description": "{subtask}",
80
+ "type": "{type}",
81
+ "status": "active",
82
+ "startedAt": "{now}",
83
+ "subtasks": [...],
84
+ "currentSubtaskIndex": 0,
85
+ "parentDescription": "$ARGUMENTS",
86
+ "externalId": "{externalId or null}",
87
+ "externalProvider": "{linear|jira|null}"
88
+ }
89
+ }
27
90
  ```
28
91
 
29
92
  **Output**:
30
93
  ```
31
- {type}: $ARGUMENTS
94
+ {type}: $ARGUMENTS
32
95
 
33
96
  Branch: {branch} | Subtasks: {count}
97
+ {externalId ? "Linked: {externalProvider} {externalId}" : ""}
34
98
 
35
99
  Next: Work on subtask, then `p. done`
36
100
  ```
@@ -5,16 +5,6 @@
5
5
  "args": ["-y", "@upstash/context7-mcp@latest"],
6
6
  "description": "Library documentation lookup"
7
7
  },
8
- "linear": {
9
- "command": "npx",
10
- "args": ["-y", "mcp-remote", "https://mcp.linear.app/mcp"],
11
- "description": "Linear issue tracking via OAuth"
12
- },
13
- "Atlassian": {
14
- "command": "npx",
15
- "args": ["-y", "mcp-remote@latest", "https://mcp.atlassian.com/v1/sse"],
16
- "description": "JIRA/Confluence via OAuth (SSO compatible)"
17
- },
18
8
  "monday": {
19
9
  "command": "npx",
20
10
  "args": ["-y", "@mondaydotcomorg/monday-api-mcp"],
@@ -34,16 +24,6 @@
34
24
  "when": ["Looking up library/framework documentation"],
35
25
  "tools": ["resolve-library-id", "get-library-docs"]
36
26
  },
37
- "linear": {
38
- "when": ["Working with Linear issues (p. linear)"],
39
- "tools": ["list_issues", "get_issue", "create_issue", "update_issue", "create_comment"],
40
- "setup": ["OAuth via browser on first use"]
41
- },
42
- "Atlassian": {
43
- "when": ["Working with JIRA issues (p. jira)", "Corporate SSO environments"],
44
- "tools": ["jira_search_issues", "jira_get_issue", "jira_transition_issue", "jira_update_issue"],
45
- "setup": ["OAuth via browser on first use"]
46
- },
47
27
  "monday": {
48
28
  "when": ["Working with Monday.com boards (p. monday)"],
49
29
  "tools": ["create_item", "delete_item", "get_board_items_by_name", "change_item_column_values"],
@@ -54,5 +34,9 @@
54
34
  "tools": ["search_issues", "get_issue", "create_issue", "update_issue", "list_issues"],
55
35
  "setup": ["Set GITHUB_TOKEN env var with repo scope"]
56
36
  }
37
+ },
38
+ "deprecated": {
39
+ "linear": "Use SDK instead. Set LINEAR_API_KEY env var.",
40
+ "Atlassian": "Use SDK instead. Set JIRA_BASE_URL, JIRA_EMAIL, JIRA_API_TOKEN env vars."
57
41
  }
58
42
  }