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,151 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { getCredentials } from '../utils/config.js';
|
|
3
|
+
export class AiService {
|
|
4
|
+
constructor() { }
|
|
5
|
+
async generate(prompt) {
|
|
6
|
+
const { aiKey, aiProvider, enableAi } = getCredentials();
|
|
7
|
+
if (!enableAi) {
|
|
8
|
+
throw new Error('AI features are disabled. Run "jira config ai enable" to enable.');
|
|
9
|
+
}
|
|
10
|
+
if (!aiKey) {
|
|
11
|
+
throw new Error('AI API Key not configured. Run "jira config ai enable" or "jira config setup".');
|
|
12
|
+
}
|
|
13
|
+
const provider = aiProvider || 'openai';
|
|
14
|
+
switch (provider) {
|
|
15
|
+
case 'openai':
|
|
16
|
+
return this.callOpenAI(aiKey, prompt);
|
|
17
|
+
case 'gemini':
|
|
18
|
+
return this.callGemini(aiKey, prompt);
|
|
19
|
+
case 'anthropic':
|
|
20
|
+
return this.callAnthropic(aiKey, prompt);
|
|
21
|
+
default:
|
|
22
|
+
throw new Error(`Unsupported AI Provider: ${provider}. Supported: openai, gemini, anthropic`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async reviewCode(diff, context) {
|
|
26
|
+
const prompt = `Review the following code changes against the issue context.
|
|
27
|
+
Issue Context: ${context}
|
|
28
|
+
|
|
29
|
+
Code Diff:
|
|
30
|
+
\`\`\`diff
|
|
31
|
+
${diff.substring(0, 10000)}
|
|
32
|
+
\`\`\`
|
|
33
|
+
(Diff truncated to 10k chars if longer)
|
|
34
|
+
|
|
35
|
+
Provide a concise code review. Focus on:
|
|
36
|
+
1. Does it meet the issue requirements?
|
|
37
|
+
2. Potential bugs or security issues.
|
|
38
|
+
3. Code quality improvements.
|
|
39
|
+
4. Verify if tests are included if applicable.`;
|
|
40
|
+
return this.generate(prompt);
|
|
41
|
+
}
|
|
42
|
+
async breakdownEpic(summary, description) {
|
|
43
|
+
const prompt = `Break down the following Epic into child Stories and Tasks.
|
|
44
|
+
Epic Summary: ${summary}
|
|
45
|
+
Epic Description: ${description || 'N/A'}
|
|
46
|
+
|
|
47
|
+
Return ONLY a valid JSON array of objects with "type" (Story, Task, Bug), "summary", and "description" fields.
|
|
48
|
+
Example: [{"type": "Story", "summary": "...", "description": "..."}]`;
|
|
49
|
+
const response = await this.generate(prompt);
|
|
50
|
+
// Clean markdown code blocks if present
|
|
51
|
+
const jsonStr = response.replace(/```json/g, '').replace(/```/g, '').trim();
|
|
52
|
+
return JSON.parse(jsonStr);
|
|
53
|
+
}
|
|
54
|
+
async generateStandup(yesterday, today) {
|
|
55
|
+
const prompt = `Generate a daily standup update based on my Jira activity.
|
|
56
|
+
Activity (Last 24h):
|
|
57
|
+
${yesterday}
|
|
58
|
+
|
|
59
|
+
Current Assignments (Today):
|
|
60
|
+
${today}
|
|
61
|
+
|
|
62
|
+
Format:
|
|
63
|
+
* **Yesterday**: (Completed items, progress made)
|
|
64
|
+
* **Today**: (Plan for today based on assignments)
|
|
65
|
+
* **Blockers**: (Identify potential blockers or ask if any)
|
|
66
|
+
|
|
67
|
+
Keep it concise and professional.`;
|
|
68
|
+
return this.generate(prompt);
|
|
69
|
+
}
|
|
70
|
+
async generateJql(query) {
|
|
71
|
+
const prompt = `Convert the following natural language query into Jira JQL.
|
|
72
|
+
Query: "${query}"
|
|
73
|
+
|
|
74
|
+
Return ONLY the raw JQL string. No markdown, no explanations.
|
|
75
|
+
Today is ${new Date().toISOString().split('T')[0]}.`;
|
|
76
|
+
const response = await this.generate(prompt);
|
|
77
|
+
return response.replace(/```/g, '').trim();
|
|
78
|
+
}
|
|
79
|
+
async callOpenAI(key, prompt) {
|
|
80
|
+
try {
|
|
81
|
+
const response = await axios.post('https://api.openai.com/v1/chat/completions', {
|
|
82
|
+
model: 'gpt-4o',
|
|
83
|
+
messages: [{ role: 'user', content: prompt }],
|
|
84
|
+
temperature: 0.7
|
|
85
|
+
}, {
|
|
86
|
+
headers: { 'Authorization': `Bearer ${key}` }
|
|
87
|
+
});
|
|
88
|
+
return response.data.choices[0].message.content;
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
throw new Error(`OpenAI API Error: ${e.response?.data?.error?.message || e.message}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async callGemini(key, prompt) {
|
|
95
|
+
try {
|
|
96
|
+
// Gemini REST API — uses generativelanguage.googleapis.com
|
|
97
|
+
const model = 'gemini-2.0-flash';
|
|
98
|
+
const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${key}`;
|
|
99
|
+
const response = await axios.post(url, {
|
|
100
|
+
contents: [{
|
|
101
|
+
parts: [{ text: prompt }]
|
|
102
|
+
}],
|
|
103
|
+
generationConfig: {
|
|
104
|
+
temperature: 0.7,
|
|
105
|
+
maxOutputTokens: 2048
|
|
106
|
+
}
|
|
107
|
+
}, {
|
|
108
|
+
headers: { 'Content-Type': 'application/json' }
|
|
109
|
+
});
|
|
110
|
+
const candidates = response.data.candidates;
|
|
111
|
+
if (!candidates || candidates.length === 0) {
|
|
112
|
+
throw new Error('No response generated by Gemini.');
|
|
113
|
+
}
|
|
114
|
+
return candidates[0].content.parts.map((p) => p.text).join('');
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
if (e.response?.data?.error) {
|
|
118
|
+
throw new Error(`Gemini API Error: ${e.response.data.error.message}`);
|
|
119
|
+
}
|
|
120
|
+
throw new Error(`Gemini API Error: ${e.message}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async callAnthropic(key, prompt) {
|
|
124
|
+
try {
|
|
125
|
+
// Anthropic Messages API
|
|
126
|
+
const response = await axios.post('https://api.anthropic.com/v1/messages', {
|
|
127
|
+
model: 'claude-sonnet-4-20250514',
|
|
128
|
+
max_tokens: 2048,
|
|
129
|
+
messages: [{ role: 'user', content: prompt }]
|
|
130
|
+
}, {
|
|
131
|
+
headers: {
|
|
132
|
+
'x-api-key': key,
|
|
133
|
+
'anthropic-version': '2023-06-01',
|
|
134
|
+
'Content-Type': 'application/json'
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
return response.data.content
|
|
138
|
+
.filter((block) => block.type === 'text')
|
|
139
|
+
.map((block) => block.text)
|
|
140
|
+
.join('');
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
if (e.response?.data?.error) {
|
|
144
|
+
throw new Error(`Anthropic API Error: ${e.response.data.error.message}`);
|
|
145
|
+
}
|
|
146
|
+
throw new Error(`Anthropic API Error: ${e.message}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
export const aiService = new AiService();
|
|
151
|
+
//# sourceMappingURL=ai-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-service.js","sourceRoot":"","sources":["../../../src/services/ai-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare class ApiService {
|
|
2
|
+
private client;
|
|
3
|
+
private agileClient;
|
|
4
|
+
private _domain;
|
|
5
|
+
constructor();
|
|
6
|
+
init(): void;
|
|
7
|
+
/** @returns {string} The Jira domain URL */
|
|
8
|
+
get domain(): string | null;
|
|
9
|
+
ensureClient(): void;
|
|
10
|
+
get(url: string, config?: any): Promise<any>;
|
|
11
|
+
post(url: string, data: any, config?: any): Promise<any>;
|
|
12
|
+
put(url: string, data: any, config?: any): Promise<any>;
|
|
13
|
+
delete(url: string, config?: any): Promise<any>;
|
|
14
|
+
upload(url: string, formData: any): Promise<any>;
|
|
15
|
+
agileGet(url: string, config?: any): Promise<any>;
|
|
16
|
+
agilePost(url: string, data: any, config?: any): Promise<any>;
|
|
17
|
+
}
|
|
18
|
+
export declare const api: ApiService;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { getCredentials } from '../utils/config.js';
|
|
4
|
+
export class ApiService {
|
|
5
|
+
client;
|
|
6
|
+
agileClient;
|
|
7
|
+
_domain = null;
|
|
8
|
+
constructor() {
|
|
9
|
+
this.init();
|
|
10
|
+
}
|
|
11
|
+
init() {
|
|
12
|
+
const { jiraUrl, email, apiToken } = getCredentials();
|
|
13
|
+
if (!jiraUrl || !email || !apiToken) {
|
|
14
|
+
this.client = null;
|
|
15
|
+
this._domain = null;
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const match = jiraUrl.match(/^https?:\/\/(.+?)(\/|$)/);
|
|
19
|
+
this._domain = match ? match[0].replace(/\/$/, '') : jiraUrl;
|
|
20
|
+
const authHeader = `Basic ${Buffer.from(`${email}:${apiToken}`).toString('base64')}`;
|
|
21
|
+
// Standard REST API v3 client
|
|
22
|
+
this.client = axios.create({
|
|
23
|
+
baseURL: `${this._domain}/rest/api/3`,
|
|
24
|
+
headers: {
|
|
25
|
+
'Authorization': authHeader,
|
|
26
|
+
'Accept': 'application/json',
|
|
27
|
+
'Content-Type': 'application/json'
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
// Agile REST API v1 client (for boards, sprints, etc.)
|
|
31
|
+
this.agileClient = axios.create({
|
|
32
|
+
baseURL: `${this._domain}/rest/agile/1.0`,
|
|
33
|
+
headers: {
|
|
34
|
+
'Authorization': authHeader,
|
|
35
|
+
'Accept': 'application/json',
|
|
36
|
+
'Content-Type': 'application/json'
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
// Shared response interceptor
|
|
40
|
+
const errorInterceptor = (error) => {
|
|
41
|
+
if (error.response) {
|
|
42
|
+
if (error.response.status === 401) {
|
|
43
|
+
console.error(chalk.red('Authentication failed. Please check your credentials using "jira config".'));
|
|
44
|
+
}
|
|
45
|
+
else if (error.response.status === 403) {
|
|
46
|
+
console.error(chalk.red('Access denied. You may not have permission for this resource.'));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return Promise.reject(error);
|
|
50
|
+
};
|
|
51
|
+
this.client.interceptors.response.use((r) => r, errorInterceptor);
|
|
52
|
+
this.agileClient.interceptors.response.use((r) => r, errorInterceptor);
|
|
53
|
+
}
|
|
54
|
+
/** @returns {string} The Jira domain URL */
|
|
55
|
+
get domain() {
|
|
56
|
+
return this._domain;
|
|
57
|
+
}
|
|
58
|
+
ensureClient() {
|
|
59
|
+
if (!this.client) {
|
|
60
|
+
this.init();
|
|
61
|
+
if (!this.client) {
|
|
62
|
+
throw new Error('Jira credentials not configured. Run "jira config" first.');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// ── Standard REST API v3 Methods ────────────────────────────────
|
|
67
|
+
async get(url, config = {}) {
|
|
68
|
+
this.ensureClient();
|
|
69
|
+
const response = await this.client.get(url, config);
|
|
70
|
+
return response.data;
|
|
71
|
+
}
|
|
72
|
+
async post(url, data, config = {}) {
|
|
73
|
+
this.ensureClient();
|
|
74
|
+
const response = await this.client.post(url, data, config);
|
|
75
|
+
return response.data;
|
|
76
|
+
}
|
|
77
|
+
async put(url, data, config = {}) {
|
|
78
|
+
this.ensureClient();
|
|
79
|
+
const response = await this.client.put(url, data, config);
|
|
80
|
+
return response.data;
|
|
81
|
+
}
|
|
82
|
+
async delete(url, config = {}) {
|
|
83
|
+
this.ensureClient();
|
|
84
|
+
const response = await this.client.delete(url, config);
|
|
85
|
+
return response.data;
|
|
86
|
+
}
|
|
87
|
+
async upload(url, formData) {
|
|
88
|
+
this.ensureClient();
|
|
89
|
+
// Jira requires this header for attachments
|
|
90
|
+
const headers = {
|
|
91
|
+
'X-Atlassian-Token': 'no-check'
|
|
92
|
+
};
|
|
93
|
+
// If using 'form-data' package, it has getHeaders().
|
|
94
|
+
// If using native FormData, axios/adapter handles Content-Type + boundary.
|
|
95
|
+
if (formData.getHeaders) {
|
|
96
|
+
Object.assign(headers, formData.getHeaders());
|
|
97
|
+
}
|
|
98
|
+
const config = { headers };
|
|
99
|
+
const response = await this.client.post(url, formData, config);
|
|
100
|
+
return response.data;
|
|
101
|
+
}
|
|
102
|
+
// ── Agile REST API v1 Methods ───────────────────────────────────
|
|
103
|
+
async agileGet(url, config = {}) {
|
|
104
|
+
this.ensureClient();
|
|
105
|
+
const response = await this.agileClient.get(url, config);
|
|
106
|
+
return response.data;
|
|
107
|
+
}
|
|
108
|
+
async agilePost(url, data, config = {}) {
|
|
109
|
+
this.ensureClient();
|
|
110
|
+
const response = await this.agileClient.post(url, data, config);
|
|
111
|
+
return response.data;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export const api = new ApiService();
|
|
115
|
+
//# sourceMappingURL=api-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-service.js","sourceRoot":"","sources":["../../../src/services/api-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import ConfigStore from '../utils/config-store.js';
|
|
2
|
+
const config = new ConfigStore('jira-pilot');
|
|
3
|
+
export class ConfigService {
|
|
4
|
+
static getConfig() {
|
|
5
|
+
return config.all;
|
|
6
|
+
}
|
|
7
|
+
static saveConfig(newConfig) {
|
|
8
|
+
config.all = newConfig;
|
|
9
|
+
}
|
|
10
|
+
static get(key) {
|
|
11
|
+
return config.get(key);
|
|
12
|
+
}
|
|
13
|
+
static set(key, value) {
|
|
14
|
+
config.set(key, value);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=config-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-service.js","sourceRoot":"","sources":["../../../src/services/config-service.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,0BAA0B,CAAC;AAEnD,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,YAAY,CAAC,CAAC;AAE7C,MAAM,OAAO,aAAa;IACtB,MAAM,CAAC,SAAS;QACZ,OAAO,MAAM,CAAC,GAAG,CAAC;IACtB,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,SAAc;QAC5B,MAAM,CAAC,GAAG,GAAG,SAAS,CAAC;IAC3B,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,GAAW;QAClB,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,GAAW,EAAE,KAAU;QAC9B,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC3B,CAAC;CACJ"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export interface JiraIssue {
|
|
2
|
+
key: string;
|
|
3
|
+
fields: {
|
|
4
|
+
summary: string;
|
|
5
|
+
description?: any;
|
|
6
|
+
status: {
|
|
7
|
+
name: string;
|
|
8
|
+
id?: string;
|
|
9
|
+
};
|
|
10
|
+
priority?: {
|
|
11
|
+
name: string;
|
|
12
|
+
id?: string;
|
|
13
|
+
};
|
|
14
|
+
assignee?: {
|
|
15
|
+
accountId: string;
|
|
16
|
+
displayName: string;
|
|
17
|
+
emailAddress?: string;
|
|
18
|
+
};
|
|
19
|
+
issuetype: {
|
|
20
|
+
name: string;
|
|
21
|
+
id?: string;
|
|
22
|
+
subtask?: boolean;
|
|
23
|
+
};
|
|
24
|
+
created: string;
|
|
25
|
+
updated: string;
|
|
26
|
+
comment?: {
|
|
27
|
+
comments: Array<{
|
|
28
|
+
id: string;
|
|
29
|
+
body: string;
|
|
30
|
+
author: {
|
|
31
|
+
displayName: string;
|
|
32
|
+
accountId: string;
|
|
33
|
+
};
|
|
34
|
+
created: string;
|
|
35
|
+
}>;
|
|
36
|
+
total: number;
|
|
37
|
+
};
|
|
38
|
+
[key: string]: any;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export interface JiraProject {
|
|
42
|
+
key: string;
|
|
43
|
+
name: string;
|
|
44
|
+
id: string;
|
|
45
|
+
lead?: {
|
|
46
|
+
displayName: string;
|
|
47
|
+
};
|
|
48
|
+
style?: string;
|
|
49
|
+
issueTypes?: Array<{
|
|
50
|
+
name: string;
|
|
51
|
+
subtask?: boolean;
|
|
52
|
+
id: string;
|
|
53
|
+
}>;
|
|
54
|
+
}
|
|
55
|
+
export interface JiraSprint {
|
|
56
|
+
id: number;
|
|
57
|
+
name: string;
|
|
58
|
+
state: 'active' | 'future' | 'closed';
|
|
59
|
+
startDate?: string;
|
|
60
|
+
endDate?: string;
|
|
61
|
+
originBoardId?: number;
|
|
62
|
+
}
|
|
63
|
+
export interface JiraBoard {
|
|
64
|
+
id: number;
|
|
65
|
+
name: string;
|
|
66
|
+
type: string;
|
|
67
|
+
location?: {
|
|
68
|
+
projectId: number;
|
|
69
|
+
displayName: string;
|
|
70
|
+
projectKey: string;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export interface ConfigProfile {
|
|
74
|
+
jiraUrl: string;
|
|
75
|
+
email: string;
|
|
76
|
+
apiToken: string;
|
|
77
|
+
aiEnabled?: boolean;
|
|
78
|
+
enableAi?: boolean;
|
|
79
|
+
aiProvider?: 'openai' | 'gemini' | 'anthropic';
|
|
80
|
+
aiKey?: string;
|
|
81
|
+
aiConfig?: {
|
|
82
|
+
apiKey?: string;
|
|
83
|
+
model?: string;
|
|
84
|
+
};
|
|
85
|
+
githubToken?: string;
|
|
86
|
+
}
|
|
87
|
+
export interface GlobalConfig {
|
|
88
|
+
profiles: Record<string, ConfigProfile>;
|
|
89
|
+
currentProfile?: string;
|
|
90
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function parseADF(content: any): any;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export function parseADF(content) {
|
|
2
|
+
if (!content)
|
|
3
|
+
return '';
|
|
4
|
+
if (typeof content === 'string')
|
|
5
|
+
return content;
|
|
6
|
+
if (content.type === 'doc') {
|
|
7
|
+
return content.content.map((node) => parseNode(node)).join('\n');
|
|
8
|
+
}
|
|
9
|
+
return JSON.stringify(content);
|
|
10
|
+
}
|
|
11
|
+
function parseNode(node) {
|
|
12
|
+
if (!node)
|
|
13
|
+
return '';
|
|
14
|
+
switch (node.type) {
|
|
15
|
+
case 'paragraph':
|
|
16
|
+
return parseParagraph(node);
|
|
17
|
+
case 'text':
|
|
18
|
+
return node.text;
|
|
19
|
+
case 'bulletList':
|
|
20
|
+
return parseList(node, '•');
|
|
21
|
+
case 'orderedList':
|
|
22
|
+
return parseList(node, '1.');
|
|
23
|
+
case 'heading':
|
|
24
|
+
return `\n${'#'.repeat(node.attrs?.level || 1)} ${node.content.map((c) => parseNode(c)).join('')}\n`;
|
|
25
|
+
case 'codeBlock':
|
|
26
|
+
return `\n\`\`\`${node.attrs?.language || ''}\n${node.content.map((c) => c.text).join('')}\n\`\`\`\n`;
|
|
27
|
+
case 'blockquote':
|
|
28
|
+
return `> ${node.content.map((c) => parseNode(c)).join('')}`;
|
|
29
|
+
default:
|
|
30
|
+
if (node.content) {
|
|
31
|
+
return node.content.map((c) => parseNode(c)).join('');
|
|
32
|
+
}
|
|
33
|
+
return ''; // Unknown node, skip or fallback
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function parseParagraph(node) {
|
|
37
|
+
if (!node.content)
|
|
38
|
+
return '\n';
|
|
39
|
+
return node.content.map((c) => parseNode(c)).join('') + '\n';
|
|
40
|
+
}
|
|
41
|
+
function parseList(node, marker) {
|
|
42
|
+
if (!node.content)
|
|
43
|
+
return '';
|
|
44
|
+
return node.content.map((item, index) => {
|
|
45
|
+
const prefix = marker === '1.' ? `${index + 1}. ` : `${marker} `;
|
|
46
|
+
return `${prefix}${item.content.map((c) => parseNode(c)).join('')}`;
|
|
47
|
+
}).join('\n') + '\n';
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=adf-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adf-parser.js","sourceRoot":"","sources":["../../../src/utils/adf-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
declare class ConfigStore {
|
|
2
|
+
private dir;
|
|
3
|
+
private path;
|
|
4
|
+
constructor(projectName: string);
|
|
5
|
+
ensureDir(): void;
|
|
6
|
+
load(): any;
|
|
7
|
+
save(data: any): void;
|
|
8
|
+
get(key?: string): any;
|
|
9
|
+
set(key: string, value: any): void;
|
|
10
|
+
delete(key: string): void;
|
|
11
|
+
clear(): void;
|
|
12
|
+
get all(): any;
|
|
13
|
+
set all(data: any);
|
|
14
|
+
}
|
|
15
|
+
export default ConfigStore;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
function getAppDataPath() {
|
|
5
|
+
if (process.platform === 'win32') {
|
|
6
|
+
return process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming');
|
|
7
|
+
}
|
|
8
|
+
if (process.platform === 'darwin') {
|
|
9
|
+
return path.join(os.homedir(), 'Library', 'Preferences');
|
|
10
|
+
}
|
|
11
|
+
return process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
|
|
12
|
+
}
|
|
13
|
+
class ConfigStore {
|
|
14
|
+
dir;
|
|
15
|
+
path;
|
|
16
|
+
constructor(projectName) {
|
|
17
|
+
this.dir = path.join(getAppDataPath(), projectName);
|
|
18
|
+
this.path = path.join(this.dir, 'config.json');
|
|
19
|
+
this.ensureDir();
|
|
20
|
+
}
|
|
21
|
+
ensureDir() {
|
|
22
|
+
if (!fs.existsSync(this.dir)) {
|
|
23
|
+
fs.mkdirSync(this.dir, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
load() {
|
|
27
|
+
try {
|
|
28
|
+
if (!fs.existsSync(this.path))
|
|
29
|
+
return {};
|
|
30
|
+
return JSON.parse(fs.readFileSync(this.path, 'utf8'));
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
return {};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
save(data) {
|
|
37
|
+
this.ensureDir();
|
|
38
|
+
fs.writeFileSync(this.path, JSON.stringify(data, null, 4), 'utf8');
|
|
39
|
+
}
|
|
40
|
+
get(key) {
|
|
41
|
+
const data = this.load();
|
|
42
|
+
if (!key)
|
|
43
|
+
return data;
|
|
44
|
+
// Support dot notation: profiles.work
|
|
45
|
+
const parts = key.split('.');
|
|
46
|
+
let current = data;
|
|
47
|
+
for (const part of parts) {
|
|
48
|
+
if (current === undefined || current === null)
|
|
49
|
+
return undefined;
|
|
50
|
+
current = current[part];
|
|
51
|
+
}
|
|
52
|
+
return current;
|
|
53
|
+
}
|
|
54
|
+
set(key, value) {
|
|
55
|
+
const data = this.load();
|
|
56
|
+
const parts = key.split('.');
|
|
57
|
+
const last = parts.pop();
|
|
58
|
+
if (!last)
|
|
59
|
+
return;
|
|
60
|
+
let current = data;
|
|
61
|
+
for (const part of parts) {
|
|
62
|
+
if (typeof current[part] !== 'object' || current[part] === null) {
|
|
63
|
+
current[part] = {};
|
|
64
|
+
}
|
|
65
|
+
current = current[part];
|
|
66
|
+
}
|
|
67
|
+
current[last] = value;
|
|
68
|
+
this.save(data);
|
|
69
|
+
}
|
|
70
|
+
delete(key) {
|
|
71
|
+
const data = this.load();
|
|
72
|
+
const parts = key.split('.');
|
|
73
|
+
const last = parts.pop();
|
|
74
|
+
if (!last)
|
|
75
|
+
return; // Should not happen
|
|
76
|
+
let current = data;
|
|
77
|
+
for (const part of parts) {
|
|
78
|
+
if (current === undefined || current === null)
|
|
79
|
+
return; // Key doesn't exist
|
|
80
|
+
current = current[part];
|
|
81
|
+
}
|
|
82
|
+
if (current && typeof current === 'object') {
|
|
83
|
+
delete current[last];
|
|
84
|
+
this.save(data);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
clear() {
|
|
88
|
+
this.save({});
|
|
89
|
+
}
|
|
90
|
+
get all() {
|
|
91
|
+
return this.load();
|
|
92
|
+
}
|
|
93
|
+
set all(data) {
|
|
94
|
+
this.save(data);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export default ConfigStore;
|
|
98
|
+
//# sourceMappingURL=config-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-store.js","sourceRoot":"","sources":["../../../src/utils/config-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ConfigProfile } from '../types.js';
|
|
2
|
+
export declare const getCredentials: () => Partial<ConfigProfile>;
|
|
3
|
+
export declare const setCredentials: ({ jiraUrl, email, apiToken, aiConfig, aiProvider, enableAi, githubToken }: Partial<ConfigProfile>) => void;
|
|
4
|
+
export declare const clearCredentials: () => void;
|
|
5
|
+
export declare const hasCredentials: () => boolean;
|
|
6
|
+
export declare const saveProfile: (name: string) => void;
|
|
7
|
+
export declare const loadProfile: (name: string) => boolean;
|
|
8
|
+
export declare const deleteProfile: (name: string) => void;
|
|
9
|
+
export declare const listProfiles: () => string[];
|
|
10
|
+
export declare const getActiveProfile: () => any;
|