jira-ai 0.3.7 → 0.3.9

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/cli.js CHANGED
@@ -1,36 +1,33 @@
1
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 list_issue_types_1 = require("./commands/list-issue-types");
16
- const run_jql_1 = require("./commands/run-jql");
17
- const update_description_1 = require("./commands/update-description");
18
- const add_comment_1 = require("./commands/add-comment");
19
- const create_task_1 = require("./commands/create-task");
20
- const about_1 = require("./commands/about");
21
- const auth_1 = require("./commands/auth");
22
- const settings_1 = require("./lib/settings");
2
+ import { Command } from 'commander';
3
+ import dotenv from 'dotenv';
4
+ import chalk from 'chalk';
5
+ import { validateEnvVars } from './lib/utils.js';
6
+ import { meCommand } from './commands/me.js';
7
+ import { projectsCommand } from './commands/projects.js';
8
+ import { taskWithDetailsCommand } from './commands/task-with-details.js';
9
+ import { projectStatusesCommand } from './commands/project-statuses.js';
10
+ import { listIssueTypesCommand } from './commands/list-issue-types.js';
11
+ import { runJqlCommand } from './commands/run-jql.js';
12
+ import { updateDescriptionCommand } from './commands/update-description.js';
13
+ import { addCommentCommand } from './commands/add-comment.js';
14
+ import { addLabelCommand } from './commands/add-label.js';
15
+ import { deleteLabelCommand } from './commands/delete-label.js';
16
+ import { createTaskCommand } from './commands/create-task.js';
17
+ import { aboutCommand } from './commands/about.js';
18
+ import { authCommand } from './commands/auth.js';
19
+ import { isCommandAllowed, getAllowedCommands } from './lib/settings.js';
23
20
  // Load environment variables
24
- dotenv_1.default.config();
21
+ dotenv.config();
25
22
  // Create CLI program
26
- const program = new commander_1.Command();
23
+ const program = new Command();
27
24
  program
28
25
  .name('jira-ai')
29
26
  .description('CLI tool for interacting with Atlassian Jira')
30
27
  .version('1.0.0');
31
28
  // Middleware to validate credentials for commands that need them
32
29
  const validateCredentials = () => {
33
- (0, utils_1.validateEnvVars)();
30
+ validateEnvVars();
34
31
  };
35
32
  // Helper function to wrap commands with permission check and credential validation
