jira-pilot 2.1.1 → 2.1.2
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/bin/jira.d.ts +2 -0
- package/dist/bin/jira.js.map +1 -0
- package/dist/src/commands/ai-actions/plan.d.ts +1 -0
- package/dist/src/commands/ai-actions/plan.js +108 -0
- package/dist/src/commands/ai-actions/plan.js.map +1 -0
- package/dist/src/commands/ai-actions/review.d.ts +1 -0
- package/dist/src/commands/ai-actions/review.js +92 -0
- package/dist/src/commands/ai-actions/review.js.map +1 -0
- package/dist/src/commands/ai-actions/standup.d.ts +1 -0
- package/dist/src/commands/ai-actions/standup.js +33 -0
- package/dist/src/commands/ai-actions/standup.js.map +1 -0
- package/dist/src/commands/ai.d.ts +2 -0
- package/dist/src/commands/ai.js +196 -0
- package/dist/src/commands/ai.js.map +1 -0
- package/dist/src/commands/board.d.ts +2 -0
- package/dist/src/commands/board.js +66 -0
- package/dist/src/commands/board.js.map +1 -0
- package/dist/src/commands/bulk.d.ts +2 -0
- package/dist/src/commands/bulk.js +205 -0
- package/dist/src/commands/bulk.js.map +1 -0
- package/dist/src/commands/config.d.ts +2 -0
- package/dist/src/commands/config.js +248 -0
- package/dist/src/commands/config.js.map +1 -0
- package/dist/src/commands/dashboard.d.ts +2 -0
- package/dist/src/commands/dashboard.js +209 -0
- package/dist/src/commands/dashboard.js.map +1 -0
- package/dist/src/commands/filter.d.ts +2 -0
- package/dist/src/commands/filter.js +71 -0
- package/dist/src/commands/filter.js.map +1 -0
- package/dist/src/commands/git.d.ts +2 -0
- package/dist/src/commands/git.js +56 -0
- package/dist/src/commands/git.js.map +1 -0
- package/dist/src/commands/issue-attach.d.ts +2 -0
- package/dist/src/commands/issue-attach.js +41 -0
- package/dist/src/commands/issue-attach.js.map +1 -0
- package/dist/src/commands/issue-pr.d.ts +2 -0
- package/dist/src/commands/issue-pr.js +76 -0
- package/dist/src/commands/issue-pr.js.map +1 -0
- package/dist/src/commands/issue-worklog.d.ts +2 -0
- package/dist/src/commands/issue-worklog.js +83 -0
- package/dist/src/commands/issue-worklog.js.map +1 -0
- package/dist/src/commands/issue.d.ts +2 -0
- package/dist/src/commands/issue.js +1148 -0
- package/dist/src/commands/issue.js.map +1 -0
- package/dist/src/commands/mcp.d.ts +2 -0
- package/dist/src/commands/mcp.js +26 -0
- package/dist/src/commands/mcp.js.map +1 -0
- package/dist/src/commands/project.d.ts +2 -0
- package/dist/src/commands/project.js +53 -0
- package/dist/src/commands/project.js.map +1 -0
- package/dist/src/commands/sprint.d.ts +2 -0
- package/dist/src/commands/sprint.js +240 -0
- package/dist/src/commands/sprint.js.map +1 -0
- package/dist/src/server/mcp-server.d.ts +1 -0
- package/dist/src/server/mcp-server.js +505 -0
- package/dist/src/server/mcp-server.js.map +1 -0
- package/dist/src/services/ai-service.d.ts +12 -0
- package/dist/src/services/ai-service.js +151 -0
- package/dist/src/services/ai-service.js.map +1 -0
- package/dist/src/services/api-service.d.ts +18 -0
- package/dist/src/services/api-service.js +115 -0
- package/dist/src/services/api-service.js.map +1 -0
- package/dist/src/services/config-service.d.ts +6 -0
- package/dist/src/services/config-service.js +17 -0
- package/dist/src/services/config-service.js.map +1 -0
- package/dist/src/types.d.ts +90 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/utils/adf-parser.d.ts +1 -0
- package/dist/src/utils/adf-parser.js +49 -0
- package/dist/src/utils/adf-parser.js.map +1 -0
- package/dist/src/utils/config-store.d.ts +15 -0
- package/dist/src/utils/config-store.js +98 -0
- package/dist/src/utils/config-store.js.map +1 -0
- package/dist/src/utils/config.d.ts +10 -0
- package/dist/src/utils/config.js +67 -0
- package/dist/src/utils/config.js.map +1 -0
- package/dist/src/utils/error-handler.d.ts +10 -0
- package/dist/src/utils/error-handler.js +44 -0
- package/dist/src/utils/error-handler.js.map +1 -0
- package/dist/src/utils/text-to-adf.d.ts +18 -0
- package/dist/src/utils/text-to-adf.js +33 -0
- package/dist/src/utils/text-to-adf.js.map +1 -0
- package/dist/src/utils/validators.d.ts +38 -0
- package/dist/src/utils/validators.js +77 -0
- package/dist/src/utils/validators.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import Table from 'cli-table3';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import enquirer from 'enquirer';
|
|
5
|
+
import { api } from '../services/api-service.js';
|
|
6
|
+
import { handleCommandError } from '../utils/error-handler.js';
|
|
7
|
+
// Utility for status icons
|
|
8
|
+
const getStatusIcon = (status) => {
|
|
9
|
+
const s = status.toLowerCase();
|
|
10
|
+
if (s.includes('done') || s.includes('closed'))
|
|
11
|
+
return '✅';
|
|
12
|
+
if (s.includes('progress'))
|
|
13
|
+
return '🏃';
|
|
14
|
+
if (s.includes('review'))
|
|
15
|
+
return '👀';
|
|
16
|
+
return '📝';
|
|
17
|
+
};
|
|
18
|
+
// Utility for priority icons/colors
|
|
19
|
+
const getPriorityColor = (priority, text) => {
|
|
20
|
+
const p = priority.toLowerCase();
|
|
21
|
+
if (p.includes('highest'))
|
|
22
|
+
return chalk.red.bold(text);
|
|
23
|
+
if (p.includes('high'))
|
|
24
|
+
return chalk.red(text);
|
|
25
|
+
if (p.includes('medium'))
|
|
26
|
+
return chalk.yellow(text);
|
|
27
|
+
if (p.includes('low'))
|
|
28
|
+
return chalk.blue(text);
|
|
29
|
+
return chalk.grey(text);
|
|
30
|
+
};
|
|
31
|
+
export function registerDashboardCommand(program) {
|
|
32
|
+
program
|
|
33
|
+
.command('dashboard')
|
|
34
|
+
.description('Interactive Jira Dashboard')
|
|
35
|
+
.option('-o, --output <format>', 'Output format (json)')
|
|
36
|
+
.action(async (options) => {
|
|
37
|
+
if (options.output === 'json') {
|
|
38
|
+
try {
|
|
39
|
+
const [myIssues, recentIssues] = await Promise.all([
|
|
40
|
+
api.post('/search/jql', {
|
|
41
|
+
jql: 'assignee = currentUser() AND statusCategory != Done ORDER BY priority ASC, updated DESC',
|
|
42
|
+
maxResults: 15,
|
|
43
|
+
fields: ['summary', 'status', 'priority', 'updated']
|
|
44
|
+
}),
|
|
45
|
+
api.post('/search/jql', {
|
|
46
|
+
jql: 'assignee = currentUser() ORDER BY updated DESC',
|
|
47
|
+
maxResults: 5,
|
|
48
|
+
fields: ['summary', 'status', 'updated']
|
|
49
|
+
})
|
|
50
|
+
]);
|
|
51
|
+
console.log(JSON.stringify({
|
|
52
|
+
openIssues: (myIssues.issues || []).map((i) => ({
|
|
53
|
+
key: i.key, summary: i.fields.summary,
|
|
54
|
+
status: i.fields.status?.name, priority: i.fields.priority?.name
|
|
55
|
+
})),
|
|
56
|
+
recentActivity: (recentIssues.issues || []).map((i) => ({
|
|
57
|
+
key: i.key, summary: i.fields.summary,
|
|
58
|
+
status: i.fields.status?.name, updated: i.fields.updated
|
|
59
|
+
}))
|
|
60
|
+
}, null, 2));
|
|
61
|
+
}
|
|
62
|
+
catch (e) {
|
|
63
|
+
console.error(JSON.stringify({ error: e.message }));
|
|
64
|
+
}
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// ── Interactive Dashboard ────────────────────────────
|
|
68
|
+
while (true) {
|
|
69
|
+
console.clear();
|
|
70
|
+
const spinner = ora('Loading dashboard...').start();
|
|
71
|
+
try {
|
|
72
|
+
const myself = await api.get('/myself');
|
|
73
|
+
// Fetch in parallel: my open issues + recently updated
|
|
74
|
+
const [myIssues, recentIssues] = await Promise.all([
|
|
75
|
+
api.post('/search/jql', {
|
|
76
|
+
jql: 'assignee = currentUser() AND statusCategory != Done ORDER BY priority ASC, updated DESC', // Fixed Sort
|
|
77
|
+
maxResults: 15,
|
|
78
|
+
fields: ['summary', 'status', 'priority', 'updated', 'issuetype']
|
|
79
|
+
}),
|
|
80
|
+
api.post('/search/jql', {
|
|
81
|
+
jql: 'assignee = currentUser() ORDER BY updated DESC',
|
|
82
|
+
maxResults: 5,
|
|
83
|
+
fields: ['summary', 'status', 'updated']
|
|
84
|
+
})
|
|
85
|
+
]);
|
|
86
|
+
spinner.stop();
|
|
87
|
+
// ── Header ───────────────────────────────────────────
|
|
88
|
+
console.log(chalk.bold.blue('\n✈️ Jira Pilot Dashboard'));
|
|
89
|
+
console.log(chalk.grey(` User: ${myself.displayName} <${myself.emailAddress}>`));
|
|
90
|
+
console.log('');
|
|
91
|
+
// ── Open Issues Table ────────────────────────────────
|
|
92
|
+
console.log(chalk.bold('📋 Your Open Issues') + chalk.grey(` (${myIssues.total || 0} total)`));
|
|
93
|
+
const issues = myIssues.issues || [];
|
|
94
|
+
if (issues.length > 0) {
|
|
95
|
+
const table = new Table({
|
|
96
|
+
head: [chalk.bold('Key'), chalk.bold('Type'), chalk.bold('Summary'), chalk.bold('Status'), chalk.bold('Priority')]
|
|
97
|
+
});
|
|
98
|
+
issues.forEach((i) => {
|
|
99
|
+
table.push([
|
|
100
|
+
chalk.cyan(i.key),
|
|
101
|
+
i.fields.issuetype?.name || '',
|
|
102
|
+
i.fields.summary ? (i.fields.summary.length > 40 ? i.fields.summary.substring(0, 37) + '...' : i.fields.summary) : '',
|
|
103
|
+
i.fields.status?.name || '',
|
|
104
|
+
getPriorityColor(i.fields.priority?.name || '', i.fields.priority?.name || '')
|
|
105
|
+
]);
|
|
106
|
+
});
|
|
107
|
+
console.log(table.toString());
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
console.log(chalk.green(' 🎉 No open issues — nice work!'));
|
|
111
|
+
}
|
|
112
|
+
console.log('');
|
|
113
|
+
// ── Interactive Menu ─────────────────────────────────
|
|
114
|
+
// Enhancing the selection UI as requested
|
|
115
|
+
const choices = [
|
|
116
|
+
...issues.map((i) => {
|
|
117
|
+
const statusIcon = getStatusIcon(i.fields.status?.name || '');
|
|
118
|
+
const priorityColor = getPriorityColor(i.fields.priority?.name || '', '●');
|
|
119
|
+
const key = chalk.cyan.bold(i.key.padEnd(10));
|
|
120
|
+
const summary = i.fields.summary.substring(0, 45);
|
|
121
|
+
return {
|
|
122
|
+
name: i.key,
|
|
123
|
+
message: `${priorityColor} ${key} ${statusIcon} ${summary}`,
|
|
124
|
+
value: i.key
|
|
125
|
+
};
|
|
126
|
+
}),
|
|
127
|
+
{ role: 'separator' },
|
|
128
|
+
{ name: 'refresh', message: '🔄 Refresh Dashboard' },
|
|
129
|
+
{ name: 'exit', message: '🚪 Exit' }
|
|
130
|
+
];
|
|
131
|
+
const { action } = await enquirer.prompt({
|
|
132
|
+
type: 'select',
|
|
133
|
+
name: 'action',
|
|
134
|
+
message: 'Select an issue to manage:',
|
|
135
|
+
choices: choices
|
|
136
|
+
});
|
|
137
|
+
if (action === 'exit') {
|
|
138
|
+
console.log('Bye! 👋');
|
|
139
|
+
process.exit(0);
|
|
140
|
+
}
|
|
141
|
+
if (action === 'refresh') {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
// Issue Selected: Show Action Menu
|
|
145
|
+
const selectedKey = action;
|
|
146
|
+
const { issueAction } = await enquirer.prompt({
|
|
147
|
+
type: 'select',
|
|
148
|
+
name: 'issueAction',
|
|
149
|
+
message: `Action for ${chalk.cyan(selectedKey)}:`,
|
|
150
|
+
choices: [
|
|
151
|
+
{ name: 'view', message: '📄 View Details' },
|
|
152
|
+
{ name: 'comment', message: '💬 Add Comment' },
|
|
153
|
+
{ name: 'transition', message: '🚀 Transition Status' },
|
|
154
|
+
{ name: 'assign', message: '👤 Assign' },
|
|
155
|
+
{ name: 'back', message: '⬅️ Back to Dashboard' }
|
|
156
|
+
]
|
|
157
|
+
});
|
|
158
|
+
if (issueAction === 'back')
|
|
159
|
+
continue;
|
|
160
|
+
if (issueAction === 'view') {
|
|
161
|
+
const issue = await api.get(`/issue/${selectedKey}`);
|
|
162
|
+
console.log(chalk.bold(`\n${issue.key}: ${issue.fields.summary}`));
|
|
163
|
+
console.log(chalk.grey('────────────────────────────────────────'));
|
|
164
|
+
console.log(`${getStatusIcon(issue.fields.status.name)} ${issue.fields.status.name} | ${getPriorityColor(issue.fields.priority?.name || '', issue.fields.priority?.name || '')}`);
|
|
165
|
+
console.log(`\n${issue.fields.description || chalk.italic('No description')}\n`);
|
|
166
|
+
await pause();
|
|
167
|
+
}
|
|
168
|
+
if (issueAction === 'comment') {
|
|
169
|
+
const { inputComment } = await enquirer.prompt({
|
|
170
|
+
type: 'input',
|
|
171
|
+
name: 'inputComment',
|
|
172
|
+
message: 'Comment:',
|
|
173
|
+
});
|
|
174
|
+
if (inputComment) {
|
|
175
|
+
const { textToADF } = await import('../utils/text-to-adf.js');
|
|
176
|
+
await api.post(`/issue/${selectedKey}/comment`, { body: textToADF(inputComment) });
|
|
177
|
+
console.log(chalk.green('Comment added.'));
|
|
178
|
+
await pause();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (issueAction === 'transition') {
|
|
182
|
+
const transData = await api.get(`/issue/${selectedKey}/transitions`);
|
|
183
|
+
const { transId } = await enquirer.prompt({
|
|
184
|
+
type: 'select',
|
|
185
|
+
name: 'transId',
|
|
186
|
+
message: 'Select Status:',
|
|
187
|
+
choices: transData.transitions.map((t) => ({ name: t.id, message: t.to.name }))
|
|
188
|
+
});
|
|
189
|
+
await api.post(`/issue/${selectedKey}/transitions`, { transition: { id: transId } });
|
|
190
|
+
console.log(chalk.green('Transitioned.'));
|
|
191
|
+
await pause();
|
|
192
|
+
}
|
|
193
|
+
if (issueAction === 'assign') {
|
|
194
|
+
await api.put(`/issue/${selectedKey}/assignee`, { accountId: myself.accountId });
|
|
195
|
+
console.log(chalk.green('Assigned to you.'));
|
|
196
|
+
await pause();
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
catch (e) {
|
|
200
|
+
handleCommandError(spinner, e, 'Dashboard Error');
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
async function pause() {
|
|
207
|
+
await enquirer.prompt({ type: 'input', name: 'cont', message: 'Press Enter to continue...' });
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=dashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../../src/commands/dashboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import Table from 'cli-table3';
|
|
4
|
+
import { ConfigService } from '../services/config-service.js';
|
|
5
|
+
export function registerFilterCommand(program) {
|
|
6
|
+
const filterCmd = new Command('filter')
|
|
7
|
+
.description('Manage saved JQL filters (Local)')
|
|
8
|
+
.addHelpText('after', `
|
|
9
|
+
Examples:
|
|
10
|
+
$ jira filter list
|
|
11
|
+
$ jira filter save "My Bugs" "assignee = currentUser() AND issuetype = Bug"
|
|
12
|
+
$ jira filter delete "My Bugs"
|
|
13
|
+
`);
|
|
14
|
+
filterCmd
|
|
15
|
+
.command('list')
|
|
16
|
+
.description('List saved filters')
|
|
17
|
+
.action(async () => {
|
|
18
|
+
const cfg = ConfigService.getConfig();
|
|
19
|
+
const filters = cfg.filters || {};
|
|
20
|
+
if (Object.keys(filters).length === 0) {
|
|
21
|
+
console.log(chalk.yellow('No local filters saved.'));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const table = new Table({
|
|
25
|
+
head: [chalk.bold('Name'), chalk.bold('JQL')]
|
|
26
|
+
});
|
|
27
|
+
for (const [name, jql] of Object.entries(filters)) {
|
|
28
|
+
table.push([chalk.cyan(name), jql]);
|
|
29
|
+
}
|
|
30
|
+
console.log(table.toString());
|
|
31
|
+
});
|
|
32
|
+
filterCmd
|
|
33
|
+
.command('save')
|
|
34
|
+
.description('Save a JQL filter locally')
|
|
35
|
+
.argument('<name>', 'Filter Name')
|
|
36
|
+
.argument('<jql>', 'JQL Query')
|
|
37
|
+
.action(async (name, jql) => {
|
|
38
|
+
try {
|
|
39
|
+
const cfg = ConfigService.getConfig();
|
|
40
|
+
if (!cfg.filters)
|
|
41
|
+
cfg.filters = {};
|
|
42
|
+
cfg.filters[name] = jql;
|
|
43
|
+
ConfigService.saveConfig(cfg);
|
|
44
|
+
console.log(chalk.green(`Filter "${chalk.bold(name)}" saved.`));
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
console.error(chalk.red(`Failed to save filter: ${e.message}`));
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
filterCmd
|
|
51
|
+
.command('delete')
|
|
52
|
+
.description('Delete a saved filter')
|
|
53
|
+
.argument('<name>', 'Filter Name')
|
|
54
|
+
.action(async (name) => {
|
|
55
|
+
try {
|
|
56
|
+
const cfg = ConfigService.getConfig();
|
|
57
|
+
if (!cfg.filters || !cfg.filters[name]) {
|
|
58
|
+
console.log(chalk.yellow(`Filter "${name}" not found.`));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
delete cfg.filters[name];
|
|
62
|
+
ConfigService.saveConfig(cfg);
|
|
63
|
+
console.log(chalk.green(`Filter "${chalk.bold(name)}" deleted.`));
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
console.error(chalk.red(`Failed to delete filter: ${e.message}`));
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
program.addCommand(filterCmd);
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../../../src/commands/filter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import { api } from '../services/api-service.js';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import enquirer from 'enquirer';
|
|
7
|
+
import { validateIssueKey } from '../utils/validators.js';
|
|
8
|
+
import { handleCommandError } from '../utils/error-handler.js';
|
|
9
|
+
export function registerGitCommand(program) {
|
|
10
|
+
const gitCmd = new Command('git')
|
|
11
|
+
.description('Git integration for Jira');
|
|
12
|
+
gitCmd
|
|
13
|
+
.command('branch')
|
|
14
|
+
.description('Create a git branch from a Jira issue')
|
|
15
|
+
.argument('<issueKey>', 'Jira Issue Key (e.g., PROJ-123)')
|
|
16
|
+
.option('-t, --type <type>', 'Branch type (feature, bugfix, hotfix)', 'feature')
|
|
17
|
+
.action(async (issueKey, options) => {
|
|
18
|
+
const check = validateIssueKey(issueKey);
|
|
19
|
+
if (!check.valid) {
|
|
20
|
+
console.error(chalk.red(check.message));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const spinner = ora(`Fetching issue ${issueKey}...`).start();
|
|
24
|
+
try {
|
|
25
|
+
const issue = await api.get(`/issue/${issueKey}`);
|
|
26
|
+
spinner.stop();
|
|
27
|
+
const summary = issue.fields.summary;
|
|
28
|
+
const sanitizedSummary = summary
|
|
29
|
+
.toLowerCase()
|
|
30
|
+
.replace(/[^a-z0-9]+/g, '-') // Replace non-alphanumeric with hyphen
|
|
31
|
+
.replace(/^-+|-+$/g, ''); // Trim leading/trailing hyphens
|
|
32
|
+
const branchName = `${options.type}/${issueKey}-${sanitizedSummary}`;
|
|
33
|
+
console.log(chalk.blue(`Proposed Branch Name: ${chalk.bold(branchName)}`));
|
|
34
|
+
const { confirm } = await enquirer.prompt({
|
|
35
|
+
type: 'confirm',
|
|
36
|
+
name: 'confirm',
|
|
37
|
+
message: 'Create and switch to this branch?',
|
|
38
|
+
initial: true
|
|
39
|
+
});
|
|
40
|
+
if (confirm) {
|
|
41
|
+
try {
|
|
42
|
+
execSync(`git checkout -b ${branchName}`, { stdio: 'inherit' });
|
|
43
|
+
console.log(chalk.green('\nBranch created and checked out!'));
|
|
44
|
+
}
|
|
45
|
+
catch (gitError) {
|
|
46
|
+
console.error(chalk.red('\nFailed to create branch. Are you in a git repository?'));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
handleCommandError(spinner, e, 'Failed to create branch');
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
program.addCommand(gitCmd);
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../../src/commands/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { api } from '../services/api-service.js';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { validateIssueKey } from '../utils/validators.js';
|
|
7
|
+
import { handleCommandError } from '../utils/error-handler.js';
|
|
8
|
+
// Node 20+ has global FormData and File, but for type safety or older environments:
|
|
9
|
+
// We rely on global FormData.
|
|
10
|
+
export function registerAttachCommand(issueCmd) {
|
|
11
|
+
issueCmd
|
|
12
|
+
.command('attach')
|
|
13
|
+
.description('Attach a file to an issue')
|
|
14
|
+
.argument('<issueKey>', 'Issue Key')
|
|
15
|
+
.argument('<filePath>', 'Path to file')
|
|
16
|
+
.action(async (issueKey, filePath) => {
|
|
17
|
+
const check = validateIssueKey(issueKey);
|
|
18
|
+
if (!check.valid) {
|
|
19
|
+
console.error(chalk.red(check.message));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (!fs.existsSync(filePath)) {
|
|
23
|
+
console.error(chalk.red(`File not found: ${filePath}`));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const spinner = ora(`Uploading ${path.basename(filePath)} to ${issueKey}...`).start();
|
|
27
|
+
try {
|
|
28
|
+
// Use fs.openAsBlob (Node 20+)
|
|
29
|
+
// @ts-ignore - TS might not know openAsBlob if target is old, but engine is Node 20
|
|
30
|
+
const blob = await fs.openAsBlob(filePath);
|
|
31
|
+
const formData = new FormData();
|
|
32
|
+
formData.append('file', blob, path.basename(filePath));
|
|
33
|
+
await api.upload(`/issue/${issueKey}/attachments`, formData);
|
|
34
|
+
spinner.succeed(chalk.green(`Attached ${chalk.bold(path.basename(filePath))} to ${issueKey}`));
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
handleCommandError(spinner, e, 'Failed to attach file');
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=issue-attach.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue-attach.js","sourceRoot":"","sources":["../../../src/commands/issue-attach.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,MAAM,4BAA4B,CAAC;AACjD,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,oFAAoF;AACpF,8BAA8B;AAE9B,MAAM,UAAU,qBAAqB,CAAC,QAAiB;IACnD,QAAQ;SACH,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,2BAA2B,CAAC;SACxC,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC;SACnC,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC;SACtC,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;QACjC,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QAEtE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC,CAAC;YACxD,OAAO;QACX,CAAC;QAED,MAAM,OAAO,GAAG,GAAG,CAAC,aAAa,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;QACtF,IAAI,CAAC;YACD,+BAA+B;YAC/B,oFAAoF;YACpF,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAE3C,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;YAChC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;YAEvD,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,QAAQ,cAAc,EAAE,QAAQ,CAAC,CAAC;YAE7D,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,QAAQ,EAAE,CAAC,CAAC,CAAC;QAEnG,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YACd,kBAAkB,CAAC,OAAO,EAAE,CAAC,EAAE,uBAAuB,CAAC,CAAC;QAC5D,CAAC;IACL,CAAC,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import enquirer from 'enquirer';
|
|
3
|
+
import { api } from '../services/api-service.js';
|
|
4
|
+
import ora from 'ora';
|
|
5
|
+
import { exec } from 'child_process';
|
|
6
|
+
import { promisify } from 'util';
|
|
7
|
+
import { validateIssueKey } from '../utils/validators.js';
|
|
8
|
+
import { handleCommandError } from '../utils/error-handler.js';
|
|
9
|
+
import { parseADF } from '../utils/adf-parser.js';
|
|
10
|
+
const execAsync = promisify(exec);
|
|
11
|
+
export function registerPrCommand(issueCmd) {
|
|
12
|
+
issueCmd
|
|
13
|
+
.command('pr')
|
|
14
|
+
.description('Create a GitHub Pull Request for an issue')
|
|
15
|
+
.argument('<issueKey>', 'Issue Key')
|
|
16
|
+
.action(async (issueKey) => {
|
|
17
|
+
const check = validateIssueKey(issueKey);
|
|
18
|
+
if (!check.valid) {
|
|
19
|
+
console.error(chalk.red(check.message));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const spinner = ora(`Fetching issue ${issueKey}...`).start();
|
|
23
|
+
try {
|
|
24
|
+
// Check if gh CLI is installed
|
|
25
|
+
try {
|
|
26
|
+
await execAsync('gh --version');
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
spinner.fail('GitHub CLI (`gh`) is not installed or not in PATH.');
|
|
30
|
+
console.log(chalk.yellow('Please install GitHub CLI to use this feature: https://cli.github.com/'));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const issue = await api.get(`/issue/${issueKey}?fields=summary,description,issuetype`);
|
|
34
|
+
spinner.stop();
|
|
35
|
+
const summary = issue.fields.summary;
|
|
36
|
+
const description = parseADF(issue.fields.description) || '';
|
|
37
|
+
const type = issue.fields.issuetype.name.toUpperCase();
|
|
38
|
+
// Construct PR Title and Body
|
|
39
|
+
const prTitle = `${issueKey}: ${summary}`;
|
|
40
|
+
const prBody = `## Related Issue\n\n[${issueKey}](${api.domain}/browse/${issueKey})\n\n## Description\n\n${description}\n\n## Type of Change\n\n- [ ] ${type}`;
|
|
41
|
+
console.log(chalk.bold('\nDraft PR Content:'));
|
|
42
|
+
console.log(chalk.cyan('Title: ') + prTitle);
|
|
43
|
+
console.log(chalk.cyan('Body: ') + prBody.substring(0, 100) + '...\n');
|
|
44
|
+
const { confirm } = await enquirer.prompt({
|
|
45
|
+
type: 'confirm',
|
|
46
|
+
name: 'confirm',
|
|
47
|
+
message: 'Create Pull Request with `gh`?',
|
|
48
|
+
initial: true
|
|
49
|
+
});
|
|
50
|
+
if (!confirm) {
|
|
51
|
+
console.log(chalk.yellow('Cancelled.'));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const prSpinner = ora('Running gh pr create...').start();
|
|
55
|
+
// Escape characters for shell is tricky, so we use --title and --body flags carefully.
|
|
56
|
+
// A better approach for robust CLI usage might be to spawn the process with args directly to avoid shell parsing issues.
|
|
57
|
+
// However, execAsync with proper escaping or spawn is needed. For simplicity in this demo, we can use a basic approach
|
|
58
|
+
// or write to a temp file. To be safe, let's just pass them as arguments but be mindful of quotes.
|
|
59
|
+
// For Windows compatibility, this can be complex.
|
|
60
|
+
// Alternative: Interactive mode of gh pr create?
|
|
61
|
+
// `gh pr create --title "..." --body "..."`
|
|
62
|
+
// We will try running interactive mode if we can't easily pass args, but interactive inside a child_process is hard.
|
|
63
|
+
// Let's try passing args.
|
|
64
|
+
// Sanitize title and body for shell execution (basic)
|
|
65
|
+
const safeTitle = prTitle.replace(/"/g, '\\"');
|
|
66
|
+
const safeBody = prBody.replace(/"/g, '\\"');
|
|
67
|
+
const command = `gh pr create --title "${safeTitle}" --body "${safeBody}" --web`;
|
|
68
|
+
await execAsync(command);
|
|
69
|
+
prSpinner.succeed('Pull Request created! (Browser opened)');
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
handleCommandError(spinner, e, 'Failed to create PR');
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=issue-pr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue-pr.js","sourceRoot":"","sources":["../../../src/commands/issue-pr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import Table from 'cli-table3';
|
|
4
|
+
import { api } from '../services/api-service.js';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import { textToADF } from '../utils/text-to-adf.js';
|
|
7
|
+
import { validateIssueKey } from '../utils/validators.js';
|
|
8
|
+
import { handleCommandError } from '../utils/error-handler.js';
|
|
9
|
+
import { parseADF } from '../utils/adf-parser.js';
|
|
10
|
+
export function registerWorklogCommand(issueCmd) {
|
|
11
|
+
const worklogCmd = new Command('worklog')
|
|
12
|
+
.description('Manage worklogs (time tracking)')
|
|
13
|
+
.addHelpText('after', `
|
|
14
|
+
Examples:
|
|
15
|
+
$ jira issue worklog add PROJ-123 2h "Researching API"
|
|
16
|
+
$ jira issue worklog list PROJ-123
|
|
17
|
+
`);
|
|
18
|
+
worklogCmd
|
|
19
|
+
.command('add')
|
|
20
|
+
.description('Add a worklog entry')
|
|
21
|
+
.argument('<issueKey>', 'Issue Key')
|
|
22
|
+
.argument('<timeSpent>', 'Time spent (e.g., 2h, 30m, 1d)')
|
|
23
|
+
.argument('[comment]', 'Worklog comment')
|
|
24
|
+
.action(async (issueKey, timeSpent, comment) => {
|
|
25
|
+
const check = validateIssueKey(issueKey);
|
|
26
|
+
if (!check.valid) {
|
|
27
|
+
console.error(chalk.red(check.message));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const spinner = ora(`Adding worklog to ${issueKey}...`).start();
|
|
31
|
+
try {
|
|
32
|
+
const body = {
|
|
33
|
+
timeSpent: timeSpent
|
|
34
|
+
};
|
|
35
|
+
if (comment) {
|
|
36
|
+
body.comment = textToADF(comment);
|
|
37
|
+
}
|
|
38
|
+
await api.post(`/issue/${issueKey}/worklog`, body);
|
|
39
|
+
spinner.succeed(chalk.green(`Logged ${chalk.bold(timeSpent)} to ${chalk.bold(issueKey)}`));
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
handleCommandError(spinner, e, 'Failed to add worklog');
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
worklogCmd
|
|
46
|
+
.command('list')
|
|
47
|
+
.description('List worklogs for an issue')
|
|
48
|
+
.argument('<issueKey>', 'Issue Key')
|
|
49
|
+
.action(async (issueKey) => {
|
|
50
|
+
const check = validateIssueKey(issueKey);
|
|
51
|
+
if (!check.valid) {
|
|
52
|
+
console.error(chalk.red(check.message));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const spinner = ora(`Fetching worklogs for ${issueKey}...`).start();
|
|
56
|
+
try {
|
|
57
|
+
const data = await api.get(`/issue/${issueKey}/worklog`);
|
|
58
|
+
spinner.stop();
|
|
59
|
+
if (!data.worklogs || data.worklogs.length === 0) {
|
|
60
|
+
console.log(chalk.yellow(`No worklogs found for ${issueKey}.`));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
console.log(chalk.bold(`\nWorklogs for ${chalk.cyan(issueKey)}:`));
|
|
64
|
+
const table = new Table({
|
|
65
|
+
head: [chalk.bold('Author'), chalk.bold('Time Spent'), chalk.bold('Date'), chalk.bold('Comment')]
|
|
66
|
+
});
|
|
67
|
+
data.worklogs.forEach((w) => {
|
|
68
|
+
table.push([
|
|
69
|
+
w.author?.displayName || 'Unknown',
|
|
70
|
+
w.timeSpent,
|
|
71
|
+
w.started.split('T')[0],
|
|
72
|
+
w.comment ? (parseADF(w.comment)?.substring(0, 50) + '...') : ''
|
|
73
|
+
]);
|
|
74
|
+
});
|
|
75
|
+
console.log(table.toString());
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
handleCommandError(spinner, e, 'Failed to list worklogs');
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
issueCmd.addCommand(worklogCmd);
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=issue-worklog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue-worklog.js","sourceRoot":"","sources":["../../../src/commands/issue-worklog.ts"],"names":[],"mappings":"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"}
|