issy 0.1.0 → 0.1.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.
- package/package.json +5 -4
- package/src/cli.ts +317 -303
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "issy",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "AI-native issue tracking. Markdown files in .issues/, managed by your coding assistant.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,10 +25,11 @@
|
|
|
25
25
|
"src"
|
|
26
26
|
],
|
|
27
27
|
"scripts": {
|
|
28
|
-
"cli": "bun src/cli.ts"
|
|
28
|
+
"cli": "bun src/cli.ts",
|
|
29
|
+
"lint": "biome check src bin"
|
|
29
30
|
},
|
|
30
31
|
"dependencies": {
|
|
31
|
-
"@miketromba/issy-app": "^0.1.
|
|
32
|
-
"@miketromba/issy-core": "^0.1.
|
|
32
|
+
"@miketromba/issy-app": "^0.1.1",
|
|
33
|
+
"@miketromba/issy-core": "^0.1.1"
|
|
33
34
|
}
|
|
34
35
|
}
|
package/src/cli.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
+
|
|
2
3
|
/**
|
|
3
4
|
* issy CLI
|
|
4
5
|
*
|
|
@@ -11,242 +12,255 @@
|
|
|
11
12
|
* issy close <id>
|
|
12
13
|
*/
|
|
13
14
|
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
15
|
+
import { join } from 'node:path'
|
|
16
|
+
import { parseArgs } from 'node:util'
|
|
16
17
|
|
|
17
18
|
// Import shared library (simple relative import since we're in the same package)
|
|
18
19
|
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
} from
|
|
20
|
+
type CreateIssueInput,
|
|
21
|
+
closeIssue,
|
|
22
|
+
createIssue,
|
|
23
|
+
filterAndSearchIssues,
|
|
24
|
+
getAllIssues,
|
|
25
|
+
getIssue,
|
|
26
|
+
setIssuesDir,
|
|
27
|
+
updateIssue
|
|
28
|
+
} from '@miketromba/issy-core'
|
|
28
29
|
|
|
29
30
|
// Initialize issues directory from env or current working directory
|
|
30
|
-
const DEFAULT_ROOT = process.env.ISSUES_ROOT || process.cwd()
|
|
31
|
-
const ISSUES_DIR = process.env.ISSUES_DIR || join(DEFAULT_ROOT,
|
|
32
|
-
setIssuesDir(ISSUES_DIR)
|
|
31
|
+
const DEFAULT_ROOT = process.env.ISSUES_ROOT || process.cwd()
|
|
32
|
+
const ISSUES_DIR = process.env.ISSUES_DIR || join(DEFAULT_ROOT, '.issues')
|
|
33
|
+
setIssuesDir(ISSUES_DIR)
|
|
33
34
|
|
|
34
35
|
// Display helpers
|
|
35
36
|
function prioritySymbol(priority: string): string {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
37
|
+
switch (priority) {
|
|
38
|
+
case 'high':
|
|
39
|
+
return '🔴'
|
|
40
|
+
case 'medium':
|
|
41
|
+
return '🟡'
|
|
42
|
+
case 'low':
|
|
43
|
+
return '🟢'
|
|
44
|
+
default:
|
|
45
|
+
return '⚪'
|
|
46
|
+
}
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
function typeSymbol(type: string): string {
|
|
49
|
-
|
|
50
|
+
return type === 'bug' ? '🐛' : '✨'
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
// Commands
|
|
53
54
|
async function listIssues(options: {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
all?: boolean
|
|
56
|
+
priority?: string
|
|
57
|
+
type?: string
|
|
58
|
+
search?: string
|
|
58
59
|
}) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
60
|
+
const allIssues = await getAllIssues()
|
|
61
|
+
|
|
62
|
+
// Apply filters
|
|
63
|
+
const issues = filterAndSearchIssues(allIssues, {
|
|
64
|
+
status: options.all ? undefined : 'open',
|
|
65
|
+
priority: options.priority,
|
|
66
|
+
type: options.type,
|
|
67
|
+
search: options.search
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
if (issues.length === 0) {
|
|
71
|
+
console.log('No issues found.')
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
console.log('\n ID Pri Type Status Title')
|
|
76
|
+
console.log(` ${'-'.repeat(70)}`)
|
|
77
|
+
|
|
78
|
+
for (const issue of issues) {
|
|
79
|
+
const status = issue.frontmatter.status === 'open' ? 'OPEN ' : 'CLOSED'
|
|
80
|
+
console.log(
|
|
81
|
+
` ${issue.id} ${prioritySymbol(
|
|
82
|
+
issue.frontmatter.priority
|
|
83
|
+
)} ${typeSymbol(
|
|
84
|
+
issue.frontmatter.type
|
|
85
|
+
)} ${status} ${issue.frontmatter.title.slice(0, 45)}`
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
console.log(`\n Total: ${issues.length} issue(s)\n`)
|
|
87
90
|
}
|
|
88
91
|
|
|
89
92
|
async function readIssue(id: string) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
93
|
+
const issue = await getIssue(id)
|
|
94
|
+
|
|
95
|
+
if (!issue) {
|
|
96
|
+
console.error(`Issue not found: ${id}`)
|
|
97
|
+
process.exit(1)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
console.log(`\n${'='.repeat(70)}`)
|
|
101
|
+
console.log(
|
|
102
|
+
` ${typeSymbol(issue.frontmatter.type)} ${issue.frontmatter.title}`
|
|
103
|
+
)
|
|
104
|
+
console.log('='.repeat(70))
|
|
105
|
+
console.log(` ID: ${issue.id}`)
|
|
106
|
+
console.log(` Status: ${issue.frontmatter.status.toUpperCase()}`)
|
|
107
|
+
console.log(
|
|
108
|
+
` Priority: ${prioritySymbol(issue.frontmatter.priority)} ${
|
|
109
|
+
issue.frontmatter.priority
|
|
110
|
+
}`
|
|
111
|
+
)
|
|
112
|
+
console.log(` Type: ${issue.frontmatter.type}`)
|
|
113
|
+
if (issue.frontmatter.labels) {
|
|
114
|
+
console.log(` Labels: ${issue.frontmatter.labels}`)
|
|
115
|
+
}
|
|
116
|
+
console.log(` Created: ${issue.frontmatter.created}`)
|
|
117
|
+
if (issue.frontmatter.updated) {
|
|
118
|
+
console.log(` Updated: ${issue.frontmatter.updated}`)
|
|
119
|
+
}
|
|
120
|
+
console.log('-'.repeat(70))
|
|
121
|
+
console.log(issue.content)
|
|
122
|
+
console.log()
|
|
116
123
|
}
|
|
117
124
|
|
|
118
125
|
async function searchIssuesCommand(query: string, options: { all?: boolean }) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
|
|
126
|
+
const allIssues = await getAllIssues()
|
|
127
|
+
|
|
128
|
+
const issues = filterAndSearchIssues(allIssues, {
|
|
129
|
+
status: options.all ? undefined : 'open',
|
|
130
|
+
search: query
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
if (issues.length === 0) {
|
|
134
|
+
console.log(`No issues found matching "${query}".`)
|
|
135
|
+
return
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
console.log(`\n Search results for "${query}":`)
|
|
139
|
+
console.log('\n ID Pri Type Status Title')
|
|
140
|
+
console.log(` ${'-'.repeat(70)}`)
|
|
141
|
+
|
|
142
|
+
for (const issue of issues) {
|
|
143
|
+
const status = issue.frontmatter.status === 'open' ? 'OPEN ' : 'CLOSED'
|
|
144
|
+
console.log(
|
|
145
|
+
` ${issue.id} ${prioritySymbol(
|
|
146
|
+
issue.frontmatter.priority
|
|
147
|
+
)} ${typeSymbol(
|
|
148
|
+
issue.frontmatter.type
|
|
149
|
+
)} ${status} ${issue.frontmatter.title.slice(0, 45)}`
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
console.log(`\n Found: ${issues.length} issue(s)\n`)
|
|
145
154
|
}
|
|
146
155
|
|
|
147
156
|
async function createIssueCommand(options: {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
157
|
+
title?: string
|
|
158
|
+
description?: string
|
|
159
|
+
priority?: string
|
|
160
|
+
type?: string
|
|
161
|
+
labels?: string
|
|
153
162
|
}) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
163
|
+
// Interactive mode if no title provided
|
|
164
|
+
if (!options.title) {
|
|
165
|
+
console.log('\nCreate New Issue')
|
|
166
|
+
console.log('-'.repeat(40))
|
|
167
|
+
|
|
168
|
+
const prompt = (question: string): Promise<string> => {
|
|
169
|
+
process.stdout.write(question)
|
|
170
|
+
return new Promise(resolve => {
|
|
171
|
+
let input = ''
|
|
172
|
+
process.stdin.setRawMode?.(false)
|
|
173
|
+
process.stdin.resume()
|
|
174
|
+
process.stdin.setEncoding('utf8')
|
|
175
|
+
process.stdin.once('data', data => {
|
|
176
|
+
input = data.toString().trim()
|
|
177
|
+
resolve(input)
|
|
178
|
+
})
|
|
179
|
+
})
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
options.title = await prompt('Title: ')
|
|
183
|
+
options.description = await prompt('Description: ')
|
|
184
|
+
options.priority = await prompt('Priority (high/medium/low) [medium]: ')
|
|
185
|
+
options.type = await prompt('Type (bug/improvement) [improvement]: ')
|
|
186
|
+
options.labels = await prompt('Labels (comma-separated) []: ')
|
|
187
|
+
|
|
188
|
+
// Apply defaults
|
|
189
|
+
if (!options.priority) options.priority = 'medium'
|
|
190
|
+
if (!options.type) options.type = 'improvement'
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (!options.title) {
|
|
194
|
+
console.error('Title is required')
|
|
195
|
+
process.exit(1)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
const input: CreateIssueInput = {
|
|
200
|
+
title: options.title,
|
|
201
|
+
description: options.description,
|
|
202
|
+
priority: options.priority as 'high' | 'medium' | 'low',
|
|
203
|
+
type: options.type as 'bug' | 'improvement',
|
|
204
|
+
labels: options.labels
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const issue = await createIssue(input)
|
|
208
|
+
console.log(`\nCreated issue: ${issue.filename}`)
|
|
209
|
+
} catch (e) {
|
|
210
|
+
console.error(e instanceof Error ? e.message : 'Failed to create issue')
|
|
211
|
+
process.exit(1)
|
|
212
|
+
}
|
|
199
213
|
}
|
|
200
214
|
|
|
201
215
|
async function updateIssueCommand(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
216
|
+
id: string,
|
|
217
|
+
options: {
|
|
218
|
+
title?: string
|
|
219
|
+
description?: string
|
|
220
|
+
priority?: string
|
|
221
|
+
type?: string
|
|
222
|
+
labels?: string
|
|
223
|
+
status?: string
|
|
224
|
+
}
|
|
211
225
|
) {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
+
try {
|
|
227
|
+
const issue = await updateIssue(id, {
|
|
228
|
+
title: options.title,
|
|
229
|
+
description: options.description,
|
|
230
|
+
priority: options.priority as 'high' | 'medium' | 'low' | undefined,
|
|
231
|
+
type: options.type as 'bug' | 'improvement' | undefined,
|
|
232
|
+
labels: options.labels,
|
|
233
|
+
status: options.status as 'open' | 'closed' | undefined
|
|
234
|
+
})
|
|
235
|
+
console.log(`Updated issue: ${issue.filename}`)
|
|
236
|
+
} catch (e) {
|
|
237
|
+
console.error(e instanceof Error ? e.message : 'Failed to update issue')
|
|
238
|
+
process.exit(1)
|
|
239
|
+
}
|
|
226
240
|
}
|
|
227
241
|
|
|
228
242
|
async function closeIssueCommand(id: string) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
243
|
+
try {
|
|
244
|
+
await closeIssue(id)
|
|
245
|
+
console.log('Issue closed.')
|
|
246
|
+
} catch (e) {
|
|
247
|
+
console.error(e instanceof Error ? e.message : 'Failed to close issue')
|
|
248
|
+
process.exit(1)
|
|
249
|
+
}
|
|
236
250
|
}
|
|
237
251
|
|
|
238
252
|
// Main
|
|
239
253
|
async function main() {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
254
|
+
const args = process.argv.slice(2)
|
|
255
|
+
const command = args[0]
|
|
256
|
+
|
|
257
|
+
if (
|
|
258
|
+
!command ||
|
|
259
|
+
command === 'help' ||
|
|
260
|
+
command === '--help' ||
|
|
261
|
+
command === '-h'
|
|
262
|
+
) {
|
|
263
|
+
console.log(`
|
|
250
264
|
issy CLI
|
|
251
265
|
|
|
252
266
|
Usage:
|
|
@@ -290,109 +304,109 @@ Examples:
|
|
|
290
304
|
issy create --title "Fix login bug" --type bug --priority high
|
|
291
305
|
issy update 0001 --priority low
|
|
292
306
|
issy close 0001
|
|
293
|
-
`)
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
307
|
+
`)
|
|
308
|
+
return
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
switch (command) {
|
|
312
|
+
case 'list': {
|
|
313
|
+
const { values } = parseArgs({
|
|
314
|
+
args: args.slice(1),
|
|
315
|
+
options: {
|
|
316
|
+
all: { type: 'boolean', short: 'a' },
|
|
317
|
+
priority: { type: 'string', short: 'p' },
|
|
318
|
+
type: { type: 'string', short: 't' },
|
|
319
|
+
search: { type: 'string', short: 's' }
|
|
320
|
+
},
|
|
321
|
+
allowPositionals: true
|
|
322
|
+
})
|
|
323
|
+
await listIssues(values)
|
|
324
|
+
break
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
case 'search': {
|
|
328
|
+
const query = args[1]
|
|
329
|
+
if (!query) {
|
|
330
|
+
console.error('Usage: issy search <query>')
|
|
331
|
+
process.exit(1)
|
|
332
|
+
}
|
|
333
|
+
const { values } = parseArgs({
|
|
334
|
+
args: args.slice(2),
|
|
335
|
+
options: {
|
|
336
|
+
all: { type: 'boolean', short: 'a' }
|
|
337
|
+
},
|
|
338
|
+
allowPositionals: true
|
|
339
|
+
})
|
|
340
|
+
await searchIssuesCommand(query, values)
|
|
341
|
+
break
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
case 'read': {
|
|
345
|
+
const id = args[1]
|
|
346
|
+
if (!id) {
|
|
347
|
+
console.error('Usage: issy read <id>')
|
|
348
|
+
process.exit(1)
|
|
349
|
+
}
|
|
350
|
+
await readIssue(id)
|
|
351
|
+
break
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
case 'create': {
|
|
355
|
+
const { values } = parseArgs({
|
|
356
|
+
args: args.slice(1),
|
|
357
|
+
options: {
|
|
358
|
+
title: { type: 'string', short: 't' },
|
|
359
|
+
description: { type: 'string', short: 'd' },
|
|
360
|
+
priority: { type: 'string', short: 'p' },
|
|
361
|
+
type: { type: 'string' },
|
|
362
|
+
labels: { type: 'string', short: 'l' }
|
|
363
|
+
},
|
|
364
|
+
allowPositionals: true
|
|
365
|
+
})
|
|
366
|
+
await createIssueCommand(values)
|
|
367
|
+
break
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
case 'update': {
|
|
371
|
+
const id = args[1]
|
|
372
|
+
if (!id) {
|
|
373
|
+
console.error('Usage: issy update <id> [options]')
|
|
374
|
+
process.exit(1)
|
|
375
|
+
}
|
|
376
|
+
const { values } = parseArgs({
|
|
377
|
+
args: args.slice(2),
|
|
378
|
+
options: {
|
|
379
|
+
title: { type: 'string', short: 't' },
|
|
380
|
+
description: { type: 'string', short: 'd' },
|
|
381
|
+
priority: { type: 'string', short: 'p' },
|
|
382
|
+
type: { type: 'string' },
|
|
383
|
+
labels: { type: 'string', short: 'l' },
|
|
384
|
+
status: { type: 'string', short: 's' }
|
|
385
|
+
},
|
|
386
|
+
allowPositionals: true
|
|
387
|
+
})
|
|
388
|
+
await updateIssueCommand(id, values)
|
|
389
|
+
break
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
case 'close': {
|
|
393
|
+
const id = args[1]
|
|
394
|
+
if (!id) {
|
|
395
|
+
console.error('Usage: issy close <id>')
|
|
396
|
+
process.exit(1)
|
|
397
|
+
}
|
|
398
|
+
await closeIssueCommand(id)
|
|
399
|
+
break
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
default:
|
|
403
|
+
console.error(`Unknown command: ${command}`)
|
|
404
|
+
console.log('Run "issy help" for usage.')
|
|
405
|
+
process.exit(1)
|
|
406
|
+
}
|
|
393
407
|
}
|
|
394
408
|
|
|
395
|
-
main().catch(
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
})
|
|
409
|
+
main().catch(err => {
|
|
410
|
+
console.error(err)
|
|
411
|
+
process.exit(1)
|
|
412
|
+
})
|