jira-ai 0.1.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.
Files changed (45) hide show
  1. package/README.md +364 -0
  2. package/dist/cli.js +87 -0
  3. package/dist/commands/about.js +83 -0
  4. package/dist/commands/add-comment.js +109 -0
  5. package/dist/commands/me.js +23 -0
  6. package/dist/commands/project-statuses.js +23 -0
  7. package/dist/commands/projects.js +35 -0
  8. package/dist/commands/run-jql.js +44 -0
  9. package/dist/commands/task-with-details.js +23 -0
  10. package/dist/commands/update-description.js +109 -0
  11. package/dist/lib/formatters.js +193 -0
  12. package/dist/lib/jira-client.js +216 -0
  13. package/dist/lib/settings.js +68 -0
  14. package/dist/lib/utils.js +79 -0
  15. package/jest.config.js +21 -0
  16. package/package.json +47 -0
  17. package/settings.yaml +24 -0
  18. package/src/cli.ts +97 -0
  19. package/src/commands/about.ts +98 -0
  20. package/src/commands/add-comment.ts +94 -0
  21. package/src/commands/me.ts +18 -0
  22. package/src/commands/project-statuses.ts +18 -0
  23. package/src/commands/projects.ts +32 -0
  24. package/src/commands/run-jql.ts +40 -0
  25. package/src/commands/task-with-details.ts +18 -0
  26. package/src/commands/update-description.ts +94 -0
  27. package/src/lib/formatters.ts +224 -0
  28. package/src/lib/jira-client.ts +319 -0
  29. package/src/lib/settings.ts +77 -0
  30. package/src/lib/utils.ts +76 -0
  31. package/src/types/md-to-adf.d.ts +14 -0
  32. package/tests/README.md +97 -0
  33. package/tests/__mocks__/jira.js.ts +4 -0
  34. package/tests/__mocks__/md-to-adf.ts +7 -0
  35. package/tests/__mocks__/mdast-util-from-adf.ts +4 -0
  36. package/tests/__mocks__/mdast-util-to-markdown.ts +1 -0
  37. package/tests/add-comment.test.ts +226 -0
  38. package/tests/cli-permissions.test.ts +156 -0
  39. package/tests/jira-client.test.ts +123 -0
  40. package/tests/projects.test.ts +205 -0
  41. package/tests/settings.test.ts +288 -0
  42. package/tests/task-with-details.test.ts +83 -0
  43. package/tests/update-description.test.ts +262 -0
  44. package/to-do.md +9 -0
  45. package/tsconfig.json +18 -0
