gh-manager-cli 1.41.0 → 1.43.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/CHANGELOG.md +14 -0
- package/README.md +10 -8
- package/dist/{chunk-UOGN2QJU.js → chunk-MKIUBPVD.js} +119 -1
- package/dist/{github-ASGTM4ZX.js → github-6HD7I2UI.js} +5 -1
- package/dist/index.js +686 -652
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
changeRepositoryVisibility,
|
|
7
7
|
checkOrganizationIsEnterprise,
|
|
8
8
|
deleteRepositoryRest,
|
|
9
|
+
enrichForksWithAheadBehind,
|
|
10
|
+
fetchRepositoryByOwnerAndName,
|
|
9
11
|
fetchRestRateLimits,
|
|
10
12
|
fetchViewerOrganizations,
|
|
11
13
|
fetchViewerReposPageUnified,
|
|
@@ -17,7 +19,6 @@ import {
|
|
|
17
19
|
makeClient,
|
|
18
20
|
purgeApolloCacheFiles,
|
|
19
21
|
renameRepositoryById,
|
|
20
|
-
searchRepositoriesUnified,
|
|
21
22
|
starRepository,
|
|
22
23
|
syncForkWithUpstream,
|
|
23
24
|
unarchiveRepositoryById,
|
|
@@ -27,14 +28,14 @@ import {
|
|
|
27
28
|
updateCacheAfterRename,
|
|
28
29
|
updateCacheAfterVisibilityChange,
|
|
29
30
|
updateCacheWithRepository
|
|
30
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-MKIUBPVD.js";
|
|
31
32
|
|
|
32
33
|
// package.json
|
|
33
34
|
var require_package = __commonJS({
|
|
34
35
|
"package.json"(exports, module) {
|
|
35
36
|
module.exports = {
|
|
36
37
|
name: "gh-manager-cli",
|
|
37
|
-
version: "1.
|
|
38
|
+
version: "1.43.0",
|
|
38
39
|
private: false,
|
|
39
40
|
description: "TUI terminal app to manage GitHub repos. Clean up your account in 5 minutes. Archive, delete, rename repos with keyboard shortcuts. Alternative to clicking through github.com",
|
|
40
41
|
license: "MIT",
|
|
@@ -97,6 +98,7 @@ var require_package = __commonJS({
|
|
|
97
98
|
chalk: "^5.6.0",
|
|
98
99
|
dotenv: "^17.2.1",
|
|
99
100
|
"env-paths": "^3.0.0",
|
|
101
|
+
"fuse.js": "^7.4.1",
|
|
100
102
|
graphql: "^16.11.0",
|
|
101
103
|
ink: "^6.2.3",
|
|
102
104
|
"ink-spinner": "^5.0.0",
|
|
@@ -153,12 +155,12 @@ var require_package = __commonJS({
|
|
|
153
155
|
|
|
154
156
|
// src/index.tsx
|
|
155
157
|
var import_package = __toESM(require_package(), 1);
|
|
156
|
-
import { render, Box as
|
|
158
|
+
import { render, Box as Box24, Text as Text25 } from "ink";
|
|
157
159
|
import "dotenv/config";
|
|
158
160
|
|
|
159
161
|
// src/ui/App.tsx
|
|
160
|
-
import { useEffect as useEffect13, useMemo as useMemo3, useState as
|
|
161
|
-
import { Box as
|
|
162
|
+
import { useEffect as useEffect13, useMemo as useMemo3, useState as useState19 } from "react";
|
|
163
|
+
import { Box as Box23, Text as Text24, useApp as useApp2, useStdout as useStdout2, useInput as useInput19 } from "ink";
|
|
162
164
|
import TextInput6 from "ink-text-input";
|
|
163
165
|
|
|
164
166
|
// src/config/config.ts
|
|
@@ -407,8 +409,8 @@ async function openGitHubAuthorizationPage() {
|
|
|
407
409
|
}
|
|
408
410
|
|
|
409
411
|
// src/ui/views/RepoList.tsx
|
|
410
|
-
import
|
|
411
|
-
import { Box as
|
|
412
|
+
import React17, { useEffect as useEffect12, useMemo as useMemo2, useState as useState17, useRef, useCallback } from "react";
|
|
413
|
+
import { Box as Box20, Text as Text21, useApp, useInput as useInput17, useStdout } from "ink";
|
|
412
414
|
import TextInput5 from "ink-text-input";
|
|
413
415
|
import chalk15 from "chalk";
|
|
414
416
|
|
|
@@ -564,11 +566,6 @@ function makeApolloKey(opts) {
|
|
|
564
566
|
const affiliations = opts.affiliations || "OWNER";
|
|
565
567
|
return `viewer:${v}|context:${context}|affiliations:${affiliations}|sort:${opts.sortKey}:${opts.sortDir}|ps:${opts.pageSize}|forks:${opts.forkTracking ? "1" : "0"}`;
|
|
566
568
|
}
|
|
567
|
-
function makeSearchKey(opts) {
|
|
568
|
-
const v = opts.viewer || "unknown";
|
|
569
|
-
const query = (opts.q || "").trim().toLowerCase();
|
|
570
|
-
return `search:${query}|viewer:${v}|sort:${opts.sortKey}:${opts.sortDir}|ps:${opts.pageSize}|forks:${opts.forkTracking ? "1" : "0"}`;
|
|
571
|
-
}
|
|
572
569
|
function isFresh(key, ttlMs = Number(process.env.APOLLO_TTL_MS || 30 * 60 * 1e3)) {
|
|
573
570
|
const meta = readMeta();
|
|
574
571
|
const iso = meta.fetched[key];
|
|
@@ -583,6 +580,26 @@ function markFetched(key) {
|
|
|
583
580
|
writeMeta(meta);
|
|
584
581
|
}
|
|
585
582
|
|
|
583
|
+
// src/lib/fuzzySearch.ts
|
|
584
|
+
import Fuse from "fuse.js";
|
|
585
|
+
var FUSE_OPTIONS = {
|
|
586
|
+
keys: [
|
|
587
|
+
{ name: "name", weight: 0.4 },
|
|
588
|
+
{ name: "nameWithOwner", weight: 0.3 },
|
|
589
|
+
{ name: "description", weight: 0.2 },
|
|
590
|
+
{ name: "primaryLanguage.name", weight: 0.1 }
|
|
591
|
+
],
|
|
592
|
+
threshold: 0.4,
|
|
593
|
+
ignoreLocation: true,
|
|
594
|
+
includeScore: true
|
|
595
|
+
};
|
|
596
|
+
function fuzzySearch(repos, query) {
|
|
597
|
+
const q = query.trim();
|
|
598
|
+
if (!q) return [];
|
|
599
|
+
const fuse = new Fuse(repos, FUSE_OPTIONS);
|
|
600
|
+
return fuse.search(q).map((r) => r.item);
|
|
601
|
+
}
|
|
602
|
+
|
|
586
603
|
// src/ui/views/RepoList.tsx
|
|
587
604
|
import { exec } from "child_process";
|
|
588
605
|
|
|
@@ -604,7 +621,7 @@ function OrgSwitcher({ token, currentContext, onSelect, onClose }) {
|
|
|
604
621
|
try {
|
|
605
622
|
setLoading(true);
|
|
606
623
|
setError(null);
|
|
607
|
-
const client = await import("./github-
|
|
624
|
+
const client = await import("./github-6HD7I2UI.js").then((m) => m.makeClient(token));
|
|
608
625
|
const orgs = await fetchViewerOrganizations(client);
|
|
609
626
|
setOrganizations(orgs);
|
|
610
627
|
const entOrgs = /* @__PURE__ */ new Set();
|
|
@@ -1855,11 +1872,76 @@ function StarModal({
|
|
|
1855
1872
|
);
|
|
1856
1873
|
}
|
|
1857
1874
|
|
|
1875
|
+
// src/ui/components/modals/OpenInBrowserModal.tsx
|
|
1876
|
+
import { useState as useState15 } from "react";
|
|
1877
|
+
import { Box as Box15, Text as Text16, useInput as useInput15 } from "ink";
|
|
1878
|
+
import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1879
|
+
function OpenInBrowserModal({ repo, onOpen, onCancel, theme: themeProp }) {
|
|
1880
|
+
const { theme, c } = useTheme(themeProp?.name ?? "default");
|
|
1881
|
+
const [focus, setFocus] = useState15("this");
|
|
1882
|
+
const forkUrl = `https://github.com/${repo.nameWithOwner}`;
|
|
1883
|
+
const upstreamUrl = repo.parent ? `https://github.com/${repo.parent.nameWithOwner}` : null;
|
|
1884
|
+
useInput15((input, key) => {
|
|
1885
|
+
if (key.escape || input.toLowerCase() === "c") {
|
|
1886
|
+
onCancel();
|
|
1887
|
+
return;
|
|
1888
|
+
}
|
|
1889
|
+
if (key.leftArrow || key.rightArrow) {
|
|
1890
|
+
setFocus((prev) => prev === "this" ? "upstream" : "this");
|
|
1891
|
+
return;
|
|
1892
|
+
}
|
|
1893
|
+
if (key.return) {
|
|
1894
|
+
if (focus === "this") {
|
|
1895
|
+
onOpen(forkUrl);
|
|
1896
|
+
} else if (upstreamUrl) {
|
|
1897
|
+
onOpen(upstreamUrl);
|
|
1898
|
+
}
|
|
1899
|
+
return;
|
|
1900
|
+
}
|
|
1901
|
+
if (input.toLowerCase() === "t") {
|
|
1902
|
+
onOpen(forkUrl);
|
|
1903
|
+
return;
|
|
1904
|
+
}
|
|
1905
|
+
if (input.toLowerCase() === "u" && upstreamUrl) {
|
|
1906
|
+
onOpen(upstreamUrl);
|
|
1907
|
+
return;
|
|
1908
|
+
}
|
|
1909
|
+
});
|
|
1910
|
+
return /* @__PURE__ */ jsxs15(
|
|
1911
|
+
Box15,
|
|
1912
|
+
{
|
|
1913
|
+
flexDirection: "column",
|
|
1914
|
+
borderStyle: "round",
|
|
1915
|
+
borderColor: theme.primary,
|
|
1916
|
+
paddingX: 3,
|
|
1917
|
+
paddingY: 2,
|
|
1918
|
+
width: 62,
|
|
1919
|
+
children: [
|
|
1920
|
+
/* @__PURE__ */ jsx16(Text16, { bold: true, color: theme.primary, children: "Open in Browser" }),
|
|
1921
|
+
/* @__PURE__ */ jsx16(Box15, { height: 1, children: /* @__PURE__ */ jsx16(Text16, { children: " " }) }),
|
|
1922
|
+
/* @__PURE__ */ jsx16(Text16, { bold: true, children: repo.nameWithOwner }),
|
|
1923
|
+
repo.parent && /* @__PURE__ */ jsxs15(Text16, { color: theme.muted, children: [
|
|
1924
|
+
"Fork of ",
|
|
1925
|
+
repo.parent.nameWithOwner
|
|
1926
|
+
] }),
|
|
1927
|
+
/* @__PURE__ */ jsx16(Box15, { height: 1, children: /* @__PURE__ */ jsx16(Text16, { children: " " }) }),
|
|
1928
|
+
/* @__PURE__ */ jsx16(Text16, { children: "Which repository would you like to open?" }),
|
|
1929
|
+
/* @__PURE__ */ jsx16(Box15, { height: 1, children: /* @__PURE__ */ jsx16(Text16, { children: " " }) }),
|
|
1930
|
+
/* @__PURE__ */ jsxs15(Box15, { marginTop: 1, flexDirection: "row", justifyContent: "center", gap: 4, children: [
|
|
1931
|
+
/* @__PURE__ */ jsx16(Box15, { paddingX: 2, paddingY: 1, children: /* @__PURE__ */ jsx16(Text16, { children: focus === "this" ? c.primary.inverse.bold(" This Repository ") : c.primary.bold("This Repository") }) }),
|
|
1932
|
+
/* @__PURE__ */ jsx16(Box15, { paddingX: 2, paddingY: 1, children: /* @__PURE__ */ jsx16(Text16, { children: focus === "upstream" ? c.success.inverse.bold(" Parent/Upstream ") : c.success.bold("Parent/Upstream") }) })
|
|
1933
|
+
] }),
|
|
1934
|
+
/* @__PURE__ */ jsx16(Box15, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsx16(Text16, { color: theme.muted, children: "\u2190/\u2192 Choose \u2022 Enter to Open \u2022 T This \u2022 U Upstream \u2022 C/Esc Cancel" }) })
|
|
1935
|
+
]
|
|
1936
|
+
}
|
|
1937
|
+
);
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1858
1940
|
// src/ui/components/modals/UnstarModal.tsx
|
|
1859
|
-
import { useEffect as useEffect11, useState as
|
|
1860
|
-
import { Box as
|
|
1861
|
-
import { useInput as
|
|
1862
|
-
import { Fragment as Fragment8, jsx as
|
|
1941
|
+
import { useEffect as useEffect11, useState as useState16 } from "react";
|
|
1942
|
+
import { Box as Box16, Text as Text17 } from "ink";
|
|
1943
|
+
import { useInput as useInput16 } from "ink";
|
|
1944
|
+
import { Fragment as Fragment8, jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1863
1945
|
function UnstarModal({
|
|
1864
1946
|
visible,
|
|
1865
1947
|
repo,
|
|
@@ -1870,8 +1952,8 @@ function UnstarModal({
|
|
|
1870
1952
|
theme: themeProp
|
|
1871
1953
|
}) {
|
|
1872
1954
|
const { theme } = useTheme(themeProp?.name ?? "default");
|
|
1873
|
-
const [focusedButton, setFocusedButton] =
|
|
1874
|
-
|
|
1955
|
+
const [focusedButton, setFocusedButton] = useState16("cancel");
|
|
1956
|
+
useInput16((input, key) => {
|
|
1875
1957
|
if (!visible) return;
|
|
1876
1958
|
if (key.escape || input === "c" || input === "C") {
|
|
1877
1959
|
onCancel();
|
|
@@ -1893,8 +1975,8 @@ function UnstarModal({
|
|
|
1893
1975
|
if (visible) setFocusedButton("cancel");
|
|
1894
1976
|
}, [visible]);
|
|
1895
1977
|
if (!visible || !repo) return null;
|
|
1896
|
-
return /* @__PURE__ */
|
|
1897
|
-
|
|
1978
|
+
return /* @__PURE__ */ jsxs16(
|
|
1979
|
+
Box16,
|
|
1898
1980
|
{
|
|
1899
1981
|
flexDirection: "column",
|
|
1900
1982
|
borderStyle: "round",
|
|
@@ -1903,28 +1985,28 @@ function UnstarModal({
|
|
|
1903
1985
|
paddingY: 1,
|
|
1904
1986
|
marginTop: 1,
|
|
1905
1987
|
children: [
|
|
1906
|
-
/* @__PURE__ */
|
|
1907
|
-
/* @__PURE__ */
|
|
1988
|
+
/* @__PURE__ */ jsx17(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsx17(Text17, { bold: true, color: theme.warning, children: "\u2B50 Unstar Repository" }) }),
|
|
1989
|
+
/* @__PURE__ */ jsx17(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsxs16(Text17, { children: [
|
|
1908
1990
|
"Are you sure you want to unstar",
|
|
1909
1991
|
" ",
|
|
1910
|
-
/* @__PURE__ */
|
|
1992
|
+
/* @__PURE__ */ jsx17(Text17, { bold: true, color: theme.primary, children: repo.nameWithOwner }),
|
|
1911
1993
|
"?"
|
|
1912
1994
|
] }) }),
|
|
1913
|
-
repo.description && /* @__PURE__ */
|
|
1914
|
-
/* @__PURE__ */
|
|
1995
|
+
repo.description && /* @__PURE__ */ jsx17(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsx17(Text17, { dimColor: true, wrap: "wrap", children: repo.description }) }),
|
|
1996
|
+
/* @__PURE__ */ jsx17(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsxs16(Text17, { dimColor: true, children: [
|
|
1915
1997
|
"Stars: ",
|
|
1916
1998
|
repo.stargazerCount,
|
|
1917
1999
|
" \u2022 Forks: ",
|
|
1918
2000
|
repo.forkCount
|
|
1919
2001
|
] }) }),
|
|
1920
|
-
error && /* @__PURE__ */
|
|
2002
|
+
error && /* @__PURE__ */ jsx17(Box16, { marginBottom: 1, flexDirection: "column", children: /* @__PURE__ */ jsxs16(Text17, { color: theme.error, wrap: "wrap", children: [
|
|
1921
2003
|
error.includes("OAuth access restrictions") ? "\u26A0\uFE0F " : "Error: ",
|
|
1922
2004
|
error
|
|
1923
2005
|
] }) }),
|
|
1924
|
-
isUnstarring ? /* @__PURE__ */
|
|
1925
|
-
/* @__PURE__ */
|
|
1926
|
-
/* @__PURE__ */
|
|
1927
|
-
|
|
2006
|
+
isUnstarring ? /* @__PURE__ */ jsx17(Box16, { children: /* @__PURE__ */ jsx17(Text17, { color: theme.warning, children: "Unstarring..." }) }) : /* @__PURE__ */ jsxs16(Fragment8, { children: [
|
|
2007
|
+
/* @__PURE__ */ jsxs16(Box16, { gap: 2, children: [
|
|
2008
|
+
/* @__PURE__ */ jsx17(Box16, { children: /* @__PURE__ */ jsxs16(
|
|
2009
|
+
Text17,
|
|
1928
2010
|
{
|
|
1929
2011
|
backgroundColor: focusedButton === "cancel" ? "white" : void 0,
|
|
1930
2012
|
color: focusedButton === "cancel" ? "black" : "white",
|
|
@@ -1936,8 +2018,8 @@ function UnstarModal({
|
|
|
1936
2018
|
]
|
|
1937
2019
|
}
|
|
1938
2020
|
) }),
|
|
1939
|
-
/* @__PURE__ */
|
|
1940
|
-
|
|
2021
|
+
/* @__PURE__ */ jsx17(Box16, { children: /* @__PURE__ */ jsxs16(
|
|
2022
|
+
Text17,
|
|
1941
2023
|
{
|
|
1942
2024
|
backgroundColor: focusedButton === "unstar" ? "yellow" : void 0,
|
|
1943
2025
|
color: focusedButton === "unstar" ? "black" : theme.warning,
|
|
@@ -1950,7 +2032,7 @@ function UnstarModal({
|
|
|
1950
2032
|
}
|
|
1951
2033
|
) })
|
|
1952
2034
|
] }),
|
|
1953
|
-
/* @__PURE__ */
|
|
2035
|
+
/* @__PURE__ */ jsx17(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Use \u2190 \u2192 to navigate, Enter to select" }) })
|
|
1954
2036
|
] })
|
|
1955
2037
|
]
|
|
1956
2038
|
}
|
|
@@ -1958,9 +2040,9 @@ function UnstarModal({
|
|
|
1958
2040
|
}
|
|
1959
2041
|
|
|
1960
2042
|
// src/ui/components/repo/RepoRow.tsx
|
|
1961
|
-
import { Box as
|
|
2043
|
+
import { Box as Box17, Text as Text18 } from "ink";
|
|
1962
2044
|
import chalk14 from "chalk";
|
|
1963
|
-
import { jsx as
|
|
2045
|
+
import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1964
2046
|
function RepoRow({
|
|
1965
2047
|
repo,
|
|
1966
2048
|
selected,
|
|
@@ -1976,8 +2058,11 @@ function RepoRow({
|
|
|
1976
2058
|
const langName = repo.primaryLanguage?.name || "";
|
|
1977
2059
|
const langColor = repo.primaryLanguage?.color || "#666666";
|
|
1978
2060
|
const hasCommitData = repo.isFork && repo.parent && repo.defaultBranchRef && repo.parent.defaultBranchRef && repo.parent.defaultBranchRef.target?.history && repo.defaultBranchRef.target?.history;
|
|
1979
|
-
const
|
|
1980
|
-
const
|
|
2061
|
+
const forkCount = hasCommitData ? repo.defaultBranchRef.target.history.totalCount : 0;
|
|
2062
|
+
const parentCount = hasCommitData ? repo.parent.defaultBranchRef.target.history.totalCount : 0;
|
|
2063
|
+
const commitsBehind = hasCommitData ? Math.max(0, parentCount - forkCount) : 0;
|
|
2064
|
+
const commitsAhead = hasCommitData ? Math.max(0, forkCount - parentCount) : 0;
|
|
2065
|
+
const showCommitData = forkTracking && hasCommitData;
|
|
1981
2066
|
let line1 = "";
|
|
1982
2067
|
const numColor = selected ? c.selected : c.muted;
|
|
1983
2068
|
const nameColor = selected ? c.selected.bold : c.text;
|
|
@@ -1997,11 +2082,14 @@ function RepoRow({
|
|
|
1997
2082
|
if (repo.isArchived) line1 += " " + chalk14.bgGray.whiteBright(" Archived ") + " ";
|
|
1998
2083
|
if (repo.isFork && repo.parent) {
|
|
1999
2084
|
line1 += c.fork(` Fork of ${repo.parent.nameWithOwner}`);
|
|
2000
|
-
if (
|
|
2001
|
-
|
|
2002
|
-
|
|
2085
|
+
if (showCommitData) {
|
|
2086
|
+
const parts = [];
|
|
2087
|
+
if (commitsAhead > 0) parts.push(c.success(`${commitsAhead} ahead`));
|
|
2088
|
+
if (commitsBehind > 0) parts.push(c.warning(`${commitsBehind} behind`));
|
|
2089
|
+
if (parts.length > 0) {
|
|
2090
|
+
line1 += c.muted(` (${parts.join(", ")})`);
|
|
2003
2091
|
} else {
|
|
2004
|
-
line1 += c.success(` (
|
|
2092
|
+
line1 += c.success(` (up to date)`);
|
|
2005
2093
|
}
|
|
2006
2094
|
}
|
|
2007
2095
|
}
|
|
@@ -2014,29 +2102,28 @@ function RepoRow({
|
|
|
2014
2102
|
if (line3) fullText += "\n" + metaColor(line3);
|
|
2015
2103
|
const spacingAbove = Math.floor(spacingLines / 2);
|
|
2016
2104
|
const spacingBelow = spacingLines - spacingAbove;
|
|
2017
|
-
return /* @__PURE__ */
|
|
2018
|
-
spacingAbove > 0 && /* @__PURE__ */
|
|
2019
|
-
/* @__PURE__ */
|
|
2020
|
-
spacingBelow > 0 && /* @__PURE__ */
|
|
2105
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", backgroundColor: selected ? "gray" : void 0, children: [
|
|
2106
|
+
spacingAbove > 0 && /* @__PURE__ */ jsx18(Box17, { height: spacingAbove, children: /* @__PURE__ */ jsx18(Text18, { children: " " }) }),
|
|
2107
|
+
/* @__PURE__ */ jsx18(Text18, { children: dim ? chalk14.dim(fullText) : fullText }),
|
|
2108
|
+
spacingBelow > 0 && /* @__PURE__ */ jsx18(Box17, { height: spacingBelow, children: /* @__PURE__ */ jsx18(Text18, { children: " " }) })
|
|
2021
2109
|
] });
|
|
2022
2110
|
}
|
|
2023
2111
|
|
|
2024
2112
|
// src/ui/components/repo/FilterInput.tsx
|
|
2025
|
-
import { Box as
|
|
2113
|
+
import { Box as Box18, Text as Text19 } from "ink";
|
|
2026
2114
|
import TextInput4 from "ink-text-input";
|
|
2027
|
-
import { jsx as
|
|
2115
|
+
import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2028
2116
|
|
|
2029
2117
|
// src/ui/components/repo/RepoListHeader.tsx
|
|
2030
|
-
import { Box as
|
|
2031
|
-
import {
|
|
2118
|
+
import { Box as Box19, Text as Text20 } from "ink";
|
|
2119
|
+
import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2032
2120
|
function RepoListHeader({
|
|
2033
2121
|
ownerContext,
|
|
2034
2122
|
sortKey,
|
|
2035
2123
|
sortDir,
|
|
2036
2124
|
forkTracking,
|
|
2037
2125
|
filter,
|
|
2038
|
-
|
|
2039
|
-
searchLoading,
|
|
2126
|
+
filterActive,
|
|
2040
2127
|
visibilityFilter = "all",
|
|
2041
2128
|
archiveFilter = "all",
|
|
2042
2129
|
isEnterprise = false,
|
|
@@ -2046,48 +2133,36 @@ function RepoListHeader({
|
|
|
2046
2133
|
const { theme } = useTheme(themeProp?.name ?? "default");
|
|
2047
2134
|
const contextLabel = ownerContext === "personal" ? "Personal Account" : ownerContext?.type === "organization" ? `Organisation: ${ownerContext.name ?? ownerContext.login}` : "";
|
|
2048
2135
|
const visibilityLabel = visibilityFilter === "public" ? "Public" : visibilityFilter === "private" ? isEnterprise ? "Private/Internal" : "Private" : visibilityFilter === "internal" ? "Internal" : "";
|
|
2049
|
-
return /* @__PURE__ */
|
|
2050
|
-
contextLabel && /* @__PURE__ */
|
|
2051
|
-
starsMode && /* @__PURE__ */
|
|
2052
|
-
/* @__PURE__ */
|
|
2136
|
+
return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "row", gap: 2, marginBottom: 1, children: [
|
|
2137
|
+
contextLabel && /* @__PURE__ */ jsx20(Text20, { children: contextLabel }),
|
|
2138
|
+
starsMode && /* @__PURE__ */ jsx20(Text20, { color: theme.warning, bold: true, children: "\u2B50 Stars Mode" }),
|
|
2139
|
+
/* @__PURE__ */ jsxs19(Text20, { color: theme.muted, dimColor: true, children: [
|
|
2053
2140
|
"Sort: ",
|
|
2054
|
-
sortKey
|
|
2055
|
-
" ",
|
|
2056
|
-
sortDir === "asc" ? "\u2191" : "\u2193"
|
|
2141
|
+
filterActive ? "relevance" : `${sortKey} ${sortDir === "asc" ? "\u2191" : "\u2193"}`
|
|
2057
2142
|
] }),
|
|
2058
|
-
/* @__PURE__ */
|
|
2143
|
+
/* @__PURE__ */ jsxs19(Text20, { color: theme.muted, dimColor: true, children: [
|
|
2059
2144
|
"Fork Status - Commits Behind: ",
|
|
2060
2145
|
forkTracking ? "ON" : "OFF"
|
|
2061
2146
|
] }),
|
|
2062
|
-
!!visibilityLabel && !starsMode && /* @__PURE__ */
|
|
2147
|
+
!!visibilityLabel && !starsMode && /* @__PURE__ */ jsxs19(Text20, { color: theme.warning, children: [
|
|
2063
2148
|
"Visibility: ",
|
|
2064
2149
|
visibilityLabel
|
|
2065
2150
|
] }),
|
|
2066
|
-
archiveFilter !== "all" && /* @__PURE__ */
|
|
2151
|
+
archiveFilter !== "all" && /* @__PURE__ */ jsxs19(Text20, { color: theme.primary, children: [
|
|
2067
2152
|
"Archive: ",
|
|
2068
2153
|
archiveFilter === "archived" ? "Archived" : "Unarchived"
|
|
2069
2154
|
] }),
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2155
|
+
(filterActive || starsMode && filter.trim().length > 0) && /* @__PURE__ */ jsxs19(Text20, { color: theme.primary, children: [
|
|
2156
|
+
starsMode ? "Filter" : "Search",
|
|
2157
|
+
': "',
|
|
2158
|
+
filter.trim(),
|
|
2073
2159
|
'"'
|
|
2074
|
-
] }),
|
|
2075
|
-
searchActive && /* @__PURE__ */ jsxs18(Fragment9, { children: [
|
|
2076
|
-
/* @__PURE__ */ jsxs18(Text19, { color: theme.primary, children: [
|
|
2077
|
-
'Search: "',
|
|
2078
|
-
filter.trim(),
|
|
2079
|
-
'"'
|
|
2080
|
-
] }),
|
|
2081
|
-
searchLoading && /* @__PURE__ */ jsx19(Box18, { marginLeft: 1, children: /* @__PURE__ */ jsxs18(Text19, { color: theme.primary, children: [
|
|
2082
|
-
/* @__PURE__ */ jsx19(SlowSpinner, {}),
|
|
2083
|
-
" Searching\u2026"
|
|
2084
|
-
] }) })
|
|
2085
2160
|
] })
|
|
2086
2161
|
] });
|
|
2087
2162
|
}
|
|
2088
2163
|
|
|
2089
2164
|
// src/ui/views/RepoList.tsx
|
|
2090
|
-
import { Fragment as
|
|
2165
|
+
import { Fragment as Fragment9, jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2091
2166
|
var getPageSize = () => {
|
|
2092
2167
|
const envValue = process.env.REPOS_PER_FETCH;
|
|
2093
2168
|
if (envValue) {
|
|
@@ -2103,7 +2178,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
2103
2178
|
const { exit } = useApp();
|
|
2104
2179
|
const { stdout } = useStdout();
|
|
2105
2180
|
const client = useMemo2(() => makeClient(token), [token]);
|
|
2106
|
-
const [debugMessages, setDebugMessages] =
|
|
2181
|
+
const [debugMessages, setDebugMessages] = useState17([]);
|
|
2107
2182
|
const addDebugMessage = useCallback((msg) => {
|
|
2108
2183
|
if (process.env.GH_MANAGER_DEBUG === "1") {
|
|
2109
2184
|
setDebugMessages((prev) => [...prev.slice(-9), msg]);
|
|
@@ -2113,7 +2188,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
2113
2188
|
useEffect12(() => {
|
|
2114
2189
|
handleOrgContextChangeRef.current = onOrgContextChange;
|
|
2115
2190
|
}, [onOrgContextChange]);
|
|
2116
|
-
|
|
2191
|
+
React17.useEffect(() => {
|
|
2117
2192
|
addDebugMessage(`[RepoList] Component mounted`);
|
|
2118
2193
|
logger.info("RepoList component mounted", {
|
|
2119
2194
|
token: token ? "present" : "missing",
|
|
@@ -2125,89 +2200,88 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
2125
2200
|
}, []);
|
|
2126
2201
|
const terminalWidth = stdout?.columns ?? 80;
|
|
2127
2202
|
const availableHeight = maxVisibleRows ?? 20;
|
|
2128
|
-
const [items, setItems] =
|
|
2129
|
-
const [cursor, setCursor] =
|
|
2130
|
-
const [endCursor, setEndCursor] =
|
|
2131
|
-
const [hasNextPage, setHasNextPage] =
|
|
2132
|
-
const [totalCount, setTotalCount] =
|
|
2133
|
-
const [loading, setLoading] =
|
|
2134
|
-
const [sortingLoading, setSortingLoading] =
|
|
2135
|
-
const [refreshing, setRefreshing] =
|
|
2136
|
-
const [loadingMore, setLoadingMore] =
|
|
2137
|
-
const [error, setError] =
|
|
2138
|
-
const [rateLimit, setRateLimit] =
|
|
2139
|
-
const [prevRateLimit, setPrevRateLimit] =
|
|
2140
|
-
const [restRateLimit, setRestRateLimit] =
|
|
2141
|
-
const [prevRestRateLimit, setPrevRestRateLimit] =
|
|
2142
|
-
const [density, setDensity] =
|
|
2143
|
-
const [prefsLoaded, setPrefsLoaded] =
|
|
2144
|
-
const [themeName, setThemeName] =
|
|
2145
|
-
const [themeToast, setThemeToast] =
|
|
2203
|
+
const [items, setItems] = useState17([]);
|
|
2204
|
+
const [cursor, setCursor] = useState17(0);
|
|
2205
|
+
const [endCursor, setEndCursor] = useState17(null);
|
|
2206
|
+
const [hasNextPage, setHasNextPage] = useState17(false);
|
|
2207
|
+
const [totalCount, setTotalCount] = useState17(0);
|
|
2208
|
+
const [loading, setLoading] = useState17(true);
|
|
2209
|
+
const [sortingLoading, setSortingLoading] = useState17(false);
|
|
2210
|
+
const [refreshing, setRefreshing] = useState17(false);
|
|
2211
|
+
const [loadingMore, setLoadingMore] = useState17(false);
|
|
2212
|
+
const [error, setError] = useState17(null);
|
|
2213
|
+
const [rateLimit, setRateLimit] = useState17(void 0);
|
|
2214
|
+
const [prevRateLimit, setPrevRateLimit] = useState17(void 0);
|
|
2215
|
+
const [restRateLimit, setRestRateLimit] = useState17(void 0);
|
|
2216
|
+
const [prevRestRateLimit, setPrevRestRateLimit] = useState17(void 0);
|
|
2217
|
+
const [density, setDensity] = useState17(2);
|
|
2218
|
+
const [prefsLoaded, setPrefsLoaded] = useState17(false);
|
|
2219
|
+
const [themeName, setThemeName] = useState17("default");
|
|
2220
|
+
const [themeToast, setThemeToast] = useState17(null);
|
|
2146
2221
|
const themeToastTimerRef = useRef(null);
|
|
2147
2222
|
const { theme, c: tc } = useTheme(themeName);
|
|
2148
|
-
const [ownerContext, setOwnerContext] =
|
|
2149
|
-
const [ownerAffiliations, setOwnerAffiliations] =
|
|
2150
|
-
const [orgSwitcherOpen, setOrgSwitcherOpen] =
|
|
2151
|
-
const [operationCount, setOperationCount] =
|
|
2152
|
-
const [showSponsorReminder, setShowSponsorReminder] =
|
|
2153
|
-
const [
|
|
2154
|
-
const [
|
|
2155
|
-
const [
|
|
2156
|
-
const [
|
|
2157
|
-
const [
|
|
2158
|
-
const [
|
|
2159
|
-
const [
|
|
2160
|
-
const [
|
|
2161
|
-
const [
|
|
2162
|
-
const [
|
|
2163
|
-
const [
|
|
2164
|
-
const [
|
|
2165
|
-
const [
|
|
2166
|
-
const [
|
|
2167
|
-
const [
|
|
2168
|
-
const [
|
|
2169
|
-
const [
|
|
2170
|
-
const [
|
|
2171
|
-
const [
|
|
2172
|
-
const [
|
|
2173
|
-
const [
|
|
2174
|
-
const [
|
|
2175
|
-
const [
|
|
2176
|
-
const [
|
|
2177
|
-
const [
|
|
2178
|
-
const [
|
|
2179
|
-
const [
|
|
2180
|
-
const [
|
|
2181
|
-
const [
|
|
2182
|
-
const [
|
|
2183
|
-
const [
|
|
2184
|
-
const [
|
|
2185
|
-
const [
|
|
2186
|
-
const [
|
|
2187
|
-
const [
|
|
2188
|
-
const [
|
|
2189
|
-
const [
|
|
2190
|
-
const [
|
|
2191
|
-
const [
|
|
2192
|
-
const [
|
|
2193
|
-
const [
|
|
2194
|
-
const [
|
|
2195
|
-
const [
|
|
2196
|
-
const [
|
|
2197
|
-
const [
|
|
2198
|
-
const [
|
|
2199
|
-
const [
|
|
2200
|
-
const [
|
|
2201
|
-
const [
|
|
2202
|
-
const [
|
|
2203
|
-
const [
|
|
2204
|
-
const [
|
|
2205
|
-
const [
|
|
2206
|
-
const [
|
|
2207
|
-
const [
|
|
2208
|
-
const [
|
|
2209
|
-
const
|
|
2210
|
-
const [starError, setStarError] = useState16(null);
|
|
2223
|
+
const [ownerContext, setOwnerContext] = useState17("personal");
|
|
2224
|
+
const [ownerAffiliations, setOwnerAffiliations] = useState17(["OWNER"]);
|
|
2225
|
+
const [orgSwitcherOpen, setOrgSwitcherOpen] = useState17(false);
|
|
2226
|
+
const [operationCount, setOperationCount] = useState17(0);
|
|
2227
|
+
const [showSponsorReminder, setShowSponsorReminder] = useState17(false);
|
|
2228
|
+
const [deleteMode, setDeleteMode] = useState17(false);
|
|
2229
|
+
const [deleteTarget, setDeleteTarget] = useState17(null);
|
|
2230
|
+
const [deleteCode, setDeleteCode] = useState17("");
|
|
2231
|
+
const [typedCode, setTypedCode] = useState17("");
|
|
2232
|
+
const [deleting, setDeleting] = useState17(false);
|
|
2233
|
+
const [deleteError, setDeleteError] = useState17(null);
|
|
2234
|
+
const [deleteConfirmStage, setDeleteConfirmStage] = useState17(false);
|
|
2235
|
+
const [confirmFocus, setConfirmFocus] = useState17("delete");
|
|
2236
|
+
const [archiveMode, setArchiveMode] = useState17(false);
|
|
2237
|
+
const [archiveTarget, setArchiveTarget] = useState17(null);
|
|
2238
|
+
const [archiving, setArchiving] = useState17(false);
|
|
2239
|
+
const [archiveError, setArchiveError] = useState17(null);
|
|
2240
|
+
const [archiveFocus, setArchiveFocus] = useState17("confirm");
|
|
2241
|
+
const [syncMode, setSyncMode] = useState17(false);
|
|
2242
|
+
const [syncTarget, setSyncTarget] = useState17(null);
|
|
2243
|
+
const [syncing, setSyncing] = useState17(false);
|
|
2244
|
+
const [syncError, setSyncError] = useState17(null);
|
|
2245
|
+
const [syncFocus, setSyncFocus] = useState17("confirm");
|
|
2246
|
+
const [renameMode, setRenameMode] = useState17(false);
|
|
2247
|
+
const [renameTarget, setRenameTarget] = useState17(null);
|
|
2248
|
+
const [copyUrlMode, setCopyUrlMode] = useState17(false);
|
|
2249
|
+
const [copyUrlTarget, setCopyUrlTarget] = useState17(null);
|
|
2250
|
+
const [copyToast, setCopyToast] = useState17(null);
|
|
2251
|
+
const [syncTrigger, setSyncTrigger] = useState17(false);
|
|
2252
|
+
const [infoMode, setInfoMode] = useState17(false);
|
|
2253
|
+
const [infoRepo, setInfoRepo] = useState17(null);
|
|
2254
|
+
const [logoutMode, setLogoutMode] = useState17(false);
|
|
2255
|
+
const [logoutFocus, setLogoutFocus] = useState17("confirm");
|
|
2256
|
+
const [logoutError, setLogoutError] = useState17(null);
|
|
2257
|
+
const [archiveFilterMode, setArchiveFilterMode] = useState17(false);
|
|
2258
|
+
const [visibilityMode, setVisibilityMode] = useState17(false);
|
|
2259
|
+
const [isEnterpriseOrg, setIsEnterpriseOrg] = useState17(false);
|
|
2260
|
+
const [hasInternalRepos, setHasInternalRepos] = useState17(false);
|
|
2261
|
+
const [changeVisibilityMode, setChangeVisibilityMode] = useState17(false);
|
|
2262
|
+
const [changeVisibilityTarget, setChangeVisibilityTarget] = useState17(null);
|
|
2263
|
+
const [changingVisibility, setChangingVisibility] = useState17(false);
|
|
2264
|
+
const [changeVisibilityError, setChangeVisibilityError] = useState17(null);
|
|
2265
|
+
const [sortMode, setSortMode] = useState17(false);
|
|
2266
|
+
const [sortDirectionMode, setSortDirectionMode] = useState17(false);
|
|
2267
|
+
const [starsMode, setStarsMode] = useState17(false);
|
|
2268
|
+
const [starredItems, setStarredItems] = useState17([]);
|
|
2269
|
+
const [starredEndCursor, setStarredEndCursor] = useState17(null);
|
|
2270
|
+
const [starredHasNextPage, setStarredHasNextPage] = useState17(false);
|
|
2271
|
+
const [starredTotalCount, setStarredTotalCount] = useState17(0);
|
|
2272
|
+
const [starredLoading, setStarredLoading] = useState17(false);
|
|
2273
|
+
const [unstarMode, setUnstarMode] = useState17(false);
|
|
2274
|
+
const [unstarTarget, setUnstarTarget] = useState17(null);
|
|
2275
|
+
const [unstarring, setUnstarring] = useState17(false);
|
|
2276
|
+
const [unstarError, setUnstarError] = useState17(null);
|
|
2277
|
+
const [starMode, setStarMode] = useState17(false);
|
|
2278
|
+
const [starTarget, setStarTarget] = useState17(null);
|
|
2279
|
+
const [starring, setStarring] = useState17(false);
|
|
2280
|
+
const [starError, setStarError] = useState17(null);
|
|
2281
|
+
const [openInBrowserMode, setOpenInBrowserMode] = useState17(false);
|
|
2282
|
+
const [openInBrowserTarget, setOpenInBrowserTarget] = useState17(null);
|
|
2283
|
+
const [enrichingForks, setEnrichingForks] = useState17(false);
|
|
2284
|
+
const enrichmentDoneRef = useRef(/* @__PURE__ */ new Set());
|
|
2211
2285
|
const appliedInitialOrg = useRef(false);
|
|
2212
2286
|
useEffect12(() => {
|
|
2213
2287
|
(async () => {
|
|
@@ -2348,7 +2422,6 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
2348
2422
|
return r;
|
|
2349
2423
|
};
|
|
2350
2424
|
setItems((prev) => prev.map(updateRepo));
|
|
2351
|
-
setSearchItems((prev) => prev.map(updateRepo));
|
|
2352
2425
|
trackSuccessfulOperation();
|
|
2353
2426
|
setStarMode(false);
|
|
2354
2427
|
setStarTarget(null);
|
|
@@ -2406,7 +2479,6 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
2406
2479
|
return r;
|
|
2407
2480
|
};
|
|
2408
2481
|
setItems((prev) => prev.map(updateSyncedRepo));
|
|
2409
|
-
setSearchItems((prev) => prev.map(updateSyncedRepo));
|
|
2410
2482
|
closeSyncModal();
|
|
2411
2483
|
} catch (e) {
|
|
2412
2484
|
setSyncing(false);
|
|
@@ -2427,7 +2499,6 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
2427
2499
|
await updateCacheAfterArchive(token, id, !isArchived);
|
|
2428
2500
|
const updateRepo = (r) => r.id === id ? { ...r, isArchived: !isArchived } : r;
|
|
2429
2501
|
setItems((prev) => prev.map(updateRepo));
|
|
2430
|
-
setSearchItems((prev) => prev.map(updateRepo));
|
|
2431
2502
|
trackSuccessfulOperation();
|
|
2432
2503
|
closeArchiveModal();
|
|
2433
2504
|
} catch (e) {
|
|
@@ -2445,7 +2516,6 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
2445
2516
|
await updateCacheAfterRename(token, id, newName, newNameWithOwner);
|
|
2446
2517
|
const updateRepo = (r) => r.id === id ? { ...r, name: newName, nameWithOwner: newNameWithOwner } : r;
|
|
2447
2518
|
setItems((prev) => prev.map(updateRepo));
|
|
2448
|
-
setSearchItems((prev) => prev.map(updateRepo));
|
|
2449
2519
|
closeRenameModal();
|
|
2450
2520
|
} catch (error2) {
|
|
2451
2521
|
throw error2;
|
|
@@ -2494,18 +2564,12 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
2494
2564
|
const shouldRemove = visibilityFilter === "public" && newVisibility !== "PUBLIC" || visibilityFilter === "private" && newVisibility !== "PRIVATE" && newVisibility !== "INTERNAL";
|
|
2495
2565
|
if (shouldRemove) {
|
|
2496
2566
|
setItems((prev) => prev.filter((r) => r.id !== id));
|
|
2497
|
-
setSearchItems((prev) => prev.filter((r) => r.id !== id));
|
|
2498
2567
|
setTotalCount((c) => Math.max(0, c - 1));
|
|
2499
|
-
|
|
2500
|
-
setSearchTotalCount((c) => Math.max(0, c - 1));
|
|
2501
|
-
}
|
|
2502
|
-
const currentItemsLength = searchActive ? searchItems.length : items.length;
|
|
2503
|
-
setCursor((c) => Math.max(0, Math.min(c, currentItemsLength - 2)));
|
|
2568
|
+
setCursor((c) => Math.max(0, Math.min(c, items.length - 2)));
|
|
2504
2569
|
} else {
|
|
2505
2570
|
const isPrivate = newVisibility === "PRIVATE";
|
|
2506
2571
|
const updateRepo = (r) => r.id === id ? { ...r, visibility: newVisibility, isPrivate } : r;
|
|
2507
2572
|
setItems((prev) => prev.map(updateRepo));
|
|
2508
|
-
setSearchItems((prev) => prev.map(updateRepo));
|
|
2509
2573
|
}
|
|
2510
2574
|
closeChangeVisibilityModal();
|
|
2511
2575
|
} catch (e) {
|
|
@@ -2518,9 +2582,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
2518
2582
|
setCursor(0);
|
|
2519
2583
|
setOrgSwitcherOpen(false);
|
|
2520
2584
|
setItems([]);
|
|
2521
|
-
setSearchItems([]);
|
|
2522
2585
|
setTotalCount(0);
|
|
2523
|
-
setSearchTotalCount(0);
|
|
2524
2586
|
setFilter("");
|
|
2525
2587
|
setFilterMode(false);
|
|
2526
2588
|
setVisibilityFilter("all");
|
|
@@ -2567,11 +2629,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
2567
2629
|
const targetId = deleteTarget.id;
|
|
2568
2630
|
await updateCacheAfterDelete(token, targetId);
|
|
2569
2631
|
setItems((prev) => prev.filter((r) => r.id !== targetId));
|
|
2570
|
-
setSearchItems((prev) => prev.filter((r) => r.id !== targetId));
|
|
2571
2632
|
setTotalCount((c) => Math.max(0, c - 1));
|
|
2572
|
-
if (searchActive) {
|
|
2573
|
-
setSearchTotalCount((c) => Math.max(0, c - 1));
|
|
2574
|
-
}
|
|
2575
2633
|
trackSuccessfulOperation();
|
|
2576
2634
|
setDeleteMode(false);
|
|
2577
2635
|
setDeleteTarget(null);
|
|
@@ -2585,14 +2643,86 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
2585
2643
|
setDeleteError("Failed to delete repository. Ensure delete_repo scope and admin permissions.");
|
|
2586
2644
|
}
|
|
2587
2645
|
}
|
|
2588
|
-
const [filter, setFilter] =
|
|
2589
|
-
const [filterMode, setFilterMode] =
|
|
2590
|
-
const [sortKey, setSortKey] =
|
|
2591
|
-
const [sortDir, setSortDir] =
|
|
2592
|
-
const [forkTracking, setForkTracking] =
|
|
2593
|
-
|
|
2646
|
+
const [filter, setFilter] = useState17("");
|
|
2647
|
+
const [filterMode, setFilterMode] = useState17(false);
|
|
2648
|
+
const [sortKey, setSortKey] = useState17("updated");
|
|
2649
|
+
const [sortDir, setSortDir] = useState17("desc");
|
|
2650
|
+
const [forkTracking, setForkTracking] = useState17(true);
|
|
2651
|
+
useEffect12(() => {
|
|
2652
|
+
if (loading || loadingMore || hasNextPage || items.length === 0) return;
|
|
2653
|
+
if (!forkTracking) return;
|
|
2654
|
+
const unenriched = items.filter(
|
|
2655
|
+
(r) => r.isFork && r.parent?.nameWithOwner && !enrichmentDoneRef.current.has(r.id) && !(r.defaultBranchRef?.target?.history && r.parent?.defaultBranchRef?.target?.history)
|
|
2656
|
+
);
|
|
2657
|
+
if (unenriched.length === 0) return;
|
|
2658
|
+
let cancelled = false;
|
|
2659
|
+
setEnrichingForks(true);
|
|
2660
|
+
;
|
|
2661
|
+
(async () => {
|
|
2662
|
+
const BATCH_DELAY_MS = 200;
|
|
2663
|
+
try {
|
|
2664
|
+
const BATCH_SIZE = 5;
|
|
2665
|
+
for (let i = 0; i < unenriched.length; i += BATCH_SIZE) {
|
|
2666
|
+
if (cancelled) break;
|
|
2667
|
+
const slice = unenriched.slice(i, i + BATCH_SIZE);
|
|
2668
|
+
const batch = slice.map((r) => ({
|
|
2669
|
+
id: r.id,
|
|
2670
|
+
parentNameWithOwner: r.parent.nameWithOwner
|
|
2671
|
+
}));
|
|
2672
|
+
const enriched = await enrichForksWithAheadBehind(client, batch);
|
|
2673
|
+
if (cancelled) break;
|
|
2674
|
+
slice.forEach((r) => enrichmentDoneRef.current.add(r.id));
|
|
2675
|
+
setItems((prev) => prev.map((repo) => {
|
|
2676
|
+
const hit = enriched.find((e) => e.id === repo.id);
|
|
2677
|
+
if (!hit || hit.forkHistoryCount === null || hit.parentHistoryCount === null) return repo;
|
|
2678
|
+
return {
|
|
2679
|
+
...repo,
|
|
2680
|
+
defaultBranchRef: repo.defaultBranchRef ? {
|
|
2681
|
+
...repo.defaultBranchRef,
|
|
2682
|
+
target: {
|
|
2683
|
+
...repo.defaultBranchRef.target || {},
|
|
2684
|
+
history: { totalCount: hit.forkHistoryCount }
|
|
2685
|
+
}
|
|
2686
|
+
} : { name: void 0, target: { history: { totalCount: hit.forkHistoryCount } } },
|
|
2687
|
+
parent: repo.parent ? {
|
|
2688
|
+
...repo.parent,
|
|
2689
|
+
defaultBranchRef: {
|
|
2690
|
+
...repo.parent.defaultBranchRef || {},
|
|
2691
|
+
target: {
|
|
2692
|
+
...repo.parent.defaultBranchRef?.target || {},
|
|
2693
|
+
history: { totalCount: hit.parentHistoryCount }
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
} : repo.parent
|
|
2697
|
+
};
|
|
2698
|
+
}));
|
|
2699
|
+
if (i + BATCH_SIZE < unenriched.length) {
|
|
2700
|
+
await new Promise((resolve) => setTimeout(resolve, BATCH_DELAY_MS));
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
} catch (err) {
|
|
2704
|
+
logger.error("Fork enrichment failed", { error: err.message });
|
|
2705
|
+
} finally {
|
|
2706
|
+
if (!cancelled) setEnrichingForks(false);
|
|
2707
|
+
}
|
|
2708
|
+
})();
|
|
2709
|
+
return () => {
|
|
2710
|
+
cancelled = true;
|
|
2711
|
+
setEnrichingForks(false);
|
|
2712
|
+
};
|
|
2713
|
+
}, [loading, loadingMore, hasNextPage, items.length, forkTracking]);
|
|
2714
|
+
async function jumpToUpstreamRepo(parentNameWithOwner) {
|
|
2715
|
+
const [parentOwner, parentName] = parentNameWithOwner.split("/");
|
|
2716
|
+
if (!parentOwner || !parentName) return;
|
|
2717
|
+
const repo = await fetchRepositoryByOwnerAndName(client, parentOwner, parentName);
|
|
2718
|
+
if (repo) {
|
|
2719
|
+
setInfoRepo(repo);
|
|
2720
|
+
setInfoMode(true);
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
const [visibilityFilter, setVisibilityFilter] = useState17("all");
|
|
2594
2724
|
const previousVisibilityFilter = useRef("all");
|
|
2595
|
-
const [archiveFilter, setArchiveFilter] =
|
|
2725
|
+
const [archiveFilter, setArchiveFilter] = useState17("all");
|
|
2596
2726
|
const sortFieldMap = {
|
|
2597
2727
|
"updated": "UPDATED_AT",
|
|
2598
2728
|
"pushed": "PUSHED_AT",
|
|
@@ -2636,6 +2766,9 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
2636
2766
|
orgLogin,
|
|
2637
2767
|
privacy
|
|
2638
2768
|
);
|
|
2769
|
+
if (reset || !after) {
|
|
2770
|
+
enrichmentDoneRef.current.clear();
|
|
2771
|
+
}
|
|
2639
2772
|
setItems((prev) => reset || !after ? page.nodes : [...prev, ...page.nodes]);
|
|
2640
2773
|
setEndCursor(page.endCursor);
|
|
2641
2774
|
setHasNextPage(page.hasNextPage);
|
|
@@ -2694,64 +2827,6 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
2694
2827
|
setLoadingMore(false);
|
|
2695
2828
|
}
|
|
2696
2829
|
};
|
|
2697
|
-
const fetchSearchPage = async (after, reset = false, policy, searchQuery) => {
|
|
2698
|
-
const query = searchQuery ?? filter;
|
|
2699
|
-
addDebugMessage(`[fetchSearchPage] query="${query}", searchQuery="${searchQuery}", filter="${filter}"`);
|
|
2700
|
-
if (!viewerLogin) {
|
|
2701
|
-
addDebugMessage("\u274C No viewerLogin for search");
|
|
2702
|
-
return;
|
|
2703
|
-
}
|
|
2704
|
-
setSearchLoading(true);
|
|
2705
|
-
try {
|
|
2706
|
-
const orderBy = { field: sortFieldMap[sortKey], direction: sortDir.toUpperCase() };
|
|
2707
|
-
const orgLogin = ownerContext !== "personal" ? ownerContext.login : void 0;
|
|
2708
|
-
addDebugMessage(`[fetchSearchPage] Calling API with viewer="${viewerLogin}", orgLogin="${orgLogin || "none"}", query="${query.trim()}"`);
|
|
2709
|
-
const page = await searchRepositoriesUnified(
|
|
2710
|
-
token,
|
|
2711
|
-
viewerLogin,
|
|
2712
|
-
query.trim(),
|
|
2713
|
-
PAGE_SIZE,
|
|
2714
|
-
after ?? null,
|
|
2715
|
-
orderBy.field,
|
|
2716
|
-
orderBy.direction,
|
|
2717
|
-
forkTracking,
|
|
2718
|
-
policy ?? (after ? "network-only" : "cache-first"),
|
|
2719
|
-
orgLogin
|
|
2720
|
-
);
|
|
2721
|
-
addDebugMessage(`[fetchSearchPage] API returned ${page.nodes.length} results, totalCount=${page.totalCount}`);
|
|
2722
|
-
if (page.nodes.length > 0) {
|
|
2723
|
-
addDebugMessage(`[fetchSearchPage] First result: ${page.nodes[0].name}`);
|
|
2724
|
-
}
|
|
2725
|
-
setSearchItems((prev) => reset || !after ? page.nodes : [...prev, ...page.nodes]);
|
|
2726
|
-
setSearchEndCursor(page.endCursor);
|
|
2727
|
-
setSearchHasNextPage(page.hasNextPage);
|
|
2728
|
-
setSearchTotalCount(page.totalCount);
|
|
2729
|
-
if (!after) {
|
|
2730
|
-
try {
|
|
2731
|
-
const key = makeSearchKey({
|
|
2732
|
-
viewer: viewerLogin || "unknown",
|
|
2733
|
-
q: query.trim(),
|
|
2734
|
-
sortKey,
|
|
2735
|
-
sortDir,
|
|
2736
|
-
pageSize: PAGE_SIZE,
|
|
2737
|
-
forkTracking
|
|
2738
|
-
});
|
|
2739
|
-
markFetched(key);
|
|
2740
|
-
} catch {
|
|
2741
|
-
}
|
|
2742
|
-
}
|
|
2743
|
-
setError(null);
|
|
2744
|
-
} catch (e) {
|
|
2745
|
-
const errorMsg = `Failed to search: ${e.message || e}`;
|
|
2746
|
-
addDebugMessage(`\u274C Search error: ${e.message || e}`);
|
|
2747
|
-
if (e.stack) {
|
|
2748
|
-
addDebugMessage(`Stack: ${e.stack.split("\n")[0]}`);
|
|
2749
|
-
}
|
|
2750
|
-
setError(errorMsg);
|
|
2751
|
-
} finally {
|
|
2752
|
-
setSearchLoading(false);
|
|
2753
|
-
}
|
|
2754
|
-
};
|
|
2755
2830
|
useEffect12(() => {
|
|
2756
2831
|
const ui = getUIPrefs();
|
|
2757
2832
|
if (ui.density !== void 0) setDensity(ui.density);
|
|
@@ -2808,65 +2883,15 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
2808
2883
|
setCursor(0);
|
|
2809
2884
|
fetchPage(null, true, false, void 0, policy);
|
|
2810
2885
|
}, [client, prefsLoaded, ownerContext, ownerAffiliations]);
|
|
2811
|
-
useEffect12(() => {
|
|
2812
|
-
if (searchActive) {
|
|
2813
|
-
if (!searchLoading && filter.trim().length >= 3) {
|
|
2814
|
-
let policy = "cache-first";
|
|
2815
|
-
try {
|
|
2816
|
-
const key = makeSearchKey({
|
|
2817
|
-
viewer: viewerLogin || "unknown",
|
|
2818
|
-
q: filter.trim(),
|
|
2819
|
-
sortKey,
|
|
2820
|
-
sortDir,
|
|
2821
|
-
pageSize: PAGE_SIZE,
|
|
2822
|
-
forkTracking
|
|
2823
|
-
});
|
|
2824
|
-
policy = isFresh(key, 90 * 1e3) ? "cache-first" : "network-only";
|
|
2825
|
-
} catch {
|
|
2826
|
-
}
|
|
2827
|
-
fetchSearchPage(null, true, policy);
|
|
2828
|
-
}
|
|
2829
|
-
}
|
|
2830
|
-
}, [sortKey, sortDir]);
|
|
2831
2886
|
useEffect12(() => {
|
|
2832
2887
|
if (visibilityFilter !== "all" || previousVisibilityFilter.current && previousVisibilityFilter.current !== visibilityFilter) {
|
|
2833
|
-
if (
|
|
2834
|
-
|
|
2835
|
-
let policy = "network-only";
|
|
2836
|
-
const orgLogin = ownerContext !== "personal" ? ownerContext.login : void 0;
|
|
2837
|
-
fetchPage(null, true, true, void 0, policy);
|
|
2838
|
-
}
|
|
2839
|
-
} else {
|
|
2840
|
-
if (!searchLoading && filter.trim().length >= 3) {
|
|
2841
|
-
let policy = "network-only";
|
|
2842
|
-
fetchSearchPage(null, true, policy);
|
|
2843
|
-
}
|
|
2888
|
+
if (items.length > 0) {
|
|
2889
|
+
fetchPage(null, true, true, void 0, "network-only");
|
|
2844
2890
|
}
|
|
2845
2891
|
}
|
|
2846
2892
|
previousVisibilityFilter.current = visibilityFilter;
|
|
2847
2893
|
}, [visibilityFilter]);
|
|
2848
|
-
|
|
2849
|
-
if (viewerLogin && searchActive && !searchLoading && searchItems.length === 0) {
|
|
2850
|
-
let policy = "cache-first";
|
|
2851
|
-
try {
|
|
2852
|
-
const orgLogin = ownerContext !== "personal" ? ownerContext.login : void 0;
|
|
2853
|
-
const key = makeSearchKey({
|
|
2854
|
-
viewer: viewerLogin || "unknown",
|
|
2855
|
-
q: filter.trim(),
|
|
2856
|
-
sortKey,
|
|
2857
|
-
sortDir,
|
|
2858
|
-
pageSize: PAGE_SIZE,
|
|
2859
|
-
forkTracking,
|
|
2860
|
-
ownerContext: orgLogin ? `org:${orgLogin}` : "personal",
|
|
2861
|
-
affiliations: ownerAffiliations.join(",")
|
|
2862
|
-
});
|
|
2863
|
-
policy = isFresh(key, 90 * 1e3) ? "cache-first" : "network-only";
|
|
2864
|
-
} catch {
|
|
2865
|
-
}
|
|
2866
|
-
fetchSearchPage(null, true, policy);
|
|
2867
|
-
}
|
|
2868
|
-
}, [viewerLogin]);
|
|
2869
|
-
useInput16((input, key) => {
|
|
2894
|
+
useInput17((input, key) => {
|
|
2870
2895
|
if (error) {
|
|
2871
2896
|
if (input && input.toUpperCase() === "Q") {
|
|
2872
2897
|
try {
|
|
@@ -3028,6 +3053,9 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3028
3053
|
if (renameMode) {
|
|
3029
3054
|
return;
|
|
3030
3055
|
}
|
|
3056
|
+
if (openInBrowserMode) {
|
|
3057
|
+
return;
|
|
3058
|
+
}
|
|
3031
3059
|
if (copyUrlMode) {
|
|
3032
3060
|
return;
|
|
3033
3061
|
}
|
|
@@ -3050,15 +3078,11 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3050
3078
|
if (key.escape) {
|
|
3051
3079
|
setFilterMode(false);
|
|
3052
3080
|
setFilter("");
|
|
3053
|
-
setSearchItems([]);
|
|
3054
|
-
setSearchEndCursor(null);
|
|
3055
|
-
setSearchHasNextPage(false);
|
|
3056
|
-
setSearchTotalCount(0);
|
|
3057
3081
|
setCursor(0);
|
|
3058
3082
|
addDebugMessage("[ESC] Cleared search and returned to normal listing");
|
|
3059
3083
|
return;
|
|
3060
3084
|
}
|
|
3061
|
-
if (key.downArrow && (
|
|
3085
|
+
if (key.downArrow && (filterActive || starsMode && filter.trim().length > 0) && visibleItems.length > 0) {
|
|
3062
3086
|
setFilterMode(false);
|
|
3063
3087
|
setCursor(0);
|
|
3064
3088
|
addDebugMessage("[DOWN] Exited filter mode and selected first result");
|
|
@@ -3066,14 +3090,8 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3066
3090
|
}
|
|
3067
3091
|
return;
|
|
3068
3092
|
}
|
|
3069
|
-
if (key.escape && (
|
|
3093
|
+
if (key.escape && (filterActive || starsMode && filter.trim().length > 0)) {
|
|
3070
3094
|
setFilter("");
|
|
3071
|
-
if (!starsMode) {
|
|
3072
|
-
setSearchItems([]);
|
|
3073
|
-
setSearchEndCursor(null);
|
|
3074
|
-
setSearchHasNextPage(false);
|
|
3075
|
-
setSearchTotalCount(0);
|
|
3076
|
-
}
|
|
3077
3095
|
setCursor(0);
|
|
3078
3096
|
addDebugMessage("[ESC] Cleared filter and returned to normal listing");
|
|
3079
3097
|
return;
|
|
@@ -3094,7 +3112,14 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3094
3112
|
if (key.pageUp) setCursor((c) => Math.max(c - 10, 0));
|
|
3095
3113
|
if (key.return) {
|
|
3096
3114
|
const repo = visibleItems[cursor];
|
|
3097
|
-
if (repo)
|
|
3115
|
+
if (repo) {
|
|
3116
|
+
if (repo.isFork && repo.parent) {
|
|
3117
|
+
setOpenInBrowserTarget(repo);
|
|
3118
|
+
setOpenInBrowserMode(true);
|
|
3119
|
+
} else {
|
|
3120
|
+
openInBrowser(`https://github.com/${repo.nameWithOwner}`);
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3098
3123
|
}
|
|
3099
3124
|
if (key.delete || key.backspace) {
|
|
3100
3125
|
const repo = visibleItems[cursor];
|
|
@@ -3223,11 +3248,11 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3223
3248
|
setOrgSwitcherOpen(true);
|
|
3224
3249
|
return;
|
|
3225
3250
|
}
|
|
3226
|
-
if (input && input.toUpperCase() === "S" && !key.shift && !key.ctrl) {
|
|
3251
|
+
if (input && input.toUpperCase() === "S" && !key.shift && !key.ctrl && !filterActive) {
|
|
3227
3252
|
setSortMode(true);
|
|
3228
3253
|
return;
|
|
3229
3254
|
}
|
|
3230
|
-
if (input && input.toUpperCase() === "D") {
|
|
3255
|
+
if (input && input.toUpperCase() === "D" && !filterActive) {
|
|
3231
3256
|
setSortDirectionMode(true);
|
|
3232
3257
|
return;
|
|
3233
3258
|
}
|
|
@@ -3239,16 +3264,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3239
3264
|
setFilterMode(false);
|
|
3240
3265
|
if (newStarsMode) {
|
|
3241
3266
|
setVisibilityFilter("all");
|
|
3242
|
-
setSearchItems([]);
|
|
3243
|
-
setSearchEndCursor(null);
|
|
3244
|
-
setSearchHasNextPage(false);
|
|
3245
|
-
setSearchTotalCount(0);
|
|
3246
3267
|
fetchStarredRepositories(null, true);
|
|
3247
|
-
} else {
|
|
3248
|
-
setSearchItems([]);
|
|
3249
|
-
setSearchEndCursor(null);
|
|
3250
|
-
setSearchHasNextPage(false);
|
|
3251
|
-
setSearchTotalCount(0);
|
|
3252
3268
|
}
|
|
3253
3269
|
return;
|
|
3254
3270
|
}
|
|
@@ -3274,7 +3290,33 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3274
3290
|
}
|
|
3275
3291
|
if (input && input.toUpperCase() === "O") {
|
|
3276
3292
|
const repo = visibleItems[cursor];
|
|
3277
|
-
if (repo)
|
|
3293
|
+
if (repo) {
|
|
3294
|
+
if (repo.isFork && repo.parent) {
|
|
3295
|
+
setOpenInBrowserTarget(repo);
|
|
3296
|
+
setOpenInBrowserMode(true);
|
|
3297
|
+
} else {
|
|
3298
|
+
openInBrowser(`https://github.com/${repo.nameWithOwner}`);
|
|
3299
|
+
}
|
|
3300
|
+
}
|
|
3301
|
+
return;
|
|
3302
|
+
}
|
|
3303
|
+
if (input && input.toUpperCase() === "P") {
|
|
3304
|
+
const repo = visibleItems[cursor];
|
|
3305
|
+
if (repo && repo.isFork && repo.parent?.nameWithOwner) {
|
|
3306
|
+
const parentName = repo.parent.nameWithOwner;
|
|
3307
|
+
const parentIdx = visibleItems.findIndex((r) => r.nameWithOwner === parentName);
|
|
3308
|
+
if (parentIdx >= 0) {
|
|
3309
|
+
setCursor(parentIdx);
|
|
3310
|
+
} else {
|
|
3311
|
+
const cachedParent = items.find((r) => r.nameWithOwner === parentName) || starredItems.find((r) => r.nameWithOwner === parentName);
|
|
3312
|
+
if (cachedParent) {
|
|
3313
|
+
setInfoRepo(cachedParent);
|
|
3314
|
+
setInfoMode(true);
|
|
3315
|
+
} else {
|
|
3316
|
+
jumpToUpstreamRepo(parentName);
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3319
|
+
}
|
|
3278
3320
|
return;
|
|
3279
3321
|
}
|
|
3280
3322
|
if (key.shift && input === "T") {
|
|
@@ -3315,14 +3357,8 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3315
3357
|
} else if (archiveFilter === "unarchived") {
|
|
3316
3358
|
result = result.filter((r) => !r.isArchived);
|
|
3317
3359
|
}
|
|
3318
|
-
const q = filter.trim().toLowerCase();
|
|
3319
|
-
if (q) {
|
|
3320
|
-
result = result.filter(
|
|
3321
|
-
(r) => r.nameWithOwner.toLowerCase().includes(q) || (r.description ? r.description.toLowerCase().includes(q) : false)
|
|
3322
|
-
);
|
|
3323
|
-
}
|
|
3324
3360
|
return result;
|
|
3325
|
-
}, [items,
|
|
3361
|
+
}, [items, visibilityFilter, archiveFilter]);
|
|
3326
3362
|
const filteredAndSorted = useMemo2(() => {
|
|
3327
3363
|
const arr = [...filtered];
|
|
3328
3364
|
const dir = sortDir === "asc" ? 1 : -1;
|
|
@@ -3343,21 +3379,19 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3343
3379
|
});
|
|
3344
3380
|
return arr;
|
|
3345
3381
|
}, [filtered, sortKey, sortDir]);
|
|
3346
|
-
const
|
|
3347
|
-
const
|
|
3348
|
-
|
|
3382
|
+
const filterActive = !starsMode && filter.trim().length > 0;
|
|
3383
|
+
const fuzzyItems = useMemo2(() => {
|
|
3384
|
+
if (!filterActive) return [];
|
|
3385
|
+
let results = fuzzySearch(items, filter);
|
|
3349
3386
|
if (visibilityFilter === "private") {
|
|
3350
|
-
|
|
3387
|
+
results = results.filter((r) => r.visibility === "PRIVATE" || r.visibility === "INTERNAL");
|
|
3351
3388
|
} else if (visibilityFilter === "public") {
|
|
3352
|
-
|
|
3353
|
-
}
|
|
3354
|
-
if (archiveFilter === "archived") {
|
|
3355
|
-
result = result.filter((r) => r.isArchived);
|
|
3356
|
-
} else if (archiveFilter === "unarchived") {
|
|
3357
|
-
result = result.filter((r) => !r.isArchived);
|
|
3389
|
+
results = results.filter((r) => r.visibility === "PUBLIC");
|
|
3358
3390
|
}
|
|
3359
|
-
|
|
3360
|
-
|
|
3391
|
+
if (archiveFilter === "archived") results = results.filter((r) => r.isArchived);
|
|
3392
|
+
else if (archiveFilter === "unarchived") results = results.filter((r) => !r.isArchived);
|
|
3393
|
+
return results;
|
|
3394
|
+
}, [filterActive, items, filter, visibilityFilter, archiveFilter]);
|
|
3361
3395
|
const filteredStarredItems = useMemo2(() => {
|
|
3362
3396
|
let result = starredItems;
|
|
3363
3397
|
if (filter && filter.trim().length > 0) {
|
|
@@ -3373,15 +3407,10 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3373
3407
|
}
|
|
3374
3408
|
return result;
|
|
3375
3409
|
}, [starredItems, filter, archiveFilter]);
|
|
3376
|
-
const visibleItems = starsMode ? filteredStarredItems :
|
|
3377
|
-
useEffect12(() => {
|
|
3378
|
-
if (searchActive) {
|
|
3379
|
-
addDebugMessage(`[State] searchActive=${searchActive}, searchItems=${searchItems.length}, visibleItems=${visibleItems.length}, filter="${filter}"`);
|
|
3380
|
-
}
|
|
3381
|
-
}, [searchActive, searchItems.length, visibleItems.length, filter]);
|
|
3410
|
+
const visibleItems = starsMode ? filteredStarredItems : filterActive ? fuzzyItems : filteredAndSorted;
|
|
3382
3411
|
useEffect12(() => {
|
|
3383
3412
|
setCursor((c) => Math.min(c, Math.max(0, visibleItems.length - 1)));
|
|
3384
|
-
}, [
|
|
3413
|
+
}, [filterActive, items.length, visibleItems.length]);
|
|
3385
3414
|
const headerHeight = 2;
|
|
3386
3415
|
const footerHeight = 4;
|
|
3387
3416
|
const containerPadding = 2;
|
|
@@ -3393,102 +3422,97 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3393
3422
|
[visibleItems, cursor, listHeight, spacingLines]
|
|
3394
3423
|
);
|
|
3395
3424
|
useEffect12(() => {
|
|
3396
|
-
const
|
|
3397
|
-
const nearEnd = visibleItems.length > 0 && cursor >= prefetchThreshold;
|
|
3398
|
-
const rawItemsLength = starsMode ? starredItems.length : searchActive ? searchItems.length : items.length;
|
|
3425
|
+
const rawItemsLength = starsMode ? starredItems.length : items.length;
|
|
3399
3426
|
const filterDrainedPage = visibleItems.length === 0 && archiveFilter !== "all" && rawItemsLength > 0;
|
|
3400
3427
|
if (starsMode) {
|
|
3401
3428
|
if (!starredLoading && starredHasNextPage) {
|
|
3402
3429
|
fetchStarredRepositories(starredEndCursor);
|
|
3403
3430
|
}
|
|
3404
|
-
} else if (searchActive) {
|
|
3405
|
-
if (!searchLoading && searchHasNextPage && (nearEnd || filterDrainedPage)) {
|
|
3406
|
-
fetchSearchPage(searchEndCursor);
|
|
3407
|
-
}
|
|
3408
3431
|
} else {
|
|
3409
3432
|
if (!loading && !loadingMore && hasNextPage) {
|
|
3410
3433
|
fetchPage(endCursor);
|
|
3411
3434
|
}
|
|
3412
3435
|
}
|
|
3413
|
-
}, [
|
|
3436
|
+
}, [visibleItems.length, archiveFilter, items.length, starredItems.length, starsMode, starredLoading, starredHasNextPage, starredEndCursor, loading, loadingMore, hasNextPage, endCursor]);
|
|
3414
3437
|
function openInBrowser(url) {
|
|
3415
3438
|
const platform = process.platform;
|
|
3416
3439
|
const cmd = platform === "darwin" ? `open "${url}"` : platform === "win32" ? `start "" "${url}"` : `xdg-open "${url}"`;
|
|
3417
3440
|
exec(cmd);
|
|
3418
3441
|
}
|
|
3419
3442
|
const lowRate = rateLimit && rateLimit.remaining <= Math.ceil(rateLimit.limit * 0.1) || restRateLimit && restRateLimit.core.remaining <= Math.ceil(restRateLimit.core.limit * 0.1);
|
|
3420
|
-
const modalOpen = deleteMode || archiveMode || syncMode || logoutMode || infoMode || visibilityMode || archiveFilterMode || sortMode || sortDirectionMode || changeVisibilityMode || copyUrlMode || renameMode;
|
|
3421
|
-
const headerBar = useMemo2(() => /* @__PURE__ */
|
|
3422
|
-
/* @__PURE__ */
|
|
3423
|
-
/* @__PURE__ */
|
|
3443
|
+
const modalOpen = deleteMode || archiveMode || syncMode || logoutMode || infoMode || visibilityMode || archiveFilterMode || sortMode || sortDirectionMode || changeVisibilityMode || copyUrlMode || renameMode || openInBrowserMode;
|
|
3444
|
+
const headerBar = useMemo2(() => /* @__PURE__ */ jsxs20(Box20, { flexDirection: "row", justifyContent: "space-between", height: 1, marginBottom: 1, children: [
|
|
3445
|
+
/* @__PURE__ */ jsxs20(Box20, { flexDirection: "row", gap: 1, children: [
|
|
3446
|
+
/* @__PURE__ */ jsxs20(Text21, { color: theme.primary, bold: !modalOpen, dimColor: modalOpen, children: [
|
|
3424
3447
|
" ",
|
|
3425
3448
|
ownerContext === "personal" ? "Personal" : ownerContext.name || ownerContext.login,
|
|
3426
3449
|
ownerContext !== "personal" && isEnterpriseOrg && " (ENT)"
|
|
3427
3450
|
] }),
|
|
3428
|
-
/* @__PURE__ */
|
|
3429
|
-
/* @__PURE__ */
|
|
3451
|
+
/* @__PURE__ */ jsx21(Text21, { bold: true, color: modalOpen ? theme.muted : void 0, dimColor: modalOpen ? true : void 0, children: "Repositories" }),
|
|
3452
|
+
/* @__PURE__ */ jsxs20(Text21, { color: theme.muted, children: [
|
|
3430
3453
|
"(",
|
|
3431
3454
|
visibleItems.length,
|
|
3432
3455
|
"/",
|
|
3433
|
-
|
|
3456
|
+
totalCount,
|
|
3434
3457
|
")"
|
|
3435
3458
|
] }),
|
|
3436
|
-
loadingMore && hasNextPage && !starsMode &&
|
|
3437
|
-
|
|
3459
|
+
loadingMore && hasNextPage && !starsMode && totalCount > 0 && /* @__PURE__ */ jsx21(Text21, { color: theme.primary, children: ` \xB7 loading ${items.length}/${totalCount}` }),
|
|
3460
|
+
enrichingForks && /* @__PURE__ */ jsx21(Text21, { color: theme.muted, children: ` \xB7 enriching forks\u2026` }),
|
|
3461
|
+
(loading || loadingMore) && /* @__PURE__ */ jsx21(Box20, { width: 2, flexShrink: 0, flexGrow: 0, marginLeft: 1, children: /* @__PURE__ */ jsx21(Text21, { color: theme.warning, children: /* @__PURE__ */ jsx21(SlowSpinner, {}) }) })
|
|
3438
3462
|
] }),
|
|
3439
|
-
(rateLimit || restRateLimit) && /* @__PURE__ */
|
|
3463
|
+
(rateLimit || restRateLimit) && /* @__PURE__ */ jsxs20(Text21, { color: lowRate ? theme.warning : theme.muted, children: [
|
|
3440
3464
|
"GraphQL: ",
|
|
3441
3465
|
rateLimit ? `${rateLimit.remaining}/${rateLimit.limit}` : "---/---",
|
|
3442
|
-
prevRateLimit !== void 0 && rateLimit && prevRateLimit !== rateLimit.remaining && /* @__PURE__ */
|
|
3466
|
+
prevRateLimit !== void 0 && rateLimit && prevRateLimit !== rateLimit.remaining && /* @__PURE__ */ jsx21(Text21, { color: rateLimit.remaining < prevRateLimit ? theme.error : theme.success, children: ` (${rateLimit.remaining - prevRateLimit > 0 ? "+" : ""}${rateLimit.remaining - prevRateLimit})` }),
|
|
3443
3467
|
" | ",
|
|
3444
3468
|
"REST: ",
|
|
3445
3469
|
restRateLimit ? `${restRateLimit.core.remaining}/${restRateLimit.core.limit}` : "---/---",
|
|
3446
|
-
prevRestRateLimit !== void 0 && restRateLimit && prevRestRateLimit !== restRateLimit.core.remaining && /* @__PURE__ */
|
|
3470
|
+
prevRestRateLimit !== void 0 && restRateLimit && prevRestRateLimit !== restRateLimit.core.remaining && /* @__PURE__ */ jsx21(Text21, { color: restRateLimit.core.remaining < prevRestRateLimit ? theme.error : theme.success, children: ` (${restRateLimit.core.remaining - prevRestRateLimit > 0 ? "+" : ""}${restRateLimit.core.remaining - prevRestRateLimit})` }),
|
|
3447
3471
|
" "
|
|
3448
3472
|
] })
|
|
3449
|
-
] }), [visibleItems.length,
|
|
3473
|
+
] }), [visibleItems.length, totalCount, loading, loadingMore, rateLimit, lowRate, modalOpen, prevRateLimit, ownerContext, isEnterpriseOrg, restRateLimit, prevRestRateLimit, enrichingForks, starsMode, hasNextPage, items.length, theme]);
|
|
3450
3474
|
if (error) {
|
|
3451
|
-
return /* @__PURE__ */
|
|
3452
|
-
/* @__PURE__ */
|
|
3453
|
-
/* @__PURE__ */
|
|
3454
|
-
/* @__PURE__ */
|
|
3475
|
+
return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", height: availableHeight, children: [
|
|
3476
|
+
/* @__PURE__ */ jsx21(Box20, { flexDirection: "row", justifyContent: "space-between", height: 1, marginBottom: 1, children: /* @__PURE__ */ jsxs20(Box20, { flexDirection: "row", gap: 1, children: [
|
|
3477
|
+
/* @__PURE__ */ jsx21(Text21, { bold: true, children: " Repositories" }),
|
|
3478
|
+
/* @__PURE__ */ jsx21(Text21, { color: "red", children: "(Error)" })
|
|
3455
3479
|
] }) }),
|
|
3456
|
-
/* @__PURE__ */
|
|
3457
|
-
/* @__PURE__ */
|
|
3458
|
-
/* @__PURE__ */
|
|
3480
|
+
/* @__PURE__ */ jsx21(Box20, { borderStyle: "single", borderColor: "red", paddingX: 1, paddingY: 1, marginX: 1, height: contentHeight + containerPadding + 2, flexDirection: "column", children: /* @__PURE__ */ jsx21(Box20, { height: contentHeight, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", alignItems: "center", children: [
|
|
3481
|
+
/* @__PURE__ */ jsx21(Text21, { color: "red", children: error }),
|
|
3482
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx21(Text21, { color: "gray", dimColor: true, children: "Press R to retry \u2022 Ctrl+L to logout \u2022 Q to quit" }) })
|
|
3459
3483
|
] }) }) }),
|
|
3460
|
-
/* @__PURE__ */
|
|
3484
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, paddingX: 1, children: /* @__PURE__ */ jsx21(Text21, { color: "gray", children: "Press R to retry \u2022 Ctrl+L to logout \u2022 Q to quit" }) })
|
|
3461
3485
|
] });
|
|
3462
3486
|
}
|
|
3463
3487
|
if (loading && items.length === 0 || sortingLoading) {
|
|
3464
|
-
return /* @__PURE__ */
|
|
3465
|
-
/* @__PURE__ */
|
|
3466
|
-
/* @__PURE__ */
|
|
3467
|
-
/* @__PURE__ */
|
|
3488
|
+
return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", height: availableHeight, children: [
|
|
3489
|
+
/* @__PURE__ */ jsx21(Box20, { flexDirection: "row", justifyContent: "space-between", height: 1, marginBottom: 1, children: /* @__PURE__ */ jsxs20(Box20, { flexDirection: "row", gap: 1, children: [
|
|
3490
|
+
/* @__PURE__ */ jsx21(Text21, { bold: true, children: " Repositories" }),
|
|
3491
|
+
/* @__PURE__ */ jsx21(Text21, { color: "gray", children: "(Loading...)" })
|
|
3468
3492
|
] }) }),
|
|
3469
|
-
/* @__PURE__ */
|
|
3470
|
-
/* @__PURE__ */
|
|
3471
|
-
/* @__PURE__ */
|
|
3472
|
-
/* @__PURE__ */
|
|
3493
|
+
/* @__PURE__ */ jsx21(Box20, { borderStyle: "single", borderColor: "yellow", paddingX: 1, paddingY: 1, marginX: 1, height: contentHeight + containerPadding + 2, flexDirection: "column", children: /* @__PURE__ */ jsx21(Box20, { height: contentHeight, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsx21(Box20, { flexDirection: "column", alignItems: "center", children: /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", alignItems: "center", children: [
|
|
3494
|
+
/* @__PURE__ */ jsxs20(Box20, { height: 1, flexDirection: "row", children: [
|
|
3495
|
+
/* @__PURE__ */ jsx21(Box20, { width: 2, flexShrink: 0, flexGrow: 0, children: /* @__PURE__ */ jsx21(Text21, { color: "cyan", children: /* @__PURE__ */ jsx21(SlowSpinner, {}) }) }),
|
|
3496
|
+
/* @__PURE__ */ jsx21(Text21, { color: "cyan", children: refreshing ? "Refreshing..." : sortingLoading ? "Applying sort..." : "Loading repositories..." })
|
|
3473
3497
|
] }),
|
|
3474
|
-
/* @__PURE__ */
|
|
3498
|
+
/* @__PURE__ */ jsx21(Box20, { height: 1, marginTop: 1, children: /* @__PURE__ */ jsx21(Text21, { color: "gray", children: refreshing ? "Fetching latest repository data" : sortingLoading ? `Sorting by ${sortKey} (${sortDir === "asc" ? "ascending" : "descending"})` : "Fetching your GitHub repositories" }) })
|
|
3475
3499
|
] }) }) }) }),
|
|
3476
|
-
/* @__PURE__ */
|
|
3500
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, paddingX: 1, children: /* @__PURE__ */ jsx21(Text21, { color: "gray", children: "Please wait..." }) })
|
|
3477
3501
|
] });
|
|
3478
3502
|
}
|
|
3479
|
-
return /* @__PURE__ */
|
|
3503
|
+
return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", height: availableHeight, children: [
|
|
3480
3504
|
headerBar,
|
|
3481
|
-
showSponsorReminder && /* @__PURE__ */
|
|
3482
|
-
/* @__PURE__ */
|
|
3483
|
-
/* @__PURE__ */
|
|
3484
|
-
/* @__PURE__ */
|
|
3505
|
+
showSponsorReminder && /* @__PURE__ */ jsx21(Box20, { marginX: 1, marginBottom: 1, children: /* @__PURE__ */ jsx21(Box20, { borderStyle: "single", borderColor: "yellow", paddingX: 2, paddingY: 1, children: /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", alignItems: "center", children: [
|
|
3506
|
+
/* @__PURE__ */ jsx21(Text21, { color: "yellow", children: "\u{1F49A} Thanks for using gh-manager-cli!" }),
|
|
3507
|
+
/* @__PURE__ */ jsx21(Text21, { color: "gray", children: "Your support helps craft more open-source tools" }),
|
|
3508
|
+
/* @__PURE__ */ jsx21(Text21, { color: "cyan", children: "\u{1F496} github.com/sponsors/wiiiimm" })
|
|
3485
3509
|
] }) }) }),
|
|
3486
|
-
/* @__PURE__ */
|
|
3510
|
+
/* @__PURE__ */ jsx21(Box20, { borderStyle: "single", borderColor: modalOpen ? theme.muted : theme.warning, paddingX: 1, paddingY: 1, marginX: 1, height: contentHeight + containerPadding + 2, flexDirection: "column", children: deleteMode && deleteTarget ? (
|
|
3487
3511
|
// Centered modal; hide list content while modal is open
|
|
3488
|
-
/* @__PURE__ */
|
|
3489
|
-
/* @__PURE__ */
|
|
3490
|
-
/* @__PURE__ */
|
|
3491
|
-
/* @__PURE__ */
|
|
3512
|
+
/* @__PURE__ */ jsx21(Box20, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 3, paddingY: 2, width: Math.min(terminalWidth - 8, 80), children: [
|
|
3513
|
+
/* @__PURE__ */ jsx21(Text21, { bold: true, children: "Delete Confirmation" }),
|
|
3514
|
+
/* @__PURE__ */ jsx21(Text21, { color: "red", children: "\u26A0\uFE0F Delete repository?" }),
|
|
3515
|
+
/* @__PURE__ */ jsx21(Box20, { height: 2, children: /* @__PURE__ */ jsx21(Text21, { children: " " }) }),
|
|
3492
3516
|
(() => {
|
|
3493
3517
|
const langName = deleteTarget.primaryLanguage?.name || "";
|
|
3494
3518
|
const langColor = deleteTarget.primaryLanguage?.color || "#666666";
|
|
@@ -3500,19 +3524,19 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3500
3524
|
let line2 = "";
|
|
3501
3525
|
if (langName) line2 += chalk15.hex(langColor)("\u25CF ") + tc.muted(`${langName} `);
|
|
3502
3526
|
line2 += tc.muted(`\u2605 ${deleteTarget.stargazerCount} \u2442 ${deleteTarget.forkCount} Updated ${formatDate(deleteTarget.updatedAt)}`);
|
|
3503
|
-
return /* @__PURE__ */
|
|
3504
|
-
/* @__PURE__ */
|
|
3505
|
-
/* @__PURE__ */
|
|
3527
|
+
return /* @__PURE__ */ jsxs20(Fragment9, { children: [
|
|
3528
|
+
/* @__PURE__ */ jsx21(Text21, { children: line1 }),
|
|
3529
|
+
/* @__PURE__ */ jsx21(Text21, { children: line2 })
|
|
3506
3530
|
] });
|
|
3507
3531
|
})(),
|
|
3508
|
-
/* @__PURE__ */
|
|
3532
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsxs20(Text21, { children: [
|
|
3509
3533
|
"Type ",
|
|
3510
|
-
/* @__PURE__ */
|
|
3534
|
+
/* @__PURE__ */ jsx21(Text21, { color: "yellow", bold: true, children: deleteCode }),
|
|
3511
3535
|
" to confirm."
|
|
3512
3536
|
] }) }),
|
|
3513
|
-
!deleteConfirmStage && /* @__PURE__ */
|
|
3514
|
-
/* @__PURE__ */
|
|
3515
|
-
/* @__PURE__ */
|
|
3537
|
+
!deleteConfirmStage && /* @__PURE__ */ jsxs20(Box20, { marginTop: 1, children: [
|
|
3538
|
+
/* @__PURE__ */ jsx21(Text21, { children: "Confirm code: " }),
|
|
3539
|
+
/* @__PURE__ */ jsx21(
|
|
3516
3540
|
TextInput5,
|
|
3517
3541
|
{
|
|
3518
3542
|
value: typedCode,
|
|
@@ -3539,11 +3563,11 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3539
3563
|
}
|
|
3540
3564
|
)
|
|
3541
3565
|
] }),
|
|
3542
|
-
deleteConfirmStage && /* @__PURE__ */
|
|
3543
|
-
/* @__PURE__ */
|
|
3544
|
-
/* @__PURE__ */
|
|
3545
|
-
/* @__PURE__ */
|
|
3546
|
-
|
|
3566
|
+
deleteConfirmStage && /* @__PURE__ */ jsxs20(Box20, { marginTop: 1, flexDirection: "column", children: [
|
|
3567
|
+
/* @__PURE__ */ jsx21(Text21, { color: "red", children: "This action will permanently delete the repository. This cannot be undone." }),
|
|
3568
|
+
/* @__PURE__ */ jsxs20(Box20, { marginTop: 1, flexDirection: "row", justifyContent: "center", gap: 6, children: [
|
|
3569
|
+
/* @__PURE__ */ jsx21(
|
|
3570
|
+
Box20,
|
|
3547
3571
|
{
|
|
3548
3572
|
borderStyle: "round",
|
|
3549
3573
|
borderColor: "red",
|
|
@@ -3552,11 +3576,11 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3552
3576
|
alignItems: "center",
|
|
3553
3577
|
justifyContent: "center",
|
|
3554
3578
|
flexDirection: "column",
|
|
3555
|
-
children: /* @__PURE__ */
|
|
3579
|
+
children: /* @__PURE__ */ jsx21(Text21, { children: confirmFocus === "delete" ? chalk15.bgRed.white.bold(" Delete ") : tc.error.bold("Delete") })
|
|
3556
3580
|
}
|
|
3557
3581
|
),
|
|
3558
|
-
/* @__PURE__ */
|
|
3559
|
-
|
|
3582
|
+
/* @__PURE__ */ jsx21(
|
|
3583
|
+
Box20,
|
|
3560
3584
|
{
|
|
3561
3585
|
borderStyle: "round",
|
|
3562
3586
|
borderColor: confirmFocus === "cancel" ? "white" : "gray",
|
|
@@ -3565,16 +3589,16 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3565
3589
|
alignItems: "center",
|
|
3566
3590
|
justifyContent: "center",
|
|
3567
3591
|
flexDirection: "column",
|
|
3568
|
-
children: /* @__PURE__ */
|
|
3592
|
+
children: /* @__PURE__ */ jsx21(Text21, { children: confirmFocus === "cancel" ? tc.btnMuted(" Cancel ") : tc.muted.bold("Cancel") })
|
|
3569
3593
|
}
|
|
3570
3594
|
)
|
|
3571
3595
|
] }),
|
|
3572
|
-
/* @__PURE__ */
|
|
3596
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs20(Text21, { color: "gray", children: [
|
|
3573
3597
|
"Press Enter to ",
|
|
3574
3598
|
confirmFocus === "delete" ? "Delete" : "Cancel",
|
|
3575
3599
|
" | Y to Delete | C to Cancel"
|
|
3576
3600
|
] }) }),
|
|
3577
|
-
/* @__PURE__ */
|
|
3601
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx21(
|
|
3578
3602
|
TextInput5,
|
|
3579
3603
|
{
|
|
3580
3604
|
value: "",
|
|
@@ -3588,18 +3612,18 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3588
3612
|
}
|
|
3589
3613
|
) })
|
|
3590
3614
|
] }),
|
|
3591
|
-
deleteError && /* @__PURE__ */
|
|
3592
|
-
deleting && /* @__PURE__ */
|
|
3615
|
+
deleteError && /* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx21(Text21, { color: "magenta", children: deleteError }) }),
|
|
3616
|
+
deleting && /* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx21(Text21, { color: "yellow", children: "Deleting..." }) })
|
|
3593
3617
|
] }) })
|
|
3594
|
-
) : archiveMode && archiveTarget ? /* @__PURE__ */
|
|
3595
|
-
/* @__PURE__ */
|
|
3596
|
-
/* @__PURE__ */
|
|
3597
|
-
/* @__PURE__ */
|
|
3598
|
-
/* @__PURE__ */
|
|
3599
|
-
/* @__PURE__ */
|
|
3600
|
-
/* @__PURE__ */
|
|
3601
|
-
/* @__PURE__ */
|
|
3602
|
-
|
|
3618
|
+
) : archiveMode && archiveTarget ? /* @__PURE__ */ jsx21(Box20, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: archiveTarget.isArchived ? "green" : "yellow", paddingX: 3, paddingY: 2, width: Math.min(terminalWidth - 8, 80), children: [
|
|
3619
|
+
/* @__PURE__ */ jsx21(Text21, { bold: true, children: archiveTarget.isArchived ? "Unarchive Confirmation" : "Archive Confirmation" }),
|
|
3620
|
+
/* @__PURE__ */ jsx21(Text21, { color: archiveTarget.isArchived ? "green" : "yellow", children: archiveTarget.isArchived ? "\u21BA Unarchive repository?" : "\u26A0\uFE0F Archive repository?" }),
|
|
3621
|
+
/* @__PURE__ */ jsx21(Box20, { height: 1, children: /* @__PURE__ */ jsx21(Text21, { children: " " }) }),
|
|
3622
|
+
/* @__PURE__ */ jsx21(Text21, { children: archiveTarget.nameWithOwner }),
|
|
3623
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx21(Text21, { children: archiveTarget.isArchived ? "This will make the repository active again." : "This will make the repository read-only." }) }),
|
|
3624
|
+
/* @__PURE__ */ jsxs20(Box20, { marginTop: 1, flexDirection: "row", justifyContent: "center", gap: 6, children: [
|
|
3625
|
+
/* @__PURE__ */ jsx21(
|
|
3626
|
+
Box20,
|
|
3603
3627
|
{
|
|
3604
3628
|
borderStyle: "round",
|
|
3605
3629
|
borderColor: archiveTarget.isArchived ? "green" : "yellow",
|
|
@@ -3608,11 +3632,11 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3608
3632
|
alignItems: "center",
|
|
3609
3633
|
justifyContent: "center",
|
|
3610
3634
|
flexDirection: "column",
|
|
3611
|
-
children: /* @__PURE__ */
|
|
3635
|
+
children: /* @__PURE__ */ jsx21(Text21, { children: archiveFocus === "confirm" ? chalk15.bgGreen.white.bold(` ${archiveTarget.isArchived ? "Unarchive" : "Archive"} `) : (archiveTarget.isArchived ? tc.success : tc.warning).bold(archiveTarget.isArchived ? "Unarchive" : "Archive") })
|
|
3612
3636
|
}
|
|
3613
3637
|
),
|
|
3614
|
-
/* @__PURE__ */
|
|
3615
|
-
|
|
3638
|
+
/* @__PURE__ */ jsx21(
|
|
3639
|
+
Box20,
|
|
3616
3640
|
{
|
|
3617
3641
|
borderStyle: "round",
|
|
3618
3642
|
borderColor: archiveFocus === "cancel" ? "white" : "gray",
|
|
@@ -3621,18 +3645,18 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3621
3645
|
alignItems: "center",
|
|
3622
3646
|
justifyContent: "center",
|
|
3623
3647
|
flexDirection: "column",
|
|
3624
|
-
children: /* @__PURE__ */
|
|
3648
|
+
children: /* @__PURE__ */ jsx21(Text21, { children: archiveFocus === "cancel" ? tc.btnMuted(" Cancel ") : tc.muted.bold("Cancel") })
|
|
3625
3649
|
}
|
|
3626
3650
|
)
|
|
3627
3651
|
] }),
|
|
3628
|
-
/* @__PURE__ */
|
|
3652
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs20(Text21, { color: theme.muted, children: [
|
|
3629
3653
|
"Press Enter to ",
|
|
3630
3654
|
archiveFocus === "confirm" ? archiveTarget.isArchived ? "Unarchive" : "Archive" : "Cancel",
|
|
3631
3655
|
" | Y to ",
|
|
3632
3656
|
archiveTarget.isArchived ? "Unarchive" : "Archive",
|
|
3633
3657
|
" | C to Cancel"
|
|
3634
3658
|
] }) }),
|
|
3635
|
-
/* @__PURE__ */
|
|
3659
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx21(
|
|
3636
3660
|
TextInput5,
|
|
3637
3661
|
{
|
|
3638
3662
|
value: "",
|
|
@@ -3647,21 +3671,34 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3647
3671
|
}
|
|
3648
3672
|
}
|
|
3649
3673
|
) }),
|
|
3650
|
-
archiveError && /* @__PURE__ */
|
|
3651
|
-
archiving && /* @__PURE__ */
|
|
3652
|
-
] }) }) : syncMode && syncTarget ? /* @__PURE__ */
|
|
3653
|
-
/* @__PURE__ */
|
|
3654
|
-
/* @__PURE__ */
|
|
3655
|
-
/* @__PURE__ */
|
|
3656
|
-
/* @__PURE__ */
|
|
3657
|
-
syncTarget.parent && /* @__PURE__ */
|
|
3674
|
+
archiveError && /* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx21(Text21, { color: "magenta", children: archiveError }) }),
|
|
3675
|
+
archiving && /* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx21(Text21, { color: "yellow", children: archiveTarget.isArchived ? "Unarchiving..." : "Archiving..." }) })
|
|
3676
|
+
] }) }) : syncMode && syncTarget ? /* @__PURE__ */ jsx21(Box20, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: "blue", paddingX: 3, paddingY: 2, width: Math.min(terminalWidth - 8, 80), children: [
|
|
3677
|
+
/* @__PURE__ */ jsx21(Text21, { bold: true, children: "Sync Fork Confirmation" }),
|
|
3678
|
+
/* @__PURE__ */ jsx21(Text21, { color: "blue", children: "\u27F2 Sync fork with upstream?" }),
|
|
3679
|
+
/* @__PURE__ */ jsx21(Box20, { height: 1, children: /* @__PURE__ */ jsx21(Text21, { children: " " }) }),
|
|
3680
|
+
/* @__PURE__ */ jsx21(Text21, { children: syncTarget.nameWithOwner }),
|
|
3681
|
+
syncTarget.parent && /* @__PURE__ */ jsxs20(Text21, { color: "gray", children: [
|
|
3658
3682
|
"Upstream: ",
|
|
3659
3683
|
syncTarget.parent.nameWithOwner
|
|
3660
3684
|
] }),
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3685
|
+
(() => {
|
|
3686
|
+
const hasData = syncTarget.isFork && syncTarget.parent && syncTarget.defaultBranchRef?.target?.history && syncTarget.parent.defaultBranchRef?.target?.history;
|
|
3687
|
+
if (!hasData) return null;
|
|
3688
|
+
const forkC = syncTarget.defaultBranchRef.target.history.totalCount;
|
|
3689
|
+
const parentC = syncTarget.parent.defaultBranchRef.target.history.totalCount;
|
|
3690
|
+
const behind = Math.max(0, parentC - forkC);
|
|
3691
|
+
const ahead = Math.max(0, forkC - parentC);
|
|
3692
|
+
const parts = [];
|
|
3693
|
+
if (ahead > 0) parts.push(chalk15.green(`${ahead} ahead`));
|
|
3694
|
+
if (behind > 0) parts.push(chalk15.yellow(`${behind} behind`));
|
|
3695
|
+
const statusText = parts.length === 0 ? chalk15.green("Your fork is up to date with upstream.") : `This fork is ${parts.join(", ")} of upstream.`;
|
|
3696
|
+
return /* @__PURE__ */ jsx21(Text21, { children: statusText });
|
|
3697
|
+
})(),
|
|
3698
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx21(Text21, { children: "This will merge upstream changes into your fork." }) }),
|
|
3699
|
+
/* @__PURE__ */ jsxs20(Box20, { marginTop: 1, flexDirection: "row", justifyContent: "center", gap: 6, children: [
|
|
3700
|
+
/* @__PURE__ */ jsx21(
|
|
3701
|
+
Box20,
|
|
3665
3702
|
{
|
|
3666
3703
|
borderStyle: "round",
|
|
3667
3704
|
borderColor: "blue",
|
|
@@ -3670,11 +3707,11 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3670
3707
|
alignItems: "center",
|
|
3671
3708
|
justifyContent: "center",
|
|
3672
3709
|
flexDirection: "column",
|
|
3673
|
-
children: /* @__PURE__ */
|
|
3710
|
+
children: /* @__PURE__ */ jsx21(Text21, { children: syncFocus === "confirm" ? tc.btnPrimary(" Sync ") : tc.primary.bold("Sync") })
|
|
3674
3711
|
}
|
|
3675
3712
|
),
|
|
3676
|
-
/* @__PURE__ */
|
|
3677
|
-
|
|
3713
|
+
/* @__PURE__ */ jsx21(
|
|
3714
|
+
Box20,
|
|
3678
3715
|
{
|
|
3679
3716
|
borderStyle: "round",
|
|
3680
3717
|
borderColor: syncFocus === "cancel" ? "white" : "gray",
|
|
@@ -3683,16 +3720,16 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3683
3720
|
alignItems: "center",
|
|
3684
3721
|
justifyContent: "center",
|
|
3685
3722
|
flexDirection: "column",
|
|
3686
|
-
children: /* @__PURE__ */
|
|
3723
|
+
children: /* @__PURE__ */ jsx21(Text21, { children: syncFocus === "cancel" ? tc.btnMuted(" Cancel ") : tc.muted.bold("Cancel") })
|
|
3687
3724
|
}
|
|
3688
3725
|
)
|
|
3689
3726
|
] }),
|
|
3690
|
-
/* @__PURE__ */
|
|
3727
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs20(Text21, { color: theme.muted, children: [
|
|
3691
3728
|
"Press Enter to ",
|
|
3692
3729
|
syncFocus === "confirm" ? "Sync" : "Cancel",
|
|
3693
3730
|
" | Y to Sync | C to Cancel"
|
|
3694
3731
|
] }) }),
|
|
3695
|
-
/* @__PURE__ */
|
|
3732
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx21(
|
|
3696
3733
|
TextInput5,
|
|
3697
3734
|
{
|
|
3698
3735
|
value: "",
|
|
@@ -3707,14 +3744,14 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3707
3744
|
}
|
|
3708
3745
|
}
|
|
3709
3746
|
) }),
|
|
3710
|
-
syncError && /* @__PURE__ */
|
|
3711
|
-
syncing && /* @__PURE__ */
|
|
3712
|
-
] }) }) : logoutMode ? /* @__PURE__ */
|
|
3713
|
-
/* @__PURE__ */
|
|
3714
|
-
/* @__PURE__ */
|
|
3715
|
-
/* @__PURE__ */
|
|
3716
|
-
/* @__PURE__ */
|
|
3717
|
-
|
|
3747
|
+
syncError && /* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx21(Text21, { color: theme.error, children: syncError }) }),
|
|
3748
|
+
syncing && /* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx21(Text21, { color: theme.warning, children: "Syncing..." }) })
|
|
3749
|
+
] }) }) : logoutMode ? /* @__PURE__ */ jsx21(Box20, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.primary, paddingX: 3, paddingY: 2, width: Math.min(terminalWidth - 8, 80), children: [
|
|
3750
|
+
/* @__PURE__ */ jsx21(Text21, { bold: true, children: "Logout Confirmation" }),
|
|
3751
|
+
/* @__PURE__ */ jsx21(Text21, { color: theme.primary, children: "Are you sure you want to log out?" }),
|
|
3752
|
+
/* @__PURE__ */ jsxs20(Box20, { marginTop: 1, flexDirection: "row", justifyContent: "center", gap: 6, children: [
|
|
3753
|
+
/* @__PURE__ */ jsx21(
|
|
3754
|
+
Box20,
|
|
3718
3755
|
{
|
|
3719
3756
|
borderStyle: "round",
|
|
3720
3757
|
borderColor: theme.primary,
|
|
@@ -3723,11 +3760,11 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3723
3760
|
alignItems: "center",
|
|
3724
3761
|
justifyContent: "center",
|
|
3725
3762
|
flexDirection: "column",
|
|
3726
|
-
children: /* @__PURE__ */
|
|
3763
|
+
children: /* @__PURE__ */ jsx21(Text21, { children: logoutFocus === "confirm" ? tc.btnPrimary(" Logout ") : tc.primary.bold("Logout") })
|
|
3727
3764
|
}
|
|
3728
3765
|
),
|
|
3729
|
-
/* @__PURE__ */
|
|
3730
|
-
|
|
3766
|
+
/* @__PURE__ */ jsx21(
|
|
3767
|
+
Box20,
|
|
3731
3768
|
{
|
|
3732
3769
|
borderStyle: "round",
|
|
3733
3770
|
borderColor: logoutFocus === "cancel" ? "white" : theme.muted,
|
|
@@ -3736,16 +3773,16 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3736
3773
|
alignItems: "center",
|
|
3737
3774
|
justifyContent: "center",
|
|
3738
3775
|
flexDirection: "column",
|
|
3739
|
-
children: /* @__PURE__ */
|
|
3776
|
+
children: /* @__PURE__ */ jsx21(Text21, { children: logoutFocus === "cancel" ? tc.btnMuted(" Cancel ") : tc.muted.bold("Cancel") })
|
|
3740
3777
|
}
|
|
3741
3778
|
)
|
|
3742
3779
|
] }),
|
|
3743
|
-
/* @__PURE__ */
|
|
3780
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs20(Text21, { color: theme.muted, children: [
|
|
3744
3781
|
"Press Enter to ",
|
|
3745
3782
|
logoutFocus === "confirm" ? "Logout" : "Cancel",
|
|
3746
3783
|
" | Y to Logout | C to Cancel"
|
|
3747
3784
|
] }) })
|
|
3748
|
-
] }) }) : orgSwitcherOpen ? /* @__PURE__ */
|
|
3785
|
+
] }) }) : orgSwitcherOpen ? /* @__PURE__ */ jsx21(Box20, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx21(
|
|
3749
3786
|
OrgSwitcher,
|
|
3750
3787
|
{
|
|
3751
3788
|
token,
|
|
@@ -3753,45 +3790,45 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3753
3790
|
onSelect: handleOrgContextChange,
|
|
3754
3791
|
onClose: () => setOrgSwitcherOpen(false)
|
|
3755
3792
|
}
|
|
3756
|
-
) }) : infoMode ? /* @__PURE__ */
|
|
3793
|
+
) }) : infoMode ? /* @__PURE__ */ jsx21(Box20, { height: contentHeight, alignItems: "center", justifyContent: "center", children: (() => {
|
|
3757
3794
|
const repo = infoRepo || visibleItems[cursor];
|
|
3758
|
-
if (!repo) return /* @__PURE__ */
|
|
3795
|
+
if (!repo) return /* @__PURE__ */ jsx21(Text21, { color: theme.error, children: "No repository selected." });
|
|
3759
3796
|
const langName = repo.primaryLanguage?.name || "N/A";
|
|
3760
3797
|
const langColor = repo.primaryLanguage?.color || "#666666";
|
|
3761
|
-
return /* @__PURE__ */
|
|
3762
|
-
/* @__PURE__ */
|
|
3798
|
+
return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.internal, paddingX: 3, paddingY: 2, width: Math.min(terminalWidth - 8, 90), children: [
|
|
3799
|
+
/* @__PURE__ */ jsxs20(Text21, { bold: true, children: [
|
|
3763
3800
|
"Repository Info ",
|
|
3764
3801
|
infoRepo ? tc.muted("(cached)") : ""
|
|
3765
3802
|
] }),
|
|
3766
|
-
/* @__PURE__ */
|
|
3767
|
-
/* @__PURE__ */
|
|
3768
|
-
repo.description && /* @__PURE__ */
|
|
3769
|
-
/* @__PURE__ */
|
|
3770
|
-
/* @__PURE__ */
|
|
3803
|
+
/* @__PURE__ */ jsx21(Box20, { height: 1, children: /* @__PURE__ */ jsx21(Text21, { children: " " }) }),
|
|
3804
|
+
/* @__PURE__ */ jsx21(Text21, { children: tc.text.bold(repo.nameWithOwner) }),
|
|
3805
|
+
repo.description && /* @__PURE__ */ jsx21(Text21, { color: theme.muted, children: repo.description }),
|
|
3806
|
+
/* @__PURE__ */ jsx21(Box20, { height: 1, children: /* @__PURE__ */ jsx21(Text21, { children: " " }) }),
|
|
3807
|
+
/* @__PURE__ */ jsxs20(Text21, { children: [
|
|
3771
3808
|
repo.visibility === "PRIVATE" ? tc.private("Private") : repo.visibility === "INTERNAL" ? tc.internal("Internal") : tc.success("Public"),
|
|
3772
3809
|
repo.isArchived ? tc.archived(" Archived") : "",
|
|
3773
3810
|
repo.isFork ? tc.fork(" Fork") : ""
|
|
3774
3811
|
] }),
|
|
3775
|
-
/* @__PURE__ */
|
|
3776
|
-
/* @__PURE__ */
|
|
3812
|
+
/* @__PURE__ */ jsx21(Text21, { children: tc.muted(`\u2605 ${repo.stargazerCount} \u2442 ${repo.forkCount}`) }),
|
|
3813
|
+
/* @__PURE__ */ jsxs20(Text21, { children: [
|
|
3777
3814
|
chalk15.hex(langColor)(`\u25CF `),
|
|
3778
3815
|
tc.muted(`${langName}`)
|
|
3779
3816
|
] }),
|
|
3780
|
-
/* @__PURE__ */
|
|
3817
|
+
/* @__PURE__ */ jsxs20(Text21, { color: theme.muted, children: [
|
|
3781
3818
|
"Updated: ",
|
|
3782
3819
|
formatDate(repo.updatedAt),
|
|
3783
3820
|
" \u2022 Pushed: ",
|
|
3784
3821
|
formatDate(repo.pushedAt)
|
|
3785
3822
|
] }),
|
|
3786
|
-
/* @__PURE__ */
|
|
3823
|
+
/* @__PURE__ */ jsxs20(Text21, { color: theme.muted, children: [
|
|
3787
3824
|
"Size: ",
|
|
3788
3825
|
repo.diskUsage,
|
|
3789
3826
|
" KB"
|
|
3790
3827
|
] }),
|
|
3791
|
-
/* @__PURE__ */
|
|
3792
|
-
/* @__PURE__ */
|
|
3828
|
+
/* @__PURE__ */ jsx21(Box20, { height: 1, children: /* @__PURE__ */ jsx21(Text21, { children: " " }) }),
|
|
3829
|
+
/* @__PURE__ */ jsx21(Text21, { color: theme.muted, children: "Press Esc or I to close" })
|
|
3793
3830
|
] });
|
|
3794
|
-
})() }) : archiveFilterMode ? /* @__PURE__ */
|
|
3831
|
+
})() }) : archiveFilterMode ? /* @__PURE__ */ jsx21(Box20, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx21(
|
|
3795
3832
|
ArchiveFilterModal,
|
|
3796
3833
|
{
|
|
3797
3834
|
currentFilter: archiveFilter,
|
|
@@ -3804,7 +3841,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3804
3841
|
onCancel: () => setArchiveFilterMode(false),
|
|
3805
3842
|
theme
|
|
3806
3843
|
}
|
|
3807
|
-
) }) : visibilityMode ? /* @__PURE__ */
|
|
3844
|
+
) }) : visibilityMode ? /* @__PURE__ */ jsx21(Box20, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx21(
|
|
3808
3845
|
VisibilityModal,
|
|
3809
3846
|
{
|
|
3810
3847
|
currentFilter: visibilityFilter,
|
|
@@ -3818,7 +3855,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3818
3855
|
onCancel: () => setVisibilityMode(false),
|
|
3819
3856
|
theme
|
|
3820
3857
|
}
|
|
3821
|
-
) }) : sortMode ? /* @__PURE__ */
|
|
3858
|
+
) }) : sortMode ? /* @__PURE__ */ jsx21(Box20, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx21(
|
|
3822
3859
|
SortModal,
|
|
3823
3860
|
{
|
|
3824
3861
|
currentSort: sortKey,
|
|
@@ -3831,7 +3868,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3831
3868
|
onCancel: () => setSortMode(false),
|
|
3832
3869
|
theme
|
|
3833
3870
|
}
|
|
3834
|
-
) }) : sortDirectionMode ? /* @__PURE__ */
|
|
3871
|
+
) }) : sortDirectionMode ? /* @__PURE__ */ jsx21(Box20, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx21(
|
|
3835
3872
|
SortDirectionModal,
|
|
3836
3873
|
{
|
|
3837
3874
|
currentDirection: sortDir,
|
|
@@ -3845,7 +3882,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3845
3882
|
onCancel: () => setSortDirectionMode(false),
|
|
3846
3883
|
theme
|
|
3847
3884
|
}
|
|
3848
|
-
) }) : changeVisibilityMode && changeVisibilityTarget ? /* @__PURE__ */
|
|
3885
|
+
) }) : changeVisibilityMode && changeVisibilityTarget ? /* @__PURE__ */ jsx21(Box20, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx21(
|
|
3849
3886
|
ChangeVisibilityModal,
|
|
3850
3887
|
{
|
|
3851
3888
|
isOpen: changeVisibilityMode,
|
|
@@ -3859,7 +3896,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3859
3896
|
error: changeVisibilityError,
|
|
3860
3897
|
theme
|
|
3861
3898
|
}
|
|
3862
|
-
) }) : renameMode && renameTarget ? /* @__PURE__ */
|
|
3899
|
+
) }) : renameMode && renameTarget ? /* @__PURE__ */ jsx21(Box20, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx21(
|
|
3863
3900
|
RenameModal,
|
|
3864
3901
|
{
|
|
3865
3902
|
repo: renameTarget,
|
|
@@ -3867,7 +3904,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3867
3904
|
onCancel: closeRenameModal,
|
|
3868
3905
|
theme
|
|
3869
3906
|
}
|
|
3870
|
-
) }) : copyUrlMode ? /* @__PURE__ */
|
|
3907
|
+
) }) : copyUrlMode ? /* @__PURE__ */ jsx21(Box20, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx21(
|
|
3871
3908
|
CopyUrlModal,
|
|
3872
3909
|
{
|
|
3873
3910
|
repo: copyUrlTarget,
|
|
@@ -3876,7 +3913,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3876
3913
|
onCopy: handleCopyUrl,
|
|
3877
3914
|
theme
|
|
3878
3915
|
}
|
|
3879
|
-
) }) : unstarMode && unstarTarget ? /* @__PURE__ */
|
|
3916
|
+
) }) : unstarMode && unstarTarget ? /* @__PURE__ */ jsx21(Box20, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx21(
|
|
3880
3917
|
UnstarModal,
|
|
3881
3918
|
{
|
|
3882
3919
|
visible: unstarMode,
|
|
@@ -3887,7 +3924,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3887
3924
|
error: unstarError,
|
|
3888
3925
|
theme
|
|
3889
3926
|
}
|
|
3890
|
-
) }) : starMode && starTarget ? /* @__PURE__ */
|
|
3927
|
+
) }) : starMode && starTarget ? /* @__PURE__ */ jsx21(Box20, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx21(
|
|
3891
3928
|
StarModal,
|
|
3892
3929
|
{
|
|
3893
3930
|
visible: starMode,
|
|
@@ -3899,8 +3936,23 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3899
3936
|
error: starError,
|
|
3900
3937
|
theme
|
|
3901
3938
|
}
|
|
3902
|
-
) }) : /* @__PURE__ */
|
|
3903
|
-
|
|
3939
|
+
) }) : openInBrowserMode && openInBrowserTarget ? /* @__PURE__ */ jsx21(Box20, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx21(
|
|
3940
|
+
OpenInBrowserModal,
|
|
3941
|
+
{
|
|
3942
|
+
repo: openInBrowserTarget,
|
|
3943
|
+
onOpen: (url) => {
|
|
3944
|
+
openInBrowser(url);
|
|
3945
|
+
setOpenInBrowserMode(false);
|
|
3946
|
+
setOpenInBrowserTarget(null);
|
|
3947
|
+
},
|
|
3948
|
+
onCancel: () => {
|
|
3949
|
+
setOpenInBrowserMode(false);
|
|
3950
|
+
setOpenInBrowserTarget(null);
|
|
3951
|
+
},
|
|
3952
|
+
theme
|
|
3953
|
+
}
|
|
3954
|
+
) }) : /* @__PURE__ */ jsxs20(Fragment9, { children: [
|
|
3955
|
+
/* @__PURE__ */ jsx21(
|
|
3904
3956
|
RepoListHeader,
|
|
3905
3957
|
{
|
|
3906
3958
|
ownerContext,
|
|
@@ -3908,8 +3960,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3908
3960
|
sortDir,
|
|
3909
3961
|
forkTracking,
|
|
3910
3962
|
filter,
|
|
3911
|
-
|
|
3912
|
-
searchLoading,
|
|
3963
|
+
filterActive,
|
|
3913
3964
|
visibilityFilter,
|
|
3914
3965
|
archiveFilter,
|
|
3915
3966
|
isEnterprise: isEnterpriseOrg,
|
|
@@ -3917,56 +3968,30 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3917
3968
|
theme
|
|
3918
3969
|
}
|
|
3919
3970
|
),
|
|
3920
|
-
filterMode && /* @__PURE__ */
|
|
3921
|
-
/* @__PURE__ */
|
|
3922
|
-
/* @__PURE__ */
|
|
3971
|
+
filterMode && /* @__PURE__ */ jsxs20(Box20, { marginBottom: 1, children: [
|
|
3972
|
+
/* @__PURE__ */ jsx21(Text21, { children: "Search: " }),
|
|
3973
|
+
/* @__PURE__ */ jsx21(
|
|
3923
3974
|
TextInput5,
|
|
3924
3975
|
{
|
|
3925
3976
|
value: filter,
|
|
3926
3977
|
onChange: (val) => {
|
|
3927
|
-
addDebugMessage(`[onChange] val="${val}"`);
|
|
3928
3978
|
setFilter(val);
|
|
3929
|
-
const q = (val || "").trim();
|
|
3930
|
-
addDebugMessage(`[onChange] trimmed="${q}", len=${q.length}`);
|
|
3931
|
-
if (q.length >= 3) {
|
|
3932
|
-
addDebugMessage(`[onChange] Triggering search for "${q}"`);
|
|
3933
|
-
let policy = "cache-first";
|
|
3934
|
-
try {
|
|
3935
|
-
const key = makeSearchKey({
|
|
3936
|
-
viewer: viewerLogin || "unknown",
|
|
3937
|
-
q,
|
|
3938
|
-
sortKey,
|
|
3939
|
-
sortDir,
|
|
3940
|
-
pageSize: PAGE_SIZE,
|
|
3941
|
-
forkTracking
|
|
3942
|
-
});
|
|
3943
|
-
policy = isFresh(key, 90 * 1e3) ? "cache-first" : "network-only";
|
|
3944
|
-
} catch {
|
|
3945
|
-
}
|
|
3946
|
-
addDebugMessage(`[onChange] Calling fetchSearchPage with q="${q}"`);
|
|
3947
|
-
fetchSearchPage(null, true, policy, q);
|
|
3948
|
-
} else {
|
|
3949
|
-
setSearchItems([]);
|
|
3950
|
-
setSearchEndCursor(null);
|
|
3951
|
-
setSearchHasNextPage(false);
|
|
3952
|
-
setSearchTotalCount(0);
|
|
3953
|
-
}
|
|
3954
3979
|
},
|
|
3955
3980
|
onSubmit: () => {
|
|
3956
3981
|
setFilterMode(false);
|
|
3957
3982
|
},
|
|
3958
|
-
placeholder: starsMode ? "Type to filter starred repositories..." : "Type to search
|
|
3983
|
+
placeholder: starsMode ? "Type to filter starred repositories..." : "Type to fuzzy-search repositories..."
|
|
3959
3984
|
}
|
|
3960
3985
|
)
|
|
3961
3986
|
] }),
|
|
3962
|
-
/* @__PURE__ */
|
|
3963
|
-
|
|
3987
|
+
/* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", height: listHeight, children: [
|
|
3988
|
+
visibleItems.slice(windowed.start, windowed.end).map((repo, i) => {
|
|
3964
3989
|
const idx = windowed.start + i;
|
|
3965
|
-
return /* @__PURE__ */
|
|
3990
|
+
return /* @__PURE__ */ jsx21(
|
|
3966
3991
|
RepoRow,
|
|
3967
3992
|
{
|
|
3968
3993
|
repo,
|
|
3969
|
-
selected: filterMode
|
|
3994
|
+
selected: filterMode ? false : idx === cursor,
|
|
3970
3995
|
index: idx + 1,
|
|
3971
3996
|
maxWidth: terminalWidth - 6,
|
|
3972
3997
|
spacingLines,
|
|
@@ -3977,46 +4002,55 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
3977
4002
|
repo.nameWithOwner
|
|
3978
4003
|
);
|
|
3979
4004
|
}),
|
|
3980
|
-
loadingMore && hasNextPage && !starsMode &&
|
|
3981
|
-
/* @__PURE__ */
|
|
3982
|
-
/* @__PURE__ */
|
|
4005
|
+
loadingMore && hasNextPage && !starsMode && /* @__PURE__ */ jsx21(Box20, { justifyContent: "center", alignItems: "center", marginTop: 1, children: /* @__PURE__ */ jsxs20(Box20, { flexDirection: "row", children: [
|
|
4006
|
+
/* @__PURE__ */ jsx21(Box20, { width: 2, flexShrink: 0, flexGrow: 0, marginRight: 1, children: /* @__PURE__ */ jsx21(Text21, { color: "cyan", children: /* @__PURE__ */ jsx21(SlowSpinner, {}) }) }),
|
|
4007
|
+
/* @__PURE__ */ jsxs20(Text21, { color: "cyan", children: [
|
|
3983
4008
|
"Loading repositories\u2026 ",
|
|
3984
4009
|
totalCount > 0 ? `(${items.length}/${totalCount})` : `(${items.length})`
|
|
3985
4010
|
] })
|
|
3986
4011
|
] }) }),
|
|
3987
|
-
loadingMore && hasNextPage &&
|
|
3988
|
-
/* @__PURE__ */
|
|
3989
|
-
/* @__PURE__ */
|
|
4012
|
+
loadingMore && hasNextPage && starsMode && /* @__PURE__ */ jsx21(Box20, { justifyContent: "center", alignItems: "center", marginTop: 1, children: /* @__PURE__ */ jsxs20(Box20, { flexDirection: "row", children: [
|
|
4013
|
+
/* @__PURE__ */ jsx21(Box20, { width: 2, flexShrink: 0, flexGrow: 0, marginRight: 1, children: /* @__PURE__ */ jsx21(Text21, { color: "cyan", children: /* @__PURE__ */ jsx21(SlowSpinner, {}) }) }),
|
|
4014
|
+
/* @__PURE__ */ jsx21(Text21, { color: "cyan", children: "Loading more repositories..." })
|
|
3990
4015
|
] }) }),
|
|
3991
|
-
|
|
4016
|
+
filterActive && hasNextPage && !starsMode && /* @__PURE__ */ jsx21(Box20, { justifyContent: "center", alignItems: "center", marginTop: 1, children: /* @__PURE__ */ jsxs20(Text21, { color: "yellow", dimColor: true, children: [
|
|
4017
|
+
"Still loading repos (",
|
|
4018
|
+
items.length,
|
|
4019
|
+
"/",
|
|
4020
|
+
totalCount > 0 ? totalCount : "?",
|
|
4021
|
+
") \u2014 fuzzy results may be incomplete"
|
|
4022
|
+
] }) }),
|
|
4023
|
+
!loading && visibleItems.length === 0 && !(filterActive && hasNextPage && !starsMode) && /* @__PURE__ */ jsx21(Box20, { justifyContent: "center", alignItems: "center", flexGrow: 1, children: /* @__PURE__ */ jsx21(Text21, { color: "gray", dimColor: true, children: filter ? "No repositories match your search" : "No repositories found" }) })
|
|
3992
4024
|
] })
|
|
3993
4025
|
] }) }),
|
|
3994
|
-
/* @__PURE__ */
|
|
3995
|
-
/* @__PURE__ */
|
|
3996
|
-
/* @__PURE__ */
|
|
3997
|
-
"/ Search
|
|
4026
|
+
/* @__PURE__ */ jsxs20(Box20, { marginTop: 1, paddingX: 1, flexDirection: "column", children: [
|
|
4027
|
+
/* @__PURE__ */ jsx21(Box20, { width: terminalWidth, justifyContent: "center", children: /* @__PURE__ */ jsx21(Text21, { color: theme.muted, dimColor: modalOpen ? true : void 0, children: "\u2191\u2193 Navigate \u2022 Ctrl+G Top \u2022 G Bottom \u2022 \u23CE/O Open \u2022 R Refresh" }) }),
|
|
4028
|
+
/* @__PURE__ */ jsx21(Box20, { width: terminalWidth, justifyContent: "center", children: /* @__PURE__ */ jsxs20(Text21, { color: theme.muted, dimColor: modalOpen ? true : void 0, children: [
|
|
4029
|
+
"/ Search",
|
|
4030
|
+
!filterActive && " \u2022 S Sort \u2022 D Direction",
|
|
4031
|
+
" \u2022 T Density \u2022 Shift+T Theme \u2022 A Archive Filter",
|
|
3998
4032
|
!starsMode && " \u2022 V Visibility Filter"
|
|
3999
4033
|
] }) }),
|
|
4000
|
-
/* @__PURE__ */
|
|
4001
|
-
/* @__PURE__ */
|
|
4002
|
-
/* @__PURE__ */
|
|
4034
|
+
/* @__PURE__ */ jsx21(Box20, { width: terminalWidth, justifyContent: "center", children: /* @__PURE__ */ jsx21(Text21, { color: theme.muted, dimColor: modalOpen ? true : void 0, children: starsMode ? "Shift+S My Repos \u2022 I Info \u2022 C Copy URL \u2022 U Unstar Repository" : `${ownerContext === "personal" ? "Shift+S Starred \u2022 " : ""}I Info \u2022 C Copy URL \u2022 Ctrl+S Un/Star \u2022 Ctrl+R Rename \u2022 Ctrl+A Un/Archive \u2022 Ctrl+V Change Visibility \u2022 Ctrl+F Sync Fork \u2022 P Jump to upstream` }) }),
|
|
4035
|
+
/* @__PURE__ */ jsx21(Box20, { width: terminalWidth, justifyContent: "center", children: /* @__PURE__ */ jsx21(Text21, { color: theme.muted, dimColor: modalOpen ? true : void 0, children: "K Cache Info \u2022 W Org Switch \u2022 Del/Backspace Delete \u2022 Ctrl+L Logout \u2022 Q Quit" }) }),
|
|
4036
|
+
/* @__PURE__ */ jsx21(Box20, { width: terminalWidth, justifyContent: "center", marginTop: 1, children: /* @__PURE__ */ jsx21(Text21, { color: theme.warning, dimColor: modalOpen ? true : void 0, children: "\u{1F496} Sponsor on GitHub: github.com/sponsors/wiiiimm" }) })
|
|
4003
4037
|
] }),
|
|
4004
|
-
process.env.GH_MANAGER_DEBUG === "1" && /* @__PURE__ */
|
|
4005
|
-
/* @__PURE__ */
|
|
4006
|
-
debugMessages.length === 0 ? /* @__PURE__ */
|
|
4038
|
+
process.env.GH_MANAGER_DEBUG === "1" && /* @__PURE__ */ jsxs20(Box20, { marginTop: 1, borderStyle: "single", borderColor: "yellow", paddingX: 1, flexDirection: "column", children: [
|
|
4039
|
+
/* @__PURE__ */ jsx21(Text21, { bold: true, color: "yellow", children: "Debug Messages:" }),
|
|
4040
|
+
debugMessages.length === 0 ? /* @__PURE__ */ jsx21(Text21, { color: "gray", children: "No debug messages yet..." }) : debugMessages.map((msg, i) => /* @__PURE__ */ jsx21(Text21, { color: "gray", children: msg }, i))
|
|
4007
4041
|
] }),
|
|
4008
|
-
themeToast && /* @__PURE__ */
|
|
4009
|
-
copyToast && /* @__PURE__ */
|
|
4042
|
+
themeToast && /* @__PURE__ */ jsx21(Box20, { marginTop: 1, justifyContent: "center", children: /* @__PURE__ */ jsx21(Box20, { borderStyle: "round", borderColor: theme.primary, paddingX: 2, paddingY: 0, children: /* @__PURE__ */ jsx21(Text21, { color: theme.primary, children: themeToast }) }) }),
|
|
4043
|
+
copyToast && /* @__PURE__ */ jsx21(Box20, { marginTop: 1, justifyContent: "center", children: /* @__PURE__ */ jsx21(Box20, { borderStyle: "round", borderColor: copyToast.includes("Failed") ? "red" : "green", paddingX: 2, paddingY: 0, children: /* @__PURE__ */ jsx21(Text21, { color: copyToast.includes("Failed") ? "red" : "green", children: copyToast }) }) })
|
|
4010
4044
|
] });
|
|
4011
4045
|
}
|
|
4012
4046
|
|
|
4013
4047
|
// src/ui/components/auth/AuthMethodSelector.tsx
|
|
4014
|
-
import { useState as
|
|
4015
|
-
import { Box as
|
|
4048
|
+
import { useState as useState18 } from "react";
|
|
4049
|
+
import { Box as Box21, Text as Text22, useInput as useInput18 } from "ink";
|
|
4016
4050
|
import chalk16 from "chalk";
|
|
4017
|
-
import { jsx as
|
|
4051
|
+
import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
4018
4052
|
function AuthMethodSelector({ onSelect, onQuit }) {
|
|
4019
|
-
const [selectedIndex, setSelectedIndex] =
|
|
4053
|
+
const [selectedIndex, setSelectedIndex] = useState18(0);
|
|
4020
4054
|
const methods = [
|
|
4021
4055
|
{
|
|
4022
4056
|
key: "oauth",
|
|
@@ -4029,7 +4063,7 @@ function AuthMethodSelector({ onSelect, onQuit }) {
|
|
|
4029
4063
|
description: "Manually enter a GitHub Personal Access Token"
|
|
4030
4064
|
}
|
|
4031
4065
|
];
|
|
4032
|
-
|
|
4066
|
+
useInput18((input, key) => {
|
|
4033
4067
|
if (key.escape || input?.toLowerCase() === "q") {
|
|
4034
4068
|
if (onQuit) {
|
|
4035
4069
|
onQuit();
|
|
@@ -4048,33 +4082,33 @@ function AuthMethodSelector({ onSelect, onQuit }) {
|
|
|
4048
4082
|
onSelect("pat");
|
|
4049
4083
|
}
|
|
4050
4084
|
});
|
|
4051
|
-
return /* @__PURE__ */
|
|
4052
|
-
/* @__PURE__ */
|
|
4053
|
-
/* @__PURE__ */
|
|
4085
|
+
return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", paddingX: 2, paddingY: 1, children: [
|
|
4086
|
+
/* @__PURE__ */ jsx22(Text22, { bold: true, marginBottom: 1, children: "Choose Authentication Method" }),
|
|
4087
|
+
/* @__PURE__ */ jsx22(Box21, { flexDirection: "column", marginY: 1, children: methods.map((method, index) => {
|
|
4054
4088
|
const isSelected = index === selectedIndex;
|
|
4055
4089
|
const prefix = isSelected ? chalk16.cyan("\u203A") : " ";
|
|
4056
4090
|
const numberPrefix = `${index + 1}.`;
|
|
4057
|
-
return /* @__PURE__ */
|
|
4058
|
-
/* @__PURE__ */
|
|
4091
|
+
return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginBottom: 1, children: [
|
|
4092
|
+
/* @__PURE__ */ jsx22(Text22, { children: /* @__PURE__ */ jsxs21(Text22, { color: isSelected ? "cyan" : void 0, bold: isSelected, children: [
|
|
4059
4093
|
prefix,
|
|
4060
4094
|
" ",
|
|
4061
4095
|
numberPrefix,
|
|
4062
4096
|
" ",
|
|
4063
4097
|
method.label
|
|
4064
4098
|
] }) }),
|
|
4065
|
-
/* @__PURE__ */
|
|
4099
|
+
/* @__PURE__ */ jsxs21(Text22, { color: "gray", dimColor: true, children: [
|
|
4066
4100
|
" ",
|
|
4067
4101
|
method.description
|
|
4068
4102
|
] })
|
|
4069
4103
|
] }, method.key);
|
|
4070
4104
|
}) }),
|
|
4071
|
-
/* @__PURE__ */
|
|
4105
|
+
/* @__PURE__ */ jsx22(Text22, { color: "gray", dimColor: true, marginTop: 1, children: "Use arrow keys to navigate, Enter to select, or press 1/2 \u2022 Q/Esc to quit" })
|
|
4072
4106
|
] });
|
|
4073
4107
|
}
|
|
4074
4108
|
|
|
4075
4109
|
// src/ui/components/auth/OAuthProgress.tsx
|
|
4076
|
-
import { Box as
|
|
4077
|
-
import { jsx as
|
|
4110
|
+
import { Box as Box22, Text as Text23 } from "ink";
|
|
4111
|
+
import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
4078
4112
|
function OAuthProgress({ status, error, deviceCode }) {
|
|
4079
4113
|
const statusMessages = {
|
|
4080
4114
|
initializing: {
|
|
@@ -4111,64 +4145,64 @@ function OAuthProgress({ status, error, deviceCode }) {
|
|
|
4111
4145
|
}
|
|
4112
4146
|
};
|
|
4113
4147
|
const { message, showSpinner } = statusMessages[status];
|
|
4114
|
-
return /* @__PURE__ */
|
|
4115
|
-
/* @__PURE__ */
|
|
4116
|
-
/* @__PURE__ */
|
|
4117
|
-
/* @__PURE__ */
|
|
4118
|
-
/* @__PURE__ */
|
|
4148
|
+
return /* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", borderStyle: "single", borderColor: status === "error" ? "red" : "cyan", paddingX: 2, paddingY: 1, children: [
|
|
4149
|
+
/* @__PURE__ */ jsx23(Text23, { bold: true, marginBottom: 1, children: "GitHub OAuth Authentication" }),
|
|
4150
|
+
/* @__PURE__ */ jsx23(Box22, { marginY: 1, children: showSpinner ? /* @__PURE__ */ jsxs22(Box22, { children: [
|
|
4151
|
+
/* @__PURE__ */ jsx23(Text23, { color: "green", children: /* @__PURE__ */ jsx23(SlowSpinner, { interval: 2e3 }) }),
|
|
4152
|
+
/* @__PURE__ */ jsxs22(Text23, { children: [
|
|
4119
4153
|
" ",
|
|
4120
4154
|
message
|
|
4121
4155
|
] })
|
|
4122
|
-
] }) : /* @__PURE__ */
|
|
4156
|
+
] }) : /* @__PURE__ */ jsxs22(Text23, { color: status === "error" ? "red" : "green", children: [
|
|
4123
4157
|
status === "error" ? "\u2717" : "\u2713",
|
|
4124
4158
|
" ",
|
|
4125
4159
|
message
|
|
4126
4160
|
] }) }),
|
|
4127
|
-
(status === "waiting_for_authorization" || status === "polling_for_token") && deviceCode && /* @__PURE__ */
|
|
4128
|
-
/* @__PURE__ */
|
|
4129
|
-
/* @__PURE__ */
|
|
4130
|
-
/* @__PURE__ */
|
|
4131
|
-
/* @__PURE__ */
|
|
4161
|
+
(status === "waiting_for_authorization" || status === "polling_for_token") && deviceCode && /* @__PURE__ */ jsxs22(Box22, { marginY: 1, flexDirection: "column", children: [
|
|
4162
|
+
/* @__PURE__ */ jsx23(Text23, { bold: true, color: "cyan", marginBottom: 1, children: "\u{1F4CB} Please complete these steps:" }),
|
|
4163
|
+
/* @__PURE__ */ jsxs22(Box22, { marginBottom: 1, children: [
|
|
4164
|
+
/* @__PURE__ */ jsx23(Text23, { children: "1. Visit: " }),
|
|
4165
|
+
/* @__PURE__ */ jsx23(Text23, { bold: true, color: "blue", children: deviceCode.verification_uri })
|
|
4132
4166
|
] }),
|
|
4133
|
-
/* @__PURE__ */
|
|
4134
|
-
/* @__PURE__ */
|
|
4135
|
-
/* @__PURE__ */
|
|
4167
|
+
/* @__PURE__ */ jsxs22(Box22, { marginBottom: 1, flexDirection: "column", children: [
|
|
4168
|
+
/* @__PURE__ */ jsx23(Text23, { children: "2. Enter this code:" }),
|
|
4169
|
+
/* @__PURE__ */ jsx23(Box22, { borderStyle: "single", borderColor: "yellow", paddingX: 2, paddingY: 1, marginTop: 1, children: /* @__PURE__ */ jsx23(Text23, { bold: true, color: "yellow", children: deviceCode.user_code }) })
|
|
4136
4170
|
] }),
|
|
4137
|
-
status === "waiting_for_authorization" && /* @__PURE__ */
|
|
4138
|
-
status === "polling_for_token" && /* @__PURE__ */
|
|
4139
|
-
/* @__PURE__ */
|
|
4140
|
-
/* @__PURE__ */
|
|
4171
|
+
status === "waiting_for_authorization" && /* @__PURE__ */ jsx23(Text23, { color: "gray", marginTop: 1, children: "Your browser should open automatically." }),
|
|
4172
|
+
status === "polling_for_token" && /* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", marginTop: 1, children: [
|
|
4173
|
+
/* @__PURE__ */ jsx23(Text23, { color: "gray", children: "Waiting for you to complete authorization in your browser..." }),
|
|
4174
|
+
/* @__PURE__ */ jsx23(Text23, { color: "gray", dimColor: true, marginTop: 1, children: "This will timeout in 15 minutes. Press Esc to cancel." })
|
|
4141
4175
|
] })
|
|
4142
4176
|
] }),
|
|
4143
|
-
status === "error" && error && /* @__PURE__ */
|
|
4144
|
-
/* @__PURE__ */
|
|
4145
|
-
/* @__PURE__ */
|
|
4177
|
+
status === "error" && error && /* @__PURE__ */ jsxs22(Box22, { marginY: 1, flexDirection: "column", children: [
|
|
4178
|
+
/* @__PURE__ */ jsx23(Text23, { color: "red", children: error }),
|
|
4179
|
+
/* @__PURE__ */ jsx23(Text23, { color: "gray", marginTop: 1, children: "Press Esc to go back and try again." })
|
|
4146
4180
|
] }),
|
|
4147
|
-
status === "success" && /* @__PURE__ */
|
|
4181
|
+
status === "success" && /* @__PURE__ */ jsx23(Text23, { color: "gray", marginTop: 1, children: "Returning to application..." })
|
|
4148
4182
|
] });
|
|
4149
4183
|
}
|
|
4150
4184
|
|
|
4151
4185
|
// src/ui/App.tsx
|
|
4152
|
-
import { jsx as
|
|
4186
|
+
import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
4153
4187
|
var packageJson = require_package();
|
|
4154
4188
|
function App({ initialOrgSlug: initialOrgSlug2, inlineToken: inlineToken2, inlineTokenEphemeral }) {
|
|
4155
4189
|
const { exit } = useApp2();
|
|
4156
4190
|
const { stdout } = useStdout2();
|
|
4157
|
-
const [mode, setMode] =
|
|
4158
|
-
const [token, setToken] =
|
|
4159
|
-
const [input, setInput] =
|
|
4160
|
-
const [error, setError] =
|
|
4161
|
-
const [viewer, setViewer] =
|
|
4162
|
-
const [rateLimitReset, setRateLimitReset] =
|
|
4163
|
-
const [wasRateLimited, setWasRateLimited] =
|
|
4164
|
-
const [orgContext, setOrgContext] =
|
|
4165
|
-
const [authMethod, setAuthMethod] =
|
|
4166
|
-
const [oauthStatus, setOAuthStatus] =
|
|
4167
|
-
const [tokenSource, setTokenSource] =
|
|
4168
|
-
const [sessionTokenOrigin, setSessionTokenOrigin] =
|
|
4169
|
-
const [deviceCodeResponse, setDeviceCodeResponse] =
|
|
4170
|
-
const [oauthDeviceCode, setOauthDeviceCode] =
|
|
4171
|
-
const [dims, setDims] =
|
|
4191
|
+
const [mode, setMode] = useState19("checking");
|
|
4192
|
+
const [token, setToken] = useState19(null);
|
|
4193
|
+
const [input, setInput] = useState19("");
|
|
4194
|
+
const [error, setError] = useState19(null);
|
|
4195
|
+
const [viewer, setViewer] = useState19(null);
|
|
4196
|
+
const [rateLimitReset, setRateLimitReset] = useState19(null);
|
|
4197
|
+
const [wasRateLimited, setWasRateLimited] = useState19(false);
|
|
4198
|
+
const [orgContext, setOrgContext] = useState19("personal");
|
|
4199
|
+
const [authMethod, setAuthMethod] = useState19("pat");
|
|
4200
|
+
const [oauthStatus, setOAuthStatus] = useState19("initializing");
|
|
4201
|
+
const [tokenSource, setTokenSource] = useState19("pat");
|
|
4202
|
+
const [sessionTokenOrigin, setSessionTokenOrigin] = useState19("stored");
|
|
4203
|
+
const [deviceCodeResponse, setDeviceCodeResponse] = useState19(null);
|
|
4204
|
+
const [oauthDeviceCode, setOauthDeviceCode] = useState19(null);
|
|
4205
|
+
const [dims, setDims] = useState19(() => {
|
|
4172
4206
|
const cols = stdout?.columns ?? 100;
|
|
4173
4207
|
const rows = stdout?.rows ?? 30;
|
|
4174
4208
|
return { cols, rows };
|
|
@@ -4373,7 +4407,7 @@ function App({ initialOrgSlug: initialOrgSlug2, inlineToken: inlineToken2, inlin
|
|
|
4373
4407
|
setTokenSource("pat");
|
|
4374
4408
|
setMode("auth_method_selection");
|
|
4375
4409
|
};
|
|
4376
|
-
|
|
4410
|
+
useInput19((input2, key) => {
|
|
4377
4411
|
if ((mode === "prompt" || mode === "auth_method_selection") && key.escape) {
|
|
4378
4412
|
exit();
|
|
4379
4413
|
}
|
|
@@ -4405,19 +4439,19 @@ function App({ initialOrgSlug: initialOrgSlug2, inlineToken: inlineToken2, inlin
|
|
|
4405
4439
|
}
|
|
4406
4440
|
});
|
|
4407
4441
|
const verticalPadding = Math.floor(dims.rows * 0.05);
|
|
4408
|
-
const header = useMemo3(() => /* @__PURE__ */
|
|
4409
|
-
/* @__PURE__ */
|
|
4410
|
-
/* @__PURE__ */
|
|
4442
|
+
const header = useMemo3(() => /* @__PURE__ */ jsxs23(Box23, { flexDirection: "row", justifyContent: "space-between", marginBottom: 1, children: [
|
|
4443
|
+
/* @__PURE__ */ jsxs23(Box23, { flexDirection: "row", gap: 1, children: [
|
|
4444
|
+
/* @__PURE__ */ jsxs23(Text24, { bold: true, color: "cyan", children: [
|
|
4411
4445
|
" ",
|
|
4412
4446
|
"GitHub Repository Manager"
|
|
4413
4447
|
] }),
|
|
4414
|
-
/* @__PURE__ */
|
|
4448
|
+
/* @__PURE__ */ jsxs23(Text24, { color: "gray", dimColor: true, children: [
|
|
4415
4449
|
"v",
|
|
4416
4450
|
packageJson.version
|
|
4417
4451
|
] }),
|
|
4418
|
-
process.env.GH_MANAGER_DEBUG === "1" && /* @__PURE__ */
|
|
4452
|
+
process.env.GH_MANAGER_DEBUG === "1" && /* @__PURE__ */ jsx24(Text24, { backgroundColor: "blue", color: "white", children: " debug mode " })
|
|
4419
4453
|
] }),
|
|
4420
|
-
viewer && /* @__PURE__ */
|
|
4454
|
+
viewer && /* @__PURE__ */ jsx24(Text24, { color: "gray", children: orgContext !== "personal" && orgContext.login ? `${orgContext.login}/@${viewer} ` : `@${viewer} ` })
|
|
4421
4455
|
] }), [viewer, orgContext]);
|
|
4422
4456
|
if (mode === "rate_limited") {
|
|
4423
4457
|
const formatResetTime = (resetTime) => {
|
|
@@ -4440,70 +4474,70 @@ function App({ initialOrgSlug: initialOrgSlug2, inlineToken: inlineToken2, inlin
|
|
|
4440
4474
|
return "Unknown";
|
|
4441
4475
|
}
|
|
4442
4476
|
};
|
|
4443
|
-
return /* @__PURE__ */
|
|
4477
|
+
return /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
|
|
4444
4478
|
header,
|
|
4445
|
-
/* @__PURE__ */
|
|
4446
|
-
/* @__PURE__ */
|
|
4447
|
-
/* @__PURE__ */
|
|
4448
|
-
/* @__PURE__ */
|
|
4449
|
-
rateLimitReset && /* @__PURE__ */
|
|
4450
|
-
/* @__PURE__ */
|
|
4451
|
-
/* @__PURE__ */
|
|
4479
|
+
/* @__PURE__ */ jsx24(Box23, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsxs23(Box23, { borderStyle: "single", borderColor: "yellow", paddingX: 3, paddingY: 2, flexDirection: "column", width: Math.min(dims.cols - 8, 80), children: [
|
|
4480
|
+
/* @__PURE__ */ jsx24(Text24, { bold: true, color: "yellow", marginBottom: 1, children: "\u26A0\uFE0F Rate Limit Exceeded" }),
|
|
4481
|
+
/* @__PURE__ */ jsx24(Text24, { color: "gray", marginBottom: 1, children: "You've hit GitHub's API rate limit for your token." }),
|
|
4482
|
+
/* @__PURE__ */ jsx24(Text24, { color: "gray", marginBottom: 1, children: "This happens when you make too many requests in a short time." }),
|
|
4483
|
+
rateLimitReset && /* @__PURE__ */ jsxs23(Box23, { marginTop: 1, marginBottom: 1, children: [
|
|
4484
|
+
/* @__PURE__ */ jsxs23(Text24, { children: [
|
|
4485
|
+
/* @__PURE__ */ jsx24(Text24, { color: "cyan", children: "Reset in:" }),
|
|
4452
4486
|
" ",
|
|
4453
|
-
/* @__PURE__ */
|
|
4487
|
+
/* @__PURE__ */ jsx24(Text24, { bold: true, children: formatResetTime(rateLimitReset) })
|
|
4454
4488
|
] }),
|
|
4455
|
-
/* @__PURE__ */
|
|
4489
|
+
/* @__PURE__ */ jsxs23(Text24, { color: "gray", dimColor: true, children: [
|
|
4456
4490
|
"(",
|
|
4457
4491
|
new Date(rateLimitReset).toLocaleTimeString(),
|
|
4458
4492
|
")"
|
|
4459
4493
|
] })
|
|
4460
4494
|
] }),
|
|
4461
|
-
/* @__PURE__ */
|
|
4462
|
-
/* @__PURE__ */
|
|
4463
|
-
/* @__PURE__ */
|
|
4464
|
-
/* @__PURE__ */
|
|
4465
|
-
/* @__PURE__ */
|
|
4495
|
+
/* @__PURE__ */ jsxs23(Box23, { marginTop: 2, flexDirection: "column", gap: 1, children: [
|
|
4496
|
+
/* @__PURE__ */ jsx24(Text24, { bold: true, children: "What would you like to do?" }),
|
|
4497
|
+
/* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", paddingLeft: 2, children: [
|
|
4498
|
+
/* @__PURE__ */ jsxs23(Text24, { children: [
|
|
4499
|
+
/* @__PURE__ */ jsx24(Text24, { color: "cyan", bold: true, children: "R" }),
|
|
4466
4500
|
" - Retry now ",
|
|
4467
4501
|
rateLimitReset && formatResetTime(rateLimitReset) !== "Now (should be reset)" ? "(likely to fail until reset)" : "(should work now)"
|
|
4468
4502
|
] }),
|
|
4469
|
-
/* @__PURE__ */
|
|
4470
|
-
/* @__PURE__ */
|
|
4503
|
+
/* @__PURE__ */ jsxs23(Text24, { children: [
|
|
4504
|
+
/* @__PURE__ */ jsx24(Text24, { color: "cyan", bold: true, children: "L" }),
|
|
4471
4505
|
" - Logout and choose authentication method"
|
|
4472
4506
|
] }),
|
|
4473
|
-
/* @__PURE__ */
|
|
4474
|
-
/* @__PURE__ */
|
|
4507
|
+
/* @__PURE__ */ jsxs23(Text24, { children: [
|
|
4508
|
+
/* @__PURE__ */ jsx24(Text24, { color: "gray", bold: true, children: "Q/Esc" }),
|
|
4475
4509
|
" - Quit application"
|
|
4476
4510
|
] })
|
|
4477
4511
|
] })
|
|
4478
4512
|
] }),
|
|
4479
|
-
/* @__PURE__ */
|
|
4513
|
+
/* @__PURE__ */ jsx24(Text24, { color: "gray", dimColor: true, marginTop: 2, children: "Tip: Using multiple tokens or waiting between requests can help avoid rate limits." })
|
|
4480
4514
|
] }) })
|
|
4481
4515
|
] });
|
|
4482
4516
|
}
|
|
4483
4517
|
if (mode === "auth_method_selection") {
|
|
4484
|
-
return /* @__PURE__ */
|
|
4518
|
+
return /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
|
|
4485
4519
|
header,
|
|
4486
|
-
/* @__PURE__ */
|
|
4487
|
-
/* @__PURE__ */
|
|
4488
|
-
error && /* @__PURE__ */
|
|
4520
|
+
/* @__PURE__ */ jsx24(Box23, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", alignItems: "center", children: [
|
|
4521
|
+
/* @__PURE__ */ jsx24(AuthMethodSelector, { onSelect: handleAuthMethodSelect }),
|
|
4522
|
+
error && /* @__PURE__ */ jsx24(Text24, { color: "red", marginTop: 1, children: error })
|
|
4489
4523
|
] }) })
|
|
4490
4524
|
] });
|
|
4491
4525
|
}
|
|
4492
4526
|
if (mode === "oauth_flow") {
|
|
4493
|
-
return /* @__PURE__ */
|
|
4527
|
+
return /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
|
|
4494
4528
|
header,
|
|
4495
|
-
/* @__PURE__ */
|
|
4529
|
+
/* @__PURE__ */ jsx24(Box23, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsx24(OAuthProgress, { status: oauthStatus, error: error || void 0, deviceCode: oauthDeviceCode || void 0 }) })
|
|
4496
4530
|
] });
|
|
4497
4531
|
}
|
|
4498
4532
|
if (mode === "prompt") {
|
|
4499
|
-
return /* @__PURE__ */
|
|
4533
|
+
return /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
|
|
4500
4534
|
header,
|
|
4501
|
-
/* @__PURE__ */
|
|
4502
|
-
/* @__PURE__ */
|
|
4503
|
-
/* @__PURE__ */
|
|
4504
|
-
/* @__PURE__ */
|
|
4505
|
-
/* @__PURE__ */
|
|
4506
|
-
/* @__PURE__ */
|
|
4535
|
+
/* @__PURE__ */ jsx24(Box23, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsxs23(Box23, { borderStyle: "single", borderColor: "cyan", paddingX: 2, paddingY: 1, flexDirection: "column", children: [
|
|
4536
|
+
/* @__PURE__ */ jsx24(Text24, { bold: true, marginBottom: 1, children: "Authentication Required" }),
|
|
4537
|
+
/* @__PURE__ */ jsx24(Text24, { color: "gray", marginBottom: 1, children: "Enter your GitHub Personal Access Token" }),
|
|
4538
|
+
/* @__PURE__ */ jsxs23(Box23, { children: [
|
|
4539
|
+
/* @__PURE__ */ jsx24(Text24, { children: "Token: " }),
|
|
4540
|
+
/* @__PURE__ */ jsx24(
|
|
4507
4541
|
TextInput6,
|
|
4508
4542
|
{
|
|
4509
4543
|
value: input,
|
|
@@ -4513,30 +4547,30 @@ function App({ initialOrgSlug: initialOrgSlug2, inlineToken: inlineToken2, inlin
|
|
|
4513
4547
|
}
|
|
4514
4548
|
)
|
|
4515
4549
|
] }),
|
|
4516
|
-
error && /* @__PURE__ */
|
|
4517
|
-
/* @__PURE__ */
|
|
4518
|
-
/* @__PURE__ */
|
|
4550
|
+
error && /* @__PURE__ */ jsx24(Text24, { color: "red", marginTop: 1, children: error }),
|
|
4551
|
+
/* @__PURE__ */ jsx24(Text24, { color: "gray", dimColor: true, marginTop: 1, children: "The token will be stored securely in your local config" }),
|
|
4552
|
+
/* @__PURE__ */ jsx24(Text24, { color: "gray", dimColor: true, marginTop: 1, children: "Press Esc to go back" })
|
|
4519
4553
|
] }) })
|
|
4520
4554
|
] });
|
|
4521
4555
|
}
|
|
4522
4556
|
if (mode === "validating" || mode === "checking") {
|
|
4523
|
-
return /* @__PURE__ */
|
|
4557
|
+
return /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
|
|
4524
4558
|
header,
|
|
4525
|
-
/* @__PURE__ */
|
|
4526
|
-
/* @__PURE__ */
|
|
4527
|
-
mode === "validating" && /* @__PURE__ */
|
|
4559
|
+
/* @__PURE__ */ jsx24(Box23, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", alignItems: "center", children: [
|
|
4560
|
+
/* @__PURE__ */ jsx24(Text24, { color: "yellow", children: "Validating token..." }),
|
|
4561
|
+
mode === "validating" && /* @__PURE__ */ jsx24(Text24, { color: "gray", dimColor: true, marginTop: 1, children: "Press Esc to cancel" })
|
|
4528
4562
|
] }) })
|
|
4529
4563
|
] });
|
|
4530
4564
|
}
|
|
4531
4565
|
if (mode === "error") {
|
|
4532
|
-
return /* @__PURE__ */
|
|
4566
|
+
return /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
|
|
4533
4567
|
header,
|
|
4534
|
-
/* @__PURE__ */
|
|
4568
|
+
/* @__PURE__ */ jsx24(Box23, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsx24(Text24, { color: "red", children: error ?? "Unexpected error" }) })
|
|
4535
4569
|
] });
|
|
4536
4570
|
}
|
|
4537
|
-
return /* @__PURE__ */
|
|
4571
|
+
return /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
|
|
4538
4572
|
header,
|
|
4539
|
-
/* @__PURE__ */
|
|
4573
|
+
/* @__PURE__ */ jsx24(
|
|
4540
4574
|
RepoList,
|
|
4541
4575
|
{
|
|
4542
4576
|
token,
|
|
@@ -4551,7 +4585,7 @@ function App({ initialOrgSlug: initialOrgSlug2, inlineToken: inlineToken2, inlin
|
|
|
4551
4585
|
}
|
|
4552
4586
|
|
|
4553
4587
|
// src/index.tsx
|
|
4554
|
-
import { jsx as
|
|
4588
|
+
import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
4555
4589
|
var argv = process.argv.slice(2);
|
|
4556
4590
|
var getFlagValue = (name) => {
|
|
4557
4591
|
const idx = argv.findIndex((a) => a === `--${name}` || a.startsWith(`--${name}=`));
|
|
@@ -4664,8 +4698,8 @@ var inlineToken = (() => {
|
|
|
4664
4698
|
})();
|
|
4665
4699
|
logger.debug("Rendering UI");
|
|
4666
4700
|
var { unmount } = render(
|
|
4667
|
-
/* @__PURE__ */
|
|
4668
|
-
/* @__PURE__ */
|
|
4669
|
-
/* @__PURE__ */
|
|
4701
|
+
/* @__PURE__ */ jsxs24(Box24, { flexDirection: "column", children: [
|
|
4702
|
+
/* @__PURE__ */ jsx25(App, { initialOrgSlug, inlineToken, inlineTokenEphemeral: Boolean(inlineToken) }),
|
|
4703
|
+
/* @__PURE__ */ jsx25(Text25, { color: "gray" })
|
|
4670
4704
|
] })
|
|
4671
4705
|
);
|