36
33
  function withPermission(commandName, commandFn, skipValidation = false) {
@@ -38,10 +35,10 @@ function withPermission(commandName, commandFn, skipValidation = false) {
38
35
  if (!skipValidation) {
39
36
  validateCredentials();
40
37
  }
41
- if (!(0, settings_1.isCommandAllowed)(commandName)) {
42
- console.error(chalk_1.default.red(`\n❌ Command '${commandName}' is not allowed.`));
43
- console.log(chalk_1.default.gray('Allowed commands: ' + (0, settings_1.getAllowedCommands)().join(', ')));
44
- console.log(chalk_1.default.gray('Update settings.yaml to enable this command.\n'));
38
+ if (!isCommandAllowed(commandName)) {
39
+ console.error(chalk.red(`\n❌ Command '${commandName}' is not allowed.`));
40
+ console.log(chalk.gray('Allowed commands: ' + getAllowedCommands().join(', ')));
41
+ console.log(chalk.gray('Update settings.yaml to enable this command.\n'));
45
42
  process.exit(1);
46
43
  }
47
44
  return commandFn(...args);
@@ -53,51 +50,61 @@ program
53
50
  .description('Set up Jira authentication credentials')
54
51
  .option('--from-json <json_string>', 'Accepts a raw JSON string with credentials')
55
52
  .option('--from-file <path>', 'Accepts a path to a file (typically .env) with credentials')
56
- .action((options) => (0, auth_1.authCommand)(options));
53
+ .action((options) => authCommand(options));
57
54
  // Me command
58
55
  program
59
56
  .command('me')
60
57
  .description('Show basic user information')
61
- .action(withPermission('me', me_1.meCommand));
58
+ .action(withPermission('me', meCommand));
62
59
  // Projects command
63
60
  program
64
61
  .command('projects')
65
62
  .description('Show list of projects')
66
- .action(withPermission('projects', projects_1.projectsCommand));
63
+ .action(withPermission('projects', projectsCommand));
67
64
  // Task with details command
68
65
  program
69
66
  .command('task-with-details <task-id>')
70
67
  .description('Show task title, body, and comments')
71
- .action(withPermission('task-with-details', task_with_details_1.taskWithDetailsCommand));
68
+ .action(withPermission('task-with-details', taskWithDetailsCommand));
72
69
  // Project statuses command
73
70
  program
74
71
  .command('project-statuses <project-id>')
75
72
  .description('Show all possible statuses for a project')
76
- .action(withPermission('project-statuses', project_statuses_1.projectStatusesCommand));
73
+ .action(withPermission('project-statuses', projectStatusesCommand));
77
74
  // List issue types command
78
75
  program
79
76
  .command('list-issue-types <project-key>')
80
77
  .description('Show all issue types for a project')
81
- .action(withPermission('list-issue-types', list_issue_types_1.listIssueTypesCommand));
78
+ .action(withPermission('list-issue-types', listIssueTypesCommand));
82
79
  // Run JQL command
83
80
  program
84
81
  .command('run-jql <jql-query>')
85
82
  .description('Execute JQL query and display results')
86
83
  .option('-l, --limit <number>', 'Maximum number of results (default: 50)', '50')
87
- .action(withPermission('run-jql', run_jql_1.runJqlCommand));
84
+ .action(withPermission('run-jql', runJqlCommand));
88
85
  // Update description command
89
86
  program
90
87
  .command('update-description <task-id>')
91
88
  .description('Update task description from a Markdown file')
92
89
  .requiredOption('--from-file <path>', 'Path to Markdown file')
93
- .action(withPermission('update-description', update_description_1.updateDescriptionCommand));
90
+ .action(withPermission('update-description', updateDescriptionCommand));
94
91
  // Add comment command
95
92
  program
96
93
  .command('add-comment')
97
94
  .description('Add a comment to a Jira issue from a Markdown file')
98
95
  .requiredOption('--file-path <path>', 'Path to Markdown file')
99
96
  .requiredOption('--issue-key <key>', 'Jira issue key (e.g., PS-123)')
100
- .action(withPermission('add-comment', add_comment_1.addCommentCommand));
97
+ .action(withPermission('add-comment', addCommentCommand));
98
+ // Add label command
99
+ program
100
+ .command('add-label-to-issue <task-id> <labels>')
101
+ .description('Add one or more labels to a Jira issue (comma-separated)')
102
+ .action(withPermission('add-label-to-issue', addLabelCommand));
103
+ // Delete label command
104
+ program
105
+ .command('delete-label-from-issue <task-id> <labels>')
106
+ .description('Remove one or more labels from a Jira issue (comma-separated)')
107
+ .action(withPermission('delete-label-from-issue', deleteLabelCommand));
101
108
  // Create task command
102
109
  program
103
110
  .command('create-task')
@@ -106,11 +113,11 @@ program
106
113
  .requiredOption('--project <project>', 'Project key (e.g., PROJ)')
107
114
  .requiredOption('--issue-type <type>', 'Issue type (e.g., Task, Epic, Subtask)')
108
115
  .option('--parent <key>', 'Parent issue key (required for subtasks)')
109
- .action(withPermission('create-task', create_task_1.createTaskCommand));
116
+ .action(withPermission('create-task', createTaskCommand));
110
117
  // About command (always allowed)
111
118
  program
112
119
  .command('about')
113
120
  .description('Show information about available commands')
114
- .action(about_1.aboutCommand);
121
+ .action(aboutCommand);
115
122
  // Parse command line arguments
116
123
  program.parse();
@@ -1,11 +1,5 @@
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");
1
+ import chalk from 'chalk';
2
+ import { getAllowedCommands, getAllowedProjects, isCommandAllowed, getSettingsPath } from '../lib/settings.js';
9
3
  const ALL_COMMANDS = [
10
4
  {
11
5
  name: 'auth',
@@ -63,36 +57,36 @@ const ALL_COMMANDS = [
63
57
  usage: 'jira-ai about'
64
58
  }
65
59
  ];
66
- async function aboutCommand() {
67
- console.log(chalk_1.default.bold.cyan('\n📋 Jira AI - Available Commands\n'));
68
- console.log(chalk_1.default.bold('Usage:'));
60
+ export async function aboutCommand() {
61
+ console.log(chalk.bold.cyan('\n📋 Jira AI - Available Commands\n'));
62
+ console.log(chalk.bold('Usage:'));
69
63
  console.log(' jira-ai <command> [options]\n');
70
- const allowedCommandsList = (0, settings_1.getAllowedCommands)();
64
+ const allowedCommandsList = getAllowedCommands();
71
65
  const isAllAllowed = allowedCommandsList.includes('all');
72
66
  // Filter commands based on settings (about is always shown)
73
- const commandsToShow = ALL_COMMANDS.filter(cmd => cmd.name === 'about' || isAllAllowed || (0, settings_1.isCommandAllowed)(cmd.name));
74
- console.log(chalk_1.default.bold('Available Commands:\n'));
67
+ const commandsToShow = ALL_COMMANDS.filter(cmd => cmd.name === 'about' || isAllAllowed || isCommandAllowed(cmd.name));
68
+ console.log(chalk.bold('Available Commands:\n'));
75
69
  for (const cmd of commandsToShow) {
76
- console.log(chalk_1.default.yellow(` ${cmd.name}`));
70
+ console.log(chalk.yellow(` ${cmd.name}`));
77
71
  console.log(` ${cmd.description}`);
78
72
  console.log(` Usage: ${cmd.usage}\n`);
79
73
  }
80
74
  // Show disabled commands if not all are allowed
81
75
  if (!isAllAllowed) {
82
- const disabledCommands = ALL_COMMANDS.filter(cmd => cmd.name !== 'about' && !(0, settings_1.isCommandAllowed)(cmd.name));
76
+ const disabledCommands = ALL_COMMANDS.filter(cmd => cmd.name !== 'about' && !isCommandAllowed(cmd.name));
83
77
  if (disabledCommands.length > 0) {
84
- console.log(chalk_1.default.bold('Disabled Commands:\n'));
78
+ console.log(chalk.bold('Disabled Commands:\n'));
85
79
  for (const cmd of disabledCommands) {
86
- console.log(chalk_1.default.gray(` ${cmd.name} - ${cmd.description}`));
80
+ console.log(chalk.gray(` ${cmd.name} - ${cmd.description}`));
87
81
  }
88
82
  console.log();
89
83
  }
90
84
  }
91
- console.log(chalk_1.default.bold('For detailed help on any command, run:'));
92
- console.log(chalk_1.default.green(' jira-ai <command> --help\n'));
93
- console.log(chalk_1.default.bold('Configuration:'));
94
- console.log(` Settings file: ${chalk_1.default.cyan((0, settings_1.getSettingsPath)())}`);
95
- const allowedProjects = (0, settings_1.getAllowedProjects)();
85
+ console.log(chalk.bold('For detailed help on any command, run:'));
86
+ console.log(chalk.green(' jira-ai <command> --help\n'));
87
+ console.log(chalk.bold('Configuration:'));
88
+ console.log(` Settings file: ${chalk.cyan(getSettingsPath())}`);
89
+ const allowedProjects = getAllowedProjects();
96
90
  console.log(` - Projects: ${allowedProjects.includes('all') ? 'All allowed' : allowedProjects.join(', ')}`);
97
91
  console.log(` - Commands: ${isAllAllowed ? 'All allowed' : allowedCommandsList.join(', ')}\n`);
98
92
  }
@@ -1,65 +1,26 @@
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 marklassian_1 = require("marklassian");
45
- const jira_client_1 = require("../lib/jira-client");
46
- async function addCommentCommand(options) {
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import * as fs from 'fs';
4
+ import * as path from 'path';
5
+ import { markdownToAdf } from 'marklassian';
6
+ import { addIssueComment } from '../lib/jira-client.js';
7
+ export async function addCommentCommand(options) {
47
8
  const { filePath, issueKey } = options;
48
9
  // Validate issueKey
49
10
  if (!issueKey || issueKey.trim() === '') {
50
- console.error(chalk_1.default.red('\nError: Issue key is required (use --issue-key)'));
11
+ console.error(chalk.red('\nError: Issue key is required (use --issue-key)'));
51
12
  process.exit(1);
52
13
  }
53
14
  // Validate file path
54
15
  if (!filePath || filePath.trim() === '') {
55
- console.error(chalk_1.default.red('\nError: File path is required (use --file-path)'));
16
+ console.error(chalk.red('\nError: File path is required (use --file-path)'));
56
17
  process.exit(1);
57
18
  }
58
19
  // Resolve file path to absolute
59
20
  const absolutePath = path.resolve(filePath);
60
21
  // Check file exists
61
22
  if (!fs.existsSync(absolutePath)) {
62
- console.error(chalk_1.default.red(`\nError: File not found: ${absolutePath}`));
23
+ console.error(chalk.red(`\nError: File not found: ${absolutePath}`));
63
24
  process.exit(1);
64
25
  }
65
26
  // Read file
@@ -68,41 +29,41 @@ async function addCommentCommand(options) {
68
29
  markdownContent = fs.readFileSync(absolutePath, 'utf-8');
69
30
  }
70
31
  catch (error) {
71
- console.error(chalk_1.default.red('\nError reading file: ' +
32
+ console.error(chalk.red('\nError reading file: ' +
72
33
  (error instanceof Error ? error.message : 'Unknown error')));
73
34
  process.exit(1);
74
35
  }
75
36
  // Validate file is not empty
76
37
  if (markdownContent.trim() === '') {
77
- console.error(chalk_1.default.red('\nError: File is empty'));
38
+ console.error(chalk.red('\nError: File is empty'));
78
39
  process.exit(1);
79
40
  }
80
41
  // Convert Markdown to ADF
81
42
  let adfContent;
82
43
  try {
83
- adfContent = (0, marklassian_1.markdownToAdf)(markdownContent);
44
+ adfContent = markdownToAdf(markdownContent);
84
45
  }
85
46
  catch (error) {
86
- console.error(chalk_1.default.red('\nError converting Markdown to ADF: ' +
47
+ console.error(chalk.red('\nError converting Markdown to ADF: ' +
87
48
  (error instanceof Error ? error.message : 'Unknown error')));
88
49
  process.exit(1);
89
50
  }
90
51
  // Add comment with spinner
91
- const spinner = (0, ora_1.default)(`Adding comment to ${issueKey}...`).start();
52
+ const spinner = ora(`Adding comment to ${issueKey}...`).start();
92
53
  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}`));
54
+ await addIssueComment(issueKey, adfContent);
55
+ spinner.succeed(chalk.green(`Comment added successfully to ${issueKey}`));
56
+ console.log(chalk.gray(`\nFile: ${absolutePath}`));
96
57
  }
97
58
  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')));
59
+ spinner.fail(chalk.red('Failed to add comment'));
60
+ console.error(chalk.red('\nError: ' + (error instanceof Error ? error.message : 'Unknown error')));
100
61
  // Provide helpful hints based on error
101
62
  if (error instanceof Error && error.message.includes('404')) {
102
- console.log(chalk_1.default.yellow('\nHint: Check that the issue key is correct'));
63
+ console.log(chalk.yellow('\nHint: Check that the issue key is correct'));
103
64
  }
104
65
  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'));
66
+ console.log(chalk.yellow('\nHint: You may not have permission to comment on this issue'));
106
67
  }
107
68
  process.exit(1);
108
69
  }
@@ -0,0 +1,34 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { addIssueLabels } from '../lib/jira-client.js';
4
+ export async function addLabelCommand(taskId, labelsString) {
5
+ // Validate input
6
+ if (!taskId || taskId.trim() === '') {
7
+ console.error(chalk.red('\nError: Task ID is required'));
8
+ process.exit(1);
9
+ }
10
+ if (!labelsString || labelsString.trim() === '') {
11
+ console.error(chalk.red('\nError: Labels are required (comma-separated)'));
12
+ process.exit(1);
13
+ }
14
+ // Parse labels
15
+ const labels = labelsString.split(',').map(l => l.trim()).filter(l => l !== '');
16
+ if (labels.length === 0) {
17
+ console.error(chalk.red('\nError: No valid labels provided'));
18
+ process.exit(1);
19
+ }
20
+ const spinner = ora(`Adding labels to ${taskId}...`).start();
21
+ try {
22
+ await addIssueLabels(taskId, labels);
23
+ spinner.succeed(chalk.green(`Labels added successfully to ${taskId}`));
24
+ console.log(chalk.gray(`\nLabels: ${labels.join(', ')}`));
25
+ }
26
+ catch (error) {
27
+ spinner.fail(chalk.red('Failed to add labels'));
28
+ console.error(chalk.red('\nError: ' + (error instanceof Error ? error.message : 'Unknown error')));
29
+ if (error instanceof Error && error.message.includes('404')) {
30
+ console.log(chalk.yellow('\nHint: Check that the issue ID/key is correct'));
31
+ }
32
+ process.exit(1);
33
+ }
34
+ }
@@ -1,17 +1,11 @@
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.authCommand = authCommand;
7
- const readline_1 = __importDefault(require("readline"));
8
- const chalk_1 = __importDefault(require("chalk"));
9
- const ora_1 = __importDefault(require("ora"));
10
- const fs_1 = __importDefault(require("fs"));
11
- const dotenv_1 = __importDefault(require("dotenv"));
12
- const jira_client_1 = require("../lib/jira-client");
13
- const auth_storage_1 = require("../lib/auth-storage");
14
- const rl = readline_1.default.createInterface({
1
+ import readline from 'readline';
2
+ import chalk from 'chalk';
3
+ import ora from 'ora';
4
+ import fs from 'fs';
5
+ import dotenv from 'dotenv';
6
+ import { createTemporaryClient } from '../lib/jira-client.js';
7
+ import { saveCredentials } from '../lib/auth-storage.js';
8
+ const rl = readline.createInterface({
15
9
  input: process.stdin,
16
10
  output: process.stdout,
17
11
  });
@@ -35,7 +29,7 @@ function askSecret(question) {
35
29
  });
36
30
  });
37
31
  }
38
- async function authCommand(options = {}) {
32
+ export async function authCommand(options = {}) {
39
33
  let host = '';
40
34
  let email = '';
41
35
  let apiToken = '';
@@ -46,53 +40,53 @@ async function authCommand(options = {}) {
46
40
  email = data.email;
47
41
  apiToken = data.apikey || data.apiToken;
48
42
  if (!host || !email || !apiToken) {
49
- console.error(chalk_1.default.red('Error: Missing required fields in JSON. Required: url/host, email, apikey/apiToken.'));
43
+ console.error(chalk.red('Error: Missing required fields in JSON. Required: url/host, email, apikey/apiToken.'));
50
44
  process.exit(1);
51
45
  }
52
46
  }
53
47
  catch (error) {
54
- console.error(chalk_1.default.red(`Error: Invalid JSON string: ${error.message}`));
48
+ console.error(chalk.red(`Error: Invalid JSON string: ${error.message}`));
55
49
  process.exit(1);
56
50
  }
57
51
  }
58
52
  else if (options.fromFile) {
59
- if (!fs_1.default.existsSync(options.fromFile)) {
60
- console.error(chalk_1.default.red(`Error: File not found: ${options.fromFile}`));
53
+ if (!fs.existsSync(options.fromFile)) {
54
+ console.error(chalk.red(`Error: File not found: ${options.fromFile}`));
61
55
  process.exit(1);
62
56
  }
63
57
  try {
64
- const content = fs_1.default.readFileSync(options.fromFile, 'utf8');
65
- const config = dotenv_1.default.parse(content);
58
+ const content = fs.readFileSync(options.fromFile, 'utf8');
59
+ const config = dotenv.parse(content);
66
60
  host = config.JIRA_HOST;
67
61
  email = config.JIRA_USER_EMAIL;
68
62
  apiToken = config.JIRA_API_TOKEN;
69
63
  if (!host || !email || !apiToken) {
70
- console.error(chalk_1.default.red('Error: Missing required environment variables in file. Required: JIRA_HOST, JIRA_USER_EMAIL, JIRA_API_TOKEN.'));
64
+ console.error(chalk.red('Error: Missing required environment variables in file. Required: JIRA_HOST, JIRA_USER_EMAIL, JIRA_API_TOKEN.'));
71
65
  process.exit(1);
72
66
  }
73
67
  }
74
68
  catch (error) {
75
- console.error(chalk_1.default.red(`Error: Failed to parse file: ${error.message}`));
69
+ console.error(chalk.red(`Error: Failed to parse file: ${error.message}`));
76
70
  process.exit(1);
77
71
  }
78
72
  }
79
73
  if (!host || !email || !apiToken) {
80
- console.log(chalk_1.default.cyan('\n--- Jira Authentication Setup ---\n'));
74
+ console.log(chalk.cyan('\n--- Jira Authentication Setup ---\n'));
81
75
  try {
82
76
  host = await ask('Jira URL (e.g., https://your-domain.atlassian.net): ');
83
77
  if (!host) {
84
- console.error(chalk_1.default.red('URL is required.'));
78
+ console.error(chalk.red('URL is required.'));
85
79
  process.exit(1);
86
80
  }
87
81
  email = await ask('Email: ');
88
82
  if (!email) {
89
- console.error(chalk_1.default.red('Email is required.'));
83
+ console.error(chalk.red('Email is required.'));
90
84
  process.exit(1);
91
85
  }
92
- console.log(chalk_1.default.gray('Get your API token from: https://id.atlassian.com/manage-profile/security/api-tokens'));
86
+ console.log(chalk.gray('Get your API token from: https://id.atlassian.com/manage-profile/security/api-tokens'));
93
87
  apiToken = await ask('API Token: ');
94
88
  if (!apiToken) {
95
- console.error(chalk_1.default.red('API Token is required.'));
89
+ console.error(chalk.red('API Token is required.'));
96
90
  process.exit(1);
97
91
  }
98
92
  }
@@ -104,21 +98,21 @@ async function authCommand(options = {}) {
104
98
  // Non-interactive mode, just close readline
105
99
  rl.close();
106
100
  }
107
- const spinner = (0, ora_1.default)('Verifying credentials...').start();
101
+ const spinner = ora('Verifying credentials...').start();
108
102
  try {
109
- const tempClient = (0, jira_client_1.createTemporaryClient)(host, email, apiToken);
103
+ const tempClient = createTemporaryClient(host, email, apiToken);
110
104
  const user = await tempClient.myself.getCurrentUser();
111
- spinner.succeed(chalk_1.default.green('Authentication successful!'));
112
- console.log(chalk_1.default.blue(`\nWelcome, ${user.displayName} (${user.emailAddress})`));
113
- (0, auth_storage_1.saveCredentials)({ host, email, apiToken });
114
- console.log(chalk_1.default.green('\nCredentials saved successfully to ~/.jira-ai/config.json'));
115
- console.log(chalk_1.default.gray('These credentials will be used for future commands on this machine.'));
105
+ spinner.succeed(chalk.green('Authentication successful!'));
106
+ console.log(chalk.blue(`\nWelcome, ${user.displayName} (${user.emailAddress})`));
107
+ saveCredentials({ host, email, apiToken });
108
+ console.log(chalk.green('\nCredentials saved successfully to ~/.jira-ai/config.json'));
109
+ console.log(chalk.gray('These credentials will be used for future commands on this machine.'));
116
110
  }
117
111
  catch (error) {
118
- spinner.fail(chalk_1.default.red('Authentication failed.'));
119
- console.error(chalk_1.default.red(`Error: ${error.message || 'Invalid credentials'}`));
112
+ spinner.fail(chalk.red('Authentication failed.'));
113
+ console.error(chalk.red(`Error: ${error.message || 'Invalid credentials'}`));
120
114
  if (error.response && error.response.status === 401) {
121
- console.error(chalk_1.default.yellow('Hint: Check if your email and API token are correct.'));
115
+ console.error(chalk.yellow('Hint: Check if your email and API token are correct.'));
122
116
  }
123
117
  process.exit(1);
124
118
  }
@@ -1,59 +1,53 @@
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.createTaskCommand = createTaskCommand;
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const ora_1 = __importDefault(require("ora"));
9
- const jira_client_1 = require("../lib/jira-client");
10
- async function createTaskCommand(options) {
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { createIssue } from '../lib/jira-client.js';
4
+ export async function createTaskCommand(options) {
11
5
  const { title, project, issueType, parent } = options;
12
6
  // Validate required fields
13
7
  if (!title || title.trim() === '') {
14
- console.error(chalk_1.default.red('\nError: Title is required (use --title)'));
8
+ console.error(chalk.red('\nError: Title is required (use --title)'));
15
9
  process.exit(1);
16
10
  }
17
11
  if (!project || project.trim() === '') {
18
- console.error(chalk_1.default.red('\nError: Project is required (use --project)'));
12
+ console.error(chalk.red('\nError: Project is required (use --project)'));
19
13
  process.exit(1);
20
14
  }
21
15
  if (!issueType || issueType.trim() === '') {
22
- console.error(chalk_1.default.red('\nError: Issue type is required (use --issue-type)'));
16
+ console.error(chalk.red('\nError: Issue type is required (use --issue-type)'));
23
17
  process.exit(1);
24
18
  }
25
19
  // Create issue with spinner
26
- const spinner = (0, ora_1.default)(`Creating ${issueType} in project ${project}...`).start();
20
+ const spinner = ora(`Creating ${issueType} in project ${project}...`).start();
27
21
  try {
28
- const result = await (0, jira_client_1.createIssue)(project, title, issueType, parent);
29
- spinner.succeed(chalk_1.default.green(`Issue created successfully: ${result.key}`));
30
- console.log(chalk_1.default.gray(`\nTitle: ${title}`));
31
- console.log(chalk_1.default.gray(`Project: ${project}`));
32
- console.log(chalk_1.default.gray(`Issue Type: ${issueType}`));
22
+ const result = await createIssue(project, title, issueType, parent);
23
+ spinner.succeed(chalk.green(`Issue created successfully: ${result.key}`));
24
+ console.log(chalk.gray(`\nTitle: ${title}`));
25
+ console.log(chalk.gray(`Project: ${project}`));
26
+ console.log(chalk.gray(`Issue Type: ${issueType}`));
33
27
  if (parent) {
34
- console.log(chalk_1.default.gray(`Parent: ${parent}`));
28
+ console.log(chalk.gray(`Parent: ${parent}`));
35
29
  }
36
- console.log(chalk_1.default.cyan(`\nIssue Key: ${result.key}`));
30
+ console.log(chalk.cyan(`\nIssue Key: ${result.key}`));
37
31
  }
38
32
  catch (error) {
39
- spinner.fail(chalk_1.default.red('Failed to create issue'));
40
- console.error(chalk_1.default.red('\nError: ' + (error instanceof Error ? error.message : 'Unknown error')));
33
+ spinner.fail(chalk.red('Failed to create issue'));
34
+ console.error(chalk.red('\nError: ' + (error instanceof Error ? error.message : 'Unknown error')));
41
35
  // Provide helpful hints based on error
42
36
  if (error instanceof Error) {
43
37
  if (error.message.includes('project') || error.message.includes('Project')) {
44
- console.log(chalk_1.default.yellow('\nHint: Check that the project key is correct'));
45
- console.log(chalk_1.default.yellow('Use "jira-ai projects" to see available projects'));
38
+ console.log(chalk.yellow('\nHint: Check that the project key is correct'));
39
+ console.log(chalk.yellow('Use "jira-ai projects" to see available projects'));
46
40
  }
47
41
  else if (error.message.includes('issue type') || error.message.includes('issuetype')) {
48
- console.log(chalk_1.default.yellow('\nHint: Check that the issue type is correct'));
49
- console.log(chalk_1.default.yellow(`Use "jira-ai list-issue-types ${project}" to see available issue types`));
42
+ console.log(chalk.yellow('\nHint: Check that the issue type is correct'));
43
+ console.log(chalk.yellow(`Use "jira-ai list-issue-types ${project}" to see available issue types`));
50
44
  }
51
45
  else if (error.message.includes('parent') || error.message.includes('Parent')) {
52
- console.log(chalk_1.default.yellow('\nHint: Check that the parent issue key is correct'));
53
- console.log(chalk_1.default.yellow('Parent issues are required for subtasks'));
46
+ console.log(chalk.yellow('\nHint: Check that the parent issue key is correct'));
47
+ console.log(chalk.yellow('Parent issues are required for subtasks'));
54
48
  }
55
49
  else if (error.message.includes('403')) {
56
- console.log(chalk_1.default.yellow('\nHint: You may not have permission to create issues in this project'));
50
+ console.log(chalk.yellow('\nHint: You may not have permission to create issues in this project'));
57
51
  }
58
52
  }
59
53
  process.exit(1);