package/README.md ADDED
@@ -0,0 +1,364 @@
1
+ # Jira AI
2
+
3
+ A TypeScript-based command-line interface for interacting with Atlassian Jira. Built with jira.js library and featuring beautiful terminal output with tables and colors.
4
+
5
+ ## Features
6
+
7
+ - View your user information
8
+ - List all projects
9
+ - View task details with comments
10
+ - Show available statuses for a project
11
+ - Update issue descriptions from Markdown files
12
+ - Execute JQL queries with formatted results
13
+ - Beautiful table formatting with cli-table3
14
+ - Colored output for better readability
15
+ - Loading spinners for async operations
16
+
17
+ ## Prerequisites
18
+
19
+ - Node.js (v14 or higher)
20
+ - npm or yarn
21
+ - Jira account with API access
22
+
23
+ ## Installation
24
+
25
+ 1. Clone or navigate to the project directory:
26
+ ```bash
27
+ cd /home/manager/jira-service
28
+ ```
29
+
30
+ 2. Install dependencies:
31
+ ```bash
32
+ npm install
33
+ ```
34
+
35
+ 3. Build the project:
36
+ ```bash
37
+ npm run build
38
+ ```
39
+
40
+ 4. Install globally:
41
+ ```bash
42
+ sudo npm link
43
+ ```
44
+
45
+ After installation, you can use the `jira-ai` command from anywhere in your terminal.
46
+
47
+ ## Configuration
48
+
49
+ Create a `.env` file in the project root with your Jira credentials:
50
+
51
+ ```env
52
+ JIRA_HOST=https://your-domain.atlassian.net
53
+ JIRA_USER_EMAIL=your-email@example.com
54
+ JIRA_API_TOKEN=your-api-token
55
+ ```
56
+
57
+ ### Getting Your API Token
58
+
59
+ 1. Go to [Atlassian API Tokens](https://id.atlassian.com/manage-profile/security/api-tokens)
60
+ 2. Click "Create API token"
61
+ 3. Give it a label and copy the generated token
62
+ 4. Add the token to your `.env` file
63
+
64
+ ## Available Commands
65
+
66
+ ### Show User Information
67
+
68
+ Display your basic Jira user information including host, display name, email, account ID, status, and timezone.
69
+
70
+ ```bash
71
+ jira-ai me
72
+ ```
73
+
74
+ **Output:**
75
+ ```
76
+ User Information:
77
+ ┌────────────────────┬──────────────────────────────────────────────────┐
78
+ │ Property │ Value │
79
+ ├────────────────────┼──────────────────────────────────────────────────┤
80
+ │ Host │ https://your-domain.atlassian.net │
81
+ ├────────────────────┼──────────────────────────────────────────────────┤
82
+ │ Display Name │ Your Name │
83
+ ├────────────────────┼──────────────────────────────────────────────────┤
84
+ │ Email │ your-email@example.com │
85
+ ├────────────────────┼──────────────────────────────────────────────────┤
86
+ │ Account ID │ 557058:xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx │
87
+ ├────────────────────┼──────────────────────────────────────────────────┤
88
+ │ Status │ Active │
89
+ ├────────────────────┼──────────────────────────────────────────────────┤
90
+ │ Time Zone │ Europe/Kiev │
91
+ └────────────────────┴──────────────────────────────────────────────────┘
92
+ ```
93
+
94
+ ### List Projects
95
+
96
+ Show all projects you have access to in a formatted table.
97
+
98
+ ```bash
99
+ jira-ai projects
100
+ ```
101
+
102
+ **Output:**
103
+ ```
104
+ Projects (25 total)
105
+
106
+ ┌────────────┬───────────────────────────────────┬───────────────┬─────────────────────────┐
107
+ │ Key │ Name │ Type │ Lead │
108
+ ├────────────┼───────────────────────────────────┼───────────────┼─────────────────────────┤
109
+ │ BP │ BookingPal │ software │ Pavel Boiko │
110
+ ├────────────┼───────────────────────────────────┼───────────────┼─────────────────────────┤
111
+ │ IT │ IT Support │ software │ Anatolii Fesiuk │
112
+ └────────────┴───────────────────────────────────┴───────────────┴─────────────────────────┘
113
+ ```
114
+
115
+ ### View Task Details
116
+
117
+ Display detailed information about a specific task including title, status, assignee, reporter, description, and all comments.
118
+
119
+ ```bash
120
+ jira-ai task-with-details <task-id>
121
+ ```
122
+
123
+ **Example:**
124
+ ```bash
125
+ jira-ai task-with-details BP-1234
126
+ ```
127
+
128
+ **Output:**
129
+ ```
130
+ BP-1234: Configure new production server
131
+
132
+ ┌───────────────┬─────────────────────────────────────────────────────────────────┐
133
+ │ Property │ Value │
134
+ ├───────────────┼─────────────────────────────────────────────────────────────────┤
135
+ │ Status │ In Progress │
136
+ ├───────────────┼─────────────────────────────────────────────────────────────────┤
137
+ │ Assignee │ John Doe │
138
+ ├───────────────┼─────────────────────────────────────────────────────────────────┤
139
+ │ Reporter │ Jane Smith │
140
+ ├───────────────┼─────────────────────────────────────────────────────────────────┤
141
+ │ Created │ Jan 10, 2026, 02:30 PM │
142
+ ├───────────────┼─────────────────────────────────────────────────────────────────┤
143
+ │ Updated │ Jan 10, 2026, 04:15 PM │
144
+ └───────────────┴─────────────────────────────────────────────────────────────────┘
145
+
146
+ Description:
147
+ ────────────────────────────────────────────────────────────────────────────────
148
+ We need to configure the production server...
149
+ ────────────────────────────────────────────────────────────────────────────────
150
+
151
+ Comments (2):
152
+
153
+ 1. John Doe - Jan 10, 2026, 03:00 PM
154
+ ────────────────────────────────────────────────────────────────────────────────
155
+ Started working on this task...
156
+ ────────────────────────────────────────────────────────────────────────────────
157
+ ```
158
+
159
+ ### Show Project Statuses
160
+
161
+ Display all possible issue statuses available in a specific project.
162
+
163
+ ```bash
164
+ jira-ai project-statuses <project-id>
165
+ ```
166
+
167
+ **Example:**
168
+ ```bash
169
+ jira-ai project-statuses BP
170
+ ```
171
+
172
+ **Output:**
173
+ ```
174
+ Project BP - Available Statuses (21 total)
175
+
176
+ ┌─────────────────────────┬────────────────────┬─────────────────────────────────────────────┐
177
+ │ Status Name │ Category │ Description │
178
+ ├─────────────────────────┼────────────────────┼─────────────────────────────────────────────┤
179
+ │ Open │ To Do │ The work item is open and ready for work │
180
+ ├─────────────────────────┼────────────────────┼─────────────────────────────────────────────┤
181
+ │ In Progress │ In Progress │ This work item is being actively worked on │
182
+ ├─────────────────────────┼────────────────────┼─────────────────────────────────────────────┤
183
+ │ Closed │ Done │ The work item is considered finished │
184
+ └─────────────────────────┴────────────────────┴─────────────────────────────────────────────┘
185
+ ```
186
+
187
+ ### Execute JQL Query
188
+
189
+ Run a JQL (Jira Query Language) query and display results in a formatted table.
190
+
191
+ ```bash
192
+ jira-ai run-jql <jql-query> [--limit <number>]
193
+ ```
194
+
195
+ **Example:**
196
+ ```bash
197
+ jira-ai run-jql "project = BP AND status = 'In Progress'" --limit 10
198
+ ```
199
+
200
+ **Output:**
201
+ ```
202
+ JQL Query Results (5 issues found)
203
+
204
+ ┌────────────┬──────────────────────────┬─────────────┬────────────┬──────────┐
205
+ │ Key │ Summary │ Status │ Assignee │ Priority │
206
+ ├────────────┼──────────────────────────┼─────────────┼────────────┼──────────┤
207
+ │ BP-1234 │ Configure production... │ In Progress │ John Doe │ High │
208
+ ├────────────┼──────────────────────────┼─────────────┼────────────┼──────────┤
209
+ │ BP-5678 │ Update documentation │ In Progress │ Jane Smith │ Medium │
210
+ └────────────┴──────────────────────────┴─────────────┴────────────┴──────────┘
211
+ ```
212
+
213
+ ### Update Issue Description
214
+
215
+ Update a Jira issue's description from a Markdown file. The Markdown content is automatically converted to Atlassian Document Format (ADF).
216
+
217
+ ```bash
218
+ jira-ai update-description <task-id> --from-file <path-to-markdown-file>
219
+ ```
220
+
221
+ **Example:**
222
+ ```bash
223
+ jira-ai update-description BP-1234 --from-file ./description.md
224
+ ```
225
+
226
+ **Requirements:**
227
+ - The command must be enabled in `settings.yaml` (commented out by default for safety)
228
+ - You must have edit permissions for the issue in Jira
229
+ - The Markdown file must exist and be non-empty
230
+
231
+ **Supported Markdown:**
232
+ - Headings (# H1, ## H2, etc.)
233
+ - Bold, italic, strikethrough
234
+ - Lists (ordered and unordered)
235
+ - Code blocks with syntax highlighting
236
+ - Links and images
237
+ - Tables
238
+ - Blockquotes
239
+
240
+ **Output:**
241
+ ```
242
+ ✔ Description updated successfully for BP-1234
243
+
244
+ File: /path/to/description.md
245
+ ```
246
+
247
+ **Note:** This command replaces the entire issue description with the content from the file.
248
+
249
+ ## Settings
250
+
251
+ The CLI uses a `settings.yaml` file to control which commands and projects are allowed. This provides an additional security layer.
252
+
253
+ **Example settings.yaml:**
254
+ ```yaml
255
+ # Projects: List of allowed projects (use "all" to allow all projects)
256
+ projects:
257
+ - all
258
+
259
+ # Commands: List of allowed commands (use "all" to allow all commands)
260
+ commands:
261
+ - me
262
+ - projects
263
+ - run-jql
264
+ - task-with-details
265
+ # - update-description # Uncomment to enable description updates
266
+ # - project-statuses
267
+ ```
268
+
269
+ **Important:** The `update-description` command is commented out by default since it's a WRITE operation. Uncomment it only if you need to update issue descriptions.
270
+
271
+ ## Development
272
+
273
+ ### Scripts
274
+
275
+ - `npm run dev` - Run in development mode with ts-node
276
+ - `npm run build` - Compile TypeScript to JavaScript
277
+ - `npm start` - Run the compiled version
278
+ - `npm run link` - Build and install globally
279
+
280
+ ### Project Structure
281
+
282
+ ```
283
+ jira-service/
284
+ ├── src/
285
+ │ ├── cli.ts # Main entry point
286
+ │ ├── commands/ # Command implementations
287
+ │ │ ├── about.ts
288
+ │ │ ├── me.ts
289
+ │ │ ├── projects.ts
290
+ │ │ ├── project-statuses.ts
291
+ │ │ ├── run-jql.ts
292
+ │ │ ├── task-with-details.ts
293
+ │ │ └── update-description.ts # Update issue descriptions
294
+ │ ├── lib/
295
+ │ │ ├── jira-client.ts # Jira API wrapper
296
+ │ │ ├── formatters.ts # Output formatting
297
+ │ │ ├── settings.ts # Settings management
298
+ │ │ └── utils.ts # Utility functions
299
+ │ └── types/
300
+ │ └── md-to-adf.d.ts # Type definitions for md-to-adf
301
+ ├── tests/ # Test files
302
+ │ ├── __mocks__/ # Jest mocks
303
+ │ ├── cli-permissions.test.ts
304
+ │ ├── projects.test.ts
305
+ │ ├── settings.test.ts
306
+ │ └── update-description.test.ts
307
+ ├── dist/ # Compiled JavaScript
308
+ ├── package.json
309
+ ├── tsconfig.json
310
+ ├── jest.config.js
311
+ ├── settings.yaml # Command/project permissions
312
+ └── .env # Environment variables
313
+ ```
314
+
315
+ ## Technologies Used
316
+
317
+ - **TypeScript** - Type-safe JavaScript
318
+ - **jira.js** - Jira API client library
319
+ - **Commander.js** - CLI framework
320
+ - **cli-table3** - Beautiful terminal tables
321
+ - **chalk** - Terminal colors and styling
322
+ - **ora** - Loading spinners
323
+ - **dotenv** - Environment variable management
324
+ - **md-to-adf** - Markdown to Atlassian Document Format conversion
325
+ - **Jest** - Testing framework
326
+
327
+ ## Error Handling
328
+
329
+ The CLI provides helpful error messages:
330
+
331
+ - Missing environment variables with instructions
332
+ - API errors with detailed messages
333
+ - Invalid task IDs or project keys
334
+ - Network connectivity issues
335
+
336
+ ## Troubleshooting
337
+
338
+ ### Command not found after installation
339
+
340
+ Make sure you ran `sudo npm link` and that your npm global bin directory is in your PATH.
341
+
342
+ ### Authentication errors
343
+
344
+ Verify your `.env` file has the correct:
345
+ - JIRA_HOST (with https://)
346
+ - JIRA_USER_EMAIL
347
+ - JIRA_API_TOKEN
348
+
349
+ Regenerate your API token if needed.
350
+
351
+ ### Permission denied
352
+
353
+ If you get permission errors, make sure the CLI is executable:
354
+ ```bash
355
+ chmod +x dist/cli.js
356
+ ```
357
+
358
+ ## License
359
+
360
+ ISC
361
+
362
+ ## Contributing
363
+
364
+ Feel free to submit issues and enhancement requests.
package/dist/cli.js ADDED
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const commander_1 = require("commander");
8
+ const dotenv_1 = __importDefault(require("dotenv"));
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ const utils_1 = require("./lib/utils");
11
+ const me_1 = require("./commands/me");
12
+ const projects_1 = require("./commands/projects");
13
+ const task_with_details_1 = require("./commands/task-with-details");
14
+ const project_statuses_1 = require("./commands/project-statuses");
15
+ const run_jql_1 = require("./commands/run-jql");
16
+ const update_description_1 = require("./commands/update-description");
17
+ const add_comment_1 = require("./commands/add-comment");
18
+ const about_1 = require("./commands/about");
19
+ const settings_1 = require("./lib/settings");
20
+ // Load environment variables
21
+ dotenv_1.default.config();
22
+ // Validate environment variables
23
+ (0, utils_1.validateEnvVars)();
24
+ // Helper function to wrap commands with permission check
25
+ function withPermission(commandName, commandFn) {
26
+ return async (...args) => {
27
+ if (!(0, settings_1.isCommandAllowed)(commandName)) {
28
+ console.error(chalk_1.default.red(`\n❌ Command '${commandName}' is not allowed.`));
29
+ console.log(chalk_1.default.gray('Allowed commands: ' + (0, settings_1.getAllowedCommands)().join(', ')));
30
+ console.log(chalk_1.default.gray('Update settings.yaml to enable this command.\n'));
31
+ process.exit(1);
32
+ }
33
+ return commandFn(...args);
34
+ };
35
+ }
36
+ // Create CLI program
37
+ const program = new commander_1.Command();
38
+ program
39
+ .name('jira-ai')
40
+ .description('CLI tool for interacting with Atlassian Jira')
41
+ .version('1.0.0');
42
+ // Me command
43
+ program
44
+ .command('me')
45
+ .description('Show basic user information')
46
+ .action(withPermission('me', me_1.meCommand));
47
+ // Projects command
48
+ program
49
+ .command('projects')
50
+ .description('Show list of projects')
51
+ .action(withPermission('projects', projects_1.projectsCommand));
52
+ // Task with details command
53
+ program
54
+ .command('task-with-details <task-id>')
55
+ .description('Show task title, body, and comments')
56
+ .action(withPermission('task-with-details', task_with_details_1.taskWithDetailsCommand));
57
+ // Project statuses command
58
+ program
59
+ .command('project-statuses <project-id>')
60
+ .description('Show all possible statuses for a project')
61
+ .action(withPermission('project-statuses', project_statuses_1.projectStatusesCommand));
62
+ // Run JQL command
63
+ program
64
+ .command('run-jql <jql-query>')
65
+ .description('Execute JQL query and display results')
66
+ .option('-l, --limit <number>', 'Maximum number of results (default: 50)', '50')
67
+ .action(withPermission('run-jql', run_jql_1.runJqlCommand));
68
+ // Update description command
69
+ program
70
+ .command('update-description <task-id>')
71
+ .description('Update task description from a Markdown file')
72
+ .requiredOption('--from-file <path>', 'Path to Markdown file')
73
+ .action(withPermission('update-description', update_description_1.updateDescriptionCommand));
74
+ // Add comment command
75
+ program
76
+ .command('add-comment')
77
+ .description('Add a comment to a Jira issue from a Markdown file')
78
+ .requiredOption('--file-path <path>', 'Path to Markdown file')
79
+ .requiredOption('--issue-key <key>', 'Jira issue key (e.g., PS-123)')
80
+ .action(withPermission('add-comment', add_comment_1.addCommentCommand));
81
+ // About command (always allowed)
82
+ program
83
+ .command('about')
84
+ .description('Show information about available commands')
85
+ .action(about_1.aboutCommand);
86
+ // Parse command line arguments
87
+ program.parse();
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.aboutCommand = aboutCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const settings_1 = require("../lib/settings");
9
+ const ALL_COMMANDS = [
10
+ {
11
+ name: 'me',
12
+ description: 'Show details of current user',
13
+ usage: 'jira-ai me --help'
14
+ },
15
+ {
16
+ name: 'projects',
17
+ description: 'List available projects',
18
+ usage: 'jira-ai projects --help'
19
+ },
20
+ {
21
+ name: 'task-with-details',
22
+ description: 'Show task title, body, and comments',
23
+ usage: 'jira-ai task-with-details --help'
24
+ },
25
+ {
26
+ name: 'project-statuses',
27
+ description: 'Show all possible statuses for a project',
28
+ usage: 'jira-ai project-statuses --help'
29
+ },
30
+ {
31
+ name: 'run-jql',
32
+ description: 'Execute JQL query and display results',
33
+ usage: 'jira-ai run-jql "<jql-query>" [-l <limit>]'
34
+ },
35
+ {
36
+ name: 'update-description',
37
+ description: 'Update task description from a Markdown file',
38
+ usage: 'jira-ai update-description <task-id> --from-file <path>'
39
+ },
40
+ {
41
+ name: 'add-comment',
42
+ description: 'Add a comment to a Jira issue from a Markdown file',
43
+ usage: 'jira-ai add-comment --file-path <path> --issue-key <key>'
44
+ },
45
+ {
46
+ name: 'about',
47
+ description: 'Show this help message',
48
+ usage: 'jira-ai about'
49
+ }
50
+ ];
51
+ async function aboutCommand() {
52
+ console.log(chalk_1.default.bold.cyan('\n📋 Jira AI - Available Commands\n'));
53
+ console.log(chalk_1.default.bold('Usage:'));
54
+ console.log(' jira-ai <command> [options]\n');
55
+ const allowedCommandsList = (0, settings_1.getAllowedCommands)();
56
+ const isAllAllowed = allowedCommandsList.includes('all');
57
+ // Filter commands based on settings (about is always shown)
58
+ const commandsToShow = ALL_COMMANDS.filter(cmd => cmd.name === 'about' || isAllAllowed || (0, settings_1.isCommandAllowed)(cmd.name));
59
+ console.log(chalk_1.default.bold('Available Commands:\n'));
60
+ for (const cmd of commandsToShow) {
61
+ console.log(chalk_1.default.yellow(` ${cmd.name}`));
62
+ console.log(` ${cmd.description}`);
63
+ console.log(` Usage: ${cmd.usage}\n`);
64
+ }
65
+ // Show disabled commands if not all are allowed
66
+ if (!isAllAllowed) {
67
+ const disabledCommands = ALL_COMMANDS.filter(cmd => cmd.name !== 'about' && !(0, settings_1.isCommandAllowed)(cmd.name));
68
+ if (disabledCommands.length > 0) {
69
+ console.log(chalk_1.default.bold('Disabled Commands:\n'));
70
+ for (const cmd of disabledCommands) {
71
+ console.log(chalk_1.default.gray(` ${cmd.name} - ${cmd.description}`));
72
+ }
73
+ console.log();
74
+ }
75
+ }
76
+ console.log(chalk_1.default.bold('For detailed help on any command, run:'));
77
+ console.log(chalk_1.default.green(' jira-ai <command> --help\n'));
78
+ console.log(chalk_1.default.bold('Configuration:'));
79
+ console.log(' Settings are managed in settings.yaml');
80
+ const allowedProjects = (0, settings_1.getAllowedProjects)();
81
+ console.log(` - Projects: ${allowedProjects.includes('all') ? 'All allowed' : allowedProjects.join(', ')}`);
82
+ console.log(` - Commands: ${isAllAllowed ? 'All allowed' : allowedCommandsList.join(', ')}\n`);
83
+ }
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.addCommentCommand = addCommentCommand;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const ora_1 = __importDefault(require("ora"));
42
+ const fs = __importStar(require("fs"));
43
+ const path = __importStar(require("path"));
44
+ const md_to_adf_1 = __importDefault(require("md-to-adf"));
45
+ const jira_client_1 = require("../lib/jira-client");
46
+ async function addCommentCommand(options) {
47
+ const { filePath, issueKey } = options;
48
+ // Validate issueKey
49
+ if (!issueKey || issueKey.trim() === '') {
50
+ console.error(chalk_1.default.red('\nError: Issue key is required (use --issue-key)'));
51
+ process.exit(1);
52
+ }
53
+ // Validate file path
54
+ if (!filePath || filePath.trim() === '') {
55
+ console.error(chalk_1.default.red('\nError: File path is required (use --file-path)'));
56
+ process.exit(1);
57
+ }
58
+ // Resolve file path to absolute
59
+ const absolutePath = path.resolve(filePath);
60
+ // Check file exists
61
+ if (!fs.existsSync(absolutePath)) {
62
+ console.error(chalk_1.default.red(`\nError: File not found: ${absolutePath}`));
63
+ process.exit(1);
64
+ }
65
+ // Read file
66
+ let markdownContent;
67
+ try {
68
+ markdownContent = fs.readFileSync(absolutePath, 'utf-8');
69
+ }
70
+ catch (error) {
71
+ console.error(chalk_1.default.red('\nError reading file: ' +
72
+ (error instanceof Error ? error.message : 'Unknown error')));
73
+ process.exit(1);
74
+ }
75
+ // Validate file is not empty
76
+ if (markdownContent.trim() === '') {
77
+ console.error(chalk_1.default.red('\nError: File is empty'));
78
+ process.exit(1);
79
+ }
80
+ // Convert Markdown to ADF
81
+ let adfContent;
82
+ try {
83
+ adfContent = (0, md_to_adf_1.default)(markdownContent);
84
+ }
85
+ catch (error) {
86
+ console.error(chalk_1.default.red('\nError converting Markdown to ADF: ' +
87
+ (error instanceof Error ? error.message : 'Unknown error')));
88
+ process.exit(1);
89
+ }
90
+ // Add comment with spinner
91
+ const spinner = (0, ora_1.default)(`Adding comment to ${issueKey}...`).start();
92
+ try {
93
+ await (0, jira_client_1.addIssueComment)(issueKey, adfContent);
94
+ spinner.succeed(chalk_1.default.green(`Comment added successfully to ${issueKey}`));
95
+ console.log(chalk_1.default.gray(`\nFile: ${absolutePath}`));
96
+ }
97
+ catch (error) {
98
+ spinner.fail(chalk_1.default.red('Failed to add comment'));
99
+ console.error(chalk_1.default.red('\nError: ' + (error instanceof Error ? error.message : 'Unknown error')));
100
+ // Provide helpful hints based on error
101
+ if (error instanceof Error && error.message.includes('404')) {
102
+ console.log(chalk_1.default.yellow('\nHint: Check that the issue key is correct'));
103
+ }
104
+ else if (error instanceof Error && error.message.includes('403')) {
105
+ console.log(chalk_1.default.yellow('\nHint: You may not have permission to comment on this issue'));
106
+ }
107
+ process.exit(1);
108
+ }
109
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.meCommand = meCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const ora_1 = __importDefault(require("ora"));
9
+ const jira_client_1 = require("../lib/jira-client");
10
+ const formatters_1 = require("../lib/formatters");
11
+ async function meCommand() {
12
+ const spinner = (0, ora_1.default)('Fetching user information...').start();
13
+ try {
14
+ const user = await (0, jira_client_1.getCurrentUser)();
15
+ spinner.succeed(chalk_1.default.green('User information retrieved'));
16
+ console.log((0, formatters_1.formatUserInfo)(user));
17
+ }
18
+ catch (error) {
19
+ spinner.fail(chalk_1.default.red('Failed to fetch user information'));
20
+ console.error(chalk_1.default.red('\nError: ' + (error instanceof Error ? error.message : 'Unknown error')));
21
+ process.exit(1);
22
+ }
23
+ }