jira-pilot 2.1.0 → 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 +6 -2
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import ConfigStore from './config-store.js';
|
|
2
|
+
const config = new ConfigStore('jira-pilot');
|
|
3
|
+
export const getCredentials = () => {
|
|
4
|
+
return {
|
|
5
|
+
jiraUrl: config.get('jiraUrl'),
|
|
6
|
+
email: config.get('email'),
|
|
7
|
+
apiToken: config.get('apiToken'),
|
|
8
|
+
aiKey: config.get('aiKey'),
|
|
9
|
+
aiProvider: config.get('aiProvider'),
|
|
10
|
+
enableAi: config.get('aiEnabled'), // Map legacy key
|
|
11
|
+
githubToken: config.get('githubToken')
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export const setCredentials = ({ jiraUrl, email, apiToken, aiConfig, aiProvider, enableAi, githubToken }) => {
|
|
15
|
+
if (jiraUrl)
|
|
16
|
+
config.set('jiraUrl', jiraUrl);
|
|
17
|
+
if (email)
|
|
18
|
+
config.set('email', email);
|
|
19
|
+
if (apiToken)
|
|
20
|
+
config.set('apiToken', apiToken);
|
|
21
|
+
if (aiConfig) {
|
|
22
|
+
if (aiConfig.apiKey)
|
|
23
|
+
config.set('aiKey', aiConfig.apiKey);
|
|
24
|
+
config.set('aiConfig', aiConfig);
|
|
25
|
+
}
|
|
26
|
+
if (aiProvider)
|
|
27
|
+
config.set('aiProvider', aiProvider);
|
|
28
|
+
if (typeof enableAi !== 'undefined')
|
|
29
|
+
config.set('enableAi', enableAi);
|
|
30
|
+
if (githubToken)
|
|
31
|
+
config.set('githubToken', githubToken);
|
|
32
|
+
};
|
|
33
|
+
export const clearCredentials = () => {
|
|
34
|
+
config.clear();
|
|
35
|
+
};
|
|
36
|
+
export const hasCredentials = () => {
|
|
37
|
+
const creds = getCredentials();
|
|
38
|
+
return !!(creds.jiraUrl && creds.email && creds.apiToken);
|
|
39
|
+
};
|
|
40
|
+
// ── Profile Management ──────────────────────────────────────────────
|
|
41
|
+
export const saveProfile = (name) => {
|
|
42
|
+
const creds = getCredentials();
|
|
43
|
+
config.set(`profiles.${name}`, creds);
|
|
44
|
+
config.set('activeProfile', name);
|
|
45
|
+
};
|
|
46
|
+
export const loadProfile = (name) => {
|
|
47
|
+
const profile = config.get(`profiles.${name}`);
|
|
48
|
+
if (!profile)
|
|
49
|
+
return false;
|
|
50
|
+
setCredentials(profile);
|
|
51
|
+
config.set('activeProfile', name);
|
|
52
|
+
return true;
|
|
53
|
+
};
|
|
54
|
+
export const deleteProfile = (name) => {
|
|
55
|
+
config.delete(`profiles.${name}`);
|
|
56
|
+
if (config.get('activeProfile') === name) {
|
|
57
|
+
config.delete('activeProfile');
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
export const listProfiles = () => {
|
|
61
|
+
const profiles = config.get('profiles') || {};
|
|
62
|
+
return Object.keys(profiles);
|
|
63
|
+
};
|
|
64
|
+
export const getActiveProfile = () => {
|
|
65
|
+
return config.get('activeProfile') || null;
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/utils/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Ora } from 'ora';
|
|
2
|
+
/**
|
|
3
|
+
* Standardized error handler for CLI commands.
|
|
4
|
+
* Stops the spinner and prints a formatted error message.
|
|
5
|
+
*
|
|
6
|
+
* @param {object|null} spinner - Ora spinner instance (will be stopped/failed)
|
|
7
|
+
* @param {Error} error - The error object
|
|
8
|
+
* @param {string} [context] - Optional context (e.g., "Failed to list issues")
|
|
9
|
+
*/
|
|
10
|
+
export declare function handleCommandError(spinner: Ora | null, error: any, context?: string): void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
/**
|
|
3
|
+
* Standardized error handler for CLI commands.
|
|
4
|
+
* Stops the spinner and prints a formatted error message.
|
|
5
|
+
*
|
|
6
|
+
* @param {object|null} spinner - Ora spinner instance (will be stopped/failed)
|
|
7
|
+
* @param {Error} error - The error object
|
|
8
|
+
* @param {string} [context] - Optional context (e.g., "Failed to list issues")
|
|
9
|
+
*/
|
|
10
|
+
export function handleCommandError(spinner, error, context = 'Operation failed') {
|
|
11
|
+
// Handle user cancellation (Ctrl+C in enquirer)
|
|
12
|
+
if (error === '' || (error && error.message === '')) {
|
|
13
|
+
if (spinner)
|
|
14
|
+
spinner.stop();
|
|
15
|
+
console.log(chalk.yellow('\nCancelled.'));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (spinner) {
|
|
19
|
+
spinner.fail(context);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
console.error(chalk.red(`\n${context}:`));
|
|
23
|
+
}
|
|
24
|
+
if (error.response) {
|
|
25
|
+
const status = error.response.status;
|
|
26
|
+
if (status === 404) {
|
|
27
|
+
console.error(chalk.red('Resource not found. Check the ID or key.'));
|
|
28
|
+
}
|
|
29
|
+
else if (status === 400) {
|
|
30
|
+
const data = error.response.data;
|
|
31
|
+
const messages = data?.errorMessages?.join(', ') || (data?.errors
|
|
32
|
+
? Object.entries(data.errors).map(([k, v]) => `${k}: ${v}`).join(', ')
|
|
33
|
+
: JSON.stringify(data));
|
|
34
|
+
console.error(chalk.red(`Bad Request: ${messages}`));
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.error(chalk.red(`Error ${status}: `), error.response.data);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
console.error(chalk.red(error.message));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=error-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../../src/utils/error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAmB,EAAE,KAAU,EAAE,OAAO,GAAG,kBAAkB;IAC5F,gDAAgD;IAChD,IAAI,KAAK,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,EAAE,CAAC,EAAE,CAAC;QAClD,IAAI,OAAO;YAAE,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC;QAC1C,OAAO;IACX,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACV,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QACrC,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC,CAAC;QACzE,CAAC;aAAM,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjC,MAAM,QAAQ,GAAG,IAAI,EAAE,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM;gBAC7D,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;gBACtE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,QAAQ,EAAE,CAAC,CAAC,CAAC;QACzD,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,MAAM,IAAI,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACvE,CAAC;IACL,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5C,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts plain text to Atlassian Document Format (ADF).
|
|
3
|
+
* Splits on newlines to create separate paragraphs.
|
|
4
|
+
*
|
|
5
|
+
* @param {string} text - Plain text string
|
|
6
|
+
* @returns {object} ADF document node
|
|
7
|
+
*/
|
|
8
|
+
export declare function textToADF(text: any): {
|
|
9
|
+
type: string;
|
|
10
|
+
version: number;
|
|
11
|
+
content: {
|
|
12
|
+
type: string;
|
|
13
|
+
content: {
|
|
14
|
+
type: string;
|
|
15
|
+
text: string;
|
|
16
|
+
}[];
|
|
17
|
+
}[];
|
|
18
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts plain text to Atlassian Document Format (ADF).
|
|
3
|
+
* Splits on newlines to create separate paragraphs.
|
|
4
|
+
*
|
|
5
|
+
* @param {string} text - Plain text string
|
|
6
|
+
* @returns {object} ADF document node
|
|
7
|
+
*/
|
|
8
|
+
export function textToADF(text) {
|
|
9
|
+
if (!text || typeof text !== 'string') {
|
|
10
|
+
return {
|
|
11
|
+
type: 'doc',
|
|
12
|
+
version: 1,
|
|
13
|
+
content: [
|
|
14
|
+
{
|
|
15
|
+
type: 'paragraph',
|
|
16
|
+
content: []
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const paragraphs = text.split('\n').map(line => ({
|
|
22
|
+
type: 'paragraph',
|
|
23
|
+
content: line.trim().length > 0
|
|
24
|
+
? [{ type: 'text', text: line }]
|
|
25
|
+
: []
|
|
26
|
+
}));
|
|
27
|
+
return {
|
|
28
|
+
type: 'doc',
|
|
29
|
+
version: 1,
|
|
30
|
+
content: paragraphs
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=text-to-adf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-to-adf.js","sourceRoot":"","sources":["../../../src/utils/text-to-adf.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,IAAS;IAC/B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO;YACH,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,CAAC;YACV,OAAO,EAAE;gBACL;oBACI,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE,EAAE;iBACd;aACJ;SACJ,CAAC;IACN,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC7C,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;YAC3B,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YAChC,CAAC,CAAC,EAAE;KACX,CAAC,CAAC,CAAC;IAEJ,OAAO;QACH,IAAI,EAAE,KAAK;QACX,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,UAAU;KACtB,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input Validators for CLI commands.
|
|
3
|
+
* Validates user input before API calls to catch errors early.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Validates a Jira issue key format (e.g., PROJ-123).
|
|
7
|
+
* @param {string} key - The issue key to validate.
|
|
8
|
+
* @returns {{ valid: boolean, message?: string }}
|
|
9
|
+
*/
|
|
10
|
+
export declare function validateIssueKey(key: any): {
|
|
11
|
+
valid: boolean;
|
|
12
|
+
message?: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Validates a Jira project key (e.g., PROJ).
|
|
16
|
+
* @param {string} key - The project key to validate.
|
|
17
|
+
* @returns {{ valid: boolean, message?: string }}
|
|
18
|
+
*/
|
|
19
|
+
export declare function validateProjectKey(key: any): {
|
|
20
|
+
valid: boolean;
|
|
21
|
+
message?: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Validates a Jira site URL.
|
|
25
|
+
* @param {string} url - The URL to validate.
|
|
26
|
+
* @returns {{ valid: boolean, message?: string }}
|
|
27
|
+
*/
|
|
28
|
+
export declare function validateUrl(url: any): {
|
|
29
|
+
valid: boolean;
|
|
30
|
+
message?: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Sanitizes a JQL string by escaping potentially dangerous characters.
|
|
34
|
+
* This is a basic sanitization — Jira's API does its own validation too.
|
|
35
|
+
* @param {string} jql - The JQL query string.
|
|
36
|
+
* @returns {string} The sanitized JQL string.
|
|
37
|
+
*/
|
|
38
|
+
export declare function sanitizeJql(jql: any): string;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input Validators for CLI commands.
|
|
3
|
+
* Validates user input before API calls to catch errors early.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Validates a Jira issue key format (e.g., PROJ-123).
|
|
7
|
+
* @param {string} key - The issue key to validate.
|
|
8
|
+
* @returns {{ valid: boolean, message?: string }}
|
|
9
|
+
*/
|
|
10
|
+
export function validateIssueKey(key) {
|
|
11
|
+
if (!key || typeof key !== 'string') {
|
|
12
|
+
return { valid: false, message: 'Issue key is required.' };
|
|
13
|
+
}
|
|
14
|
+
const trimmed = key.trim().toUpperCase();
|
|
15
|
+
const pattern = /^[A-Z][A-Z0-9_]+-\d+$/;
|
|
16
|
+
if (!pattern.test(trimmed)) {
|
|
17
|
+
return {
|
|
18
|
+
valid: false,
|
|
19
|
+
message: `Invalid issue key "${key}". Expected format: PROJ-123 (letters/numbers, dash, digits).`
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return { valid: true };
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Validates a Jira project key (e.g., PROJ).
|
|
26
|
+
* @param {string} key - The project key to validate.
|
|
27
|
+
* @returns {{ valid: boolean, message?: string }}
|
|
28
|
+
*/
|
|
29
|
+
export function validateProjectKey(key) {
|
|
30
|
+
if (!key || typeof key !== 'string') {
|
|
31
|
+
return { valid: false, message: 'Project key is required.' };
|
|
32
|
+
}
|
|
33
|
+
const trimmed = key.trim().toUpperCase();
|
|
34
|
+
const pattern = /^[A-Z][A-Z0-9_]+$/;
|
|
35
|
+
if (!pattern.test(trimmed)) {
|
|
36
|
+
return {
|
|
37
|
+
valid: false,
|
|
38
|
+
message: `Invalid project key "${key}". Must start with a letter and contain only uppercase letters, digits, or underscores.`
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return { valid: true };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Validates a Jira site URL.
|
|
45
|
+
* @param {string} url - The URL to validate.
|
|
46
|
+
* @returns {{ valid: boolean, message?: string }}
|
|
47
|
+
*/
|
|
48
|
+
export function validateUrl(url) {
|
|
49
|
+
if (!url || typeof url !== 'string') {
|
|
50
|
+
return { valid: false, message: 'URL is required.' };
|
|
51
|
+
}
|
|
52
|
+
const trimmed = url.trim();
|
|
53
|
+
try {
|
|
54
|
+
const parsed = new URL(trimmed);
|
|
55
|
+
if (!['http:', 'https:'].includes(parsed.protocol)) {
|
|
56
|
+
return { valid: false, message: 'URL must use http or https protocol.' };
|
|
57
|
+
}
|
|
58
|
+
return { valid: true };
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return { valid: false, message: `Invalid URL: "${url}". Example: https://your-company.atlassian.net` };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Sanitizes a JQL string by escaping potentially dangerous characters.
|
|
66
|
+
* This is a basic sanitization — Jira's API does its own validation too.
|
|
67
|
+
* @param {string} jql - The JQL query string.
|
|
68
|
+
* @returns {string} The sanitized JQL string.
|
|
69
|
+
*/
|
|
70
|
+
export function sanitizeJql(jql) {
|
|
71
|
+
if (!jql || typeof jql !== 'string') {
|
|
72
|
+
return '';
|
|
73
|
+
}
|
|
74
|
+
// Remove null bytes and control characters
|
|
75
|
+
return jql.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '').trim();
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=validators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../../../src/utils/validators.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAQ;IACrC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC;IAC/D,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,uBAAuB,CAAC;IAExC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,OAAO;YACH,KAAK,EAAE,KAAK;YACZ,OAAO,EAAE,sBAAsB,GAAG,+DAA+D;SACpG,CAAC;IACN,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAQ;IACvC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC;IACjE,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,mBAAmB,CAAC;IAEpC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,OAAO;YACH,KAAK,EAAE,KAAK;YACZ,OAAO,EAAE,wBAAwB,GAAG,yFAAyF;SAChI,CAAC;IACN,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,GAAQ;IAChC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC;IACzD,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAE3B,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QAChC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,sCAAsC,EAAE,CAAC;QAC7E,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,iBAAiB,GAAG,gDAAgD,EAAE,CAAC;IAC3G,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,GAAQ;IAChC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,EAAE,CAAC;IACd,CAAC;IAED,2CAA2C;IAC3C,OAAO,GAAG,CAAC,OAAO,CAAC,mCAAmC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AACvE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jira-pilot",
|
|
3
|
-
"version": "2.1.
|
|
4
|
-
"description": "AI powered Jira CLI and MCP server for humans and agents — manage issues, sprints, boards with interactive wizards, multi-provider AI (OpenAI/Gemini/Anthropic), and an
|
|
3
|
+
"version": "2.1.2",
|
|
4
|
+
"description": "AI powered Jira CLI and MCP server for humans and agents — manage issues, sprints, boards with interactive wizards, multi-provider AI (OpenAI/Gemini/Anthropic), and an 14-tool MCP server for AI assistants",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
"jira-pilot": "./dist/bin/jira.js"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
|
+
"clean": "rimraf dist",
|
|
13
|
+
"prebuild": "npm run clean",
|
|
12
14
|
"build": "tsc",
|
|
13
15
|
"start": "node dist/bin/jira.js",
|
|
14
16
|
"start:dev": "tsx bin/jira.ts",
|
|
@@ -24,6 +26,7 @@
|
|
|
24
26
|
"node": ">=20.0.0"
|
|
25
27
|
},
|
|
26
28
|
"files": [
|
|
29
|
+
"dist/",
|
|
27
30
|
"bin/",
|
|
28
31
|
"src/",
|
|
29
32
|
"README.md",
|
|
@@ -90,6 +93,7 @@
|
|
|
90
93
|
"devDependencies": {
|
|
91
94
|
"@types/node": "^25.2.3",
|
|
92
95
|
"@vitest/coverage-v8": "^4.0.18",
|
|
96
|
+
"rimraf": "^6.1.2",
|
|
93
97
|
"tsx": "^4.21.0",
|
|
94
98
|
"typescript": "^5.9.3",
|
|
95
99
|
"vitest": "^4.0.18"
|