jira-pilot 2.1.2 → 2.1.3
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/README.md +23 -0
- package/bin/jira.ts +2 -0
- package/dist/bin/jira.js +2 -0
- package/dist/bin/jira.js.map +1 -1
- package/dist/src/commands/ai-actions/plan.js +1 -1
- package/dist/src/commands/ai-actions/plan.js.map +1 -1
- package/dist/src/commands/ai-actions/review.js +5 -4
- package/dist/src/commands/ai-actions/review.js.map +1 -1
- package/dist/src/commands/ai-actions/standup.js +1 -1
- package/dist/src/commands/ai-actions/standup.js.map +1 -1
- package/dist/src/commands/ai.js +1 -1
- package/dist/src/commands/ai.js.map +1 -1
- package/dist/src/commands/board.js +10 -5
- package/dist/src/commands/board.js.map +1 -1
- package/dist/src/commands/bulk.js +1 -1
- package/dist/src/commands/bulk.js.map +1 -1
- package/dist/src/commands/config.js +1 -1
- package/dist/src/commands/config.js.map +1 -1
- package/dist/src/commands/dashboard.js +11 -5
- package/dist/src/commands/dashboard.js.map +1 -1
- package/dist/src/commands/filter.js +7 -4
- package/dist/src/commands/filter.js.map +1 -1
- package/dist/src/commands/git.js +1 -1
- package/dist/src/commands/git.js.map +1 -1
- package/dist/src/commands/issue-attach.js +1 -1
- package/dist/src/commands/issue-attach.js.map +1 -1
- package/dist/src/commands/issue-pr.js +1 -1
- package/dist/src/commands/issue-pr.js.map +1 -1
- package/dist/src/commands/issue-worklog.js +10 -5
- package/dist/src/commands/issue-worklog.js.map +1 -1
- package/dist/src/commands/issue.js +142 -87
- package/dist/src/commands/issue.js.map +1 -1
- package/dist/src/commands/project.js +10 -5
- package/dist/src/commands/project.js.map +1 -1
- package/dist/src/commands/sprint.js +19 -8
- package/dist/src/commands/sprint.js.map +1 -1
- package/dist/src/commands/tui.d.ts +2 -0
- package/dist/src/commands/tui.js +10 -0
- package/dist/src/commands/tui.js.map +1 -0
- package/dist/src/services/ai-service.js +7 -4
- package/dist/src/services/ai-service.js.map +1 -1
- package/dist/src/services/api-service.d.ts +2 -0
- package/dist/src/services/api-service.js +29 -20
- package/dist/src/services/api-service.js.map +1 -1
- package/dist/src/tui/App.d.ts +1 -0
- package/dist/src/tui/App.js +26 -0
- package/dist/src/tui/App.js.map +1 -0
- package/dist/src/tui/index.d.ts +1 -0
- package/dist/src/tui/index.js +8 -0
- package/dist/src/tui/index.js.map +1 -0
- package/dist/src/tui/screens/BoardList.d.ts +1 -0
- package/dist/src/tui/screens/BoardList.js +71 -0
- package/dist/src/tui/screens/BoardList.js.map +1 -0
- package/dist/src/tui/screens/Dashboard.d.ts +1 -0
- package/dist/src/tui/screens/Dashboard.js +41 -0
- package/dist/src/tui/screens/Dashboard.js.map +1 -0
- package/dist/src/tui/screens/IssueDetail.d.ts +6 -0
- package/dist/src/tui/screens/IssueDetail.js +40 -0
- package/dist/src/tui/screens/IssueDetail.js.map +1 -0
- package/dist/src/tui/screens/IssueList.d.ts +1 -0
- package/dist/src/tui/screens/IssueList.js +72 -0
- package/dist/src/tui/screens/IssueList.js.map +1 -0
- package/dist/src/tui/screens/KanbanBoard.d.ts +6 -0
- package/dist/src/tui/screens/KanbanBoard.js +86 -0
- package/dist/src/tui/screens/KanbanBoard.js.map +1 -0
- package/dist/src/tui/utils/adf-render.d.ts +1 -0
- package/dist/src/tui/utils/adf-render.js +29 -0
- package/dist/src/tui/utils/adf-render.js.map +1 -0
- package/dist/src/utils/error-handler.d.ts +2 -2
- package/dist/src/utils/error-handler.js.map +1 -1
- package/dist/src/utils/http.d.ts +27 -0
- package/dist/src/utils/http.js +95 -0
- package/dist/src/utils/http.js.map +1 -0
- package/dist/src/utils/spinner.d.ts +21 -0
- package/dist/src/utils/spinner.js +79 -0
- package/dist/src/utils/spinner.js.map +1 -0
- package/package.json +10 -5
- package/src/commands/ai-actions/plan.ts +1 -1
- package/src/commands/ai-actions/review.ts +5 -4
- package/src/commands/ai-actions/standup.ts +1 -1
- package/src/commands/ai.ts +1 -1
- package/src/commands/board.ts +10 -5
- package/src/commands/bulk.ts +1 -1
- package/src/commands/config.ts +1 -1
- package/src/commands/dashboard.ts +11 -5
- package/src/commands/filter.ts +8 -5
- package/src/commands/git.ts +1 -1
- package/src/commands/issue-attach.ts +1 -1
- package/src/commands/issue-pr.ts +1 -1
- package/src/commands/issue-worklog.ts +10 -5
- package/src/commands/issue.ts +149 -89
- package/src/commands/project.ts +10 -5
- package/src/commands/sprint.ts +19 -8
- package/src/commands/tui.ts +11 -0
- package/src/services/ai-service.ts +7 -4
- package/src/services/api-service.ts +29 -21
- package/src/tui/App.tsx +61 -0
- package/src/tui/index.tsx +8 -0
- package/src/tui/screens/BoardList.tsx +102 -0
- package/src/tui/screens/Dashboard.tsx +75 -0
- package/src/tui/screens/IssueDetail.tsx +93 -0
- package/src/tui/screens/IssueList.tsx +116 -0
- package/src/tui/screens/KanbanBoard.tsx +133 -0
- package/src/tui/utils/adf-render.ts +30 -0
- package/src/utils/error-handler.ts +2 -2
- package/src/utils/http.ts +128 -0
- package/src/utils/spinner.ts +87 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { Box, Text, useInput } from 'ink';
|
|
4
|
+
import SpinnerOriginal from 'ink-spinner';
|
|
5
|
+
const Spinner = SpinnerOriginal;
|
|
6
|
+
import { api } from '../../services/api-service.js';
|
|
7
|
+
import { renderADF } from '../utils/adf-render.js';
|
|
8
|
+
export default function IssueDetail({ issueKey, onBack }) {
|
|
9
|
+
const [loading, setLoading] = useState(true);
|
|
10
|
+
const [issue, setIssue] = useState(null);
|
|
11
|
+
const [error, setError] = useState(null);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const fetchIssue = async () => {
|
|
14
|
+
try {
|
|
15
|
+
const results = await api.get(`/issue/${issueKey}`);
|
|
16
|
+
setIssue(results);
|
|
17
|
+
setLoading(false);
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
setError(err.message);
|
|
21
|
+
setLoading(false);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
fetchIssue();
|
|
25
|
+
}, [issueKey]);
|
|
26
|
+
useInput((input, key) => {
|
|
27
|
+
if (key.escape || input === 'b') {
|
|
28
|
+
onBack();
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
if (loading) {
|
|
32
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "green", children: _jsx(Spinner, { type: "dots" }) }), _jsxs(Text, { children: [" Loading Issue ", issueKey, "..."] })] }));
|
|
33
|
+
}
|
|
34
|
+
if (error) {
|
|
35
|
+
return _jsxs(Text, { color: "red", children: ["Error: ", error] });
|
|
36
|
+
}
|
|
37
|
+
const { summary, description, status, priority, assignee, reporter, comment } = issue.fields;
|
|
38
|
+
return (_jsxs(Box, { flexDirection: "column", padding: 1, borderStyle: "single", children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { bold: true, color: "cyan", children: [issue.key, ": ", summary] }) }), _jsxs(Box, { flexDirection: "row", marginBottom: 1, children: [_jsxs(Box, { width: "50%", children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, children: "Status:" }), " ", status.name] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, children: "Priority:" }), " ", priority.name] })] }), _jsxs(Box, { width: "50%", children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, children: "Assignee:" }), " ", assignee ? assignee.displayName : 'Unassigned'] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, children: "Reporter:" }), " ", reporter ? reporter.displayName : 'Unknown'] })] })] }), _jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, underline: true, children: "Description:" }), _jsx(Text, { children: renderADF(description) || 'No description provided.' })] }), comment && comment.comments && comment.comments.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { bold: true, underline: true, children: ["Comments (", comment.total, "):"] }), comment.comments.slice(-3).map((c) => (_jsxs(Box, { borderStyle: "round", borderColor: "gray", padding: 1, marginTop: 1, children: [_jsxs(Text, { bold: true, color: "blue", children: [c.author.displayName, ":"] }), _jsx(Text, { children: renderADF(c.body) })] }, c.id)))] })), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "gray", children: ["Press ", _jsx(Text, { bold: true, children: "Esc" }), " or ", _jsx(Text, { bold: true, children: "b" }), " to go back."] }) })] }));
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=IssueDetail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IssueDetail.js","sourceRoot":"","sources":["../../../../src/tui/screens/IssueDetail.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function IssueList(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { Box, Text, useInput } from 'ink';
|
|
4
|
+
import SpinnerOriginal from 'ink-spinner';
|
|
5
|
+
const Spinner = SpinnerOriginal;
|
|
6
|
+
import { api } from '../../services/api-service.js';
|
|
7
|
+
import IssueDetail from './IssueDetail.js';
|
|
8
|
+
export default function IssueList() {
|
|
9
|
+
const [loading, setLoading] = useState(true);
|
|
10
|
+
const [issues, setIssues] = useState([]);
|
|
11
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
12
|
+
const [selectedIssueKey, setSelectedIssueKey] = useState(null);
|
|
13
|
+
const [error, setError] = useState(null);
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const fetchIssues = async () => {
|
|
16
|
+
try {
|
|
17
|
+
// Default search: Assigned to me or reported by me, unresolved
|
|
18
|
+
const results = await api.search('assignee = currentUser() OR reporter = currentUser() AND resolution = Unresolved order by updated DESC', 0, 20);
|
|
19
|
+
setIssues(results.issues);
|
|
20
|
+
setLoading(false);
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
setError(err.message);
|
|
24
|
+
setLoading(false);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
fetchIssues();
|
|
28
|
+
}, []);
|
|
29
|
+
useInput((input, key) => {
|
|
30
|
+
if (selectedIssueKey)
|
|
31
|
+
return; // Let Detail view handle input if active
|
|
32
|
+
if (key.upArrow) {
|
|
33
|
+
setSelectedIndex((prev) => Math.max(0, prev - 1));
|
|
34
|
+
}
|
|
35
|
+
if (key.downArrow) {
|
|
36
|
+
setSelectedIndex((prev) => Math.min(issues.length - 1, prev + 1));
|
|
37
|
+
}
|
|
38
|
+
if (key.return) {
|
|
39
|
+
if (issues[selectedIndex]) {
|
|
40
|
+
setSelectedIssueKey(issues[selectedIndex].key);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
if (selectedIssueKey) {
|
|
45
|
+
return _jsx(IssueDetail, { issueKey: selectedIssueKey, onBack: () => setSelectedIssueKey(null) });
|
|
46
|
+
}
|
|
47
|
+
if (loading) {
|
|
48
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "green", children: _jsx(Spinner, { type: "dots" }) }), _jsx(Text, { children: " Loading Issues..." })] }));
|
|
49
|
+
}
|
|
50
|
+
// ... rest of the file ...
|
|
51
|
+
if (error) {
|
|
52
|
+
return _jsxs(Text, { color: "red", children: ["Error: ", error] });
|
|
53
|
+
}
|
|
54
|
+
if (issues.length === 0) {
|
|
55
|
+
return _jsx(Text, { children: "No issues found." });
|
|
56
|
+
}
|
|
57
|
+
// Pagination/Windowing logic could go here, for now just slice a window around selected
|
|
58
|
+
const windowSize = 10;
|
|
59
|
+
const start = Math.max(0, selectedIndex - Math.floor(windowSize / 2));
|
|
60
|
+
const end = Math.min(issues.length, start + windowSize);
|
|
61
|
+
const visibleIssues = issues.slice(start, end);
|
|
62
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { bold: true, underline: true, children: ["Issue Navigator (", issues.length, ")"] }) }), visibleIssues.map((issue, index) => {
|
|
63
|
+
const globalIndex = start + index;
|
|
64
|
+
const isSelected = globalIndex === selectedIndex;
|
|
65
|
+
const key = issue.key;
|
|
66
|
+
const summary = issue.fields.summary;
|
|
67
|
+
const status = issue.fields.status.name;
|
|
68
|
+
const priority = issue.fields.priority.name;
|
|
69
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: isSelected ? 'green' : 'white', bold: isSelected, children: isSelected ? '> ' : ' ' }), _jsx(Box, { width: 12, children: _jsx(Text, { color: "cyan", children: key }) }), _jsx(Box, { width: 12, children: _jsx(Text, { color: "yellow", children: status }) }), _jsx(Box, { width: 10, children: _jsx(Text, { color: "magenta", children: priority }) }), _jsx(Box, { flexGrow: 1, children: _jsx(Text, { wrap: "truncate-end", children: summary }) })] }, issue.id));
|
|
70
|
+
}), _jsx(Box, { marginTop: 1, borderStyle: "single", borderColor: "gray", children: _jsxs(Text, { color: "gray", children: ["Selected: ", issues[selectedIndex]?.key, " - ", issues[selectedIndex]?.fields?.summary] }) })] }));
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=IssueList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IssueList.js","sourceRoot":"","sources":["../../../../src/tui/screens/IssueList.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { Box, Text, useInput } from 'ink';
|
|
4
|
+
import SpinnerOriginal from 'ink-spinner';
|
|
5
|
+
const Spinner = SpinnerOriginal;
|
|
6
|
+
import { api } from '../../services/api-service.js';
|
|
7
|
+
export default function KanbanBoard({ boardId, onBack }) {
|
|
8
|
+
const [loading, setLoading] = useState(true);
|
|
9
|
+
const [columns, setColumns] = useState([]);
|
|
10
|
+
const [issues, setIssues] = useState({});
|
|
11
|
+
const [activeColumnIndex, setActiveColumnIndex] = useState(0);
|
|
12
|
+
const [error, setError] = useState(null);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
const fetchData = async () => {
|
|
15
|
+
try {
|
|
16
|
+
// parallel fetch
|
|
17
|
+
const [config, boardIssues] = await Promise.all([
|
|
18
|
+
api.agileGet(`/board/${boardId}/configuration`),
|
|
19
|
+
api.agileGet(`/board/${boardId}/issue`)
|
|
20
|
+
]);
|
|
21
|
+
const cols = config.columnConfig.columns;
|
|
22
|
+
setColumns(cols);
|
|
23
|
+
// Group issues by status/column
|
|
24
|
+
// This is simplified mapping logic. Jira statuses map to columns.
|
|
25
|
+
const issuesByStatus = {};
|
|
26
|
+
cols.forEach((col) => {
|
|
27
|
+
issuesByStatus[col.name] = [];
|
|
28
|
+
});
|
|
29
|
+
boardIssues.issues.forEach((issue) => {
|
|
30
|
+
const statusName = issue.fields.status.name;
|
|
31
|
+
// Find which column this status belongs to involves checking config.columnConfig.columns[i].statuses
|
|
32
|
+
// For now, let's just try to match column name or push to 'Other'
|
|
33
|
+
let placed = false;
|
|
34
|
+
for (const col of cols) {
|
|
35
|
+
// Check if status in column statuses
|
|
36
|
+
// config.columnConfig.columns structure: { name: 'To Do', statuses: [ { id: '10000', self: '...' } ] }
|
|
37
|
+
if (col.statuses && col.statuses.some((s) => s.id === issue.fields.status.id)) {
|
|
38
|
+
if (!issuesByStatus[col.name])
|
|
39
|
+
issuesByStatus[col.name] = [];
|
|
40
|
+
issuesByStatus[col.name].push(issue);
|
|
41
|
+
placed = true;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (!placed) {
|
|
46
|
+
// fallback: try direct name match
|
|
47
|
+
if (issuesByStatus[statusName]) {
|
|
48
|
+
issuesByStatus[statusName].push(issue);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
setIssues(issuesByStatus);
|
|
53
|
+
setLoading(false);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
setError(err.message);
|
|
57
|
+
setLoading(false);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
fetchData();
|
|
61
|
+
}, [boardId]);
|
|
62
|
+
useInput((input, key) => {
|
|
63
|
+
if (key.escape || input === 'b') {
|
|
64
|
+
onBack();
|
|
65
|
+
}
|
|
66
|
+
if (key.leftArrow) {
|
|
67
|
+
setActiveColumnIndex((prev) => Math.max(0, prev - 1));
|
|
68
|
+
}
|
|
69
|
+
if (key.rightArrow) {
|
|
70
|
+
setActiveColumnIndex((prev) => Math.min(columns.length - 1, prev + 1));
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
if (loading) {
|
|
74
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "green", children: _jsx(Spinner, { type: "dots" }) }), _jsx(Text, { children: " Loading Board..." })] }));
|
|
75
|
+
}
|
|
76
|
+
if (error) {
|
|
77
|
+
return _jsxs(Text, { color: "red", children: ["Error: ", error] });
|
|
78
|
+
}
|
|
79
|
+
return (_jsxs(Box, { flexDirection: "column", height: "100%", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: "Board View (Use \u2190/\u2192 to switch columns, Esc to back)" }) }), _jsx(Box, { flexDirection: "row", flexGrow: 1, children: columns.map((col, index) => {
|
|
80
|
+
const isActive = index === activeColumnIndex;
|
|
81
|
+
const colIssues = issues[col.name] || [];
|
|
82
|
+
return (_jsxs(Box, { flexDirection: "column", width: 30, borderStyle: isActive ? 'double' : 'single', borderColor: isActive ? 'green' : 'gray', marginRight: 1, paddingX: 1, children: [_jsx(Box, { marginBottom: 1, borderStyle: "single", borderBottom: false, borderLeft: false, borderRight: false, borderTop: false, children: _jsxs(Text, { bold: true, underline: true, color: isActive ? 'green' : 'white', children: [col.name, " (", colIssues.length, ")"] }) }), colIssues.slice(0, 10).map((issue) => ( // Limit simplified list
|
|
83
|
+
_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "cyan", children: issue.key }), _jsx(Text, { wrap: "truncate", children: issue.fields.summary })] }, issue.id)))] }, col.name));
|
|
84
|
+
}) })] }));
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=KanbanBoard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KanbanBoard.js","sourceRoot":"","sources":["../../../../src/tui/screens/KanbanBoard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function renderADF(node: any): string;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export function renderADF(node) {
|
|
2
|
+
if (!node)
|
|
3
|
+
return '';
|
|
4
|
+
if (typeof node === 'string')
|
|
5
|
+
return node;
|
|
6
|
+
// Handle text nodes
|
|
7
|
+
if (node.type === 'text') {
|
|
8
|
+
return node.text || '';
|
|
9
|
+
}
|
|
10
|
+
// Handle content arrays
|
|
11
|
+
if (node.content && Array.isArray(node.content)) {
|
|
12
|
+
return node.content.map(renderADF).join('');
|
|
13
|
+
}
|
|
14
|
+
// Handle specific block types (optional formatting)
|
|
15
|
+
switch (node.type) {
|
|
16
|
+
case 'paragraph':
|
|
17
|
+
return renderADF({ content: node.content }) + '\n';
|
|
18
|
+
case 'bulletList':
|
|
19
|
+
case 'orderedList':
|
|
20
|
+
return renderADF({ content: node.content });
|
|
21
|
+
case 'listItem':
|
|
22
|
+
return '• ' + renderADF({ content: node.content });
|
|
23
|
+
case 'hardBreak':
|
|
24
|
+
return '\n';
|
|
25
|
+
default:
|
|
26
|
+
return '';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=adf-render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adf-render.js","sourceRoot":"","sources":["../../../../src/tui/utils/adf-render.ts"],"names":[],"mappings":"AACA,MAAM,UAAU,SAAS,CAAC,IAAS;IAC/B,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE1C,oBAAoB;IACpB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,wBAAwB;IACxB,IAAI,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,oDAAoD;IACpD,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAChB,KAAK,WAAW;YACZ,OAAO,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;QACvD,KAAK,YAAY,CAAC;QAClB,KAAK,aAAa;YACd,OAAO,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAChD,KAAK,UAAU;YACX,OAAO,IAAI,GAAG,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACvD,KAAK,WAAW;YACZ,OAAO,IAAI,CAAC;QAChB;YACI,OAAO,EAAE,CAAC;IAClB,CAAC;AACL,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Spinner } from './spinner.js';
|
|
2
2
|
/**
|
|
3
3
|
* Standardized error handler for CLI commands.
|
|
4
4
|
* Stops the spinner and prints a formatted error message.
|
|
@@ -7,4 +7,4 @@ import { Ora } from 'ora';
|
|
|
7
7
|
* @param {Error} error - The error object
|
|
8
8
|
* @param {string} [context] - Optional context (e.g., "Failed to list issues")
|
|
9
9
|
*/
|
|
10
|
-
export declare function handleCommandError(spinner:
|
|
10
|
+
export declare function handleCommandError(spinner: Spinner | null, error: any, context?: string): void;
|
|
@@ -1 +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,
|
|
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,OAAuB,EAAE,KAAU,EAAE,OAAO,GAAG,kBAAkB;IAChG,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,27 @@
|
|
|
1
|
+
import https from 'https';
|
|
2
|
+
interface HelperConfig {
|
|
3
|
+
baseURL?: string;
|
|
4
|
+
headers?: Record<string, string>;
|
|
5
|
+
validateStatus?: (status: number) => boolean;
|
|
6
|
+
httpsAgent?: https.Agent;
|
|
7
|
+
}
|
|
8
|
+
interface RequestConfig extends HelperConfig {
|
|
9
|
+
params?: Record<string, any>;
|
|
10
|
+
}
|
|
11
|
+
interface Response<T = any> {
|
|
12
|
+
data: T;
|
|
13
|
+
status: number;
|
|
14
|
+
statusText: string;
|
|
15
|
+
headers: Record<string, string>;
|
|
16
|
+
}
|
|
17
|
+
export declare class HttpClient {
|
|
18
|
+
private defaults;
|
|
19
|
+
constructor(defaults?: HelperConfig);
|
|
20
|
+
static create(config?: HelperConfig): HttpClient;
|
|
21
|
+
request<T = any>(url: string, options?: RequestInit & RequestConfig): Promise<Response<T>>;
|
|
22
|
+
get<T = any>(url: string, config?: RequestConfig): Promise<Response<T>>;
|
|
23
|
+
post<T = any>(url: string, data?: any, config?: RequestConfig): Promise<Response<T>>;
|
|
24
|
+
put<T = any>(url: string, data?: any, config?: RequestConfig): Promise<Response<T>>;
|
|
25
|
+
delete<T = any>(url: string, config?: RequestConfig): Promise<Response<T>>;
|
|
26
|
+
}
|
|
27
|
+
export default HttpClient;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
export class HttpClient {
|
|
2
|
+
defaults;
|
|
3
|
+
constructor(defaults = {}) {
|
|
4
|
+
this.defaults = defaults;
|
|
5
|
+
}
|
|
6
|
+
static create(config = {}) {
|
|
7
|
+
return new HttpClient(config);
|
|
8
|
+
}
|
|
9
|
+
async request(url, options = {}) {
|
|
10
|
+
const baseURL = options.baseURL || this.defaults.baseURL || '';
|
|
11
|
+
const fullUrl = new URL(url.startsWith('http') ? url : `${baseURL}${url}`);
|
|
12
|
+
if (options.params) {
|
|
13
|
+
Object.entries(options.params).forEach(([key, value]) => {
|
|
14
|
+
if (value !== undefined)
|
|
15
|
+
fullUrl.searchParams.append(key, String(value));
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
const headers = {
|
|
19
|
+
...this.defaults.headers,
|
|
20
|
+
...options.headers
|
|
21
|
+
};
|
|
22
|
+
// Handle body for JSON
|
|
23
|
+
let body = options.body;
|
|
24
|
+
if (body && typeof body === 'object') {
|
|
25
|
+
const explicitContentType = headers['Content-Type'];
|
|
26
|
+
if (!explicitContentType || explicitContentType.includes('application/json')) {
|
|
27
|
+
if (!explicitContentType) {
|
|
28
|
+
headers['Content-Type'] = 'application/json';
|
|
29
|
+
}
|
|
30
|
+
body = JSON.stringify(body);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const fetchOptions = {
|
|
34
|
+
method: options.method || 'GET',
|
|
35
|
+
headers,
|
|
36
|
+
body: body,
|
|
37
|
+
// Node native fetch doesn't support 'agent' directly in standard RequestInit
|
|
38
|
+
// but we can pass it via 'dispatcher' in undici, or ignore if using global fetch.
|
|
39
|
+
// For simple usage we usually ignore httpsAgent unless strictly needed.
|
|
40
|
+
};
|
|
41
|
+
const response = await fetch(fullUrl.toString(), fetchOptions);
|
|
42
|
+
let data;
|
|
43
|
+
const contentType = response.headers.get('content-type');
|
|
44
|
+
const contentLength = response.headers.get('content-length');
|
|
45
|
+
if (response.status === 204 || (contentLength && parseInt(contentLength) === 0)) {
|
|
46
|
+
data = null;
|
|
47
|
+
}
|
|
48
|
+
else if (contentType && contentType.includes('application/json')) {
|
|
49
|
+
try {
|
|
50
|
+
data = await response.json();
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
// If JSON parsing fails (e.g. empty body despite content-type), fallback to text or null
|
|
54
|
+
const text = await response.text();
|
|
55
|
+
try {
|
|
56
|
+
data = JSON.parse(text);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
data = text || null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
data = await response.text();
|
|
65
|
+
}
|
|
66
|
+
const res = {
|
|
67
|
+
data,
|
|
68
|
+
status: response.status,
|
|
69
|
+
statusText: response.statusText,
|
|
70
|
+
headers: Object.fromEntries(response.headers.entries())
|
|
71
|
+
};
|
|
72
|
+
const validateStatus = options.validateStatus || this.defaults.validateStatus || ((s) => s >= 200 && s < 300);
|
|
73
|
+
if (!validateStatus(res.status)) {
|
|
74
|
+
const error = new Error(`Request failed with status ${res.status}`);
|
|
75
|
+
error.response = res;
|
|
76
|
+
error.status = res.status;
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
return res;
|
|
80
|
+
}
|
|
81
|
+
async get(url, config = {}) {
|
|
82
|
+
return this.request(url, { ...config, method: 'GET' });
|
|
83
|
+
}
|
|
84
|
+
async post(url, data, config = {}) {
|
|
85
|
+
return this.request(url, { ...config, method: 'POST', body: data });
|
|
86
|
+
}
|
|
87
|
+
async put(url, data, config = {}) {
|
|
88
|
+
return this.request(url, { ...config, method: 'PUT', body: data });
|
|
89
|
+
}
|
|
90
|
+
async delete(url, config = {}) {
|
|
91
|
+
return this.request(url, { ...config, method: 'DELETE' });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
export default HttpClient;
|
|
95
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/utils/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare class Spinner {
|
|
2
|
+
private timer;
|
|
3
|
+
private frameIndex;
|
|
4
|
+
private frames;
|
|
5
|
+
text: string;
|
|
6
|
+
constructor(text: string | {
|
|
7
|
+
text: string;
|
|
8
|
+
});
|
|
9
|
+
start(text?: string): Spinner;
|
|
10
|
+
stop(): Spinner;
|
|
11
|
+
succeed(text?: string): Spinner;
|
|
12
|
+
fail(text?: string): Spinner;
|
|
13
|
+
info(text?: string): Spinner;
|
|
14
|
+
warn(text?: string): Spinner;
|
|
15
|
+
private clearLine;
|
|
16
|
+
private write;
|
|
17
|
+
private color;
|
|
18
|
+
}
|
|
19
|
+
export default function ora(options?: string | {
|
|
20
|
+
text: string;
|
|
21
|
+
}): Spinner;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export class Spinner {
|
|
2
|
+
timer = null;
|
|
3
|
+
frameIndex = 0;
|
|
4
|
+
frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
5
|
+
text;
|
|
6
|
+
constructor(text) {
|
|
7
|
+
this.text = typeof text === 'string' ? text : (text?.text || '');
|
|
8
|
+
}
|
|
9
|
+
start(text) {
|
|
10
|
+
if (text)
|
|
11
|
+
this.text = text;
|
|
12
|
+
this.frameIndex = 0;
|
|
13
|
+
// Only start animation if TTY and not CI (basic check)
|
|
14
|
+
if (process.stdout.isTTY) {
|
|
15
|
+
this.timer = setInterval(() => {
|
|
16
|
+
const frame = this.frames[this.frameIndex];
|
|
17
|
+
this.frameIndex = (this.frameIndex + 1) % this.frames.length;
|
|
18
|
+
this.write(`\r${frame} ${this.text}`);
|
|
19
|
+
}, 80);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
console.log(this.text);
|
|
23
|
+
}
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
stop() {
|
|
27
|
+
if (this.timer) {
|
|
28
|
+
clearInterval(this.timer);
|
|
29
|
+
this.timer = null;
|
|
30
|
+
this.clearLine();
|
|
31
|
+
}
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
succeed(text) {
|
|
35
|
+
this.stop();
|
|
36
|
+
const msg = text || this.text;
|
|
37
|
+
console.log(`${this.color('green', '✔')} ${msg}`);
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
fail(text) {
|
|
41
|
+
this.stop();
|
|
42
|
+
const msg = text || this.text;
|
|
43
|
+
console.log(`${this.color('red', '✖')} ${msg}`);
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
info(text) {
|
|
47
|
+
this.stop();
|
|
48
|
+
console.log(`${this.color('blue', 'ℹ')} ${text || this.text}`);
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
warn(text) {
|
|
52
|
+
this.stop();
|
|
53
|
+
console.log(`${this.color('yellow', '⚠')} ${text || this.text}`);
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
56
|
+
clearLine() {
|
|
57
|
+
if (process.stdout.isTTY) {
|
|
58
|
+
process.stdout.clearLine(0);
|
|
59
|
+
process.stdout.cursorTo(0);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
write(str) {
|
|
63
|
+
process.stdout.write(str);
|
|
64
|
+
}
|
|
65
|
+
color(color, str) {
|
|
66
|
+
const colors = {
|
|
67
|
+
green: '\x1b[32m',
|
|
68
|
+
red: '\x1b[31m',
|
|
69
|
+
blue: '\x1b[34m',
|
|
70
|
+
yellow: '\x1b[33m',
|
|
71
|
+
reset: '\x1b[0m'
|
|
72
|
+
};
|
|
73
|
+
return `${colors[color] || ''}${str}${colors.reset}`;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export default function ora(options = '') {
|
|
77
|
+
return new Spinner(options);
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=spinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../../src/utils/spinner.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jira-pilot",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.3",
|
|
4
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",
|
|
@@ -82,16 +82,21 @@
|
|
|
82
82
|
"license": "ISC",
|
|
83
83
|
"dependencies": {
|
|
84
84
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
85
|
-
"axios": "^1.13.5",
|
|
86
85
|
"chalk": "^5.3.0",
|
|
87
|
-
"
|
|
86
|
+
"cmd-table": "^0.1.0",
|
|
88
87
|
"commander": "^14.0.3",
|
|
89
88
|
"enquirer": "^2.4.1",
|
|
90
|
-
"
|
|
91
|
-
"
|
|
89
|
+
"ink": "^6.7.0",
|
|
90
|
+
"ink-select-input": "^6.2.0",
|
|
91
|
+
"ink-spinner": "^5.0.0",
|
|
92
|
+
"ink-table": "^3.1.0",
|
|
93
|
+
"ink-text-input": "^6.0.0",
|
|
94
|
+
"react": "^19.2.4"
|
|
92
95
|
},
|
|
93
96
|
"devDependencies": {
|
|
97
|
+
"@types/ink": "^0.5.2",
|
|
94
98
|
"@types/node": "^25.2.3",
|
|
99
|
+
"@types/react": "^19.2.14",
|
|
95
100
|
"@vitest/coverage-v8": "^4.0.18",
|
|
96
101
|
"rimraf": "^6.1.2",
|
|
97
102
|
"tsx": "^4.21.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import ora from '
|
|
3
|
-
import
|
|
2
|
+
import ora from '../../utils/spinner.js';
|
|
3
|
+
import { HttpClient } from '../../utils/http.js';
|
|
4
4
|
import { execSync } from 'child_process';
|
|
5
5
|
import { api } from '../../services/api-service.js';
|
|
6
6
|
import { aiService } from '../../services/ai-service.js';
|
|
@@ -52,7 +52,8 @@ export async function reviewAction(issueKey: string, options: any) {
|
|
|
52
52
|
|
|
53
53
|
// 3. Search GitHub PRs
|
|
54
54
|
// We search for PRs that mention the issue key in title or branch name
|
|
55
|
-
const
|
|
55
|
+
const http = new HttpClient();
|
|
56
|
+
const searchRes = await http.get(`https://api.github.com/search/issues`, {
|
|
56
57
|
params: {
|
|
57
58
|
q: `repo:${repoOwner}/${repoName} is:pr ${issueKey}`
|
|
58
59
|
},
|
|
@@ -73,7 +74,7 @@ export async function reviewAction(issueKey: string, options: any) {
|
|
|
73
74
|
spinner.text = `Analyzing PR #${pr.number}: ${pr.title}...`;
|
|
74
75
|
|
|
75
76
|
// 4. Fetch Diff
|
|
76
|
-
const diffRes = await
|
|
77
|
+
const diffRes = await http.get(pr.pull_request.url, {
|
|
77
78
|
headers: {
|
|
78
79
|
'Authorization': `token ${githubToken}`,
|
|
79
80
|
'Accept': 'application/vnd.github.v3.diff'
|
package/src/commands/ai.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import ora from '
|
|
3
|
+
import ora from '../utils/spinner.js';
|
|
4
4
|
import enquirer from 'enquirer';
|
|
5
5
|
import { api } from '../services/api-service.js';
|
|
6
6
|
import { aiService } from '../services/ai-service.js';
|