clairo 2.2.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/cli.js +728 -252
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import meow from "meow";
|
|
5
5
|
|
|
6
6
|
// src/app.tsx
|
|
7
|
-
import { useCallback as
|
|
8
|
-
import { Box as
|
|
7
|
+
import { useCallback as useCallback12, useMemo as useMemo4, useState as useState23 } from "react";
|
|
8
|
+
import { Box as Box24, Text as Text23, useApp, useInput as useInput19 } from "ink";
|
|
9
9
|
|
|
10
10
|
// src/components/github/GitHubView.tsx
|
|
11
11
|
import { useCallback as useCallback8, useEffect as useEffect9, useRef as useRef5, useState as useState12 } from "react";
|
|
@@ -194,7 +194,7 @@ function resolveCheckStatus(check) {
|
|
|
194
194
|
const conclusion = check.conclusion ?? check.state;
|
|
195
195
|
if (conclusion === "SUCCESS") return "success";
|
|
196
196
|
if (conclusion === "FAILURE" || conclusion === "ERROR") return "failure";
|
|
197
|
-
if (conclusion === "SKIPPED" || conclusion === "NEUTRAL") return "skipped";
|
|
197
|
+
if (conclusion === "SKIPPED" || conclusion === "NEUTRAL" || conclusion === "CANCELLED") return "skipped";
|
|
198
198
|
if (conclusion === "PENDING" || check.status === "IN_PROGRESS" || check.status === "QUEUED" || check.status === "WAITING")
|
|
199
199
|
return "pending";
|
|
200
200
|
return "pending";
|
|
@@ -261,7 +261,7 @@ async function listPRsForBranch(branch, repo) {
|
|
|
261
261
|
errorType: "not_authenticated"
|
|
262
262
|
};
|
|
263
263
|
}
|
|
264
|
-
const fields = "number,title,state,author,createdAt,isDraft";
|
|
264
|
+
const fields = "number,title,state,author,createdAt,isDraft,reviewDecision,statusCheckRollup";
|
|
265
265
|
try {
|
|
266
266
|
const { stdout } = await execAsync(`gh pr view --json ${fields} 2>/dev/null`);
|
|
267
267
|
const pr = JSON.parse(stdout);
|
|
@@ -1557,6 +1557,7 @@ import open from "open";
|
|
|
1557
1557
|
import { useRef as useRef2 } from "react";
|
|
1558
1558
|
import { Box as Box3, Text as Text3, useInput, useStdout } from "ink";
|
|
1559
1559
|
import { ScrollView } from "ink-scroll-view";
|
|
1560
|
+
import Spinner from "ink-spinner";
|
|
1560
1561
|
|
|
1561
1562
|
// src/components/ui/Badge.tsx
|
|
1562
1563
|
import { Text } from "ink";
|
|
@@ -1701,10 +1702,9 @@ function renderInlineToString(tokens) {
|
|
|
1701
1702
|
|
|
1702
1703
|
// src/components/github/PRDetailsBox.tsx
|
|
1703
1704
|
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1704
|
-
function PRDetailsBox({ pr, loading, error, isActive }) {
|
|
1705
|
+
function PRDetailsBox({ pr, loading, error, isActive, title = "[3] PR Details" }) {
|
|
1705
1706
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
1706
1707
|
const scrollRef = useRef2(null);
|
|
1707
|
-
const title = "[3] PR Details";
|
|
1708
1708
|
const borderColor = isActive ? "yellow" : void 0;
|
|
1709
1709
|
const displayTitle = pr ? `${title} - #${pr.number}` : title;
|
|
1710
1710
|
const reviewDisplay = resolveReviewDisplay((pr == null ? void 0 : pr.reviewDecision) ?? null);
|
|
@@ -1744,7 +1744,10 @@ function PRDetailsBox({ pr, loading, error, isActive }) {
|
|
|
1744
1744
|
borderTop: false,
|
|
1745
1745
|
borderColor,
|
|
1746
1746
|
children: /* @__PURE__ */ jsx4(ScrollView, { ref: scrollRef, children: /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", paddingX: 1, children: [
|
|
1747
|
-
loading && /* @__PURE__ */
|
|
1747
|
+
loading && /* @__PURE__ */ jsxs3(Text3, { color: "yellow", children: [
|
|
1748
|
+
/* @__PURE__ */ jsx4(Spinner, { type: "dots" }),
|
|
1749
|
+
" Loading details..."
|
|
1750
|
+
] }),
|
|
1748
1751
|
error && /* @__PURE__ */ jsx4(Text3, { color: "red", children: error }),
|
|
1749
1752
|
!loading && !error && !pr && /* @__PURE__ */ jsx4(Text3, { dimColor: true, children: "Select a PR to view details" }),
|
|
1750
1753
|
!loading && !error && pr && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
@@ -2095,13 +2098,13 @@ function useLogs() {
|
|
|
2095
2098
|
import { useCallback as useCallback6, useState as useState7 } from "react";
|
|
2096
2099
|
function useModal() {
|
|
2097
2100
|
const [modalType, setModalType] = useState7("none");
|
|
2098
|
-
const
|
|
2101
|
+
const open7 = useCallback6((type) => setModalType(type), []);
|
|
2099
2102
|
const close = useCallback6(() => setModalType("none"), []);
|
|
2100
2103
|
const isOpen = modalType !== "none";
|
|
2101
2104
|
return {
|
|
2102
2105
|
type: modalType,
|
|
2103
2106
|
isOpen,
|
|
2104
|
-
open:
|
|
2107
|
+
open: open7,
|
|
2105
2108
|
close
|
|
2106
2109
|
};
|
|
2107
2110
|
}
|
|
@@ -2508,6 +2511,45 @@ var REACTION_MESSAGES = {
|
|
|
2508
2511
|
{ template: "{ticketKey} is in {assignee}'s hands now.", requires: ["ticketKey", "assignee"] },
|
|
2509
2512
|
{ template: "{assignee}: you own {ticketKey}. No takebacks.", requires: ["ticketKey", "assignee"] }
|
|
2510
2513
|
],
|
|
2514
|
+
"pr:checkout": [
|
|
2515
|
+
"Branch switched!",
|
|
2516
|
+
"Checked out!",
|
|
2517
|
+
"New branch, who dis?",
|
|
2518
|
+
"*lands on a new branch*",
|
|
2519
|
+
"Context switch complete.",
|
|
2520
|
+
"Off to a new adventure!",
|
|
2521
|
+
"*hops to a different branch*",
|
|
2522
|
+
"The code is fresh here.",
|
|
2523
|
+
"New branch energy.",
|
|
2524
|
+
"Branch hopping like a pro.",
|
|
2525
|
+
"Let's see what we're working with.",
|
|
2526
|
+
"*settles into the new branch*",
|
|
2527
|
+
"Ready to review locally.",
|
|
2528
|
+
"Local checkout achieved.",
|
|
2529
|
+
{ template: "Checked out PR #{prNumber}!", requires: ["prNumber"] },
|
|
2530
|
+
{ template: "#{prNumber} is now local. Dive in!", requires: ["prNumber"] },
|
|
2531
|
+
{ template: '"{prTitle}" checked out. Time to explore.', requires: ["prTitle"] },
|
|
2532
|
+
{ template: "#{prNumber}: now on your machine.", requires: ["prNumber"] },
|
|
2533
|
+
{ template: "Landed on #{prNumber}. Looking good.", requires: ["prNumber"] },
|
|
2534
|
+
{ template: '"{prTitle}" is ready for local testing.', requires: ["prTitle"] },
|
|
2535
|
+
{ template: "#{prNumber} checked out. Your terminal, your rules.", requires: ["prNumber"] }
|
|
2536
|
+
],
|
|
2537
|
+
"pr:filtered": [
|
|
2538
|
+
"Narrowing it down!",
|
|
2539
|
+
"Filtered!",
|
|
2540
|
+
"Less noise, more signal.",
|
|
2541
|
+
"*puts on reading glasses*",
|
|
2542
|
+
"Search complete.",
|
|
2543
|
+
"The results are in.",
|
|
2544
|
+
"*sorts through the PRs*",
|
|
2545
|
+
"Finding what matters.",
|
|
2546
|
+
"Filtered to perfection.",
|
|
2547
|
+
"Focus mode: engaged.",
|
|
2548
|
+
"*adjusts the lens*",
|
|
2549
|
+
"The haystack just got smaller.",
|
|
2550
|
+
"Precision browsing.",
|
|
2551
|
+
"Now we can see clearly."
|
|
2552
|
+
],
|
|
2511
2553
|
"jira:unassigned": [
|
|
2512
2554
|
"Unassigned!",
|
|
2513
2555
|
"Free agent!",
|
|
@@ -3067,18 +3109,18 @@ var proto = Object.defineProperties(() => {
|
|
|
3067
3109
|
}
|
|
3068
3110
|
}
|
|
3069
3111
|
});
|
|
3070
|
-
var createStyler = (
|
|
3112
|
+
var createStyler = (open7, close, parent) => {
|
|
3071
3113
|
let openAll;
|
|
3072
3114
|
let closeAll;
|
|
3073
3115
|
if (parent === void 0) {
|
|
3074
|
-
openAll =
|
|
3116
|
+
openAll = open7;
|
|
3075
3117
|
closeAll = close;
|
|
3076
3118
|
} else {
|
|
3077
|
-
openAll = parent.openAll +
|
|
3119
|
+
openAll = parent.openAll + open7;
|
|
3078
3120
|
closeAll = close + parent.closeAll;
|
|
3079
3121
|
}
|
|
3080
3122
|
return {
|
|
3081
|
-
open:
|
|
3123
|
+
open: open7,
|
|
3082
3124
|
close,
|
|
3083
3125
|
openAll,
|
|
3084
3126
|
closeAll,
|
|
@@ -3684,7 +3726,7 @@ ${body}`;
|
|
|
3684
3726
|
|
|
3685
3727
|
// src/components/jira-browser/JiraBrowserView.tsx
|
|
3686
3728
|
import { useCallback as useCallback10, useEffect as useEffect13, useMemo as useMemo3, useRef as useRef7, useState as useState17 } from "react";
|
|
3687
|
-
import { Box as
|
|
3729
|
+
import { Box as Box13, useInput as useInput10 } from "ink";
|
|
3688
3730
|
|
|
3689
3731
|
// src/components/jira-browser/AddViewModal.tsx
|
|
3690
3732
|
import { useState as useState13 } from "react";
|
|
@@ -3784,19 +3826,57 @@ function AddViewModal({ onSubmit, onCancel, loading, error }) {
|
|
|
3784
3826
|
// src/components/jira-browser/JiraSavedViewBrowserBox.tsx
|
|
3785
3827
|
import open4 from "open";
|
|
3786
3828
|
import { useCallback as useCallback9, useEffect as useEffect11, useMemo as useMemo2, useState as useState15 } from "react";
|
|
3787
|
-
import {
|
|
3788
|
-
import { Box as Box10, Text as Text11, useInput as useInput8 } from "ink";
|
|
3829
|
+
import { Box as Box11, Text as Text12, useInput as useInput8 } from "ink";
|
|
3789
3830
|
import { ScrollView as ScrollView6 } from "ink-scroll-view";
|
|
3790
|
-
import
|
|
3831
|
+
import Spinner3 from "ink-spinner";
|
|
3832
|
+
|
|
3833
|
+
// src/components/ui/TitledBox.tsx
|
|
3834
|
+
import { Box as Box9, Text as Text10, useStdout as useStdout2 } from "ink";
|
|
3835
|
+
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
3836
|
+
function TitledBox4({ title, borderColor, scrollRatio = null, fillColor = "#CC6600", children }) {
|
|
3837
|
+
const { stdout } = useStdout2();
|
|
3838
|
+
const terminalWidth = (stdout == null ? void 0 : stdout.columns) ?? 80;
|
|
3839
|
+
const columnWidth = Math.floor(terminalWidth / 2);
|
|
3840
|
+
const titlePart = `\u256D ${title} `;
|
|
3841
|
+
const totalDashes = Math.max(0, columnWidth - titlePart.length - 1);
|
|
3842
|
+
const topBorder = scrollRatio !== null && scrollRatio >= 0 ? /* @__PURE__ */ jsxs9(Text10, { children: [
|
|
3843
|
+
/* @__PURE__ */ jsx11(Text10, { color: borderColor, children: titlePart }),
|
|
3844
|
+
/* @__PURE__ */ jsx11(Text10, { color: fillColor, children: "\u2500".repeat(Math.round(scrollRatio * totalDashes)) }),
|
|
3845
|
+
/* @__PURE__ */ jsxs9(Text10, { color: borderColor, children: [
|
|
3846
|
+
"\u2500".repeat(totalDashes - Math.round(scrollRatio * totalDashes)),
|
|
3847
|
+
"\u256E"
|
|
3848
|
+
] })
|
|
3849
|
+
] }) : /* @__PURE__ */ jsxs9(Text10, { color: borderColor, children: [
|
|
3850
|
+
titlePart,
|
|
3851
|
+
"\u2500".repeat(totalDashes),
|
|
3852
|
+
"\u256E"
|
|
3853
|
+
] });
|
|
3854
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", flexGrow: 1, children: [
|
|
3855
|
+
topBorder,
|
|
3856
|
+
/* @__PURE__ */ jsx11(
|
|
3857
|
+
Box9,
|
|
3858
|
+
{
|
|
3859
|
+
flexDirection: "column",
|
|
3860
|
+
flexGrow: 1,
|
|
3861
|
+
flexBasis: 0,
|
|
3862
|
+
overflow: "hidden",
|
|
3863
|
+
borderStyle: "round",
|
|
3864
|
+
borderTop: false,
|
|
3865
|
+
borderColor,
|
|
3866
|
+
children
|
|
3867
|
+
}
|
|
3868
|
+
)
|
|
3869
|
+
] });
|
|
3870
|
+
}
|
|
3791
3871
|
|
|
3792
3872
|
// src/components/jira-browser/JiraIssueDetailView.tsx
|
|
3793
3873
|
import open3 from "open";
|
|
3794
3874
|
import { useEffect as useEffect10, useRef as useRef6, useState as useState14 } from "react";
|
|
3795
|
-
import { Box as
|
|
3875
|
+
import { Box as Box10, Text as Text11, useInput as useInput7 } from "ink";
|
|
3796
3876
|
import { ScrollView as ScrollView5 } from "ink-scroll-view";
|
|
3797
3877
|
import SelectInput from "ink-select-input";
|
|
3798
|
-
import
|
|
3799
|
-
import { jsx as
|
|
3878
|
+
import Spinner2 from "ink-spinner";
|
|
3879
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3800
3880
|
function JiraIssueDetailView({
|
|
3801
3881
|
issueKey,
|
|
3802
3882
|
issueSummary,
|
|
@@ -3951,44 +4031,44 @@ function JiraIssueDetailView({
|
|
|
3951
4031
|
const descriptionMd = (detail == null ? void 0 : detail.fields.description) ? adfToMarkdown(detail.fields.description) : null;
|
|
3952
4032
|
const comments = (detail == null ? void 0 : detail.fields.comment.comments) ?? [];
|
|
3953
4033
|
const totalComments = (detail == null ? void 0 : detail.fields.comment.total) ?? 0;
|
|
3954
|
-
return /* @__PURE__ */
|
|
3955
|
-
/* @__PURE__ */
|
|
3956
|
-
loading && /* @__PURE__ */
|
|
3957
|
-
/* @__PURE__ */
|
|
4034
|
+
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", flexGrow: 1, children: [
|
|
4035
|
+
/* @__PURE__ */ jsxs10(Box10, { flexGrow: 1, flexBasis: 0, overflow: "hidden", children: [
|
|
4036
|
+
loading && /* @__PURE__ */ jsx12(Box10, { paddingX: 1, children: /* @__PURE__ */ jsxs10(Text11, { color: "yellow", children: [
|
|
4037
|
+
/* @__PURE__ */ jsx12(Spinner2, { type: "dots" }),
|
|
3958
4038
|
" Loading issue details..."
|
|
3959
4039
|
] }) }),
|
|
3960
|
-
error && /* @__PURE__ */
|
|
3961
|
-
!loading && !error && detail && /* @__PURE__ */
|
|
3962
|
-
/* @__PURE__ */
|
|
3963
|
-
/* @__PURE__ */
|
|
3964
|
-
/* @__PURE__ */
|
|
4040
|
+
error && /* @__PURE__ */ jsx12(Box10, { paddingX: 1, children: /* @__PURE__ */ jsx12(Text11, { color: "red", children: error }) }),
|
|
4041
|
+
!loading && !error && detail && /* @__PURE__ */ jsx12(ScrollView5, { ref: scrollRef, children: /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", paddingX: 1, children: [
|
|
4042
|
+
/* @__PURE__ */ jsxs10(Box10, { children: [
|
|
4043
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, color: "blue", children: detail.key }),
|
|
4044
|
+
/* @__PURE__ */ jsxs10(Text11, { bold: true, children: [
|
|
3965
4045
|
" ",
|
|
3966
4046
|
detail.fields.summary
|
|
3967
4047
|
] })
|
|
3968
4048
|
] }),
|
|
3969
|
-
/* @__PURE__ */
|
|
3970
|
-
/* @__PURE__ */
|
|
3971
|
-
/* @__PURE__ */
|
|
3972
|
-
/* @__PURE__ */
|
|
3973
|
-
/* @__PURE__ */
|
|
3974
|
-
/* @__PURE__ */
|
|
3975
|
-
/* @__PURE__ */
|
|
4049
|
+
/* @__PURE__ */ jsxs10(Box10, { gap: 1, children: [
|
|
4050
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "Status:" }),
|
|
4051
|
+
/* @__PURE__ */ jsx12(Text11, { color: statusColor, children: detail.fields.status.name }),
|
|
4052
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "Assignee:" }),
|
|
4053
|
+
/* @__PURE__ */ jsx12(Text11, { children: ((_a = detail.fields.assignee) == null ? void 0 : _a.displayName) ?? "Unassigned" }),
|
|
4054
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "Reporter:" }),
|
|
4055
|
+
/* @__PURE__ */ jsx12(Text11, { children: ((_b = detail.fields.reporter) == null ? void 0 : _b.displayName) ?? "Unknown" })
|
|
3976
4056
|
] }),
|
|
3977
|
-
/* @__PURE__ */
|
|
3978
|
-
/* @__PURE__ */
|
|
3979
|
-
/* @__PURE__ */
|
|
3980
|
-
descriptionMd ? /* @__PURE__ */
|
|
4057
|
+
/* @__PURE__ */ jsx12(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx12(Divider, {}) }),
|
|
4058
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
4059
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "Description:" }),
|
|
4060
|
+
descriptionMd ? /* @__PURE__ */ jsx12(Markdown, { children: descriptionMd }) : /* @__PURE__ */ jsx12(Text11, { dimColor: true, italic: true, children: "No description" })
|
|
3981
4061
|
] }),
|
|
3982
|
-
/* @__PURE__ */
|
|
3983
|
-
/* @__PURE__ */
|
|
3984
|
-
/* @__PURE__ */
|
|
4062
|
+
/* @__PURE__ */ jsx12(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx12(Divider, {}) }),
|
|
4063
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
4064
|
+
/* @__PURE__ */ jsxs10(Text11, { dimColor: true, children: [
|
|
3985
4065
|
"Comments (",
|
|
3986
4066
|
totalComments,
|
|
3987
4067
|
"):"
|
|
3988
4068
|
] }),
|
|
3989
|
-
comments.length === 0 && /* @__PURE__ */
|
|
3990
|
-
comments.map((comment) => /* @__PURE__ */
|
|
3991
|
-
comments.length < totalComments && /* @__PURE__ */
|
|
4069
|
+
comments.length === 0 && /* @__PURE__ */ jsx12(Text11, { dimColor: true, italic: true, children: "No comments" }),
|
|
4070
|
+
comments.map((comment) => /* @__PURE__ */ jsx12(CommentBlock, { comment }, comment.id)),
|
|
4071
|
+
comments.length < totalComments && /* @__PURE__ */ jsx12(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text11, { dimColor: true, children: [
|
|
3992
4072
|
"Showing ",
|
|
3993
4073
|
comments.length,
|
|
3994
4074
|
" of ",
|
|
@@ -3998,40 +4078,40 @@ function JiraIssueDetailView({
|
|
|
3998
4078
|
] })
|
|
3999
4079
|
] }) })
|
|
4000
4080
|
] }),
|
|
4001
|
-
mode === "transitions" && /* @__PURE__ */
|
|
4002
|
-
/* @__PURE__ */
|
|
4003
|
-
/* @__PURE__ */
|
|
4081
|
+
mode === "transitions" && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
4082
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, color: "yellow", children: "Change Status" }),
|
|
4083
|
+
/* @__PURE__ */ jsx12(
|
|
4004
4084
|
SelectInput,
|
|
4005
4085
|
{
|
|
4006
4086
|
items: transitions.map((t) => ({ label: t.name, value: t.id })),
|
|
4007
4087
|
onSelect: handleTransitionSelect
|
|
4008
4088
|
}
|
|
4009
4089
|
),
|
|
4010
|
-
/* @__PURE__ */
|
|
4090
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "Esc to cancel" })
|
|
4011
4091
|
] }),
|
|
4012
|
-
/* @__PURE__ */
|
|
4013
|
-
actionLoading && /* @__PURE__ */
|
|
4014
|
-
/* @__PURE__ */
|
|
4092
|
+
/* @__PURE__ */ jsxs10(Box10, { paddingX: 1, flexDirection: "column", children: [
|
|
4093
|
+
actionLoading && /* @__PURE__ */ jsxs10(Text11, { color: "yellow", children: [
|
|
4094
|
+
/* @__PURE__ */ jsx12(Spinner2, { type: "dots" }),
|
|
4015
4095
|
" ",
|
|
4016
4096
|
actionLoading
|
|
4017
4097
|
] }),
|
|
4018
|
-
actionError && /* @__PURE__ */
|
|
4019
|
-
transitionsLoading && /* @__PURE__ */
|
|
4020
|
-
/* @__PURE__ */
|
|
4098
|
+
actionError && /* @__PURE__ */ jsx12(Text11, { color: "red", children: actionError }),
|
|
4099
|
+
transitionsLoading && /* @__PURE__ */ jsxs10(Text11, { color: "yellow", children: [
|
|
4100
|
+
/* @__PURE__ */ jsx12(Spinner2, { type: "dots" }),
|
|
4021
4101
|
" Loading transitions..."
|
|
4022
4102
|
] }),
|
|
4023
|
-
!actionLoading && !transitionsLoading && mode === "normal" && /* @__PURE__ */
|
|
4103
|
+
!actionLoading && !transitionsLoading && mode === "normal" && /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "Esc close \xB7 j/k scroll \xB7 s status \xB7 a assign \xB7 A unassign \xB7 o open \xB7 y copy" })
|
|
4024
4104
|
] })
|
|
4025
4105
|
] });
|
|
4026
4106
|
}
|
|
4027
4107
|
function CommentBlock({ comment }) {
|
|
4028
4108
|
const bodyMd = adfToMarkdown(comment.body);
|
|
4029
|
-
return /* @__PURE__ */
|
|
4030
|
-
/* @__PURE__ */
|
|
4031
|
-
/* @__PURE__ */
|
|
4032
|
-
/* @__PURE__ */
|
|
4109
|
+
return /* @__PURE__ */ jsxs10(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
4110
|
+
/* @__PURE__ */ jsxs10(Box10, { gap: 1, children: [
|
|
4111
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, children: comment.author.displayName }),
|
|
4112
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: timeAgo(comment.created) })
|
|
4033
4113
|
] }),
|
|
4034
|
-
bodyMd ? /* @__PURE__ */
|
|
4114
|
+
bodyMd ? /* @__PURE__ */ jsx12(Markdown, { children: bodyMd }) : /* @__PURE__ */ jsx12(Text11, { dimColor: true, italic: true, children: "Empty comment" })
|
|
4035
4115
|
] });
|
|
4036
4116
|
}
|
|
4037
4117
|
function getStatusColor(status) {
|
|
@@ -4042,7 +4122,7 @@ function getStatusColor(status) {
|
|
|
4042
4122
|
}
|
|
4043
4123
|
|
|
4044
4124
|
// src/components/jira-browser/JiraSavedViewBrowserBox.tsx
|
|
4045
|
-
import { Fragment as Fragment3, jsx as
|
|
4125
|
+
import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
4046
4126
|
function groupBySprint(issues) {
|
|
4047
4127
|
const groups = /* @__PURE__ */ new Map();
|
|
4048
4128
|
for (const issue of issues) {
|
|
@@ -4277,11 +4357,12 @@ function JiraSavedViewBrowserBox({
|
|
|
4277
4357
|
},
|
|
4278
4358
|
{ isActive }
|
|
4279
4359
|
);
|
|
4360
|
+
const scrollRatio = isActive && !detailIssue && navigableIndices.length > 1 ? highlightedIndex / (navigableIndices.length - 1) : null;
|
|
4280
4361
|
const filterParts = [];
|
|
4281
4362
|
if (assigneeFilter === "unassigned") filterParts.push("unassigned");
|
|
4282
4363
|
if (assigneeFilter === "me") filterParts.push("mine");
|
|
4283
4364
|
if (searchText) filterParts.push(`"${searchText}"`);
|
|
4284
|
-
return /* @__PURE__ */
|
|
4365
|
+
return /* @__PURE__ */ jsx13(TitledBox4, { title: displayTitle, borderColor, scrollRatio, children: /* @__PURE__ */ jsx13(Box11, { flexDirection: "column", flexGrow: 1, children: detailIssue && auth ? /* @__PURE__ */ jsx13(
|
|
4285
4366
|
JiraIssueDetailView,
|
|
4286
4367
|
{
|
|
4287
4368
|
issueKey: detailIssue.key,
|
|
@@ -4295,15 +4376,15 @@ function JiraSavedViewBrowserBox({
|
|
|
4295
4376
|
onIssueUpdated: handleIssueUpdated,
|
|
4296
4377
|
onLogUpdated
|
|
4297
4378
|
}
|
|
4298
|
-
) : /* @__PURE__ */
|
|
4299
|
-
(isFiltering || hasActiveFilters) && /* @__PURE__ */
|
|
4300
|
-
/* @__PURE__ */
|
|
4301
|
-
isFiltering ? /* @__PURE__ */
|
|
4302
|
-
/* @__PURE__ */
|
|
4303
|
-
/* @__PURE__ */
|
|
4304
|
-
] }) : /* @__PURE__ */
|
|
4305
|
-
/* @__PURE__ */
|
|
4306
|
-
/* @__PURE__ */
|
|
4379
|
+
) : /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
4380
|
+
(isFiltering || hasActiveFilters) && /* @__PURE__ */ jsxs11(Box11, { paddingX: 1, children: [
|
|
4381
|
+
/* @__PURE__ */ jsx13(Text12, { color: "blue", children: "Search: " }),
|
|
4382
|
+
isFiltering ? /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
4383
|
+
/* @__PURE__ */ jsx13(Text12, { children: inputText }),
|
|
4384
|
+
/* @__PURE__ */ jsx13(Text12, { backgroundColor: "yellow", children: " " })
|
|
4385
|
+
] }) : /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
4386
|
+
/* @__PURE__ */ jsx13(Text12, { children: filterParts.join(" + ") }),
|
|
4387
|
+
/* @__PURE__ */ jsxs11(Text12, { dimColor: true, children: [
|
|
4307
4388
|
" ",
|
|
4308
4389
|
"(",
|
|
4309
4390
|
issues.length,
|
|
@@ -4313,37 +4394,37 @@ function JiraSavedViewBrowserBox({
|
|
|
4313
4394
|
] })
|
|
4314
4395
|
] })
|
|
4315
4396
|
] }),
|
|
4316
|
-
/* @__PURE__ */
|
|
4317
|
-
!view && /* @__PURE__ */
|
|
4318
|
-
view && loading && issues.length === 0 && /* @__PURE__ */
|
|
4319
|
-
/* @__PURE__ */
|
|
4397
|
+
/* @__PURE__ */ jsxs11(Box11, { flexGrow: 1, flexBasis: 0, overflow: "hidden", children: [
|
|
4398
|
+
!view && /* @__PURE__ */ jsx13(Box11, { paddingX: 1, children: /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: "Select a view to browse issues" }) }),
|
|
4399
|
+
view && loading && issues.length === 0 && /* @__PURE__ */ jsx13(Box11, { paddingX: 1, children: /* @__PURE__ */ jsxs11(Text12, { color: "yellow", children: [
|
|
4400
|
+
/* @__PURE__ */ jsx13(Spinner3, { type: "dots" }),
|
|
4320
4401
|
" Loading issues..."
|
|
4321
4402
|
] }) }),
|
|
4322
|
-
view && error && /* @__PURE__ */
|
|
4323
|
-
view && !loading && !error && issues.length === 0 && /* @__PURE__ */
|
|
4324
|
-
rows.length > 0 && /* @__PURE__ */
|
|
4403
|
+
view && error && /* @__PURE__ */ jsx13(Box11, { paddingX: 1, children: /* @__PURE__ */ jsx13(Text12, { color: "red", children: error }) }),
|
|
4404
|
+
view && !loading && !error && issues.length === 0 && /* @__PURE__ */ jsx13(Box11, { paddingX: 1, children: /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: hasActiveFilters ? "No issues match filter" : "No issues found" }) }),
|
|
4405
|
+
rows.length > 0 && /* @__PURE__ */ jsx13(ScrollView6, { ref: scrollRef, children: rows.map((row, rowIdx) => {
|
|
4325
4406
|
if (row.type === "header") {
|
|
4326
4407
|
const stateLabel = row.state === "active" ? " (active)" : "";
|
|
4327
|
-
return /* @__PURE__ */
|
|
4408
|
+
return /* @__PURE__ */ jsx13(Box11, { paddingX: 1, marginTop: rowIdx > 0 ? 1 : 0, children: /* @__PURE__ */ jsxs11(Text12, { bold: true, color: "magenta", children: [
|
|
4328
4409
|
row.label,
|
|
4329
|
-
stateLabel && /* @__PURE__ */
|
|
4410
|
+
stateLabel && /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: stateLabel })
|
|
4330
4411
|
] }) }, `header-${row.label}`);
|
|
4331
4412
|
}
|
|
4332
4413
|
const navIdx = navigableIndices.indexOf(rowIdx);
|
|
4333
4414
|
const isHighlighted = navIdx === highlightedIndex;
|
|
4334
4415
|
const cursor = isHighlighted ? ">" : " ";
|
|
4335
4416
|
const statusColor = getStatusColor2(row.issue.fields.status.name);
|
|
4336
|
-
return /* @__PURE__ */
|
|
4337
|
-
/* @__PURE__ */
|
|
4417
|
+
return /* @__PURE__ */ jsxs11(Box11, { paddingX: 1, children: [
|
|
4418
|
+
/* @__PURE__ */ jsxs11(Text12, { color: isHighlighted ? "yellow" : void 0, children: [
|
|
4338
4419
|
cursor,
|
|
4339
4420
|
" "
|
|
4340
4421
|
] }),
|
|
4341
|
-
/* @__PURE__ */
|
|
4342
|
-
/* @__PURE__ */
|
|
4422
|
+
/* @__PURE__ */ jsx13(Text12, { bold: true, color: "blue", children: row.issue.key }),
|
|
4423
|
+
/* @__PURE__ */ jsxs11(Text12, { children: [
|
|
4343
4424
|
" ",
|
|
4344
4425
|
row.issue.fields.summary
|
|
4345
4426
|
] }),
|
|
4346
|
-
/* @__PURE__ */
|
|
4427
|
+
/* @__PURE__ */ jsxs11(Text12, { color: statusColor, children: [
|
|
4347
4428
|
" [",
|
|
4348
4429
|
row.issue.fields.status.name,
|
|
4349
4430
|
"]"
|
|
@@ -4351,14 +4432,14 @@ function JiraSavedViewBrowserBox({
|
|
|
4351
4432
|
] }, row.issue.key);
|
|
4352
4433
|
}) })
|
|
4353
4434
|
] }),
|
|
4354
|
-
view && !loading && issues.length > 0 && /* @__PURE__ */
|
|
4435
|
+
view && !loading && issues.length > 0 && /* @__PURE__ */ jsx13(Box11, { paddingX: 1, children: /* @__PURE__ */ jsxs11(Text12, { dimColor: true, children: [
|
|
4355
4436
|
issues.length,
|
|
4356
4437
|
" of ",
|
|
4357
4438
|
total,
|
|
4358
4439
|
" loaded",
|
|
4359
4440
|
hasMore && " \xB7 l to load more"
|
|
4360
4441
|
] }) }),
|
|
4361
|
-
view && loading && issues.length > 0 && /* @__PURE__ */
|
|
4442
|
+
view && loading && issues.length > 0 && /* @__PURE__ */ jsx13(Box11, { paddingX: 1, children: /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: "Loading more..." }) })
|
|
4362
4443
|
] }) }) });
|
|
4363
4444
|
}
|
|
4364
4445
|
function getStatusColor2(status) {
|
|
@@ -4371,9 +4452,9 @@ function getStatusColor2(status) {
|
|
|
4371
4452
|
// src/components/jira-browser/JiraSavedViewsBox.tsx
|
|
4372
4453
|
import { useEffect as useEffect12, useState as useState16 } from "react";
|
|
4373
4454
|
import { TitledBox as TitledBox5 } from "@mishieck/ink-titled-box";
|
|
4374
|
-
import { Box as
|
|
4455
|
+
import { Box as Box12, Text as Text13, useInput as useInput9 } from "ink";
|
|
4375
4456
|
import { ScrollView as ScrollView7 } from "ink-scroll-view";
|
|
4376
|
-
import { Fragment as Fragment4, jsx as
|
|
4457
|
+
import { Fragment as Fragment4, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
4377
4458
|
function JiraSavedViewsBox({
|
|
4378
4459
|
views,
|
|
4379
4460
|
selectedViewId,
|
|
@@ -4442,23 +4523,23 @@ function JiraSavedViewsBox({
|
|
|
4442
4523
|
},
|
|
4443
4524
|
{ isActive }
|
|
4444
4525
|
);
|
|
4445
|
-
return /* @__PURE__ */
|
|
4446
|
-
views.length === 0 && /* @__PURE__ */
|
|
4447
|
-
views.length > 0 && /* @__PURE__ */
|
|
4526
|
+
return /* @__PURE__ */ jsx14(TitledBox5, { borderStyle: "round", titles: [title], borderColor, height: 5, children: /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingX: 1, flexGrow: 1, overflow: "hidden", children: [
|
|
4527
|
+
views.length === 0 && /* @__PURE__ */ jsx14(Text13, { dimColor: true, children: "No saved views" }),
|
|
4528
|
+
views.length > 0 && /* @__PURE__ */ jsx14(ScrollView7, { ref: scrollRef, children: views.map((view, idx) => {
|
|
4448
4529
|
const isHighlighted = isActive && idx === highlightedIndex;
|
|
4449
4530
|
const isSelected = view.id === selectedViewId;
|
|
4450
4531
|
const isRenaming = view.id === renaming;
|
|
4451
4532
|
const cursor = isHighlighted ? ">" : " ";
|
|
4452
4533
|
const nameColor = isSelected ? "green" : void 0;
|
|
4453
4534
|
const indicator = isSelected ? " *" : "";
|
|
4454
|
-
return /* @__PURE__ */
|
|
4455
|
-
/* @__PURE__ */
|
|
4535
|
+
return /* @__PURE__ */ jsxs12(Box12, { children: [
|
|
4536
|
+
/* @__PURE__ */ jsxs12(Text13, { color: isHighlighted ? "yellow" : void 0, children: [
|
|
4456
4537
|
cursor,
|
|
4457
4538
|
" "
|
|
4458
4539
|
] }),
|
|
4459
|
-
isRenaming ? /* @__PURE__ */
|
|
4460
|
-
/* @__PURE__ */
|
|
4461
|
-
/* @__PURE__ */
|
|
4540
|
+
isRenaming ? /* @__PURE__ */ jsx14(TextInput, { value: renameValue, onChange: setRenameValue, isActive: true }) : /* @__PURE__ */ jsxs12(Fragment4, { children: [
|
|
4541
|
+
/* @__PURE__ */ jsx14(Text13, { color: nameColor, children: view.name }),
|
|
4542
|
+
/* @__PURE__ */ jsx14(Text13, { dimColor: true, children: indicator })
|
|
4462
4543
|
] })
|
|
4463
4544
|
] }, view.id);
|
|
4464
4545
|
}) })
|
|
@@ -4466,7 +4547,7 @@ function JiraSavedViewsBox({
|
|
|
4466
4547
|
}
|
|
4467
4548
|
|
|
4468
4549
|
// src/components/jira-browser/JiraBrowserView.tsx
|
|
4469
|
-
import { jsx as
|
|
4550
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
4470
4551
|
function JiraBrowserView({
|
|
4471
4552
|
isActive,
|
|
4472
4553
|
focusedBox,
|
|
@@ -4583,7 +4664,7 @@ function JiraBrowserView({
|
|
|
4583
4664
|
{ isActive: isActive && !modal.isOpen && !inputModeActive }
|
|
4584
4665
|
);
|
|
4585
4666
|
if (modal.type === "add") {
|
|
4586
|
-
return /* @__PURE__ */
|
|
4667
|
+
return /* @__PURE__ */ jsx15(Box13, { flexDirection: "column", flexGrow: 1, children: /* @__PURE__ */ jsx15(
|
|
4587
4668
|
AddViewModal,
|
|
4588
4669
|
{
|
|
4589
4670
|
onSubmit: handleAddView,
|
|
@@ -4596,8 +4677,8 @@ function JiraBrowserView({
|
|
|
4596
4677
|
}
|
|
4597
4678
|
) });
|
|
4598
4679
|
}
|
|
4599
|
-
return /* @__PURE__ */
|
|
4600
|
-
/* @__PURE__ */
|
|
4680
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", flexGrow: 1, children: [
|
|
4681
|
+
/* @__PURE__ */ jsx15(
|
|
4601
4682
|
JiraSavedViewsBox,
|
|
4602
4683
|
{
|
|
4603
4684
|
views,
|
|
@@ -4612,7 +4693,7 @@ function JiraBrowserView({
|
|
|
4612
4693
|
onInputModeChange: setInputModeActive
|
|
4613
4694
|
}
|
|
4614
4695
|
),
|
|
4615
|
-
/* @__PURE__ */
|
|
4696
|
+
/* @__PURE__ */ jsx15(
|
|
4616
4697
|
JiraSavedViewBrowserBox,
|
|
4617
4698
|
{
|
|
4618
4699
|
view: selectedView,
|
|
@@ -4634,8 +4715,8 @@ import { useEffect as useEffect15, useRef as useRef8 } from "react";
|
|
|
4634
4715
|
|
|
4635
4716
|
// src/components/jira/LinkTicketModal.tsx
|
|
4636
4717
|
import { useState as useState18 } from "react";
|
|
4637
|
-
import { Box as
|
|
4638
|
-
import { jsx as
|
|
4718
|
+
import { Box as Box14, Text as Text14, useInput as useInput11 } from "ink";
|
|
4719
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4639
4720
|
function LinkTicketModal({ onSubmit, onCancel, loading, error }) {
|
|
4640
4721
|
const [ticketInput, setTicketInput] = useState18("");
|
|
4641
4722
|
const canSubmit = ticketInput.trim().length > 0;
|
|
@@ -4652,29 +4733,29 @@ function LinkTicketModal({ onSubmit, onCancel, loading, error }) {
|
|
|
4652
4733
|
},
|
|
4653
4734
|
{ isActive: !loading }
|
|
4654
4735
|
);
|
|
4655
|
-
return /* @__PURE__ */
|
|
4656
|
-
/* @__PURE__ */
|
|
4657
|
-
/* @__PURE__ */
|
|
4658
|
-
/* @__PURE__ */
|
|
4659
|
-
error && /* @__PURE__ */
|
|
4660
|
-
/* @__PURE__ */
|
|
4661
|
-
/* @__PURE__ */
|
|
4662
|
-
/* @__PURE__ */
|
|
4736
|
+
return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, paddingY: 1, children: [
|
|
4737
|
+
/* @__PURE__ */ jsx16(Text14, { bold: true, color: "yellow", children: "Link Jira Ticket" }),
|
|
4738
|
+
/* @__PURE__ */ jsx16(Text14, { dimColor: true, children: "Type ticket ID, Enter to submit, Esc to cancel" }),
|
|
4739
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1 }),
|
|
4740
|
+
error && /* @__PURE__ */ jsx16(Box14, { marginBottom: 1, children: /* @__PURE__ */ jsx16(Text14, { color: "red", children: error }) }),
|
|
4741
|
+
/* @__PURE__ */ jsxs14(Box14, { children: [
|
|
4742
|
+
/* @__PURE__ */ jsx16(Text14, { color: "blue", children: "Ticket: " }),
|
|
4743
|
+
/* @__PURE__ */ jsx16(TextInput, { value: ticketInput, onChange: setTicketInput, placeholder: "PROJ-123", isActive: !loading })
|
|
4663
4744
|
] }),
|
|
4664
|
-
loading && /* @__PURE__ */
|
|
4665
|
-
/* @__PURE__ */
|
|
4745
|
+
loading && /* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(Text14, { color: "yellow", children: "Fetching ticket..." }) }),
|
|
4746
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(Text14, { dimColor: true, children: "Examples: PROJ-123 or https://company.atlassian.net/browse/PROJ-123" }) })
|
|
4666
4747
|
] });
|
|
4667
4748
|
}
|
|
4668
4749
|
|
|
4669
4750
|
// src/components/jira/JiraView.tsx
|
|
4670
4751
|
import { TitledBox as TitledBox6 } from "@mishieck/ink-titled-box";
|
|
4671
|
-
import { Box as
|
|
4752
|
+
import { Box as Box18, Text as Text18, useInput as useInput14 } from "ink";
|
|
4672
4753
|
|
|
4673
4754
|
// src/components/jira/ChangeStatusModal.tsx
|
|
4674
4755
|
import { useEffect as useEffect14, useState as useState19 } from "react";
|
|
4675
|
-
import { Box as
|
|
4756
|
+
import { Box as Box15, Text as Text15, useInput as useInput12 } from "ink";
|
|
4676
4757
|
import SelectInput2 from "ink-select-input";
|
|
4677
|
-
import { jsx as
|
|
4758
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4678
4759
|
function ChangeStatusModal({ repoPath, ticketKey, currentStatus, onComplete, onCancel }) {
|
|
4679
4760
|
const [transitions, setTransitions] = useState19([]);
|
|
4680
4761
|
const [loading, setLoading] = useState19(true);
|
|
@@ -4742,23 +4823,23 @@ function ChangeStatusModal({ repoPath, ticketKey, currentStatus, onComplete, onC
|
|
|
4742
4823
|
0,
|
|
4743
4824
|
transitions.findIndex((t) => t.to.name === currentStatus)
|
|
4744
4825
|
);
|
|
4745
|
-
return /* @__PURE__ */
|
|
4746
|
-
/* @__PURE__ */
|
|
4826
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, paddingY: 1, children: [
|
|
4827
|
+
/* @__PURE__ */ jsxs15(Text15, { bold: true, color: "yellow", children: [
|
|
4747
4828
|
"Change Status: ",
|
|
4748
4829
|
ticketKey
|
|
4749
4830
|
] }),
|
|
4750
|
-
loading && /* @__PURE__ */
|
|
4751
|
-
error && /* @__PURE__ */
|
|
4752
|
-
!loading && !error && transitions.length === 0 && /* @__PURE__ */
|
|
4753
|
-
!loading && !error && transitions.length > 0 && !applying && /* @__PURE__ */
|
|
4754
|
-
applying && /* @__PURE__ */
|
|
4755
|
-
/* @__PURE__ */
|
|
4831
|
+
loading && /* @__PURE__ */ jsx17(Text15, { dimColor: true, children: "Loading transitions..." }),
|
|
4832
|
+
error && /* @__PURE__ */ jsx17(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx17(Text15, { color: "red", children: error }) }),
|
|
4833
|
+
!loading && !error && transitions.length === 0 && /* @__PURE__ */ jsx17(Text15, { dimColor: true, children: "No available transitions" }),
|
|
4834
|
+
!loading && !error && transitions.length > 0 && !applying && /* @__PURE__ */ jsx17(Box15, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx17(SelectInput2, { items, initialIndex, onSelect: handleSelect }) }),
|
|
4835
|
+
applying && /* @__PURE__ */ jsx17(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx17(Text15, { color: "yellow", children: "Updating status..." }) }),
|
|
4836
|
+
/* @__PURE__ */ jsx17(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx17(Text15, { dimColor: true, children: "Esc to cancel" }) })
|
|
4756
4837
|
] });
|
|
4757
4838
|
}
|
|
4758
4839
|
|
|
4759
4840
|
// src/components/jira/ConfigureJiraSiteModal.tsx
|
|
4760
4841
|
import { useState as useState20 } from "react";
|
|
4761
|
-
import { Box as
|
|
4842
|
+
import { Box as Box16, Text as Text16, useInput as useInput13 } from "ink";
|
|
4762
4843
|
import { ScrollView as ScrollView8 } from "ink-scroll-view";
|
|
4763
4844
|
|
|
4764
4845
|
// src/lib/editor.ts
|
|
@@ -4790,7 +4871,7 @@ function openInEditor(content, filename) {
|
|
|
4790
4871
|
}
|
|
4791
4872
|
|
|
4792
4873
|
// src/components/jira/ConfigureJiraSiteModal.tsx
|
|
4793
|
-
import { jsx as
|
|
4874
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4794
4875
|
var MAX_VISIBLE_ITEMS = 4;
|
|
4795
4876
|
function ConfigureJiraSiteModal({
|
|
4796
4877
|
initialSiteUrl,
|
|
@@ -4884,38 +4965,38 @@ function ConfigureJiraSiteModal({
|
|
|
4884
4965
|
const prefix = isSelected ? "> " : " ";
|
|
4885
4966
|
const color = isSelected ? "yellow" : void 0;
|
|
4886
4967
|
const displayValue = isSensitive && value ? "*".repeat(Math.min(value.length, 20)) : value;
|
|
4887
|
-
return /* @__PURE__ */
|
|
4888
|
-
/* @__PURE__ */
|
|
4968
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
4969
|
+
/* @__PURE__ */ jsxs16(Text16, { color, bold: isSelected, children: [
|
|
4889
4970
|
prefix,
|
|
4890
4971
|
label
|
|
4891
4972
|
] }),
|
|
4892
|
-
value !== void 0 && /* @__PURE__ */
|
|
4973
|
+
value !== void 0 && /* @__PURE__ */ jsx18(Box16, { marginLeft: 4, children: /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: displayValue || "(empty - press Enter to edit)" }) })
|
|
4893
4974
|
] });
|
|
4894
4975
|
};
|
|
4895
4976
|
if (mode === "choose") {
|
|
4896
4977
|
const totalItems = existingConfigs.length + 1;
|
|
4897
4978
|
const listHeight = Math.min(totalItems * 2, MAX_VISIBLE_ITEMS * 2);
|
|
4898
|
-
return /* @__PURE__ */
|
|
4899
|
-
/* @__PURE__ */
|
|
4900
|
-
/* @__PURE__ */
|
|
4901
|
-
/* @__PURE__ */
|
|
4902
|
-
error && /* @__PURE__ */
|
|
4903
|
-
/* @__PURE__ */
|
|
4979
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, paddingY: 1, children: [
|
|
4980
|
+
/* @__PURE__ */ jsx18(Text16, { bold: true, color: "cyan", children: "Configure Jira Site" }),
|
|
4981
|
+
/* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Select an existing configuration or enter new credentials" }),
|
|
4982
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1 }),
|
|
4983
|
+
error && /* @__PURE__ */ jsx18(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsx18(Text16, { color: "red", children: error }) }),
|
|
4984
|
+
/* @__PURE__ */ jsx18(Box16, { height: listHeight, overflow: "hidden", children: /* @__PURE__ */ jsxs16(ScrollView8, { ref: scrollRef, children: [
|
|
4904
4985
|
existingConfigs.map((config, idx) => {
|
|
4905
4986
|
const isSelected = selectedExisting === idx;
|
|
4906
|
-
return /* @__PURE__ */
|
|
4907
|
-
/* @__PURE__ */
|
|
4987
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
4988
|
+
/* @__PURE__ */ jsxs16(Text16, { color: isSelected ? "yellow" : void 0, bold: isSelected, children: [
|
|
4908
4989
|
isSelected ? "> " : " ",
|
|
4909
4990
|
config.siteUrl
|
|
4910
4991
|
] }),
|
|
4911
|
-
/* @__PURE__ */
|
|
4992
|
+
/* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
|
|
4912
4993
|
" ",
|
|
4913
4994
|
config.email
|
|
4914
4995
|
] })
|
|
4915
4996
|
] }, config.siteUrl + config.email);
|
|
4916
4997
|
}),
|
|
4917
|
-
/* @__PURE__ */
|
|
4918
|
-
|
|
4998
|
+
/* @__PURE__ */ jsx18(Box16, { children: /* @__PURE__ */ jsxs16(
|
|
4999
|
+
Text16,
|
|
4919
5000
|
{
|
|
4920
5001
|
color: selectedExisting === existingConfigs.length ? "yellow" : void 0,
|
|
4921
5002
|
bold: selectedExisting === existingConfigs.length,
|
|
@@ -4926,44 +5007,44 @@ function ConfigureJiraSiteModal({
|
|
|
4926
5007
|
}
|
|
4927
5008
|
) })
|
|
4928
5009
|
] }) }),
|
|
4929
|
-
loading && /* @__PURE__ */
|
|
5010
|
+
loading && /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(Text16, { color: "yellow", children: "Validating credentials..." }) })
|
|
4930
5011
|
] });
|
|
4931
5012
|
}
|
|
4932
|
-
return /* @__PURE__ */
|
|
4933
|
-
/* @__PURE__ */
|
|
4934
|
-
/* @__PURE__ */
|
|
5013
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, paddingY: 1, children: [
|
|
5014
|
+
/* @__PURE__ */ jsx18(Text16, { bold: true, color: "cyan", children: "Configure Jira Site" }),
|
|
5015
|
+
/* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
|
|
4935
5016
|
"Up/Down to select, Enter to edit, Esc to ",
|
|
4936
5017
|
hasExisting ? "go back" : "cancel"
|
|
4937
5018
|
] }),
|
|
4938
|
-
/* @__PURE__ */
|
|
4939
|
-
error && /* @__PURE__ */
|
|
5019
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1 }),
|
|
5020
|
+
error && /* @__PURE__ */ jsx18(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsx18(Text16, { color: "red", children: error }) }),
|
|
4940
5021
|
renderItem("siteUrl", "Site URL (e.g., https://company.atlassian.net)", siteUrl),
|
|
4941
|
-
/* @__PURE__ */
|
|
5022
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1 }),
|
|
4942
5023
|
renderItem("email", "Email", email),
|
|
4943
|
-
/* @__PURE__ */
|
|
5024
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1 }),
|
|
4944
5025
|
renderItem("apiToken", "API Token", apiToken, true),
|
|
4945
|
-
/* @__PURE__ */
|
|
4946
|
-
/* @__PURE__ */
|
|
5026
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1 }),
|
|
5027
|
+
/* @__PURE__ */ jsx18(Box16, { children: /* @__PURE__ */ jsxs16(Text16, { color: selectedItem === "submit" ? "green" : void 0, bold: selectedItem === "submit", children: [
|
|
4947
5028
|
selectedItem === "submit" ? "> " : " ",
|
|
4948
5029
|
canSubmit ? "[Save Configuration]" : "[Fill all fields first]"
|
|
4949
5030
|
] }) }),
|
|
4950
|
-
loading && /* @__PURE__ */
|
|
4951
|
-
/* @__PURE__ */
|
|
5031
|
+
loading && /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(Text16, { color: "yellow", children: "Validating credentials..." }) }),
|
|
5032
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Get your API token from: https://id.atlassian.com/manage-profile/security/api-tokens" }) })
|
|
4952
5033
|
] });
|
|
4953
5034
|
}
|
|
4954
5035
|
|
|
4955
5036
|
// src/components/jira/TicketItem.tsx
|
|
4956
|
-
import { Box as
|
|
4957
|
-
import { jsx as
|
|
5037
|
+
import { Box as Box17, Text as Text17 } from "ink";
|
|
5038
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4958
5039
|
function TicketItem({ ticketKey, summary, status, isHighlighted, isSelected }) {
|
|
4959
5040
|
const prefix = isHighlighted ? "> " : isSelected ? "\u25CF " : " ";
|
|
4960
5041
|
const textColor = isSelected ? "green" : void 0;
|
|
4961
|
-
return /* @__PURE__ */
|
|
5042
|
+
return /* @__PURE__ */ jsx19(Box17, { children: /* @__PURE__ */ jsxs17(Text17, { color: textColor, children: [
|
|
4962
5043
|
prefix,
|
|
4963
|
-
/* @__PURE__ */
|
|
5044
|
+
/* @__PURE__ */ jsx19(Text17, { bold: true, color: "blue", children: ticketKey }),
|
|
4964
5045
|
" ",
|
|
4965
5046
|
summary,
|
|
4966
|
-
status && /* @__PURE__ */
|
|
5047
|
+
status && /* @__PURE__ */ jsxs17(Text17, { dimColor: true, children: [
|
|
4967
5048
|
" [",
|
|
4968
5049
|
status,
|
|
4969
5050
|
"]"
|
|
@@ -4972,7 +5053,7 @@ function TicketItem({ ticketKey, summary, status, isHighlighted, isSelected }) {
|
|
|
4972
5053
|
}
|
|
4973
5054
|
|
|
4974
5055
|
// src/components/jira/JiraView.tsx
|
|
4975
|
-
import { jsx as
|
|
5056
|
+
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
4976
5057
|
function JiraView({ isActive, onModalChange, onJiraStateChange, onLogUpdated }) {
|
|
4977
5058
|
const repo = useGitRepo();
|
|
4978
5059
|
const jira = useJiraTickets();
|
|
@@ -5070,13 +5151,13 @@ function JiraView({ isActive, onModalChange, onJiraStateChange, onLogUpdated })
|
|
|
5070
5151
|
{ isActive: isActive && !modal.isOpen }
|
|
5071
5152
|
);
|
|
5072
5153
|
if (repo.isRepo === false) {
|
|
5073
|
-
return /* @__PURE__ */
|
|
5154
|
+
return /* @__PURE__ */ jsx20(TitledBox6, { borderStyle: "round", titles: ["Jira"], flexShrink: 0, children: /* @__PURE__ */ jsx20(Text18, { color: "red", children: "Not a git repository" }) });
|
|
5074
5155
|
}
|
|
5075
5156
|
if (modal.type === "configure") {
|
|
5076
5157
|
const siteUrl = repo.repoPath ? getJiraSiteUrl(repo.repoPath) : void 0;
|
|
5077
5158
|
const creds = repo.repoPath ? getJiraCredentials(repo.repoPath) : { email: null, apiToken: null };
|
|
5078
5159
|
const existingConfigs = getExistingJiraConfigs(repo.repoPath ?? void 0);
|
|
5079
|
-
return /* @__PURE__ */
|
|
5160
|
+
return /* @__PURE__ */ jsx20(Box18, { flexDirection: "column", flexShrink: 0, children: /* @__PURE__ */ jsx20(
|
|
5080
5161
|
ConfigureJiraSiteModal,
|
|
5081
5162
|
{
|
|
5082
5163
|
initialSiteUrl: siteUrl ?? void 0,
|
|
@@ -5093,7 +5174,7 @@ function JiraView({ isActive, onModalChange, onJiraStateChange, onLogUpdated })
|
|
|
5093
5174
|
) });
|
|
5094
5175
|
}
|
|
5095
5176
|
if (modal.type === "link") {
|
|
5096
|
-
return /* @__PURE__ */
|
|
5177
|
+
return /* @__PURE__ */ jsx20(Box18, { flexDirection: "column", flexShrink: 0, children: /* @__PURE__ */ jsx20(
|
|
5097
5178
|
LinkTicketModal,
|
|
5098
5179
|
{
|
|
5099
5180
|
onSubmit: handleLinkSubmit,
|
|
@@ -5107,7 +5188,7 @@ function JiraView({ isActive, onModalChange, onJiraStateChange, onLogUpdated })
|
|
|
5107
5188
|
) });
|
|
5108
5189
|
}
|
|
5109
5190
|
if (modal.type === "status" && repo.repoPath && repo.currentBranch && currentTicket) {
|
|
5110
|
-
return /* @__PURE__ */
|
|
5191
|
+
return /* @__PURE__ */ jsx20(Box18, { flexDirection: "column", flexShrink: 0, children: /* @__PURE__ */ jsx20(
|
|
5111
5192
|
ChangeStatusModal,
|
|
5112
5193
|
{
|
|
5113
5194
|
repoPath: repo.repoPath,
|
|
@@ -5120,10 +5201,10 @@ function JiraView({ isActive, onModalChange, onJiraStateChange, onLogUpdated })
|
|
|
5120
5201
|
}
|
|
5121
5202
|
const title = "[4] Jira";
|
|
5122
5203
|
const borderColor = isActive ? "yellow" : void 0;
|
|
5123
|
-
return /* @__PURE__ */
|
|
5124
|
-
jira.jiraState === "not_configured" && /* @__PURE__ */
|
|
5125
|
-
jira.jiraState === "no_tickets" && /* @__PURE__ */
|
|
5126
|
-
jira.jiraState === "has_tickets" && jira.tickets.map((ticket, idx) => /* @__PURE__ */
|
|
5204
|
+
return /* @__PURE__ */ jsx20(TitledBox6, { borderStyle: "round", titles: [title], borderColor, flexShrink: 0, children: /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", paddingX: 1, children: [
|
|
5205
|
+
jira.jiraState === "not_configured" && /* @__PURE__ */ jsx20(Text18, { dimColor: true, children: "No Jira site configured" }),
|
|
5206
|
+
jira.jiraState === "no_tickets" && /* @__PURE__ */ jsx20(Text18, { dimColor: true, children: "No tickets linked to this branch" }),
|
|
5207
|
+
jira.jiraState === "has_tickets" && jira.tickets.map((ticket, idx) => /* @__PURE__ */ jsx20(
|
|
5127
5208
|
TicketItem,
|
|
5128
5209
|
{
|
|
5129
5210
|
ticketKey: ticket.key,
|
|
@@ -5138,15 +5219,15 @@ function JiraView({ isActive, onModalChange, onJiraStateChange, onLogUpdated })
|
|
|
5138
5219
|
|
|
5139
5220
|
// src/components/logs/LogsView.tsx
|
|
5140
5221
|
import { useEffect as useEffect17 } from "react";
|
|
5141
|
-
import { Box as
|
|
5222
|
+
import { Box as Box21, useInput as useInput17 } from "ink";
|
|
5142
5223
|
|
|
5143
5224
|
// src/components/logs/LogViewerBox.tsx
|
|
5144
5225
|
import { useEffect as useEffect16, useRef as useRef9, useState as useState21 } from "react";
|
|
5145
5226
|
import { TitledBox as TitledBox7 } from "@mishieck/ink-titled-box";
|
|
5146
|
-
import { Box as
|
|
5227
|
+
import { Box as Box19, Text as Text19, useInput as useInput15 } from "ink";
|
|
5147
5228
|
import { ScrollView as ScrollView9 } from "ink-scroll-view";
|
|
5148
5229
|
import TextInput2 from "ink-text-input";
|
|
5149
|
-
import { jsx as
|
|
5230
|
+
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
5150
5231
|
function LogViewerBox({ date, content, isActive, onRefresh, onLogCreated }) {
|
|
5151
5232
|
const scrollRef = useRef9(null);
|
|
5152
5233
|
const [isInputMode, setIsInputMode] = useState21(false);
|
|
@@ -5242,14 +5323,14 @@ ${value.trim()}
|
|
|
5242
5323
|
setIsInputMode(false);
|
|
5243
5324
|
onRefresh();
|
|
5244
5325
|
};
|
|
5245
|
-
return /* @__PURE__ */
|
|
5246
|
-
/* @__PURE__ */
|
|
5247
|
-
!date && /* @__PURE__ */
|
|
5248
|
-
date && content === null && /* @__PURE__ */
|
|
5249
|
-
date && content !== null && content.trim() === "" && /* @__PURE__ */
|
|
5250
|
-
date && content && content.trim() !== "" && /* @__PURE__ */
|
|
5326
|
+
return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", flexGrow: 1, children: [
|
|
5327
|
+
/* @__PURE__ */ jsx21(TitledBox7, { borderStyle: "round", titles: [displayTitle], borderColor, flexGrow: 1, children: /* @__PURE__ */ jsx21(Box19, { flexDirection: "column", flexGrow: 1, children: /* @__PURE__ */ jsx21(ScrollView9, { ref: scrollRef, children: /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", paddingX: 1, children: [
|
|
5328
|
+
!date && /* @__PURE__ */ jsx21(Text19, { dimColor: true, children: "Select a log file to view" }),
|
|
5329
|
+
date && content === null && /* @__PURE__ */ jsx21(Text19, { dimColor: true, children: "Log file not found" }),
|
|
5330
|
+
date && content !== null && content.trim() === "" && /* @__PURE__ */ jsx21(Text19, { dimColor: true, children: "Empty log file" }),
|
|
5331
|
+
date && content && content.trim() !== "" && /* @__PURE__ */ jsx21(Markdown, { children: content })
|
|
5251
5332
|
] }) }) }) }),
|
|
5252
|
-
isInputMode && /* @__PURE__ */
|
|
5333
|
+
isInputMode && /* @__PURE__ */ jsx21(TitledBox7, { borderStyle: "round", titles: ["Add Entry"], borderColor: "yellow", children: /* @__PURE__ */ jsx21(Box19, { paddingX: 1, children: /* @__PURE__ */ jsx21(
|
|
5253
5334
|
TextInput2,
|
|
5254
5335
|
{
|
|
5255
5336
|
value: inputValue,
|
|
@@ -5257,19 +5338,19 @@ ${value.trim()}
|
|
|
5257
5338
|
onSubmit: handleInputSubmit
|
|
5258
5339
|
}
|
|
5259
5340
|
) }) }),
|
|
5260
|
-
isGeneratingStandup && /* @__PURE__ */
|
|
5261
|
-
/* @__PURE__ */
|
|
5262
|
-
/* @__PURE__ */
|
|
5341
|
+
isGeneratingStandup && /* @__PURE__ */ jsx21(TitledBox7, { borderStyle: "round", titles: ["Standup Notes"], borderColor: "yellow", children: /* @__PURE__ */ jsxs19(Box19, { paddingX: 1, flexDirection: "column", children: [
|
|
5342
|
+
/* @__PURE__ */ jsx21(AnimatedText, { name: "radar", config: { baseColor: "#CC6600" }, children: "Generating standup notes with Claude..." }),
|
|
5343
|
+
/* @__PURE__ */ jsx21(Text19, { dimColor: true, children: "Press Esc to cancel" })
|
|
5263
5344
|
] }) }),
|
|
5264
|
-
standupResult && /* @__PURE__ */
|
|
5345
|
+
standupResult && /* @__PURE__ */ jsx21(
|
|
5265
5346
|
TitledBox7,
|
|
5266
5347
|
{
|
|
5267
5348
|
borderStyle: "round",
|
|
5268
5349
|
titles: ["Standup Notes"],
|
|
5269
5350
|
borderColor: standupResult.type === "error" ? "red" : "green",
|
|
5270
|
-
children: /* @__PURE__ */
|
|
5271
|
-
standupResult.type === "error" ? /* @__PURE__ */
|
|
5272
|
-
/* @__PURE__ */
|
|
5351
|
+
children: /* @__PURE__ */ jsxs19(Box19, { paddingX: 1, flexDirection: "column", children: [
|
|
5352
|
+
standupResult.type === "error" ? /* @__PURE__ */ jsx21(Text19, { color: "red", children: standupResult.message }) : /* @__PURE__ */ jsx21(Markdown, { children: standupResult.message }),
|
|
5353
|
+
/* @__PURE__ */ jsx21(Text19, { dimColor: true, children: "Press Esc to dismiss" })
|
|
5273
5354
|
] })
|
|
5274
5355
|
}
|
|
5275
5356
|
)
|
|
@@ -5278,9 +5359,9 @@ ${value.trim()}
|
|
|
5278
5359
|
|
|
5279
5360
|
// src/components/logs/LogsHistoryBox.tsx
|
|
5280
5361
|
import { TitledBox as TitledBox8 } from "@mishieck/ink-titled-box";
|
|
5281
|
-
import { Box as
|
|
5362
|
+
import { Box as Box20, Text as Text20, useInput as useInput16 } from "ink";
|
|
5282
5363
|
import { ScrollView as ScrollView10 } from "ink-scroll-view";
|
|
5283
|
-
import { jsx as
|
|
5364
|
+
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
5284
5365
|
function LogsHistoryBox({
|
|
5285
5366
|
logFiles,
|
|
5286
5367
|
selectedDate,
|
|
@@ -5310,28 +5391,28 @@ function LogsHistoryBox({
|
|
|
5310
5391
|
},
|
|
5311
5392
|
{ isActive }
|
|
5312
5393
|
);
|
|
5313
|
-
return /* @__PURE__ */
|
|
5314
|
-
logFiles.length === 0 && /* @__PURE__ */
|
|
5315
|
-
logFiles.length > 0 && /* @__PURE__ */
|
|
5394
|
+
return /* @__PURE__ */ jsx22(TitledBox8, { borderStyle: "round", titles: [title], borderColor, height: 5, children: /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", paddingX: 1, flexGrow: 1, overflow: "hidden", children: [
|
|
5395
|
+
logFiles.length === 0 && /* @__PURE__ */ jsx22(Text20, { dimColor: true, children: "No logs yet" }),
|
|
5396
|
+
logFiles.length > 0 && /* @__PURE__ */ jsx22(ScrollView10, { ref: scrollRef, children: logFiles.map((file, idx) => {
|
|
5316
5397
|
const isHighlighted = idx === highlightedIndex;
|
|
5317
5398
|
const isSelected = file.date === selectedDate;
|
|
5318
5399
|
const cursor = isHighlighted ? ">" : " ";
|
|
5319
5400
|
const indicator = isSelected ? " *" : "";
|
|
5320
|
-
return /* @__PURE__ */
|
|
5321
|
-
/* @__PURE__ */
|
|
5401
|
+
return /* @__PURE__ */ jsxs20(Box20, { children: [
|
|
5402
|
+
/* @__PURE__ */ jsxs20(Text20, { color: isHighlighted ? "yellow" : void 0, children: [
|
|
5322
5403
|
cursor,
|
|
5323
5404
|
" "
|
|
5324
5405
|
] }),
|
|
5325
|
-
/* @__PURE__ */
|
|
5326
|
-
file.isToday && /* @__PURE__ */
|
|
5327
|
-
/* @__PURE__ */
|
|
5406
|
+
/* @__PURE__ */ jsx22(Text20, { color: file.isToday ? "green" : void 0, bold: file.isToday, children: file.date }),
|
|
5407
|
+
file.isToday && /* @__PURE__ */ jsx22(Text20, { color: "green", children: " (today)" }),
|
|
5408
|
+
/* @__PURE__ */ jsx22(Text20, { dimColor: true, children: indicator })
|
|
5328
5409
|
] }, file.date);
|
|
5329
5410
|
}) })
|
|
5330
5411
|
] }) });
|
|
5331
5412
|
}
|
|
5332
5413
|
|
|
5333
5414
|
// src/components/logs/LogsView.tsx
|
|
5334
|
-
import { jsx as
|
|
5415
|
+
import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
5335
5416
|
function LogsView({ isActive, refreshKey, focusedBox, onFocusedBoxChange }) {
|
|
5336
5417
|
const logs = useLogs();
|
|
5337
5418
|
useEffect17(() => {
|
|
@@ -5346,8 +5427,8 @@ function LogsView({ isActive, refreshKey, focusedBox, onFocusedBoxChange }) {
|
|
|
5346
5427
|
},
|
|
5347
5428
|
{ isActive }
|
|
5348
5429
|
);
|
|
5349
|
-
return /* @__PURE__ */
|
|
5350
|
-
/* @__PURE__ */
|
|
5430
|
+
return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", flexGrow: 1, children: [
|
|
5431
|
+
/* @__PURE__ */ jsx23(
|
|
5351
5432
|
LogsHistoryBox,
|
|
5352
5433
|
{
|
|
5353
5434
|
logFiles: logs.logFiles,
|
|
@@ -5358,7 +5439,7 @@ function LogsView({ isActive, refreshKey, focusedBox, onFocusedBoxChange }) {
|
|
|
5358
5439
|
isActive: isActive && focusedBox === "history"
|
|
5359
5440
|
}
|
|
5360
5441
|
),
|
|
5361
|
-
/* @__PURE__ */
|
|
5442
|
+
/* @__PURE__ */ jsx23(
|
|
5362
5443
|
LogViewerBox,
|
|
5363
5444
|
{
|
|
5364
5445
|
date: logs.selectedDate,
|
|
@@ -5371,9 +5452,376 @@ function LogsView({ isActive, refreshKey, focusedBox, onFocusedBoxChange }) {
|
|
|
5371
5452
|
] });
|
|
5372
5453
|
}
|
|
5373
5454
|
|
|
5455
|
+
// src/components/pull-requests/AllPullRequestsView.tsx
|
|
5456
|
+
import open6 from "open";
|
|
5457
|
+
import { useCallback as useCallback11, useEffect as useEffect18, useState as useState22 } from "react";
|
|
5458
|
+
import { Box as Box22, Text as Text21, useInput as useInput18 } from "ink";
|
|
5459
|
+
import { ScrollView as ScrollView11 } from "ink-scroll-view";
|
|
5460
|
+
import Spinner4 from "ink-spinner";
|
|
5461
|
+
|
|
5462
|
+
// src/lib/github/pr-list.ts
|
|
5463
|
+
import { exec as exec4 } from "child_process";
|
|
5464
|
+
import { promisify as promisify2 } from "util";
|
|
5465
|
+
var execAsync2 = promisify2(exec4);
|
|
5466
|
+
async function listPRs(repo, opts) {
|
|
5467
|
+
if (!await isGhInstalled()) {
|
|
5468
|
+
return {
|
|
5469
|
+
success: false,
|
|
5470
|
+
error: "GitHub CLI (gh) is not installed. Install from https://cli.github.com",
|
|
5471
|
+
errorType: "not_installed"
|
|
5472
|
+
};
|
|
5473
|
+
}
|
|
5474
|
+
if (!await isGhAuthenticated()) {
|
|
5475
|
+
return {
|
|
5476
|
+
success: false,
|
|
5477
|
+
error: "Not authenticated. Run 'gh auth login' to authenticate.",
|
|
5478
|
+
errorType: "not_authenticated"
|
|
5479
|
+
};
|
|
5480
|
+
}
|
|
5481
|
+
const fields = "number,title,state,author,createdAt,isDraft,reviewDecision,statusCheckRollup";
|
|
5482
|
+
const state = (opts == null ? void 0 : opts.state) ?? "open";
|
|
5483
|
+
const limit = (opts == null ? void 0 : opts.limit) ?? 30;
|
|
5484
|
+
const args = [`gh pr list`, `--state ${state}`, `--limit ${limit}`, `--json ${fields}`, `--repo "${repo}"`];
|
|
5485
|
+
if (opts == null ? void 0 : opts.search) {
|
|
5486
|
+
args.push(`--search "${opts.search.replace(/"/g, '\\"')}"`);
|
|
5487
|
+
}
|
|
5488
|
+
try {
|
|
5489
|
+
const { stdout } = await execAsync2(`${args.join(" ")} 2>/dev/null`);
|
|
5490
|
+
const prs = JSON.parse(stdout);
|
|
5491
|
+
return { success: true, data: prs };
|
|
5492
|
+
} catch {
|
|
5493
|
+
return { success: false, error: "Failed to fetch PRs", errorType: "api_error" };
|
|
5494
|
+
}
|
|
5495
|
+
}
|
|
5496
|
+
async function checkoutPR(prNumber, repo) {
|
|
5497
|
+
if (!await isGhInstalled()) {
|
|
5498
|
+
return { success: false, error: "gh CLI not installed", errorType: "not_installed" };
|
|
5499
|
+
}
|
|
5500
|
+
if (!await isGhAuthenticated()) {
|
|
5501
|
+
return { success: false, error: "gh CLI not authenticated", errorType: "not_authenticated" };
|
|
5502
|
+
}
|
|
5503
|
+
try {
|
|
5504
|
+
await execAsync2(`gh pr checkout ${prNumber} --repo "${repo}" 2>&1`);
|
|
5505
|
+
return { success: true, data: `Checked out PR #${prNumber}` };
|
|
5506
|
+
} catch (e) {
|
|
5507
|
+
const msg = e instanceof Error ? e.message.split("\n").pop() ?? e.message : "Failed to checkout PR";
|
|
5508
|
+
return { success: false, error: msg, errorType: "api_error" };
|
|
5509
|
+
}
|
|
5510
|
+
}
|
|
5511
|
+
|
|
5512
|
+
// src/components/pull-requests/AllPullRequestsView.tsx
|
|
5513
|
+
import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
5514
|
+
var STATE_CYCLE = ["open", "closed", "all"];
|
|
5515
|
+
function computeOverallCheck(checks) {
|
|
5516
|
+
if (!checks || checks.length === 0) return null;
|
|
5517
|
+
const statuses = checks.map(resolveCheckStatus);
|
|
5518
|
+
if (statuses.some((s) => s === "failure")) return "failure";
|
|
5519
|
+
if (statuses.some((s) => s === "pending")) return "pending";
|
|
5520
|
+
return "success";
|
|
5521
|
+
}
|
|
5522
|
+
function AllPullRequestsView({ isActive, onModalChange }) {
|
|
5523
|
+
const repo = useGitRepo();
|
|
5524
|
+
const [prs, setPrs] = useState22([]);
|
|
5525
|
+
const [loading, setLoading] = useState22(false);
|
|
5526
|
+
const [error, setError] = useState22(null);
|
|
5527
|
+
const [detailPR, setDetailPR] = useState22(null);
|
|
5528
|
+
const [prDetails, setPrDetails] = useState22(null);
|
|
5529
|
+
const [detailsLoading, setDetailsLoading] = useState22(false);
|
|
5530
|
+
const [detailsError, setDetailsError] = useState22(void 0);
|
|
5531
|
+
const [stateFilter, setStateFilter] = useState22("open");
|
|
5532
|
+
const [searchText, setSearchText] = useState22("");
|
|
5533
|
+
const [inputText, setInputText] = useState22("");
|
|
5534
|
+
const [limit, setLimit] = useState22(30);
|
|
5535
|
+
const [isSearching, setIsSearching] = useState22(false);
|
|
5536
|
+
const [checkoutLoading, setCheckoutLoading] = useState22(false);
|
|
5537
|
+
const [checkoutResult, setCheckoutResult] = useState22(null);
|
|
5538
|
+
useEffect18(() => {
|
|
5539
|
+
onModalChange == null ? void 0 : onModalChange(isSearching || detailPR !== null);
|
|
5540
|
+
}, [isSearching, detailPR, onModalChange]);
|
|
5541
|
+
const doFetch = useCallback11(
|
|
5542
|
+
async (state, search, fetchLimit = 30) => {
|
|
5543
|
+
if (!repo.currentRepoSlug) return;
|
|
5544
|
+
setLoading(true);
|
|
5545
|
+
setError(null);
|
|
5546
|
+
setPrs([]);
|
|
5547
|
+
const result = await listPRs(repo.currentRepoSlug, {
|
|
5548
|
+
state,
|
|
5549
|
+
search: search || void 0,
|
|
5550
|
+
limit: fetchLimit
|
|
5551
|
+
});
|
|
5552
|
+
if (result.success) {
|
|
5553
|
+
setPrs(result.data);
|
|
5554
|
+
} else {
|
|
5555
|
+
setError(result.error);
|
|
5556
|
+
}
|
|
5557
|
+
setLoading(false);
|
|
5558
|
+
},
|
|
5559
|
+
[repo.currentRepoSlug]
|
|
5560
|
+
);
|
|
5561
|
+
useEffect18(() => {
|
|
5562
|
+
if (repo.currentRepoSlug) {
|
|
5563
|
+
setStateFilter("open");
|
|
5564
|
+
setSearchText("");
|
|
5565
|
+
setInputText("");
|
|
5566
|
+
doFetch("open", "");
|
|
5567
|
+
}
|
|
5568
|
+
}, [repo.currentRepoSlug]);
|
|
5569
|
+
const fetchDetails = useCallback11(
|
|
5570
|
+
async (pr) => {
|
|
5571
|
+
if (!repo.currentRepoSlug) return;
|
|
5572
|
+
setDetailsLoading(true);
|
|
5573
|
+
setDetailsError(void 0);
|
|
5574
|
+
const result = await getPRDetails(pr.number, repo.currentRepoSlug);
|
|
5575
|
+
if (result.success) {
|
|
5576
|
+
setPrDetails(result.data);
|
|
5577
|
+
setDetailsError(void 0);
|
|
5578
|
+
} else {
|
|
5579
|
+
setDetailsError(result.error);
|
|
5580
|
+
}
|
|
5581
|
+
setDetailsLoading(false);
|
|
5582
|
+
},
|
|
5583
|
+
[repo.currentRepoSlug]
|
|
5584
|
+
);
|
|
5585
|
+
const handleSelect = useCallback11(
|
|
5586
|
+
(index) => {
|
|
5587
|
+
const pr = prs[index];
|
|
5588
|
+
if (pr) {
|
|
5589
|
+
setDetailPR(pr);
|
|
5590
|
+
fetchDetails(pr);
|
|
5591
|
+
}
|
|
5592
|
+
},
|
|
5593
|
+
[prs, fetchDetails]
|
|
5594
|
+
);
|
|
5595
|
+
const { highlightedIndex, scrollRef } = useListNavigation({
|
|
5596
|
+
items: prs,
|
|
5597
|
+
selectedIndex: detailPR ? prs.findIndex((p) => p.number === detailPR.number) : -1,
|
|
5598
|
+
onSelect: handleSelect,
|
|
5599
|
+
isActive: isActive && !detailPR && !isSearching
|
|
5600
|
+
});
|
|
5601
|
+
const currentPR = prs[highlightedIndex] ?? null;
|
|
5602
|
+
const getPRUrl = (pr) => {
|
|
5603
|
+
if (!repo.currentRepoSlug) return null;
|
|
5604
|
+
return `https://github.com/${repo.currentRepoSlug}/pull/${pr.number}`;
|
|
5605
|
+
};
|
|
5606
|
+
const hasActiveFilters = stateFilter !== "open" || searchText.length > 0;
|
|
5607
|
+
useInput18(
|
|
5608
|
+
(input, key) => {
|
|
5609
|
+
if (isSearching) {
|
|
5610
|
+
if (key.escape) {
|
|
5611
|
+
setIsSearching(false);
|
|
5612
|
+
setInputText(searchText);
|
|
5613
|
+
return;
|
|
5614
|
+
}
|
|
5615
|
+
if (key.return) {
|
|
5616
|
+
setIsSearching(false);
|
|
5617
|
+
const newSearch = inputText.trim();
|
|
5618
|
+
if (newSearch !== searchText) {
|
|
5619
|
+
setSearchText(newSearch);
|
|
5620
|
+
setLimit(30);
|
|
5621
|
+
doFetch(stateFilter, newSearch);
|
|
5622
|
+
duckEvents.emit("pr:filtered");
|
|
5623
|
+
}
|
|
5624
|
+
return;
|
|
5625
|
+
}
|
|
5626
|
+
if (key.backspace || key.delete) {
|
|
5627
|
+
setInputText((prev) => prev.slice(0, -1));
|
|
5628
|
+
return;
|
|
5629
|
+
}
|
|
5630
|
+
if (input && input.length > 0) {
|
|
5631
|
+
const printable = input.replace(/[^\x20-\x7E\u00A0-\uFFFF]/g, "");
|
|
5632
|
+
if (printable.length > 0) {
|
|
5633
|
+
setInputText((prev) => prev + printable);
|
|
5634
|
+
}
|
|
5635
|
+
return;
|
|
5636
|
+
}
|
|
5637
|
+
return;
|
|
5638
|
+
}
|
|
5639
|
+
if (input === "/") {
|
|
5640
|
+
setIsSearching(true);
|
|
5641
|
+
setInputText(searchText);
|
|
5642
|
+
return;
|
|
5643
|
+
}
|
|
5644
|
+
if (input === "s") {
|
|
5645
|
+
const idx = STATE_CYCLE.indexOf(stateFilter);
|
|
5646
|
+
const newState = STATE_CYCLE[(idx + 1) % STATE_CYCLE.length];
|
|
5647
|
+
setStateFilter(newState);
|
|
5648
|
+
setLimit(30);
|
|
5649
|
+
doFetch(newState, searchText);
|
|
5650
|
+
duckEvents.emit("pr:filtered");
|
|
5651
|
+
return;
|
|
5652
|
+
}
|
|
5653
|
+
if (input === "x") {
|
|
5654
|
+
setStateFilter("open");
|
|
5655
|
+
setSearchText("");
|
|
5656
|
+
setInputText("");
|
|
5657
|
+
setLimit(30);
|
|
5658
|
+
doFetch("open", "");
|
|
5659
|
+
return;
|
|
5660
|
+
}
|
|
5661
|
+
if (input === "o" && currentPR) {
|
|
5662
|
+
const url = getPRUrl(currentPR);
|
|
5663
|
+
if (url) open6(url).catch(() => {
|
|
5664
|
+
});
|
|
5665
|
+
}
|
|
5666
|
+
if (input === "y" && currentPR) {
|
|
5667
|
+
const url = getPRUrl(currentPR);
|
|
5668
|
+
if (url) copyToClipboard(url);
|
|
5669
|
+
}
|
|
5670
|
+
if (input === "l") {
|
|
5671
|
+
const newLimit = limit + 30;
|
|
5672
|
+
setLimit(newLimit);
|
|
5673
|
+
doFetch(stateFilter, searchText, newLimit);
|
|
5674
|
+
return;
|
|
5675
|
+
}
|
|
5676
|
+
if (input === "r") {
|
|
5677
|
+
doFetch(stateFilter, searchText, limit);
|
|
5678
|
+
}
|
|
5679
|
+
},
|
|
5680
|
+
{ isActive: isActive && !detailPR }
|
|
5681
|
+
);
|
|
5682
|
+
useInput18(
|
|
5683
|
+
(input, key) => {
|
|
5684
|
+
if (key.escape) {
|
|
5685
|
+
setDetailPR(null);
|
|
5686
|
+
setCheckoutResult(null);
|
|
5687
|
+
return;
|
|
5688
|
+
}
|
|
5689
|
+
if (input === "y" && detailPR) {
|
|
5690
|
+
const url = getPRUrl(detailPR);
|
|
5691
|
+
if (url) copyToClipboard(url);
|
|
5692
|
+
}
|
|
5693
|
+
if (input === "c" && detailPR && !checkoutLoading && repo.currentRepoSlug) {
|
|
5694
|
+
setCheckoutLoading(true);
|
|
5695
|
+
setCheckoutResult(null);
|
|
5696
|
+
checkoutPR(detailPR.number, repo.currentRepoSlug).then((result) => {
|
|
5697
|
+
setCheckoutLoading(false);
|
|
5698
|
+
if (result.success) {
|
|
5699
|
+
setCheckoutResult({ success: true, message: `Checked out #${detailPR.number}` });
|
|
5700
|
+
duckEvents.emit("pr:checkout", { prNumber: detailPR.number, prTitle: detailPR.title });
|
|
5701
|
+
repo.refreshBranch();
|
|
5702
|
+
} else {
|
|
5703
|
+
setCheckoutResult({ success: false, message: result.error });
|
|
5704
|
+
}
|
|
5705
|
+
});
|
|
5706
|
+
}
|
|
5707
|
+
},
|
|
5708
|
+
{ isActive: isActive && detailPR !== null }
|
|
5709
|
+
);
|
|
5710
|
+
const filterParts = [];
|
|
5711
|
+
if (stateFilter !== "open") filterParts.push(stateFilter);
|
|
5712
|
+
if (searchText) filterParts.push(`"${searchText}"`);
|
|
5713
|
+
const borderColor = isActive ? "yellow" : void 0;
|
|
5714
|
+
const scrollRatio = isActive && prs.length > 1 ? highlightedIndex / (prs.length - 1) : null;
|
|
5715
|
+
const stateColor = (pr) => {
|
|
5716
|
+
const display = resolveMergeDisplay({
|
|
5717
|
+
state: pr.state,
|
|
5718
|
+
isDraft: pr.isDraft,
|
|
5719
|
+
mergeable: "UNKNOWN"
|
|
5720
|
+
});
|
|
5721
|
+
return display.color;
|
|
5722
|
+
};
|
|
5723
|
+
const stateLabel = (pr) => {
|
|
5724
|
+
if (pr.isDraft) return "Draft";
|
|
5725
|
+
if (pr.state === "MERGED") return "Merged";
|
|
5726
|
+
if (pr.state === "CLOSED") return "Closed";
|
|
5727
|
+
return "Open";
|
|
5728
|
+
};
|
|
5729
|
+
if (detailPR) {
|
|
5730
|
+
return /* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", flexGrow: 1, children: [
|
|
5731
|
+
/* @__PURE__ */ jsx24(
|
|
5732
|
+
PRDetailsBox,
|
|
5733
|
+
{
|
|
5734
|
+
pr: prDetails,
|
|
5735
|
+
loading: detailsLoading,
|
|
5736
|
+
error: detailsError,
|
|
5737
|
+
isActive,
|
|
5738
|
+
title: "[5] Pull Requests"
|
|
5739
|
+
}
|
|
5740
|
+
),
|
|
5741
|
+
checkoutLoading ? /* @__PURE__ */ jsxs22(Text21, { color: "yellow", children: [
|
|
5742
|
+
" ",
|
|
5743
|
+
/* @__PURE__ */ jsx24(Spinner4, { type: "dots" }),
|
|
5744
|
+
" Checking out..."
|
|
5745
|
+
] }) : checkoutResult ? /* @__PURE__ */ jsxs22(Text21, { color: checkoutResult.success ? "green" : "red", children: [
|
|
5746
|
+
" ",
|
|
5747
|
+
checkoutResult.message
|
|
5748
|
+
] }) : /* @__PURE__ */ jsx24(Text21, { dimColor: true, children: " Esc back \xB7 j/k scroll \xB7 o open \xB7 y copy \xB7 c checkout" })
|
|
5749
|
+
] });
|
|
5750
|
+
}
|
|
5751
|
+
return /* @__PURE__ */ jsx24(TitledBox4, { title: "[5] Pull Requests", borderColor, scrollRatio, children: /* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", paddingX: 1, flexGrow: 1, flexBasis: 0, overflow: "hidden", children: [
|
|
5752
|
+
(isSearching || hasActiveFilters) && /* @__PURE__ */ jsxs22(Box22, { children: [
|
|
5753
|
+
/* @__PURE__ */ jsx24(Text21, { color: "blue", children: "Filter: " }),
|
|
5754
|
+
isSearching ? /* @__PURE__ */ jsxs22(Fragment5, { children: [
|
|
5755
|
+
/* @__PURE__ */ jsx24(Text21, { children: inputText }),
|
|
5756
|
+
/* @__PURE__ */ jsx24(Text21, { backgroundColor: "yellow", children: " " })
|
|
5757
|
+
] }) : /* @__PURE__ */ jsxs22(Fragment5, { children: [
|
|
5758
|
+
/* @__PURE__ */ jsx24(Text21, { children: filterParts.join(" + ") }),
|
|
5759
|
+
/* @__PURE__ */ jsxs22(Text21, { dimColor: true, children: [
|
|
5760
|
+
" (",
|
|
5761
|
+
prs.length,
|
|
5762
|
+
")"
|
|
5763
|
+
] })
|
|
5764
|
+
] })
|
|
5765
|
+
] }),
|
|
5766
|
+
loading && /* @__PURE__ */ jsxs22(Text21, { color: "yellow", children: [
|
|
5767
|
+
/* @__PURE__ */ jsx24(Spinner4, { type: "dots" }),
|
|
5768
|
+
" Loading PRs 1-",
|
|
5769
|
+
limit,
|
|
5770
|
+
"..."
|
|
5771
|
+
] }),
|
|
5772
|
+
error && /* @__PURE__ */ jsx24(Text21, { color: "red", children: error }),
|
|
5773
|
+
!loading && !error && prs.length === 0 && /* @__PURE__ */ jsx24(Text21, { dimColor: true, children: hasActiveFilters ? "No PRs match filter" : "No open PRs" }),
|
|
5774
|
+
!loading && !error && prs.length > 0 && /* @__PURE__ */ jsx24(Box22, { flexGrow: 1, flexBasis: 0, overflow: "hidden", children: /* @__PURE__ */ jsx24(ScrollView11, { ref: scrollRef, children: prs.map((pr, idx) => {
|
|
5775
|
+
const isHighlighted = isActive && idx === highlightedIndex;
|
|
5776
|
+
const cursor = isHighlighted ? ">" : " ";
|
|
5777
|
+
const review = resolveReviewDisplay(pr.reviewDecision);
|
|
5778
|
+
const overallCheck = computeOverallCheck(pr.statusCheckRollup);
|
|
5779
|
+
return /* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", children: [
|
|
5780
|
+
/* @__PURE__ */ jsxs22(Box22, { children: [
|
|
5781
|
+
/* @__PURE__ */ jsxs22(Text21, { color: isHighlighted ? "yellow" : void 0, children: [
|
|
5782
|
+
cursor,
|
|
5783
|
+
" "
|
|
5784
|
+
] }),
|
|
5785
|
+
/* @__PURE__ */ jsxs22(Text21, { children: [
|
|
5786
|
+
"#",
|
|
5787
|
+
pr.number
|
|
5788
|
+
] }),
|
|
5789
|
+
/* @__PURE__ */ jsxs22(Text21, { children: [
|
|
5790
|
+
" ",
|
|
5791
|
+
pr.title,
|
|
5792
|
+
" "
|
|
5793
|
+
] }),
|
|
5794
|
+
(pr.state !== "OPEN" || pr.isDraft) && /* @__PURE__ */ jsxs22(Text21, { color: stateColor(pr), children: [
|
|
5795
|
+
"[",
|
|
5796
|
+
stateLabel(pr),
|
|
5797
|
+
"]"
|
|
5798
|
+
] })
|
|
5799
|
+
] }),
|
|
5800
|
+
/* @__PURE__ */ jsxs22(Box22, { children: [
|
|
5801
|
+
/* @__PURE__ */ jsx24(Text21, { children: " " }),
|
|
5802
|
+
/* @__PURE__ */ jsxs22(Text21, { dimColor: true, children: [
|
|
5803
|
+
" ",
|
|
5804
|
+
pr.author.login,
|
|
5805
|
+
" \xB7 ",
|
|
5806
|
+
timeAgo(pr.createdAt)
|
|
5807
|
+
] }),
|
|
5808
|
+
pr.reviewDecision && /* @__PURE__ */ jsxs22(Text21, { dimColor: true, children: [
|
|
5809
|
+
" \xB7 ",
|
|
5810
|
+
review.text
|
|
5811
|
+
] }),
|
|
5812
|
+
overallCheck && /* @__PURE__ */ jsxs22(Text21, { color: CHECK_COLORS[overallCheck], children: [
|
|
5813
|
+
" ",
|
|
5814
|
+
CHECK_ICONS[overallCheck]
|
|
5815
|
+
] })
|
|
5816
|
+
] })
|
|
5817
|
+
] }, pr.number);
|
|
5818
|
+
}) }) })
|
|
5819
|
+
] }) });
|
|
5820
|
+
}
|
|
5821
|
+
|
|
5374
5822
|
// src/components/ui/KeybindingsBar.tsx
|
|
5375
|
-
import { Box as
|
|
5376
|
-
import { jsx as
|
|
5823
|
+
import { Box as Box23, Text as Text22 } from "ink";
|
|
5824
|
+
import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
5377
5825
|
var globalBindings = [
|
|
5378
5826
|
{ key: "1-4", label: "Focus" },
|
|
5379
5827
|
{ key: "Tab", label: "Switch Tab" },
|
|
@@ -5384,14 +5832,14 @@ var modalBindings = [{ key: "Esc", label: "Cancel" }];
|
|
|
5384
5832
|
var DUCK_ASCII = "<(')___";
|
|
5385
5833
|
function KeybindingsBar({ contextBindings = [], modalOpen = false, duck }) {
|
|
5386
5834
|
const allBindings = modalOpen ? [...contextBindings, ...modalBindings] : [...contextBindings, ...globalBindings];
|
|
5387
|
-
return /* @__PURE__ */
|
|
5388
|
-
allBindings.map((binding) => /* @__PURE__ */
|
|
5389
|
-
/* @__PURE__ */
|
|
5390
|
-
/* @__PURE__ */
|
|
5835
|
+
return /* @__PURE__ */ jsxs23(Box23, { flexShrink: 0, paddingX: 1, gap: 2, children: [
|
|
5836
|
+
allBindings.map((binding) => /* @__PURE__ */ jsxs23(Box23, { gap: 1, children: [
|
|
5837
|
+
/* @__PURE__ */ jsx25(Text22, { bold: true, color: binding.color ?? "yellow", children: binding.key }),
|
|
5838
|
+
/* @__PURE__ */ jsx25(Text22, { dimColor: true, children: binding.label })
|
|
5391
5839
|
] }, binding.key)),
|
|
5392
|
-
(duck == null ? void 0 : duck.visible) && /* @__PURE__ */
|
|
5393
|
-
/* @__PURE__ */
|
|
5394
|
-
/* @__PURE__ */
|
|
5840
|
+
(duck == null ? void 0 : duck.visible) && /* @__PURE__ */ jsxs23(Box23, { flexGrow: 1, justifyContent: "flex-end", gap: 1, children: [
|
|
5841
|
+
/* @__PURE__ */ jsx25(Text22, { children: DUCK_ASCII }),
|
|
5842
|
+
/* @__PURE__ */ jsx25(Text22, { dimColor: true, children: duck.message })
|
|
5395
5843
|
] })
|
|
5396
5844
|
] });
|
|
5397
5845
|
}
|
|
@@ -5399,7 +5847,8 @@ function KeybindingsBar({ contextBindings = [], modalOpen = false, duck }) {
|
|
|
5399
5847
|
// src/constants/tabs.ts
|
|
5400
5848
|
var COLUMN2_TABS = [
|
|
5401
5849
|
{ id: "logs", label: "Logs" },
|
|
5402
|
-
{ id: "jira-browser", label: "Jira" }
|
|
5850
|
+
{ id: "jira-browser", label: "Jira" },
|
|
5851
|
+
{ id: "pull-requests", label: "PRs" }
|
|
5403
5852
|
];
|
|
5404
5853
|
|
|
5405
5854
|
// src/constants/github.ts
|
|
@@ -5469,6 +5918,18 @@ var LOGS_KEYBINDINGS = {
|
|
|
5469
5918
|
]
|
|
5470
5919
|
};
|
|
5471
5920
|
|
|
5921
|
+
// src/constants/pull-requests.ts
|
|
5922
|
+
var PULL_REQUESTS_KEYBINDINGS = [
|
|
5923
|
+
{ key: "Space", label: "Details" },
|
|
5924
|
+
{ key: "/", label: "Search" },
|
|
5925
|
+
{ key: "s", label: "State" },
|
|
5926
|
+
{ key: "l", label: "Load More" },
|
|
5927
|
+
{ key: "x", label: "Clear Filters" },
|
|
5928
|
+
{ key: "o", label: "Open", color: "green" },
|
|
5929
|
+
{ key: "y", label: "Copy Link" },
|
|
5930
|
+
{ key: "r", label: "Refresh" }
|
|
5931
|
+
];
|
|
5932
|
+
|
|
5472
5933
|
// src/lib/keybindings.ts
|
|
5473
5934
|
function computeKeybindings(focusedView, state) {
|
|
5474
5935
|
switch (focusedView) {
|
|
@@ -5482,39 +5943,53 @@ function computeKeybindings(focusedView, state) {
|
|
|
5482
5943
|
case "jira-browser":
|
|
5483
5944
|
if (state["jira-browser"].modalOpen) return [];
|
|
5484
5945
|
return JIRA_BROWSER_KEYBINDINGS[state["jira-browser"].focusedBox];
|
|
5946
|
+
case "pull-requests":
|
|
5947
|
+
if (state["pull-requests"].modalOpen) return [];
|
|
5948
|
+
return PULL_REQUESTS_KEYBINDINGS;
|
|
5485
5949
|
default:
|
|
5486
5950
|
return [];
|
|
5487
5951
|
}
|
|
5488
5952
|
}
|
|
5489
5953
|
|
|
5490
5954
|
// src/app.tsx
|
|
5491
|
-
import { jsx as
|
|
5955
|
+
import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
5492
5956
|
function App() {
|
|
5493
5957
|
const { exit } = useApp();
|
|
5494
|
-
const [focusedView, setFocusedView] =
|
|
5495
|
-
const [modalOpen, setModalOpen] =
|
|
5496
|
-
const [logRefreshKey, setLogRefreshKey] =
|
|
5497
|
-
const [activeTab, setActiveTab] =
|
|
5958
|
+
const [focusedView, setFocusedView] = useState23("github");
|
|
5959
|
+
const [modalOpen, setModalOpen] = useState23(false);
|
|
5960
|
+
const [logRefreshKey, setLogRefreshKey] = useState23(0);
|
|
5961
|
+
const [activeTab, setActiveTab] = useState23("logs");
|
|
5498
5962
|
const duck = useRubberDuck();
|
|
5499
|
-
const [githubFocusedBox, setGithubFocusedBox] =
|
|
5500
|
-
const [jiraState, setJiraState] =
|
|
5501
|
-
const [logsFocusedBox, setLogsFocusedBox] =
|
|
5502
|
-
const [jiraBrowserFocusedBox, setJiraBrowserFocusedBox] =
|
|
5503
|
-
const [jiraBrowserModalOpen, setJiraBrowserModalOpen] =
|
|
5963
|
+
const [githubFocusedBox, setGithubFocusedBox] = useState23("remotes");
|
|
5964
|
+
const [jiraState, setJiraState] = useState23("not_configured");
|
|
5965
|
+
const [logsFocusedBox, setLogsFocusedBox] = useState23("history");
|
|
5966
|
+
const [jiraBrowserFocusedBox, setJiraBrowserFocusedBox] = useState23("saved-views");
|
|
5967
|
+
const [jiraBrowserModalOpen, setJiraBrowserModalOpen] = useState23(false);
|
|
5968
|
+
const [pullRequestsModalOpen, setPullRequestsModalOpen] = useState23(false);
|
|
5504
5969
|
const keybindings = useMemo4(
|
|
5505
5970
|
() => computeKeybindings(focusedView, {
|
|
5506
5971
|
github: { focusedBox: githubFocusedBox },
|
|
5507
5972
|
jira: { jiraState, modalOpen },
|
|
5508
5973
|
logs: { focusedBox: logsFocusedBox },
|
|
5509
|
-
"jira-browser": { focusedBox: jiraBrowserFocusedBox, modalOpen: jiraBrowserModalOpen }
|
|
5974
|
+
"jira-browser": { focusedBox: jiraBrowserFocusedBox, modalOpen: jiraBrowserModalOpen },
|
|
5975
|
+
"pull-requests": { modalOpen: pullRequestsModalOpen }
|
|
5510
5976
|
}),
|
|
5511
|
-
[
|
|
5977
|
+
[
|
|
5978
|
+
focusedView,
|
|
5979
|
+
githubFocusedBox,
|
|
5980
|
+
jiraState,
|
|
5981
|
+
modalOpen,
|
|
5982
|
+
logsFocusedBox,
|
|
5983
|
+
jiraBrowserFocusedBox,
|
|
5984
|
+
jiraBrowserModalOpen,
|
|
5985
|
+
pullRequestsModalOpen
|
|
5986
|
+
]
|
|
5512
5987
|
);
|
|
5513
|
-
const handleLogUpdated =
|
|
5988
|
+
const handleLogUpdated = useCallback12(() => {
|
|
5514
5989
|
setLogRefreshKey((prev) => prev + 1);
|
|
5515
5990
|
}, []);
|
|
5516
|
-
const anyModalOpen = modalOpen || jiraBrowserModalOpen;
|
|
5517
|
-
|
|
5991
|
+
const anyModalOpen = modalOpen || jiraBrowserModalOpen || pullRequestsModalOpen;
|
|
5992
|
+
useInput19(
|
|
5518
5993
|
(input, key) => {
|
|
5519
5994
|
if (key.ctrl && input === "c") {
|
|
5520
5995
|
exit();
|
|
@@ -5553,17 +6028,17 @@ function App() {
|
|
|
5553
6028
|
},
|
|
5554
6029
|
{ isActive: !anyModalOpen }
|
|
5555
6030
|
);
|
|
5556
|
-
return /* @__PURE__ */
|
|
5557
|
-
/* @__PURE__ */
|
|
5558
|
-
/* @__PURE__ */
|
|
5559
|
-
/* @__PURE__ */
|
|
5560
|
-
/* @__PURE__ */
|
|
5561
|
-
COLUMN2_TABS.map((tab) => /* @__PURE__ */
|
|
6031
|
+
return /* @__PURE__ */ jsxs24(Box24, { flexGrow: 1, flexDirection: "column", overflow: "hidden", children: [
|
|
6032
|
+
/* @__PURE__ */ jsxs24(Box24, { height: 1, flexDirection: "row", columnGap: 1, children: [
|
|
6033
|
+
/* @__PURE__ */ jsx26(Box24, { flexGrow: 1, paddingX: 1, flexBasis: 0, children: /* @__PURE__ */ jsx26(Text23, { color: "gray", children: "Current branch" }) }),
|
|
6034
|
+
/* @__PURE__ */ jsxs24(Box24, { flexGrow: 1, gap: 1, flexBasis: 0, children: [
|
|
6035
|
+
/* @__PURE__ */ jsx26(Text23, { color: "gray", children: "Dashboards" }),
|
|
6036
|
+
COLUMN2_TABS.map((tab) => /* @__PURE__ */ jsx26(Text23, { bold: true, dimColor: activeTab !== tab.id, children: tab.label }, tab.id))
|
|
5562
6037
|
] })
|
|
5563
6038
|
] }),
|
|
5564
|
-
/* @__PURE__ */
|
|
5565
|
-
/* @__PURE__ */
|
|
5566
|
-
/* @__PURE__ */
|
|
6039
|
+
/* @__PURE__ */ jsxs24(Box24, { flexGrow: 1, flexDirection: "row", columnGap: 1, children: [
|
|
6040
|
+
/* @__PURE__ */ jsxs24(Box24, { flexDirection: "column", flexGrow: 1, flexBasis: 0, children: [
|
|
6041
|
+
/* @__PURE__ */ jsx26(
|
|
5567
6042
|
GitHubView,
|
|
5568
6043
|
{
|
|
5569
6044
|
isActive: focusedView === "github",
|
|
@@ -5571,7 +6046,7 @@ function App() {
|
|
|
5571
6046
|
onLogUpdated: handleLogUpdated
|
|
5572
6047
|
}
|
|
5573
6048
|
),
|
|
5574
|
-
/* @__PURE__ */
|
|
6049
|
+
/* @__PURE__ */ jsx26(
|
|
5575
6050
|
JiraView,
|
|
5576
6051
|
{
|
|
5577
6052
|
isActive: focusedView === "jira",
|
|
@@ -5581,8 +6056,8 @@ function App() {
|
|
|
5581
6056
|
}
|
|
5582
6057
|
)
|
|
5583
6058
|
] }),
|
|
5584
|
-
/* @__PURE__ */
|
|
5585
|
-
activeTab === "logs" && /* @__PURE__ */
|
|
6059
|
+
/* @__PURE__ */ jsxs24(Box24, { flexDirection: "column", flexGrow: 1, flexBasis: 0, children: [
|
|
6060
|
+
activeTab === "logs" && /* @__PURE__ */ jsx26(
|
|
5586
6061
|
LogsView,
|
|
5587
6062
|
{
|
|
5588
6063
|
isActive: focusedView === "logs",
|
|
@@ -5591,7 +6066,7 @@ function App() {
|
|
|
5591
6066
|
onFocusedBoxChange: setLogsFocusedBox
|
|
5592
6067
|
}
|
|
5593
6068
|
),
|
|
5594
|
-
activeTab === "jira-browser" && /* @__PURE__ */
|
|
6069
|
+
activeTab === "jira-browser" && /* @__PURE__ */ jsx26(
|
|
5595
6070
|
JiraBrowserView,
|
|
5596
6071
|
{
|
|
5597
6072
|
isActive: focusedView === "jira-browser",
|
|
@@ -5600,10 +6075,11 @@ function App() {
|
|
|
5600
6075
|
onModalChange: setJiraBrowserModalOpen,
|
|
5601
6076
|
onLogUpdated: handleLogUpdated
|
|
5602
6077
|
}
|
|
5603
|
-
)
|
|
6078
|
+
),
|
|
6079
|
+
activeTab === "pull-requests" && /* @__PURE__ */ jsx26(AllPullRequestsView, { isActive: focusedView === "pull-requests", onModalChange: setPullRequestsModalOpen })
|
|
5604
6080
|
] })
|
|
5605
6081
|
] }),
|
|
5606
|
-
/* @__PURE__ */
|
|
6082
|
+
/* @__PURE__ */ jsx26(
|
|
5607
6083
|
KeybindingsBar,
|
|
5608
6084
|
{
|
|
5609
6085
|
contextBindings: keybindings,
|
|
@@ -5618,31 +6094,31 @@ function App() {
|
|
|
5618
6094
|
import { render as inkRender } from "ink";
|
|
5619
6095
|
|
|
5620
6096
|
// src/lib/Screen.tsx
|
|
5621
|
-
import { useCallback as
|
|
5622
|
-
import { Box as
|
|
5623
|
-
import { jsx as
|
|
6097
|
+
import { useCallback as useCallback13, useEffect as useEffect19, useState as useState24 } from "react";
|
|
6098
|
+
import { Box as Box25, useStdout as useStdout3 } from "ink";
|
|
6099
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
5624
6100
|
function Screen({ children }) {
|
|
5625
|
-
const { stdout } =
|
|
5626
|
-
const getSize =
|
|
5627
|
-
const [size, setSize] =
|
|
5628
|
-
|
|
6101
|
+
const { stdout } = useStdout3();
|
|
6102
|
+
const getSize = useCallback13(() => ({ height: stdout.rows, width: stdout.columns }), [stdout]);
|
|
6103
|
+
const [size, setSize] = useState24(getSize);
|
|
6104
|
+
useEffect19(() => {
|
|
5629
6105
|
const onResize = () => setSize(getSize());
|
|
5630
6106
|
stdout.on("resize", onResize);
|
|
5631
6107
|
return () => {
|
|
5632
6108
|
stdout.off("resize", onResize);
|
|
5633
6109
|
};
|
|
5634
6110
|
}, [stdout, getSize]);
|
|
5635
|
-
return /* @__PURE__ */
|
|
6111
|
+
return /* @__PURE__ */ jsx27(Box25, { height: size.height, width: size.width, children });
|
|
5636
6112
|
}
|
|
5637
6113
|
|
|
5638
6114
|
// src/lib/render.tsx
|
|
5639
|
-
import { jsx as
|
|
6115
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
5640
6116
|
var ENTER_ALT_BUFFER = "\x1B[?1049h";
|
|
5641
6117
|
var EXIT_ALT_BUFFER = "\x1B[?1049l";
|
|
5642
6118
|
var CLEAR_SCREEN = "\x1B[2J\x1B[H";
|
|
5643
6119
|
function render(node, options) {
|
|
5644
6120
|
process.stdout.write(ENTER_ALT_BUFFER + CLEAR_SCREEN);
|
|
5645
|
-
const element = /* @__PURE__ */
|
|
6121
|
+
const element = /* @__PURE__ */ jsx28(Screen, { children: node });
|
|
5646
6122
|
const instance = inkRender(element, options);
|
|
5647
6123
|
setImmediate(() => instance.rerender(element));
|
|
5648
6124
|
const cleanup = () => process.stdout.write(EXIT_ALT_BUFFER);
|
|
@@ -5663,7 +6139,7 @@ function render(node, options) {
|
|
|
5663
6139
|
}
|
|
5664
6140
|
|
|
5665
6141
|
// src/cli.tsx
|
|
5666
|
-
import { jsx as
|
|
6142
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
5667
6143
|
var cli = meow(
|
|
5668
6144
|
`
|
|
5669
6145
|
Usage
|
|
@@ -5696,4 +6172,4 @@ if (cli.flags.cwd) {
|
|
|
5696
6172
|
process.exit(1);
|
|
5697
6173
|
}
|
|
5698
6174
|
}
|
|
5699
|
-
render(/* @__PURE__ */
|
|
6175
|
+
render(/* @__PURE__ */ jsx29(App, {}));
|