clairo 2.2.1 → 3.0.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 +2 -0
- package/dist/cli.js +463 -70
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,6 +11,8 @@ dashboard tui for github PRs, jira tickets, and daily logs.
|
|
|
11
11
|
- view open PRs with status, reviews, and checks
|
|
12
12
|
- see full PR details with description, labels, and assignees
|
|
13
13
|
- create new PRs from the terminal
|
|
14
|
+
- browse all PRs across the repo with state, search, and status filters
|
|
15
|
+
- checkout PRs directly from the detail view
|
|
14
16
|
- jira integration
|
|
15
17
|
- auto ticket detection based on branch name
|
|
16
18
|
- link tickets and change status from the terminal
|
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 Box23, Text as Text22, 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
|
}
|
|
@@ -3067,18 +3070,18 @@ var proto = Object.defineProperties(() => {
|
|
|
3067
3070
|
}
|
|
3068
3071
|
}
|
|
3069
3072
|
});
|
|
3070
|
-
var createStyler = (
|
|
3073
|
+
var createStyler = (open7, close, parent) => {
|
|
3071
3074
|
let openAll;
|
|
3072
3075
|
let closeAll;
|
|
3073
3076
|
if (parent === void 0) {
|
|
3074
|
-
openAll =
|
|
3077
|
+
openAll = open7;
|
|
3075
3078
|
closeAll = close;
|
|
3076
3079
|
} else {
|
|
3077
|
-
openAll = parent.openAll +
|
|
3080
|
+
openAll = parent.openAll + open7;
|
|
3078
3081
|
closeAll = close + parent.closeAll;
|
|
3079
3082
|
}
|
|
3080
3083
|
return {
|
|
3081
|
-
open:
|
|
3084
|
+
open: open7,
|
|
3082
3085
|
close,
|
|
3083
3086
|
openAll,
|
|
3084
3087
|
closeAll,
|
|
@@ -3787,7 +3790,7 @@ import { useCallback as useCallback9, useEffect as useEffect11, useMemo as useMe
|
|
|
3787
3790
|
import { TitledBox as TitledBox4 } from "@mishieck/ink-titled-box";
|
|
3788
3791
|
import { Box as Box10, Text as Text11, useInput as useInput8 } from "ink";
|
|
3789
3792
|
import { ScrollView as ScrollView6 } from "ink-scroll-view";
|
|
3790
|
-
import
|
|
3793
|
+
import Spinner3 from "ink-spinner";
|
|
3791
3794
|
|
|
3792
3795
|
// src/components/jira-browser/JiraIssueDetailView.tsx
|
|
3793
3796
|
import open3 from "open";
|
|
@@ -3795,7 +3798,7 @@ import { useEffect as useEffect10, useRef as useRef6, useState as useState14 } f
|
|
|
3795
3798
|
import { Box as Box9, Text as Text10, useInput as useInput7 } from "ink";
|
|
3796
3799
|
import { ScrollView as ScrollView5 } from "ink-scroll-view";
|
|
3797
3800
|
import SelectInput from "ink-select-input";
|
|
3798
|
-
import
|
|
3801
|
+
import Spinner2 from "ink-spinner";
|
|
3799
3802
|
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
3800
3803
|
function JiraIssueDetailView({
|
|
3801
3804
|
issueKey,
|
|
@@ -3954,7 +3957,7 @@ function JiraIssueDetailView({
|
|
|
3954
3957
|
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", flexGrow: 1, children: [
|
|
3955
3958
|
/* @__PURE__ */ jsxs9(Box9, { flexGrow: 1, flexBasis: 0, overflow: "hidden", children: [
|
|
3956
3959
|
loading && /* @__PURE__ */ jsx11(Box9, { paddingX: 1, children: /* @__PURE__ */ jsxs9(Text10, { color: "yellow", children: [
|
|
3957
|
-
/* @__PURE__ */ jsx11(
|
|
3960
|
+
/* @__PURE__ */ jsx11(Spinner2, { type: "dots" }),
|
|
3958
3961
|
" Loading issue details..."
|
|
3959
3962
|
] }) }),
|
|
3960
3963
|
error && /* @__PURE__ */ jsx11(Box9, { paddingX: 1, children: /* @__PURE__ */ jsx11(Text10, { color: "red", children: error }) }),
|
|
@@ -4011,13 +4014,13 @@ function JiraIssueDetailView({
|
|
|
4011
4014
|
] }),
|
|
4012
4015
|
/* @__PURE__ */ jsxs9(Box9, { paddingX: 1, flexDirection: "column", children: [
|
|
4013
4016
|
actionLoading && /* @__PURE__ */ jsxs9(Text10, { color: "yellow", children: [
|
|
4014
|
-
/* @__PURE__ */ jsx11(
|
|
4017
|
+
/* @__PURE__ */ jsx11(Spinner2, { type: "dots" }),
|
|
4015
4018
|
" ",
|
|
4016
4019
|
actionLoading
|
|
4017
4020
|
] }),
|
|
4018
4021
|
actionError && /* @__PURE__ */ jsx11(Text10, { color: "red", children: actionError }),
|
|
4019
4022
|
transitionsLoading && /* @__PURE__ */ jsxs9(Text10, { color: "yellow", children: [
|
|
4020
|
-
/* @__PURE__ */ jsx11(
|
|
4023
|
+
/* @__PURE__ */ jsx11(Spinner2, { type: "dots" }),
|
|
4021
4024
|
" Loading transitions..."
|
|
4022
4025
|
] }),
|
|
4023
4026
|
!actionLoading && !transitionsLoading && mode === "normal" && /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "Esc close \xB7 j/k scroll \xB7 s status \xB7 a assign \xB7 A unassign \xB7 o open \xB7 y copy" })
|
|
@@ -4316,7 +4319,7 @@ function JiraSavedViewBrowserBox({
|
|
|
4316
4319
|
/* @__PURE__ */ jsxs10(Box10, { flexGrow: 1, flexBasis: 0, overflow: "hidden", children: [
|
|
4317
4320
|
!view && /* @__PURE__ */ jsx12(Box10, { paddingX: 1, children: /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "Select a view to browse issues" }) }),
|
|
4318
4321
|
view && loading && issues.length === 0 && /* @__PURE__ */ jsx12(Box10, { paddingX: 1, children: /* @__PURE__ */ jsxs10(Text11, { color: "yellow", children: [
|
|
4319
|
-
/* @__PURE__ */ jsx12(
|
|
4322
|
+
/* @__PURE__ */ jsx12(Spinner3, { type: "dots" }),
|
|
4320
4323
|
" Loading issues..."
|
|
4321
4324
|
] }) }),
|
|
4322
4325
|
view && error && /* @__PURE__ */ jsx12(Box10, { paddingX: 1, children: /* @__PURE__ */ jsx12(Text11, { color: "red", children: error }) }),
|
|
@@ -5371,9 +5374,371 @@ function LogsView({ isActive, refreshKey, focusedBox, onFocusedBoxChange }) {
|
|
|
5371
5374
|
] });
|
|
5372
5375
|
}
|
|
5373
5376
|
|
|
5377
|
+
// src/components/pull-requests/AllPullRequestsView.tsx
|
|
5378
|
+
import open6 from "open";
|
|
5379
|
+
import { useCallback as useCallback11, useEffect as useEffect18, useState as useState22 } from "react";
|
|
5380
|
+
import { TitledBox as TitledBox9 } from "@mishieck/ink-titled-box";
|
|
5381
|
+
import { Box as Box21, Text as Text20, useInput as useInput18 } from "ink";
|
|
5382
|
+
import { ScrollView as ScrollView11 } from "ink-scroll-view";
|
|
5383
|
+
import Spinner4 from "ink-spinner";
|
|
5384
|
+
|
|
5385
|
+
// src/lib/github/pr-list.ts
|
|
5386
|
+
import { exec as exec4 } from "child_process";
|
|
5387
|
+
import { promisify as promisify2 } from "util";
|
|
5388
|
+
var execAsync2 = promisify2(exec4);
|
|
5389
|
+
async function listPRs(repo, opts) {
|
|
5390
|
+
if (!await isGhInstalled()) {
|
|
5391
|
+
return {
|
|
5392
|
+
success: false,
|
|
5393
|
+
error: "GitHub CLI (gh) is not installed. Install from https://cli.github.com",
|
|
5394
|
+
errorType: "not_installed"
|
|
5395
|
+
};
|
|
5396
|
+
}
|
|
5397
|
+
if (!await isGhAuthenticated()) {
|
|
5398
|
+
return {
|
|
5399
|
+
success: false,
|
|
5400
|
+
error: "Not authenticated. Run 'gh auth login' to authenticate.",
|
|
5401
|
+
errorType: "not_authenticated"
|
|
5402
|
+
};
|
|
5403
|
+
}
|
|
5404
|
+
const fields = "number,title,state,author,createdAt,isDraft,reviewDecision,statusCheckRollup";
|
|
5405
|
+
const state = (opts == null ? void 0 : opts.state) ?? "open";
|
|
5406
|
+
const limit = (opts == null ? void 0 : opts.limit) ?? 30;
|
|
5407
|
+
const args = [`gh pr list`, `--state ${state}`, `--limit ${limit}`, `--json ${fields}`, `--repo "${repo}"`];
|
|
5408
|
+
if (opts == null ? void 0 : opts.search) {
|
|
5409
|
+
args.push(`--search "${opts.search.replace(/"/g, '\\"')}"`);
|
|
5410
|
+
}
|
|
5411
|
+
try {
|
|
5412
|
+
const { stdout } = await execAsync2(`${args.join(" ")} 2>/dev/null`);
|
|
5413
|
+
const prs = JSON.parse(stdout);
|
|
5414
|
+
return { success: true, data: prs };
|
|
5415
|
+
} catch {
|
|
5416
|
+
return { success: false, error: "Failed to fetch PRs", errorType: "api_error" };
|
|
5417
|
+
}
|
|
5418
|
+
}
|
|
5419
|
+
async function checkoutPR(prNumber, repo) {
|
|
5420
|
+
if (!await isGhInstalled()) {
|
|
5421
|
+
return { success: false, error: "gh CLI not installed", errorType: "not_installed" };
|
|
5422
|
+
}
|
|
5423
|
+
if (!await isGhAuthenticated()) {
|
|
5424
|
+
return { success: false, error: "gh CLI not authenticated", errorType: "not_authenticated" };
|
|
5425
|
+
}
|
|
5426
|
+
try {
|
|
5427
|
+
await execAsync2(`gh pr checkout ${prNumber} --repo "${repo}" 2>&1`);
|
|
5428
|
+
return { success: true, data: `Checked out PR #${prNumber}` };
|
|
5429
|
+
} catch (e) {
|
|
5430
|
+
const msg = e instanceof Error ? e.message.split("\n").pop() ?? e.message : "Failed to checkout PR";
|
|
5431
|
+
return { success: false, error: msg, errorType: "api_error" };
|
|
5432
|
+
}
|
|
5433
|
+
}
|
|
5434
|
+
|
|
5435
|
+
// src/components/pull-requests/AllPullRequestsView.tsx
|
|
5436
|
+
import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
5437
|
+
var STATE_CYCLE = ["open", "closed", "all"];
|
|
5438
|
+
function computeOverallCheck(checks) {
|
|
5439
|
+
if (!checks || checks.length === 0) return null;
|
|
5440
|
+
const statuses = checks.map(resolveCheckStatus);
|
|
5441
|
+
if (statuses.some((s) => s === "failure")) return "failure";
|
|
5442
|
+
if (statuses.some((s) => s === "pending")) return "pending";
|
|
5443
|
+
return "success";
|
|
5444
|
+
}
|
|
5445
|
+
function AllPullRequestsView({ isActive, onModalChange }) {
|
|
5446
|
+
const repo = useGitRepo();
|
|
5447
|
+
const [prs, setPrs] = useState22([]);
|
|
5448
|
+
const [loading, setLoading] = useState22(false);
|
|
5449
|
+
const [error, setError] = useState22(null);
|
|
5450
|
+
const [detailPR, setDetailPR] = useState22(null);
|
|
5451
|
+
const [prDetails, setPrDetails] = useState22(null);
|
|
5452
|
+
const [detailsLoading, setDetailsLoading] = useState22(false);
|
|
5453
|
+
const [detailsError, setDetailsError] = useState22(void 0);
|
|
5454
|
+
const [stateFilter, setStateFilter] = useState22("open");
|
|
5455
|
+
const [searchText, setSearchText] = useState22("");
|
|
5456
|
+
const [inputText, setInputText] = useState22("");
|
|
5457
|
+
const [limit, setLimit] = useState22(30);
|
|
5458
|
+
const [isSearching, setIsSearching] = useState22(false);
|
|
5459
|
+
const [checkoutLoading, setCheckoutLoading] = useState22(false);
|
|
5460
|
+
const [checkoutResult, setCheckoutResult] = useState22(null);
|
|
5461
|
+
useEffect18(() => {
|
|
5462
|
+
onModalChange == null ? void 0 : onModalChange(isSearching || detailPR !== null);
|
|
5463
|
+
}, [isSearching, detailPR, onModalChange]);
|
|
5464
|
+
const doFetch = useCallback11(
|
|
5465
|
+
async (state, search, fetchLimit = 30) => {
|
|
5466
|
+
if (!repo.currentRepoSlug) return;
|
|
5467
|
+
setLoading(true);
|
|
5468
|
+
setError(null);
|
|
5469
|
+
setPrs([]);
|
|
5470
|
+
const result = await listPRs(repo.currentRepoSlug, {
|
|
5471
|
+
state,
|
|
5472
|
+
search: search || void 0,
|
|
5473
|
+
limit: fetchLimit
|
|
5474
|
+
});
|
|
5475
|
+
if (result.success) {
|
|
5476
|
+
setPrs(result.data);
|
|
5477
|
+
} else {
|
|
5478
|
+
setError(result.error);
|
|
5479
|
+
}
|
|
5480
|
+
setLoading(false);
|
|
5481
|
+
},
|
|
5482
|
+
[repo.currentRepoSlug]
|
|
5483
|
+
);
|
|
5484
|
+
useEffect18(() => {
|
|
5485
|
+
if (repo.currentRepoSlug) {
|
|
5486
|
+
setStateFilter("open");
|
|
5487
|
+
setSearchText("");
|
|
5488
|
+
setInputText("");
|
|
5489
|
+
doFetch("open", "");
|
|
5490
|
+
}
|
|
5491
|
+
}, [repo.currentRepoSlug]);
|
|
5492
|
+
const fetchDetails = useCallback11(
|
|
5493
|
+
async (pr) => {
|
|
5494
|
+
if (!repo.currentRepoSlug) return;
|
|
5495
|
+
setDetailsLoading(true);
|
|
5496
|
+
setDetailsError(void 0);
|
|
5497
|
+
const result = await getPRDetails(pr.number, repo.currentRepoSlug);
|
|
5498
|
+
if (result.success) {
|
|
5499
|
+
setPrDetails(result.data);
|
|
5500
|
+
setDetailsError(void 0);
|
|
5501
|
+
} else {
|
|
5502
|
+
setDetailsError(result.error);
|
|
5503
|
+
}
|
|
5504
|
+
setDetailsLoading(false);
|
|
5505
|
+
},
|
|
5506
|
+
[repo.currentRepoSlug]
|
|
5507
|
+
);
|
|
5508
|
+
const handleSelect = useCallback11(
|
|
5509
|
+
(index) => {
|
|
5510
|
+
const pr = prs[index];
|
|
5511
|
+
if (pr) {
|
|
5512
|
+
setDetailPR(pr);
|
|
5513
|
+
fetchDetails(pr);
|
|
5514
|
+
}
|
|
5515
|
+
},
|
|
5516
|
+
[prs, fetchDetails]
|
|
5517
|
+
);
|
|
5518
|
+
const { highlightedIndex, scrollRef } = useListNavigation({
|
|
5519
|
+
items: prs,
|
|
5520
|
+
selectedIndex: detailPR ? prs.findIndex((p) => p.number === detailPR.number) : -1,
|
|
5521
|
+
onSelect: handleSelect,
|
|
5522
|
+
isActive: isActive && !detailPR && !isSearching
|
|
5523
|
+
});
|
|
5524
|
+
const currentPR = prs[highlightedIndex] ?? null;
|
|
5525
|
+
const getPRUrl = (pr) => {
|
|
5526
|
+
if (!repo.currentRepoSlug) return null;
|
|
5527
|
+
return `https://github.com/${repo.currentRepoSlug}/pull/${pr.number}`;
|
|
5528
|
+
};
|
|
5529
|
+
const hasActiveFilters = stateFilter !== "open" || searchText.length > 0;
|
|
5530
|
+
useInput18(
|
|
5531
|
+
(input, key) => {
|
|
5532
|
+
if (isSearching) {
|
|
5533
|
+
if (key.escape) {
|
|
5534
|
+
setIsSearching(false);
|
|
5535
|
+
setInputText(searchText);
|
|
5536
|
+
return;
|
|
5537
|
+
}
|
|
5538
|
+
if (key.return) {
|
|
5539
|
+
setIsSearching(false);
|
|
5540
|
+
const newSearch = inputText.trim();
|
|
5541
|
+
if (newSearch !== searchText) {
|
|
5542
|
+
setSearchText(newSearch);
|
|
5543
|
+
setLimit(30);
|
|
5544
|
+
doFetch(stateFilter, newSearch);
|
|
5545
|
+
}
|
|
5546
|
+
return;
|
|
5547
|
+
}
|
|
5548
|
+
if (key.backspace || key.delete) {
|
|
5549
|
+
setInputText((prev) => prev.slice(0, -1));
|
|
5550
|
+
return;
|
|
5551
|
+
}
|
|
5552
|
+
if (input && input.length > 0) {
|
|
5553
|
+
const printable = input.replace(/[^\x20-\x7E\u00A0-\uFFFF]/g, "");
|
|
5554
|
+
if (printable.length > 0) {
|
|
5555
|
+
setInputText((prev) => prev + printable);
|
|
5556
|
+
}
|
|
5557
|
+
return;
|
|
5558
|
+
}
|
|
5559
|
+
return;
|
|
5560
|
+
}
|
|
5561
|
+
if (input === "/") {
|
|
5562
|
+
setIsSearching(true);
|
|
5563
|
+
setInputText(searchText);
|
|
5564
|
+
return;
|
|
5565
|
+
}
|
|
5566
|
+
if (input === "s") {
|
|
5567
|
+
const idx = STATE_CYCLE.indexOf(stateFilter);
|
|
5568
|
+
const newState = STATE_CYCLE[(idx + 1) % STATE_CYCLE.length];
|
|
5569
|
+
setStateFilter(newState);
|
|
5570
|
+
setLimit(30);
|
|
5571
|
+
doFetch(newState, searchText);
|
|
5572
|
+
return;
|
|
5573
|
+
}
|
|
5574
|
+
if (input === "x") {
|
|
5575
|
+
setStateFilter("open");
|
|
5576
|
+
setSearchText("");
|
|
5577
|
+
setInputText("");
|
|
5578
|
+
setLimit(30);
|
|
5579
|
+
doFetch("open", "");
|
|
5580
|
+
return;
|
|
5581
|
+
}
|
|
5582
|
+
if (input === "o" && currentPR) {
|
|
5583
|
+
const url = getPRUrl(currentPR);
|
|
5584
|
+
if (url) open6(url).catch(() => {
|
|
5585
|
+
});
|
|
5586
|
+
}
|
|
5587
|
+
if (input === "y" && currentPR) {
|
|
5588
|
+
const url = getPRUrl(currentPR);
|
|
5589
|
+
if (url) copyToClipboard(url);
|
|
5590
|
+
}
|
|
5591
|
+
if (input === "l") {
|
|
5592
|
+
const newLimit = limit + 30;
|
|
5593
|
+
setLimit(newLimit);
|
|
5594
|
+
doFetch(stateFilter, searchText, newLimit);
|
|
5595
|
+
return;
|
|
5596
|
+
}
|
|
5597
|
+
if (input === "r") {
|
|
5598
|
+
doFetch(stateFilter, searchText, limit);
|
|
5599
|
+
}
|
|
5600
|
+
},
|
|
5601
|
+
{ isActive: isActive && !detailPR }
|
|
5602
|
+
);
|
|
5603
|
+
useInput18(
|
|
5604
|
+
(input, key) => {
|
|
5605
|
+
if (key.escape) {
|
|
5606
|
+
setDetailPR(null);
|
|
5607
|
+
setCheckoutResult(null);
|
|
5608
|
+
return;
|
|
5609
|
+
}
|
|
5610
|
+
if (input === "y" && detailPR) {
|
|
5611
|
+
const url = getPRUrl(detailPR);
|
|
5612
|
+
if (url) copyToClipboard(url);
|
|
5613
|
+
}
|
|
5614
|
+
if (input === "c" && detailPR && !checkoutLoading && repo.currentRepoSlug) {
|
|
5615
|
+
setCheckoutLoading(true);
|
|
5616
|
+
setCheckoutResult(null);
|
|
5617
|
+
checkoutPR(detailPR.number, repo.currentRepoSlug).then((result) => {
|
|
5618
|
+
setCheckoutLoading(false);
|
|
5619
|
+
if (result.success) {
|
|
5620
|
+
setCheckoutResult({ success: true, message: `Checked out #${detailPR.number}` });
|
|
5621
|
+
repo.refreshBranch();
|
|
5622
|
+
} else {
|
|
5623
|
+
setCheckoutResult({ success: false, message: result.error });
|
|
5624
|
+
}
|
|
5625
|
+
});
|
|
5626
|
+
}
|
|
5627
|
+
},
|
|
5628
|
+
{ isActive: isActive && detailPR !== null }
|
|
5629
|
+
);
|
|
5630
|
+
const filterParts = [];
|
|
5631
|
+
if (stateFilter !== "open") filterParts.push(stateFilter);
|
|
5632
|
+
if (searchText) filterParts.push(`"${searchText}"`);
|
|
5633
|
+
const borderColor = isActive ? "yellow" : void 0;
|
|
5634
|
+
const stateColor = (pr) => {
|
|
5635
|
+
const display = resolveMergeDisplay({
|
|
5636
|
+
state: pr.state,
|
|
5637
|
+
isDraft: pr.isDraft,
|
|
5638
|
+
mergeable: "UNKNOWN"
|
|
5639
|
+
});
|
|
5640
|
+
return display.color;
|
|
5641
|
+
};
|
|
5642
|
+
const stateLabel = (pr) => {
|
|
5643
|
+
if (pr.isDraft) return "Draft";
|
|
5644
|
+
if (pr.state === "MERGED") return "Merged";
|
|
5645
|
+
if (pr.state === "CLOSED") return "Closed";
|
|
5646
|
+
return "Open";
|
|
5647
|
+
};
|
|
5648
|
+
if (detailPR) {
|
|
5649
|
+
return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", flexGrow: 1, children: [
|
|
5650
|
+
/* @__PURE__ */ jsx23(
|
|
5651
|
+
PRDetailsBox,
|
|
5652
|
+
{
|
|
5653
|
+
pr: prDetails,
|
|
5654
|
+
loading: detailsLoading,
|
|
5655
|
+
error: detailsError,
|
|
5656
|
+
isActive,
|
|
5657
|
+
title: "[5] Pull Requests"
|
|
5658
|
+
}
|
|
5659
|
+
),
|
|
5660
|
+
checkoutLoading ? /* @__PURE__ */ jsxs21(Text20, { color: "yellow", children: [
|
|
5661
|
+
" ",
|
|
5662
|
+
/* @__PURE__ */ jsx23(Spinner4, { type: "dots" }),
|
|
5663
|
+
" Checking out..."
|
|
5664
|
+
] }) : checkoutResult ? /* @__PURE__ */ jsxs21(Text20, { color: checkoutResult.success ? "green" : "red", children: [
|
|
5665
|
+
" ",
|
|
5666
|
+
checkoutResult.message
|
|
5667
|
+
] }) : /* @__PURE__ */ jsx23(Text20, { dimColor: true, children: " Esc back \xB7 j/k scroll \xB7 o open \xB7 y copy \xB7 c checkout" })
|
|
5668
|
+
] });
|
|
5669
|
+
}
|
|
5670
|
+
return /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", flexGrow: 1, children: /* @__PURE__ */ jsx23(TitledBox9, { borderStyle: "round", titles: ["[5] Pull Requests"], borderColor, flexGrow: 1, children: /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", paddingX: 1, flexGrow: 1, overflow: "hidden", children: [
|
|
5671
|
+
(isSearching || hasActiveFilters) && /* @__PURE__ */ jsxs21(Box21, { children: [
|
|
5672
|
+
/* @__PURE__ */ jsx23(Text20, { color: "blue", children: "Filter: " }),
|
|
5673
|
+
isSearching ? /* @__PURE__ */ jsxs21(Fragment5, { children: [
|
|
5674
|
+
/* @__PURE__ */ jsx23(Text20, { children: inputText }),
|
|
5675
|
+
/* @__PURE__ */ jsx23(Text20, { backgroundColor: "yellow", children: " " })
|
|
5676
|
+
] }) : /* @__PURE__ */ jsxs21(Fragment5, { children: [
|
|
5677
|
+
/* @__PURE__ */ jsx23(Text20, { children: filterParts.join(" + ") }),
|
|
5678
|
+
/* @__PURE__ */ jsxs21(Text20, { dimColor: true, children: [
|
|
5679
|
+
" (",
|
|
5680
|
+
prs.length,
|
|
5681
|
+
")"
|
|
5682
|
+
] })
|
|
5683
|
+
] })
|
|
5684
|
+
] }),
|
|
5685
|
+
loading && /* @__PURE__ */ jsxs21(Text20, { color: "yellow", children: [
|
|
5686
|
+
/* @__PURE__ */ jsx23(Spinner4, { type: "dots" }),
|
|
5687
|
+
" Loading PRs..."
|
|
5688
|
+
] }),
|
|
5689
|
+
error && /* @__PURE__ */ jsx23(Text20, { color: "red", children: error }),
|
|
5690
|
+
!loading && !error && prs.length === 0 && /* @__PURE__ */ jsx23(Text20, { dimColor: true, children: hasActiveFilters ? "No PRs match filter" : "No open PRs" }),
|
|
5691
|
+
!loading && !error && prs.length > 0 && /* @__PURE__ */ jsx23(ScrollView11, { ref: scrollRef, children: prs.map((pr, idx) => {
|
|
5692
|
+
const isHighlighted = isActive && idx === highlightedIndex;
|
|
5693
|
+
const cursor = isHighlighted ? ">" : " ";
|
|
5694
|
+
const review = resolveReviewDisplay(pr.reviewDecision);
|
|
5695
|
+
const overallCheck = computeOverallCheck(pr.statusCheckRollup);
|
|
5696
|
+
return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
|
|
5697
|
+
/* @__PURE__ */ jsxs21(Box21, { children: [
|
|
5698
|
+
/* @__PURE__ */ jsxs21(Text20, { color: isHighlighted ? "yellow" : void 0, children: [
|
|
5699
|
+
cursor,
|
|
5700
|
+
" "
|
|
5701
|
+
] }),
|
|
5702
|
+
/* @__PURE__ */ jsxs21(Text20, { children: [
|
|
5703
|
+
"#",
|
|
5704
|
+
pr.number
|
|
5705
|
+
] }),
|
|
5706
|
+
/* @__PURE__ */ jsxs21(Text20, { children: [
|
|
5707
|
+
" ",
|
|
5708
|
+
pr.title,
|
|
5709
|
+
" "
|
|
5710
|
+
] }),
|
|
5711
|
+
(pr.state !== "OPEN" || pr.isDraft) && /* @__PURE__ */ jsxs21(Text20, { color: stateColor(pr), children: [
|
|
5712
|
+
"[",
|
|
5713
|
+
stateLabel(pr),
|
|
5714
|
+
"]"
|
|
5715
|
+
] })
|
|
5716
|
+
] }),
|
|
5717
|
+
/* @__PURE__ */ jsxs21(Box21, { children: [
|
|
5718
|
+
/* @__PURE__ */ jsx23(Text20, { children: " " }),
|
|
5719
|
+
/* @__PURE__ */ jsxs21(Text20, { dimColor: true, children: [
|
|
5720
|
+
" ",
|
|
5721
|
+
pr.author.login,
|
|
5722
|
+
" \xB7 ",
|
|
5723
|
+
timeAgo(pr.createdAt)
|
|
5724
|
+
] }),
|
|
5725
|
+
pr.reviewDecision && /* @__PURE__ */ jsxs21(Text20, { dimColor: true, children: [
|
|
5726
|
+
" \xB7 ",
|
|
5727
|
+
review.text
|
|
5728
|
+
] }),
|
|
5729
|
+
overallCheck && /* @__PURE__ */ jsxs21(Text20, { color: CHECK_COLORS[overallCheck], children: [
|
|
5730
|
+
" ",
|
|
5731
|
+
CHECK_ICONS[overallCheck]
|
|
5732
|
+
] })
|
|
5733
|
+
] })
|
|
5734
|
+
] }, pr.number);
|
|
5735
|
+
}) })
|
|
5736
|
+
] }) }) });
|
|
5737
|
+
}
|
|
5738
|
+
|
|
5374
5739
|
// src/components/ui/KeybindingsBar.tsx
|
|
5375
|
-
import { Box as
|
|
5376
|
-
import { jsx as
|
|
5740
|
+
import { Box as Box22, Text as Text21 } from "ink";
|
|
5741
|
+
import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
5377
5742
|
var globalBindings = [
|
|
5378
5743
|
{ key: "1-4", label: "Focus" },
|
|
5379
5744
|
{ key: "Tab", label: "Switch Tab" },
|
|
@@ -5384,14 +5749,14 @@ var modalBindings = [{ key: "Esc", label: "Cancel" }];
|
|
|
5384
5749
|
var DUCK_ASCII = "<(')___";
|
|
5385
5750
|
function KeybindingsBar({ contextBindings = [], modalOpen = false, duck }) {
|
|
5386
5751
|
const allBindings = modalOpen ? [...contextBindings, ...modalBindings] : [...contextBindings, ...globalBindings];
|
|
5387
|
-
return /* @__PURE__ */
|
|
5388
|
-
allBindings.map((binding) => /* @__PURE__ */
|
|
5389
|
-
/* @__PURE__ */
|
|
5390
|
-
/* @__PURE__ */
|
|
5752
|
+
return /* @__PURE__ */ jsxs22(Box22, { flexShrink: 0, paddingX: 1, gap: 2, children: [
|
|
5753
|
+
allBindings.map((binding) => /* @__PURE__ */ jsxs22(Box22, { gap: 1, children: [
|
|
5754
|
+
/* @__PURE__ */ jsx24(Text21, { bold: true, color: binding.color ?? "yellow", children: binding.key }),
|
|
5755
|
+
/* @__PURE__ */ jsx24(Text21, { dimColor: true, children: binding.label })
|
|
5391
5756
|
] }, binding.key)),
|
|
5392
|
-
(duck == null ? void 0 : duck.visible) && /* @__PURE__ */
|
|
5393
|
-
/* @__PURE__ */
|
|
5394
|
-
/* @__PURE__ */
|
|
5757
|
+
(duck == null ? void 0 : duck.visible) && /* @__PURE__ */ jsxs22(Box22, { flexGrow: 1, justifyContent: "flex-end", gap: 1, children: [
|
|
5758
|
+
/* @__PURE__ */ jsx24(Text21, { children: DUCK_ASCII }),
|
|
5759
|
+
/* @__PURE__ */ jsx24(Text21, { dimColor: true, children: duck.message })
|
|
5395
5760
|
] })
|
|
5396
5761
|
] });
|
|
5397
5762
|
}
|
|
@@ -5399,7 +5764,8 @@ function KeybindingsBar({ contextBindings = [], modalOpen = false, duck }) {
|
|
|
5399
5764
|
// src/constants/tabs.ts
|
|
5400
5765
|
var COLUMN2_TABS = [
|
|
5401
5766
|
{ id: "logs", label: "Logs" },
|
|
5402
|
-
{ id: "jira-browser", label: "Jira" }
|
|
5767
|
+
{ id: "jira-browser", label: "Jira" },
|
|
5768
|
+
{ id: "pull-requests", label: "PRs" }
|
|
5403
5769
|
];
|
|
5404
5770
|
|
|
5405
5771
|
// src/constants/github.ts
|
|
@@ -5469,6 +5835,18 @@ var LOGS_KEYBINDINGS = {
|
|
|
5469
5835
|
]
|
|
5470
5836
|
};
|
|
5471
5837
|
|
|
5838
|
+
// src/constants/pull-requests.ts
|
|
5839
|
+
var PULL_REQUESTS_KEYBINDINGS = [
|
|
5840
|
+
{ key: "Space", label: "Details" },
|
|
5841
|
+
{ key: "/", label: "Search" },
|
|
5842
|
+
{ key: "s", label: "State" },
|
|
5843
|
+
{ key: "l", label: "Load More" },
|
|
5844
|
+
{ key: "x", label: "Clear Filters" },
|
|
5845
|
+
{ key: "o", label: "Open", color: "green" },
|
|
5846
|
+
{ key: "y", label: "Copy Link" },
|
|
5847
|
+
{ key: "r", label: "Refresh" }
|
|
5848
|
+
];
|
|
5849
|
+
|
|
5472
5850
|
// src/lib/keybindings.ts
|
|
5473
5851
|
function computeKeybindings(focusedView, state) {
|
|
5474
5852
|
switch (focusedView) {
|
|
@@ -5482,39 +5860,53 @@ function computeKeybindings(focusedView, state) {
|
|
|
5482
5860
|
case "jira-browser":
|
|
5483
5861
|
if (state["jira-browser"].modalOpen) return [];
|
|
5484
5862
|
return JIRA_BROWSER_KEYBINDINGS[state["jira-browser"].focusedBox];
|
|
5863
|
+
case "pull-requests":
|
|
5864
|
+
if (state["pull-requests"].modalOpen) return [];
|
|
5865
|
+
return PULL_REQUESTS_KEYBINDINGS;
|
|
5485
5866
|
default:
|
|
5486
5867
|
return [];
|
|
5487
5868
|
}
|
|
5488
5869
|
}
|
|
5489
5870
|
|
|
5490
5871
|
// src/app.tsx
|
|
5491
|
-
import { jsx as
|
|
5872
|
+
import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
5492
5873
|
function App() {
|
|
5493
5874
|
const { exit } = useApp();
|
|
5494
|
-
const [focusedView, setFocusedView] =
|
|
5495
|
-
const [modalOpen, setModalOpen] =
|
|
5496
|
-
const [logRefreshKey, setLogRefreshKey] =
|
|
5497
|
-
const [activeTab, setActiveTab] =
|
|
5875
|
+
const [focusedView, setFocusedView] = useState23("github");
|
|
5876
|
+
const [modalOpen, setModalOpen] = useState23(false);
|
|
5877
|
+
const [logRefreshKey, setLogRefreshKey] = useState23(0);
|
|
5878
|
+
const [activeTab, setActiveTab] = useState23("logs");
|
|
5498
5879
|
const duck = useRubberDuck();
|
|
5499
|
-
const [githubFocusedBox, setGithubFocusedBox] =
|
|
5500
|
-
const [jiraState, setJiraState] =
|
|
5501
|
-
const [logsFocusedBox, setLogsFocusedBox] =
|
|
5502
|
-
const [jiraBrowserFocusedBox, setJiraBrowserFocusedBox] =
|
|
5503
|
-
const [jiraBrowserModalOpen, setJiraBrowserModalOpen] =
|
|
5880
|
+
const [githubFocusedBox, setGithubFocusedBox] = useState23("remotes");
|
|
5881
|
+
const [jiraState, setJiraState] = useState23("not_configured");
|
|
5882
|
+
const [logsFocusedBox, setLogsFocusedBox] = useState23("history");
|
|
5883
|
+
const [jiraBrowserFocusedBox, setJiraBrowserFocusedBox] = useState23("saved-views");
|
|
5884
|
+
const [jiraBrowserModalOpen, setJiraBrowserModalOpen] = useState23(false);
|
|
5885
|
+
const [pullRequestsModalOpen, setPullRequestsModalOpen] = useState23(false);
|
|
5504
5886
|
const keybindings = useMemo4(
|
|
5505
5887
|
() => computeKeybindings(focusedView, {
|
|
5506
5888
|
github: { focusedBox: githubFocusedBox },
|
|
5507
5889
|
jira: { jiraState, modalOpen },
|
|
5508
5890
|
logs: { focusedBox: logsFocusedBox },
|
|
5509
|
-
"jira-browser": { focusedBox: jiraBrowserFocusedBox, modalOpen: jiraBrowserModalOpen }
|
|
5891
|
+
"jira-browser": { focusedBox: jiraBrowserFocusedBox, modalOpen: jiraBrowserModalOpen },
|
|
5892
|
+
"pull-requests": { modalOpen: pullRequestsModalOpen }
|
|
5510
5893
|
}),
|
|
5511
|
-
[
|
|
5894
|
+
[
|
|
5895
|
+
focusedView,
|
|
5896
|
+
githubFocusedBox,
|
|
5897
|
+
jiraState,
|
|
5898
|
+
modalOpen,
|
|
5899
|
+
logsFocusedBox,
|
|
5900
|
+
jiraBrowserFocusedBox,
|
|
5901
|
+
jiraBrowserModalOpen,
|
|
5902
|
+
pullRequestsModalOpen
|
|
5903
|
+
]
|
|
5512
5904
|
);
|
|
5513
|
-
const handleLogUpdated =
|
|
5905
|
+
const handleLogUpdated = useCallback12(() => {
|
|
5514
5906
|
setLogRefreshKey((prev) => prev + 1);
|
|
5515
5907
|
}, []);
|
|
5516
|
-
const anyModalOpen = modalOpen || jiraBrowserModalOpen;
|
|
5517
|
-
|
|
5908
|
+
const anyModalOpen = modalOpen || jiraBrowserModalOpen || pullRequestsModalOpen;
|
|
5909
|
+
useInput19(
|
|
5518
5910
|
(input, key) => {
|
|
5519
5911
|
if (key.ctrl && input === "c") {
|
|
5520
5912
|
exit();
|
|
@@ -5553,17 +5945,17 @@ function App() {
|
|
|
5553
5945
|
},
|
|
5554
5946
|
{ isActive: !anyModalOpen }
|
|
5555
5947
|
);
|
|
5556
|
-
return /* @__PURE__ */
|
|
5557
|
-
/* @__PURE__ */
|
|
5558
|
-
/* @__PURE__ */
|
|
5559
|
-
/* @__PURE__ */
|
|
5560
|
-
/* @__PURE__ */
|
|
5561
|
-
COLUMN2_TABS.map((tab) => /* @__PURE__ */
|
|
5948
|
+
return /* @__PURE__ */ jsxs23(Box23, { flexGrow: 1, flexDirection: "column", overflow: "hidden", children: [
|
|
5949
|
+
/* @__PURE__ */ jsxs23(Box23, { height: 1, flexDirection: "row", columnGap: 1, children: [
|
|
5950
|
+
/* @__PURE__ */ jsx25(Box23, { flexGrow: 1, paddingX: 1, flexBasis: 0, children: /* @__PURE__ */ jsx25(Text22, { color: "gray", children: "Current branch" }) }),
|
|
5951
|
+
/* @__PURE__ */ jsxs23(Box23, { flexGrow: 1, gap: 1, flexBasis: 0, children: [
|
|
5952
|
+
/* @__PURE__ */ jsx25(Text22, { color: "gray", children: "Dashboards" }),
|
|
5953
|
+
COLUMN2_TABS.map((tab) => /* @__PURE__ */ jsx25(Text22, { bold: true, dimColor: activeTab !== tab.id, children: tab.label }, tab.id))
|
|
5562
5954
|
] })
|
|
5563
5955
|
] }),
|
|
5564
|
-
/* @__PURE__ */
|
|
5565
|
-
/* @__PURE__ */
|
|
5566
|
-
/* @__PURE__ */
|
|
5956
|
+
/* @__PURE__ */ jsxs23(Box23, { flexGrow: 1, flexDirection: "row", columnGap: 1, children: [
|
|
5957
|
+
/* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", flexGrow: 1, flexBasis: 0, children: [
|
|
5958
|
+
/* @__PURE__ */ jsx25(
|
|
5567
5959
|
GitHubView,
|
|
5568
5960
|
{
|
|
5569
5961
|
isActive: focusedView === "github",
|
|
@@ -5571,7 +5963,7 @@ function App() {
|
|
|
5571
5963
|
onLogUpdated: handleLogUpdated
|
|
5572
5964
|
}
|
|
5573
5965
|
),
|
|
5574
|
-
/* @__PURE__ */
|
|
5966
|
+
/* @__PURE__ */ jsx25(
|
|
5575
5967
|
JiraView,
|
|
5576
5968
|
{
|
|
5577
5969
|
isActive: focusedView === "jira",
|
|
@@ -5581,8 +5973,8 @@ function App() {
|
|
|
5581
5973
|
}
|
|
5582
5974
|
)
|
|
5583
5975
|
] }),
|
|
5584
|
-
/* @__PURE__ */
|
|
5585
|
-
activeTab === "logs" && /* @__PURE__ */
|
|
5976
|
+
/* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", flexGrow: 1, flexBasis: 0, children: [
|
|
5977
|
+
activeTab === "logs" && /* @__PURE__ */ jsx25(
|
|
5586
5978
|
LogsView,
|
|
5587
5979
|
{
|
|
5588
5980
|
isActive: focusedView === "logs",
|
|
@@ -5591,7 +5983,7 @@ function App() {
|
|
|
5591
5983
|
onFocusedBoxChange: setLogsFocusedBox
|
|
5592
5984
|
}
|
|
5593
5985
|
),
|
|
5594
|
-
activeTab === "jira-browser" && /* @__PURE__ */
|
|
5986
|
+
activeTab === "jira-browser" && /* @__PURE__ */ jsx25(
|
|
5595
5987
|
JiraBrowserView,
|
|
5596
5988
|
{
|
|
5597
5989
|
isActive: focusedView === "jira-browser",
|
|
@@ -5600,10 +5992,11 @@ function App() {
|
|
|
5600
5992
|
onModalChange: setJiraBrowserModalOpen,
|
|
5601
5993
|
onLogUpdated: handleLogUpdated
|
|
5602
5994
|
}
|
|
5603
|
-
)
|
|
5995
|
+
),
|
|
5996
|
+
activeTab === "pull-requests" && /* @__PURE__ */ jsx25(AllPullRequestsView, { isActive: focusedView === "pull-requests", onModalChange: setPullRequestsModalOpen })
|
|
5604
5997
|
] })
|
|
5605
5998
|
] }),
|
|
5606
|
-
/* @__PURE__ */
|
|
5999
|
+
/* @__PURE__ */ jsx25(
|
|
5607
6000
|
KeybindingsBar,
|
|
5608
6001
|
{
|
|
5609
6002
|
contextBindings: keybindings,
|
|
@@ -5618,31 +6011,31 @@ function App() {
|
|
|
5618
6011
|
import { render as inkRender } from "ink";
|
|
5619
6012
|
|
|
5620
6013
|
// src/lib/Screen.tsx
|
|
5621
|
-
import { useCallback as
|
|
5622
|
-
import { Box as
|
|
5623
|
-
import { jsx as
|
|
6014
|
+
import { useCallback as useCallback13, useEffect as useEffect19, useState as useState24 } from "react";
|
|
6015
|
+
import { Box as Box24, useStdout as useStdout2 } from "ink";
|
|
6016
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
5624
6017
|
function Screen({ children }) {
|
|
5625
6018
|
const { stdout } = useStdout2();
|
|
5626
|
-
const getSize =
|
|
5627
|
-
const [size, setSize] =
|
|
5628
|
-
|
|
6019
|
+
const getSize = useCallback13(() => ({ height: stdout.rows, width: stdout.columns }), [stdout]);
|
|
6020
|
+
const [size, setSize] = useState24(getSize);
|
|
6021
|
+
useEffect19(() => {
|
|
5629
6022
|
const onResize = () => setSize(getSize());
|
|
5630
6023
|
stdout.on("resize", onResize);
|
|
5631
6024
|
return () => {
|
|
5632
6025
|
stdout.off("resize", onResize);
|
|
5633
6026
|
};
|
|
5634
6027
|
}, [stdout, getSize]);
|
|
5635
|
-
return /* @__PURE__ */
|
|
6028
|
+
return /* @__PURE__ */ jsx26(Box24, { height: size.height, width: size.width, children });
|
|
5636
6029
|
}
|
|
5637
6030
|
|
|
5638
6031
|
// src/lib/render.tsx
|
|
5639
|
-
import { jsx as
|
|
6032
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
5640
6033
|
var ENTER_ALT_BUFFER = "\x1B[?1049h";
|
|
5641
6034
|
var EXIT_ALT_BUFFER = "\x1B[?1049l";
|
|
5642
6035
|
var CLEAR_SCREEN = "\x1B[2J\x1B[H";
|
|
5643
6036
|
function render(node, options) {
|
|
5644
6037
|
process.stdout.write(ENTER_ALT_BUFFER + CLEAR_SCREEN);
|
|
5645
|
-
const element = /* @__PURE__ */
|
|
6038
|
+
const element = /* @__PURE__ */ jsx27(Screen, { children: node });
|
|
5646
6039
|
const instance = inkRender(element, options);
|
|
5647
6040
|
setImmediate(() => instance.rerender(element));
|
|
5648
6041
|
const cleanup = () => process.stdout.write(EXIT_ALT_BUFFER);
|
|
@@ -5663,7 +6056,7 @@ function render(node, options) {
|
|
|
5663
6056
|
}
|
|
5664
6057
|
|
|
5665
6058
|
// src/cli.tsx
|
|
5666
|
-
import { jsx as
|
|
6059
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
5667
6060
|
var cli = meow(
|
|
5668
6061
|
`
|
|
5669
6062
|
Usage
|
|
@@ -5696,4 +6089,4 @@ if (cli.flags.cwd) {
|
|
|
5696
6089
|
process.exit(1);
|
|
5697
6090
|
}
|
|
5698
6091
|
}
|
|
5699
|
-
render(/* @__PURE__ */
|
|
6092
|
+
render(/* @__PURE__ */ jsx28(App, {}));
|