linear-cli-agents 0.4.1 → 0.5.1

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.
@@ -0,0 +1,676 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { success, print } from '../lib/output.js';
3
+ const COMMANDS = {
4
+ // Authentication
5
+ 'auth login': {
6
+ description: 'Authenticate with Linear',
7
+ flags: {
8
+ token: { type: 'string', description: 'API token (or enter interactively)' },
9
+ },
10
+ examples: ['linear auth login', 'linear auth login --token lin_api_xxx'],
11
+ },
12
+ 'auth logout': {
13
+ description: 'Remove stored credentials',
14
+ flags: {},
15
+ examples: ['linear auth logout'],
16
+ },
17
+ 'auth status': {
18
+ description: 'Check authentication status',
19
+ flags: {},
20
+ examples: ['linear auth status'],
21
+ },
22
+ // Issues
23
+ 'issues list': {
24
+ description: 'List issues with optional filters',
25
+ flags: {
26
+ format: { type: 'string', options: ['json', 'table', 'plain'], default: 'json' },
27
+ first: { type: 'number', description: 'Number of results (default: 50)' },
28
+ after: { type: 'string', description: 'Pagination cursor' },
29
+ filter: { type: 'string', description: 'JSON filter object' },
30
+ team: { type: 'string', description: 'Team key (e.g., ENG)' },
31
+ state: { type: 'string', description: 'State name filter' },
32
+ assignee: { type: 'string', description: 'Assignee name filter' },
33
+ },
34
+ examples: [
35
+ 'linear issues list',
36
+ 'linear issues list --team MITO',
37
+ 'linear issues list --state "In Progress"',
38
+ 'linear issues list --filter \'{"priority":{"lte":2}}\'',
39
+ ],
40
+ },
41
+ 'issues get': {
42
+ description: 'Get issue details',
43
+ args: { id: { description: 'Issue ID or identifier (e.g., ENG-123)', required: true } },
44
+ flags: {
45
+ format: { type: 'string', options: ['json', 'table', 'plain'], default: 'json' },
46
+ },
47
+ examples: ['linear issues get ENG-123', 'linear issues get abc123-uuid'],
48
+ },
49
+ 'issues create': {
50
+ description: 'Create a new issue',
51
+ flags: {
52
+ input: { type: 'string', description: 'JSON input (IssueCreateInput)' },
53
+ title: { type: 'string', description: 'Issue title', required: true },
54
+ 'team-id': { type: 'string', description: 'Team ID (uses default if configured)' },
55
+ description: { type: 'string', char: 'd', description: 'Description (markdown)' },
56
+ priority: { type: 'number', description: '0=none, 1=urgent, 2=high, 3=medium, 4=low' },
57
+ 'assignee-id': { type: 'string', description: 'Assignee user ID' },
58
+ 'state-id': { type: 'string', description: 'Workflow state ID' },
59
+ 'project-id': { type: 'string', description: 'Project ID' },
60
+ estimate: { type: 'number', description: 'Story points' },
61
+ 'label-ids': { type: 'string', description: 'Comma-separated label IDs' },
62
+ },
63
+ examples: [
64
+ 'linear issues create --title "Fix bug" --team-id xxx',
65
+ 'linear issues create --title "Task" --team-id xxx --priority 2',
66
+ 'linear issues create --input \'{"title":"Bug","teamId":"xxx"}\'',
67
+ ],
68
+ },
69
+ 'issues update': {
70
+ description: 'Update an existing issue',
71
+ args: { id: { description: 'Issue ID or identifier', required: true } },
72
+ flags: {
73
+ input: { type: 'string', description: 'JSON input (IssueUpdateInput)' },
74
+ title: { type: 'string', description: 'New title' },
75
+ description: { type: 'string', char: 'd', description: 'New description' },
76
+ priority: { type: 'number', description: 'New priority' },
77
+ 'assignee-id': { type: 'string', description: 'New assignee (empty to unassign)' },
78
+ 'state-id': { type: 'string', description: 'New state ID' },
79
+ 'project-id': { type: 'string', description: 'New project ID' },
80
+ estimate: { type: 'number', description: 'New estimate' },
81
+ 'label-ids': { type: 'string', description: 'Replace labels (comma-separated)' },
82
+ },
83
+ examples: [
84
+ 'linear issues update ENG-123 --title "Updated title"',
85
+ 'linear issues update ENG-123 --state-id xxx --priority 1',
86
+ ],
87
+ },
88
+ 'issues delete': {
89
+ description: 'Delete an issue',
90
+ args: { id: { description: 'Issue ID or identifier', required: true } },
91
+ flags: {},
92
+ examples: ['linear issues delete ENG-123'],
93
+ },
94
+ 'issues archive': {
95
+ description: 'Archive an issue',
96
+ args: { id: { description: 'Issue ID or identifier', required: true } },
97
+ flags: {},
98
+ examples: ['linear issues archive ENG-123'],
99
+ },
100
+ 'issues add-labels': {
101
+ description: 'Add labels to an issue',
102
+ args: { id: { description: 'Issue ID or identifier', required: true } },
103
+ flags: {
104
+ 'label-ids': { type: 'string', description: 'Comma-separated label IDs', required: true },
105
+ },
106
+ examples: ['linear issues add-labels ENG-123 --label-ids LABEL1,LABEL2'],
107
+ },
108
+ 'issues remove-labels': {
109
+ description: 'Remove labels from an issue',
110
+ args: { id: { description: 'Issue ID or identifier', required: true } },
111
+ flags: {
112
+ 'label-ids': { type: 'string', description: 'Comma-separated label IDs', required: true },
113
+ },
114
+ examples: ['linear issues remove-labels ENG-123 --label-ids LABEL1'],
115
+ },
116
+ 'issues bulk-update': {
117
+ description: 'Update multiple issues at once',
118
+ flags: {
119
+ ids: { type: 'string', description: 'Comma-separated issue IDs or identifiers', required: true },
120
+ 'state-id': { type: 'string', description: 'New state ID' },
121
+ priority: { type: 'number', description: 'New priority' },
122
+ 'assignee-id': { type: 'string', description: 'New assignee' },
123
+ 'project-id': { type: 'string', description: 'New project ID' },
124
+ },
125
+ examples: [
126
+ 'linear issues bulk-update --ids ENG-1,ENG-2,ENG-3 --state-id xxx',
127
+ 'linear issues bulk-update --ids ENG-1,ENG-2 --priority 2',
128
+ ],
129
+ },
130
+ 'issues bulk-label': {
131
+ description: 'Add or remove labels from multiple issues',
132
+ flags: {
133
+ ids: { type: 'string', description: 'Comma-separated issue IDs', required: true },
134
+ 'add-labels': { type: 'string', description: 'Label IDs to add' },
135
+ 'remove-labels': { type: 'string', description: 'Label IDs to remove' },
136
+ },
137
+ examples: [
138
+ 'linear issues bulk-label --ids ENG-1,ENG-2 --add-labels LABEL1,LABEL2',
139
+ 'linear issues bulk-label --ids ENG-1,ENG-2 --remove-labels LABEL1',
140
+ ],
141
+ },
142
+ // Projects
143
+ 'projects list': {
144
+ description: 'List projects',
145
+ flags: {
146
+ format: { type: 'string', options: ['json', 'table', 'plain'], default: 'json' },
147
+ first: { type: 'number', description: 'Number of results' },
148
+ after: { type: 'string', description: 'Pagination cursor' },
149
+ },
150
+ examples: ['linear projects list'],
151
+ },
152
+ 'projects get': {
153
+ description: 'Get project details',
154
+ args: { id: { description: 'Project ID', required: true } },
155
+ flags: { format: { type: 'string', options: ['json', 'table', 'plain'], default: 'json' } },
156
+ examples: ['linear projects get PROJECT_ID'],
157
+ },
158
+ 'projects create': {
159
+ description: 'Create a project',
160
+ flags: {
161
+ name: { type: 'string', char: 'n', description: 'Project name', required: true },
162
+ description: { type: 'string', char: 'd', description: 'Project description' },
163
+ state: { type: 'string', options: ['planned', 'started', 'paused', 'completed', 'canceled'] },
164
+ 'team-ids': { type: 'string', description: 'Team IDs (uses default if configured)' },
165
+ 'lead-id': { type: 'string', description: 'Lead user ID' },
166
+ 'start-date': { type: 'string', description: 'Start date (YYYY-MM-DD)' },
167
+ 'target-date': { type: 'string', description: 'Target date (YYYY-MM-DD)' },
168
+ },
169
+ examples: [
170
+ 'linear projects create --name "My Project" --team-ids TEAM_ID',
171
+ 'linear projects create --name "Q1" --target-date 2024-03-31',
172
+ ],
173
+ },
174
+ 'projects update': {
175
+ description: 'Update a project',
176
+ args: { id: { description: 'Project ID', required: true } },
177
+ flags: {
178
+ name: { type: 'string', description: 'New name' },
179
+ description: { type: 'string', description: 'New description' },
180
+ state: { type: 'string', options: ['planned', 'started', 'paused', 'completed', 'canceled'] },
181
+ },
182
+ examples: ['linear projects update PROJECT_ID --name "New Name"'],
183
+ },
184
+ 'projects delete': {
185
+ description: 'Delete a project',
186
+ args: { id: { description: 'Project ID', required: true } },
187
+ flags: {},
188
+ examples: ['linear projects delete PROJECT_ID'],
189
+ },
190
+ 'projects archive': {
191
+ description: 'Archive a project',
192
+ args: { id: { description: 'Project ID', required: true } },
193
+ flags: {},
194
+ examples: ['linear projects archive PROJECT_ID'],
195
+ },
196
+ // Teams
197
+ 'teams list': {
198
+ description: 'List teams',
199
+ flags: { format: { type: 'string', options: ['json', 'table', 'plain'], default: 'json' } },
200
+ examples: ['linear teams list'],
201
+ },
202
+ // Users
203
+ 'users list': {
204
+ description: 'List users',
205
+ flags: { format: { type: 'string', options: ['json', 'table', 'plain'], default: 'json' } },
206
+ examples: ['linear users list'],
207
+ },
208
+ 'users get': {
209
+ description: 'Get user details',
210
+ args: { id: { description: 'User ID', required: true } },
211
+ flags: { format: { type: 'string', options: ['json', 'table', 'plain'], default: 'json' } },
212
+ examples: ['linear users get USER_ID'],
213
+ },
214
+ // Labels
215
+ 'labels list': {
216
+ description: 'List labels',
217
+ flags: {
218
+ format: { type: 'string', options: ['json', 'table', 'plain'], default: 'json' },
219
+ 'team-id': { type: 'string', description: 'Filter by team' },
220
+ },
221
+ examples: ['linear labels list', 'linear labels list --team-id TEAM_ID'],
222
+ },
223
+ 'labels create': {
224
+ description: 'Create a label',
225
+ flags: {
226
+ name: { type: 'string', description: 'Label name', required: true },
227
+ color: { type: 'string', description: 'Label color (hex)', required: true },
228
+ 'team-id': { type: 'string', description: 'Team ID' },
229
+ description: { type: 'string', description: 'Label description' },
230
+ },
231
+ examples: ['linear labels create --name "bug" --color "#ff0000"'],
232
+ },
233
+ 'labels update': {
234
+ description: 'Update a label',
235
+ args: { id: { description: 'Label ID', required: true } },
236
+ flags: {
237
+ name: { type: 'string', description: 'New name' },
238
+ color: { type: 'string', description: 'New color' },
239
+ },
240
+ examples: ['linear labels update LABEL_ID --name "Bug"'],
241
+ },
242
+ 'labels delete': {
243
+ description: 'Delete a label',
244
+ args: { id: { description: 'Label ID', required: true } },
245
+ flags: {},
246
+ examples: ['linear labels delete LABEL_ID'],
247
+ },
248
+ // States
249
+ 'states list': {
250
+ description: 'List workflow states',
251
+ flags: {
252
+ format: { type: 'string', options: ['json', 'table', 'plain'], default: 'json' },
253
+ 'team-id': { type: 'string', description: 'Filter by team' },
254
+ },
255
+ examples: ['linear states list', 'linear states list --team-id TEAM_ID'],
256
+ },
257
+ // Comments
258
+ 'comments list': {
259
+ description: 'List comments on an issue',
260
+ flags: {
261
+ 'issue-id': { type: 'string', description: 'Issue ID', required: true },
262
+ format: { type: 'string', options: ['json', 'table', 'plain'], default: 'json' },
263
+ },
264
+ examples: ['linear comments list --issue-id ISSUE_ID'],
265
+ },
266
+ 'comments add': {
267
+ description: 'Add a comment to an issue',
268
+ flags: {
269
+ 'issue-id': { type: 'string', description: 'Issue ID', required: true },
270
+ body: { type: 'string', description: 'Comment body (markdown)', required: true },
271
+ },
272
+ examples: ['linear comments add --issue-id ISSUE_ID --body "Comment text"'],
273
+ },
274
+ 'comments update': {
275
+ description: 'Update a comment',
276
+ args: { id: { description: 'Comment ID', required: true } },
277
+ flags: { body: { type: 'string', description: 'New body', required: true } },
278
+ examples: ['linear comments update COMMENT_ID --body "Updated text"'],
279
+ },
280
+ 'comments delete': {
281
+ description: 'Delete a comment',
282
+ args: { id: { description: 'Comment ID', required: true } },
283
+ flags: {},
284
+ examples: ['linear comments delete COMMENT_ID'],
285
+ },
286
+ // Relations
287
+ 'relations list': {
288
+ description: 'List issue relations',
289
+ args: { id: { description: 'Issue ID', required: true } },
290
+ flags: { format: { type: 'string', options: ['json', 'table', 'plain'], default: 'json' } },
291
+ examples: ['linear relations list ENG-123'],
292
+ },
293
+ 'relations create': {
294
+ description: 'Create issue relation',
295
+ flags: {
296
+ 'issue-id': { type: 'string', description: 'Source issue ID', required: true },
297
+ 'related-issue-id': { type: 'string', description: 'Related issue ID', required: true },
298
+ type: { type: 'string', options: ['blocks', 'blocked_by', 'related', 'duplicate'], required: true },
299
+ },
300
+ examples: ['linear relations create --issue-id ENG-1 --related-issue-id ENG-2 --type blocks'],
301
+ },
302
+ 'relations delete': {
303
+ description: 'Delete issue relation',
304
+ args: { id: { description: 'Relation ID', required: true } },
305
+ flags: {},
306
+ examples: ['linear relations delete RELATION_ID'],
307
+ },
308
+ // Milestones
309
+ 'milestones list': {
310
+ description: 'List project milestones',
311
+ flags: {
312
+ 'project-id': { type: 'string', description: 'Project ID', required: true },
313
+ format: { type: 'string', options: ['json', 'table', 'plain'], default: 'json' },
314
+ },
315
+ examples: ['linear milestones list --project-id PROJECT_ID'],
316
+ },
317
+ 'milestones get': {
318
+ description: 'Get milestone details',
319
+ args: { id: { description: 'Milestone ID', required: true } },
320
+ flags: {},
321
+ examples: ['linear milestones get MILESTONE_ID'],
322
+ },
323
+ 'milestones create': {
324
+ description: 'Create a milestone',
325
+ flags: {
326
+ 'project-id': { type: 'string', description: 'Project ID', required: true },
327
+ name: { type: 'string', description: 'Milestone name', required: true },
328
+ description: { type: 'string', description: 'Description' },
329
+ 'target-date': { type: 'string', description: 'Target date (YYYY-MM-DD)' },
330
+ },
331
+ examples: ['linear milestones create --project-id xxx --name "Alpha"'],
332
+ },
333
+ 'milestones update': {
334
+ description: 'Update a milestone',
335
+ args: { id: { description: 'Milestone ID', required: true } },
336
+ flags: {
337
+ name: { type: 'string', description: 'New name' },
338
+ description: { type: 'string', description: 'New description' },
339
+ },
340
+ examples: ['linear milestones update MILESTONE_ID --name "Beta"'],
341
+ },
342
+ // Project Updates
343
+ 'project-updates list': {
344
+ description: 'List project status updates',
345
+ flags: {
346
+ 'project-id': { type: 'string', description: 'Project ID', required: true },
347
+ format: { type: 'string', options: ['json', 'table', 'plain'], default: 'json' },
348
+ },
349
+ examples: ['linear project-updates list --project-id PROJECT_ID'],
350
+ },
351
+ 'project-updates get': {
352
+ description: 'Get project update details',
353
+ args: { id: { description: 'Update ID', required: true } },
354
+ flags: {},
355
+ examples: ['linear project-updates get UPDATE_ID'],
356
+ },
357
+ 'project-updates create': {
358
+ description: 'Create a project status update',
359
+ flags: {
360
+ 'project-id': { type: 'string', description: 'Project ID', required: true },
361
+ body: { type: 'string', description: 'Update body (markdown)', required: true },
362
+ health: { type: 'string', options: ['onTrack', 'atRisk', 'offTrack'] },
363
+ },
364
+ examples: ['linear project-updates create --project-id xxx --body "Progress update"'],
365
+ },
366
+ 'project-updates update': {
367
+ description: 'Update a project status update',
368
+ args: { id: { description: 'Update ID', required: true } },
369
+ flags: {
370
+ body: { type: 'string', description: 'New body' },
371
+ health: { type: 'string', options: ['onTrack', 'atRisk', 'offTrack'] },
372
+ },
373
+ examples: ['linear project-updates update UPDATE_ID --health atRisk'],
374
+ },
375
+ // Templates
376
+ 'templates list': {
377
+ description: 'List issue templates',
378
+ flags: {
379
+ 'team-id': { type: 'string', description: 'Team ID' },
380
+ format: { type: 'string', options: ['json', 'table', 'plain'], default: 'json' },
381
+ },
382
+ examples: ['linear templates list'],
383
+ },
384
+ 'templates get': {
385
+ description: 'Get template details',
386
+ args: { id: { description: 'Template ID', required: true } },
387
+ flags: {},
388
+ examples: ['linear templates get TEMPLATE_ID'],
389
+ },
390
+ 'templates create': {
391
+ description: 'Create an issue template',
392
+ flags: {
393
+ 'team-id': { type: 'string', description: 'Team ID', required: true },
394
+ name: { type: 'string', description: 'Template name', required: true },
395
+ description: { type: 'string', description: 'Template description' },
396
+ },
397
+ examples: ['linear templates create --team-id xxx --name "Bug Report"'],
398
+ },
399
+ 'templates update': {
400
+ description: 'Update a template',
401
+ args: { id: { description: 'Template ID', required: true } },
402
+ flags: {
403
+ name: { type: 'string', description: 'New name' },
404
+ description: { type: 'string', description: 'New description' },
405
+ },
406
+ examples: ['linear templates update TEMPLATE_ID --name "New Name"'],
407
+ },
408
+ // Config
409
+ 'config set': {
410
+ description: 'Set a configuration value',
411
+ args: {
412
+ key: { description: 'Config key', required: true },
413
+ value: { description: 'Config value', required: true },
414
+ },
415
+ flags: {},
416
+ examples: [
417
+ 'linear config set default-team-id TEAM_UUID',
418
+ 'linear config set default-team-key MITO',
419
+ ],
420
+ },
421
+ 'config get': {
422
+ description: 'Get a configuration value',
423
+ args: { key: { description: 'Config key', required: true } },
424
+ flags: {},
425
+ examples: ['linear config get default-team-id'],
426
+ },
427
+ 'config list': {
428
+ description: 'List all configuration values',
429
+ flags: {},
430
+ examples: ['linear config list'],
431
+ },
432
+ // Other
433
+ me: {
434
+ description: 'Get current user info',
435
+ flags: { format: { type: 'string', options: ['json', 'table', 'plain'], default: 'json' } },
436
+ examples: ['linear me'],
437
+ },
438
+ search: {
439
+ description: 'Search for issues',
440
+ args: { query: { description: 'Search query', required: true } },
441
+ flags: {
442
+ format: { type: 'string', options: ['json', 'table', 'plain'], default: 'json' },
443
+ first: { type: 'number', description: 'Number of results' },
444
+ },
445
+ examples: ['linear search "bug fix"'],
446
+ },
447
+ open: {
448
+ description: 'Open issue/project in browser',
449
+ args: { id: { description: 'Issue identifier (e.g., ENG-123)', required: true } },
450
+ flags: {},
451
+ examples: ['linear open ENG-123'],
452
+ },
453
+ query: {
454
+ description: 'Execute raw GraphQL query',
455
+ flags: {
456
+ query: { type: 'string', char: 'q', description: 'GraphQL query', required: true },
457
+ variables: { type: 'string', char: 'v', description: 'JSON variables' },
458
+ },
459
+ examples: ['linear query --query "{ viewer { id name } }"'],
460
+ },
461
+ schema: {
462
+ description: 'Show entity schema info',
463
+ args: { entity: { description: 'Entity name (issues, projects, etc.)' } },
464
+ flags: {
465
+ full: { type: 'boolean', description: 'Show full schema for all entities' },
466
+ 'include-examples': { type: 'boolean', description: 'Include usage examples' },
467
+ },
468
+ examples: ['linear schema', 'linear schema issues', 'linear schema --full'],
469
+ },
470
+ info: {
471
+ description: 'Show comprehensive CLI documentation (this command)',
472
+ flags: {
473
+ compact: { type: 'boolean', description: 'Compact output (fewer examples)' },
474
+ },
475
+ examples: ['linear info', 'linear info --compact'],
476
+ },
477
+ setup: {
478
+ description: 'Add Linear CLI instructions to your CLAUDE.md',
479
+ flags: {
480
+ remove: { type: 'boolean', description: 'Remove the section instead' },
481
+ },
482
+ examples: ['linear setup', 'linear setup --remove'],
483
+ },
484
+ };
485
+ const ENTITY_SCHEMAS = {
486
+ issues: {
487
+ entity: 'issues',
488
+ operations: ['list', 'get', 'create', 'update', 'delete', 'archive', 'add-labels', 'remove-labels', 'bulk-update', 'bulk-label'],
489
+ description: 'Work items (bugs, features, tasks)',
490
+ fields: {
491
+ id: 'Unique identifier',
492
+ identifier: 'Human-readable (e.g., ENG-123)',
493
+ title: 'Issue title',
494
+ description: 'Markdown description',
495
+ priority: '0=none, 1=urgent, 2=high, 3=medium, 4=low',
496
+ state: 'Workflow state',
497
+ assignee: 'Assigned user',
498
+ labels: 'Issue labels',
499
+ project: 'Parent project',
500
+ url: 'Linear URL',
501
+ },
502
+ },
503
+ projects: {
504
+ entity: 'projects',
505
+ operations: ['list', 'get', 'create', 'update', 'delete', 'archive'],
506
+ description: 'Group related issues',
507
+ fields: {
508
+ id: 'Unique identifier',
509
+ name: 'Project name',
510
+ description: 'Project description',
511
+ state: 'planned/started/paused/completed/canceled',
512
+ progress: 'Completion percentage',
513
+ startDate: 'Start date',
514
+ targetDate: 'Target date',
515
+ lead: 'Project lead',
516
+ teams: 'Associated teams',
517
+ },
518
+ },
519
+ teams: {
520
+ entity: 'teams',
521
+ operations: ['list'],
522
+ description: 'Organize members and issues',
523
+ fields: {
524
+ id: 'Unique identifier',
525
+ key: 'Team key (e.g., ENG)',
526
+ name: 'Team name',
527
+ },
528
+ },
529
+ users: {
530
+ entity: 'users',
531
+ operations: ['list', 'get', 'me'],
532
+ description: 'Workspace members',
533
+ fields: {
534
+ id: 'Unique identifier',
535
+ name: 'User name',
536
+ email: 'User email',
537
+ displayName: 'Display name',
538
+ },
539
+ },
540
+ labels: {
541
+ entity: 'labels',
542
+ operations: ['list', 'create', 'update', 'delete'],
543
+ description: 'Categorize issues',
544
+ fields: {
545
+ id: 'Unique identifier',
546
+ name: 'Label name',
547
+ color: 'Hex color',
548
+ },
549
+ },
550
+ states: {
551
+ entity: 'states',
552
+ operations: ['list'],
553
+ description: 'Workflow states',
554
+ fields: {
555
+ id: 'Unique identifier',
556
+ name: 'State name',
557
+ type: 'backlog/unstarted/started/completed/canceled',
558
+ color: 'Hex color',
559
+ },
560
+ },
561
+ comments: {
562
+ entity: 'comments',
563
+ operations: ['list', 'add', 'update', 'delete'],
564
+ description: 'Comments on issues',
565
+ fields: {
566
+ id: 'Unique identifier',
567
+ body: 'Markdown body',
568
+ createdAt: 'Creation timestamp',
569
+ },
570
+ },
571
+ };
572
+ const WORKFLOWS = {
573
+ createIssue: {
574
+ description: 'Create a new issue',
575
+ steps: [
576
+ '1. Get team ID: linear teams list',
577
+ '2. (Optional) Get state ID: linear states list --team-id TEAM_ID',
578
+ '3. (Optional) Get label IDs: linear labels list --team-id TEAM_ID',
579
+ '4. Create issue: linear issues create --title "Title" --team-id TEAM_ID',
580
+ ],
581
+ },
582
+ updateIssueState: {
583
+ description: 'Change issue status',
584
+ steps: [
585
+ '1. Get state ID: linear states list --team-id TEAM_ID',
586
+ '2. Update issue: linear issues update ENG-123 --state-id STATE_ID',
587
+ ],
588
+ },
589
+ bulkUpdateIssues: {
590
+ description: 'Update multiple issues at once',
591
+ steps: [
592
+ '1. Get state ID (if needed): linear states list --team-id TEAM_ID',
593
+ '2. Bulk update: linear issues bulk-update --ids ENG-1,ENG-2,ENG-3 --state-id STATE_ID',
594
+ ],
595
+ },
596
+ assignLabels: {
597
+ description: 'Add labels to issues',
598
+ steps: [
599
+ '1. Get label IDs: linear labels list --team-id TEAM_ID',
600
+ '2. Add labels: linear issues add-labels ENG-123 --label-ids LABEL1,LABEL2',
601
+ ],
602
+ },
603
+ createProject: {
604
+ description: 'Create a new project',
605
+ steps: [
606
+ '1. Get team ID: linear teams list',
607
+ '2. Create project: linear projects create --name "Project" --team-ids TEAM_ID',
608
+ ],
609
+ },
610
+ };
611
+ const CONFIG_KEYS = {
612
+ 'default-team-id': {
613
+ description: 'Default team UUID for issue/project creation',
614
+ example: 'd1ad1a80-9267-4ebc-979a-eaf885898a2c',
615
+ },
616
+ 'default-team-key': {
617
+ description: 'Default team key for reference',
618
+ example: 'MITO',
619
+ },
620
+ };
621
+ export default class Info extends Command {
622
+ static description = 'Show comprehensive CLI documentation for LLM agents';
623
+ static examples = [
624
+ '<%= config.bin %> info',
625
+ '<%= config.bin %> info --compact',
626
+ '<%= config.bin %> info | jq .data.commands',
627
+ ];
628
+ static flags = {
629
+ compact: Flags.boolean({
630
+ description: 'Compact output with fewer examples',
631
+ default: false,
632
+ }),
633
+ };
634
+ async run() {
635
+ const { flags } = await this.parse(Info);
636
+ if (flags.compact) {
637
+ // Compact version: command list with descriptions only
638
+ const compactCommands = Object.entries(COMMANDS).reduce((acc, [name, cmd]) => {
639
+ acc[name] = {
640
+ description: cmd.description,
641
+ ...(cmd.args && { args: cmd.args }),
642
+ flags: cmd.flags,
643
+ };
644
+ return acc;
645
+ }, {});
646
+ print(success({
647
+ version: '0.5.1',
648
+ commands: compactCommands,
649
+ configKeys: CONFIG_KEYS,
650
+ note: 'Use "linear info" for full documentation with examples and workflows',
651
+ }));
652
+ return;
653
+ }
654
+ // Full documentation
655
+ print(success({
656
+ version: '0.5.1',
657
+ overview: {
658
+ description: 'CLI for interacting with Linear, designed for LLMs and agents',
659
+ authentication: 'Run "linear auth login" or set LINEAR_API_KEY environment variable',
660
+ outputFormat: 'All commands output JSON by default. Use --format for table/plain.',
661
+ defaults: 'Configure default team with "linear config set default-team-id TEAM_ID"',
662
+ },
663
+ commands: COMMANDS,
664
+ schemas: ENTITY_SCHEMAS,
665
+ workflows: WORKFLOWS,
666
+ configKeys: CONFIG_KEYS,
667
+ tips: [
668
+ 'Use issue identifiers (ENG-123) instead of UUIDs when possible',
669
+ 'Set default-team-id to skip --team-id on every create command',
670
+ 'Use --format plain for scripting (outputs only IDs)',
671
+ 'Use bulk-update and bulk-label for batch operations',
672
+ 'Pipe to jq for JSON processing: linear issues list | jq ".data[].identifier"',
673
+ ],
674
+ }));
675
+ }
676
+ }