gh-manager-cli 1.10.4 → 1.10.6
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 +36 -19
- package/dist/{chunk-KOZ6QCTU.js → chunk-XCFI3TG5.js} +3 -13
- package/dist/{github-HC6GZCKR.js → github-6IFMCQKW.js} +1 -1
- package/dist/index.js +69 -65
- package/package.json +18 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [1.10.6](https://github.com/wiiiimm/gh-manager-cli/compare/v1.10.5...v1.10.6) (2025-09-01)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* clear token input field after logout and successful login ([243d963](https://github.com/wiiiimm/gh-manager-cli/commit/243d963a8603580c921d01c8380a23c0e511c113))
|
|
7
|
+
|
|
8
|
+
## [1.10.5](https://github.com/wiiiimm/gh-manager-cli/compare/v1.10.4...v1.10.5) (2025-09-01)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* prevent duplicate modal handlers and improve modal UI ([79281d3](https://github.com/wiiiimm/gh-manager-cli/commit/79281d34fe42d3345885cad257e6800e94eb2bb3))
|
|
14
|
+
|
|
1
15
|
## [1.10.4](https://github.com/wiiiimm/gh-manager-cli/compare/v1.10.3...v1.10.4) (2025-09-01)
|
|
2
16
|
|
|
3
17
|
|
package/README.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# gh-manager-cli
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/gh-manager-cli)
|
|
4
|
+
[](https://github.com/wiiiimm/gh-manager-cli/releases)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://nodejs.org)
|
|
7
|
+
[](https://github.com/wiiiimm/gh-manager-cli/stargazers)
|
|
8
|
+
[](https://www.anthropic.com)
|
|
9
|
+
[](https://openai.com)
|
|
10
|
+
|
|
3
11
|
Interactive terminal app to browse and manage your personal GitHub repositories. Built with Ink (React for CLIs) and the GitHub GraphQL API.
|
|
4
12
|
|
|
5
13
|
## Screenshots
|
|
@@ -27,7 +35,7 @@ Safe repository deletion with two-step confirmation process.
|
|
|
27
35
|
|
|
28
36
|
```bash
|
|
29
37
|
# Run with npx (no install)
|
|
30
|
-
npx gh-manager
|
|
38
|
+
npx gh-manager-cli
|
|
31
39
|
```
|
|
32
40
|
|
|
33
41
|
On first run, you'll be prompted for a GitHub Personal Access Token.
|
|
@@ -68,30 +76,30 @@ On first run, you'll be prompted for a GitHub Personal Access Token.
|
|
|
68
76
|
Run instantly without installing:
|
|
69
77
|
|
|
70
78
|
```bash
|
|
71
|
-
npx gh-manager
|
|
79
|
+
npx gh-manager-cli
|
|
72
80
|
```
|
|
73
81
|
|
|
74
82
|
### NPM Global Install
|
|
75
83
|
|
|
76
|
-
Install globally for persistent `gh-manager` command:
|
|
84
|
+
Install globally for persistent `gh-manager-cli` command:
|
|
77
85
|
|
|
78
86
|
```bash
|
|
79
87
|
npm install -g gh-manager-cli
|
|
80
|
-
gh-manager
|
|
88
|
+
gh-manager-cli
|
|
81
89
|
```
|
|
82
90
|
|
|
83
91
|
### Pre-built Binaries (No Node.js Required)
|
|
84
92
|
|
|
85
93
|
Download standalone executables from [GitHub Releases](https://github.com/wiiiimm/gh-manager-cli/releases):
|
|
86
94
|
|
|
87
|
-
- **Linux**: `gh-manager-linux-x64`
|
|
88
|
-
- **macOS**: `gh-manager-macos-x64`
|
|
89
|
-
- **Windows**: `gh-manager-windows-x64.exe`
|
|
95
|
+
- **Linux**: `gh-manager-cli-linux-x64`
|
|
96
|
+
- **macOS**: `gh-manager-cli-macos-x64`
|
|
97
|
+
- **Windows**: `gh-manager-cli-windows-x64.exe`
|
|
90
98
|
|
|
91
99
|
Make the binary executable (Linux/macOS):
|
|
92
100
|
```bash
|
|
93
|
-
chmod +x gh-manager-*
|
|
94
|
-
./gh-manager-*
|
|
101
|
+
chmod +x gh-manager-cli-*
|
|
102
|
+
./gh-manager-cli-*
|
|
95
103
|
```
|
|
96
104
|
|
|
97
105
|
### From Source
|
|
@@ -113,7 +121,7 @@ Run locally:
|
|
|
113
121
|
node dist/index.js
|
|
114
122
|
# Or add to PATH for dev
|
|
115
123
|
pnpm link
|
|
116
|
-
gh-manager
|
|
124
|
+
gh-manager-cli
|
|
117
125
|
```
|
|
118
126
|
|
|
119
127
|
## Token & Security
|
|
@@ -162,8 +170,8 @@ Status bar shows loaded count vs total. A rate-limit line displays `remaining/li
|
|
|
162
170
|
## Pagination Details
|
|
163
171
|
|
|
164
172
|
- Uses GitHub GraphQL `viewer.repositories` with `ownerAffiliations: OWNER`, ordered by `UPDATED_AT DESC`.
|
|
165
|
-
- Fetches
|
|
166
|
-
-
|
|
173
|
+
- Fetches 15 repos per page by default (configurable via `REPOS_PER_FETCH` environment variable, 1-50).
|
|
174
|
+
- Updates `totalCount` each time and prefetches the next page when selection nears the end of loaded list.
|
|
167
175
|
|
|
168
176
|
## Development
|
|
169
177
|
|
|
@@ -180,11 +188,14 @@ Scripts:
|
|
|
180
188
|
pnpm build # build to dist/
|
|
181
189
|
pnpm build:binaries # build cross-platform binaries to ./binaries/
|
|
182
190
|
pnpm dev # watch mode
|
|
183
|
-
pnpm start #
|
|
191
|
+
pnpm start # run normally
|
|
192
|
+
pnpm start:debug # run with debug mode enabled
|
|
193
|
+
pnpm start:dev # run with 5 repos per page and debug mode
|
|
184
194
|
```
|
|
185
195
|
|
|
186
|
-
|
|
187
|
-
-
|
|
196
|
+
Environment variables:
|
|
197
|
+
- `REPOS_PER_FETCH`: Number of repositories to fetch per page (1-50, default: 15)
|
|
198
|
+
- `GH_MANAGER_DEBUG=1`: Enables debug mode with performance metrics and detailed errors
|
|
188
199
|
|
|
189
200
|
Project layout:
|
|
190
201
|
- `src/index.tsx` — CLI entry and error handling
|
|
@@ -209,7 +220,7 @@ gh-manager-cli includes built-in Apollo Client caching to reduce GitHub API call
|
|
|
209
220
|
|
|
210
221
|
Run with `GH_MANAGER_DEBUG=1` to enable debugging features:
|
|
211
222
|
```bash
|
|
212
|
-
GH_MANAGER_DEBUG=1 npx gh-manager
|
|
223
|
+
GH_MANAGER_DEBUG=1 npx gh-manager-cli
|
|
213
224
|
```
|
|
214
225
|
|
|
215
226
|
Debug mode provides:
|
|
@@ -241,14 +252,20 @@ Even with caching enabled, API credits may decrease due to:
|
|
|
241
252
|
- **Cache-and-network policy**: Updates stale cache data in background
|
|
242
253
|
- **Sorting changes**: Different sort orders create new cache entries
|
|
243
254
|
|
|
244
|
-
###
|
|
255
|
+
### Configuration
|
|
245
256
|
|
|
246
257
|
```bash
|
|
258
|
+
# Number of repositories to fetch per page (1-50, default: 15)
|
|
259
|
+
REPOS_PER_FETCH=10 npx gh-manager-cli
|
|
260
|
+
|
|
247
261
|
# Custom cache TTL (milliseconds) - default: 30 minutes
|
|
248
|
-
APOLLO_TTL_MS=1800000 npx gh-manager
|
|
262
|
+
APOLLO_TTL_MS=1800000 npx gh-manager-cli
|
|
249
263
|
|
|
250
264
|
# Enable debug mode to see cache performance
|
|
251
|
-
GH_MANAGER_DEBUG=1 npx gh-manager
|
|
265
|
+
GH_MANAGER_DEBUG=1 npx gh-manager-cli
|
|
266
|
+
|
|
267
|
+
# Combine multiple environment variables
|
|
268
|
+
REPOS_PER_FETCH=5 GH_MANAGER_DEBUG=1 npx gh-manager-cli-cli
|
|
252
269
|
```
|
|
253
270
|
|
|
254
271
|
## Troubleshooting
|
|
@@ -668,19 +668,6 @@ async function syncForkWithUpstream(token, owner, repo, branch = "main") {
|
|
|
668
668
|
const body = await res.json();
|
|
669
669
|
return body;
|
|
670
670
|
}
|
|
671
|
-
if (res.status === 422) {
|
|
672
|
-
try {
|
|
673
|
-
const body = await res.json();
|
|
674
|
-
if (body && body.message && body.message.includes("There was a problem updating the branch")) {
|
|
675
|
-
return {
|
|
676
|
-
message: "Sync completed (with warnings)",
|
|
677
|
-
merge_type: "merge",
|
|
678
|
-
base_branch: branch
|
|
679
|
-
};
|
|
680
|
-
}
|
|
681
|
-
} catch {
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
671
|
let msg = `Fork sync failed (status ${res.status})`;
|
|
685
672
|
try {
|
|
686
673
|
const body = await res.json();
|
|
@@ -689,6 +676,9 @@ async function syncForkWithUpstream(token, owner, repo, branch = "main") {
|
|
|
689
676
|
if (res.status === 409) {
|
|
690
677
|
msg += " (conflicts detected - manual merge required)";
|
|
691
678
|
}
|
|
679
|
+
if (res.status === 422) {
|
|
680
|
+
msg += " (branch could not be synced)";
|
|
681
|
+
}
|
|
692
682
|
}
|
|
693
683
|
} catch {
|
|
694
684
|
}
|
package/dist/index.js
CHANGED
|
@@ -16,20 +16,20 @@ import {
|
|
|
16
16
|
updateCacheAfterArchive,
|
|
17
17
|
updateCacheAfterDelete,
|
|
18
18
|
updateCacheWithRepository
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-XCFI3TG5.js";
|
|
20
20
|
|
|
21
21
|
// package.json
|
|
22
22
|
var require_package = __commonJS({
|
|
23
23
|
"package.json"(exports, module) {
|
|
24
24
|
module.exports = {
|
|
25
25
|
name: "gh-manager-cli",
|
|
26
|
-
version: "1.10.
|
|
26
|
+
version: "1.10.6",
|
|
27
27
|
private: false,
|
|
28
28
|
description: "Interactive CLI to manage your GitHub repos (personal) with Ink",
|
|
29
29
|
license: "MIT",
|
|
30
30
|
main: "dist/index.js",
|
|
31
31
|
bin: {
|
|
32
|
-
"gh-manager": "dist/index.js"
|
|
32
|
+
"gh-manager-cli": "dist/index.js"
|
|
33
33
|
},
|
|
34
34
|
files: [
|
|
35
35
|
"dist/",
|
|
@@ -52,10 +52,12 @@ var require_package = __commonJS({
|
|
|
52
52
|
"build:binaries": "npm run build && pkg dist/index.js --targets node18-linux-x64,node18-macos-x64,node18-windows-x64 --out-path ./binaries",
|
|
53
53
|
dev: "tsup --watch",
|
|
54
54
|
start: "node dist/index.js",
|
|
55
|
-
"start:
|
|
56
|
-
"start:
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
"start:debug": "GH_MANAGER_DEBUG=1 node dist/index.js",
|
|
56
|
+
"start:dev": "REPOS_PER_FETCH=5 GH_MANAGER_DEBUG=1 node dist/index.js",
|
|
57
|
+
prepublishOnly: "pnpm run build",
|
|
58
|
+
test: "vitest run",
|
|
59
|
+
"test:watch": "vitest",
|
|
60
|
+
"test:coverage": "vitest run --coverage"
|
|
59
61
|
},
|
|
60
62
|
engines: {
|
|
61
63
|
node: ">=18"
|
|
@@ -78,10 +80,13 @@ var require_package = __commonJS({
|
|
|
78
80
|
"@semantic-release/git": "^10.0.1",
|
|
79
81
|
"@types/node": "^24.3.0",
|
|
80
82
|
"@types/react": "^19.1.12",
|
|
83
|
+
"ink-testing-library": "^3.0.0",
|
|
81
84
|
pkg: "^5.8.1",
|
|
82
85
|
"semantic-release": "^24.2.7",
|
|
83
86
|
tsup: "^8.5.0",
|
|
84
|
-
typescript: "^5.9.2"
|
|
87
|
+
typescript: "^5.9.2",
|
|
88
|
+
vitest: "^2.1.3",
|
|
89
|
+
"@vitest/coverage-v8": "^2.1.3"
|
|
85
90
|
},
|
|
86
91
|
repository: {
|
|
87
92
|
type: "git",
|
|
@@ -115,18 +120,18 @@ var require_package = __commonJS({
|
|
|
115
120
|
{
|
|
116
121
|
assets: [
|
|
117
122
|
{
|
|
118
|
-
path: "binaries/gh-manager-linux-x64/gh-manager-linux-x64",
|
|
119
|
-
name: "gh-manager-linux-x64",
|
|
123
|
+
path: "binaries/gh-manager-cli-linux-x64/gh-manager-cli-linux-x64",
|
|
124
|
+
name: "gh-manager-cli-linux-x64",
|
|
120
125
|
label: "Linux x64 Binary"
|
|
121
126
|
},
|
|
122
127
|
{
|
|
123
|
-
path: "binaries/gh-manager-macos-x64/gh-manager-macos-x64",
|
|
124
|
-
name: "gh-manager-macos-x64",
|
|
128
|
+
path: "binaries/gh-manager-cli-macos-x64/gh-manager-cli-macos-x64",
|
|
129
|
+
name: "gh-manager-cli-macos-x64",
|
|
125
130
|
label: "macOS x64 Binary"
|
|
126
131
|
},
|
|
127
132
|
{
|
|
128
|
-
path: "binaries/gh-manager-windows-x64/gh-manager-windows-x64.exe",
|
|
129
|
-
name: "gh-manager-windows-x64.exe",
|
|
133
|
+
path: "binaries/gh-manager-cli-windows-x64/gh-manager-cli-windows-x64.exe",
|
|
134
|
+
name: "gh-manager-cli-windows-x64.exe",
|
|
130
135
|
label: "Windows x64 Binary"
|
|
131
136
|
}
|
|
132
137
|
]
|
|
@@ -279,7 +284,7 @@ function OrgSwitcher({ token, currentContext, onSelect, onClose }) {
|
|
|
279
284
|
const loadOrgs = async () => {
|
|
280
285
|
try {
|
|
281
286
|
setLoading(true);
|
|
282
|
-
const client = await import("./github-
|
|
287
|
+
const client = await import("./github-6IFMCQKW.js").then((m) => m.makeClient(token));
|
|
283
288
|
const orgs = await fetchViewerOrganizations(client);
|
|
284
289
|
setOrganizations(orgs);
|
|
285
290
|
if (!isPersonalContext) {
|
|
@@ -430,7 +435,17 @@ import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
|
430
435
|
|
|
431
436
|
// src/ui/RepoList.tsx
|
|
432
437
|
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
433
|
-
var
|
|
438
|
+
var getPageSize = () => {
|
|
439
|
+
const envValue = process.env.REPOS_PER_FETCH;
|
|
440
|
+
if (envValue) {
|
|
441
|
+
const parsed = parseInt(envValue, 10);
|
|
442
|
+
if (!isNaN(parsed) && parsed >= 1 && parsed <= 50) {
|
|
443
|
+
return parsed;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return 15;
|
|
447
|
+
};
|
|
448
|
+
var PAGE_SIZE = getPageSize();
|
|
434
449
|
function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextChange }) {
|
|
435
450
|
const { exit } = useApp();
|
|
436
451
|
const { stdout } = useStdout();
|
|
@@ -546,6 +561,27 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
546
561
|
setSyncError(e.message || "Failed to sync fork. Check permissions and network.");
|
|
547
562
|
}
|
|
548
563
|
}
|
|
564
|
+
async function executeArchive() {
|
|
565
|
+
if (!archiveTarget || archiving) return;
|
|
566
|
+
try {
|
|
567
|
+
setArchiving(true);
|
|
568
|
+
const isArchived = archiveTarget.isArchived;
|
|
569
|
+
const id = archiveTarget.id;
|
|
570
|
+
if (isArchived) {
|
|
571
|
+
await unarchiveRepositoryById(client, id);
|
|
572
|
+
} else {
|
|
573
|
+
await archiveRepositoryById(client, id);
|
|
574
|
+
}
|
|
575
|
+
await updateCacheAfterArchive(token, id, !isArchived);
|
|
576
|
+
const updateRepo = (r) => r.id === id ? { ...r, isArchived: !isArchived } : r;
|
|
577
|
+
setItems((prev) => prev.map(updateRepo));
|
|
578
|
+
setSearchItems((prev) => prev.map(updateRepo));
|
|
579
|
+
closeArchiveModal();
|
|
580
|
+
} catch (e) {
|
|
581
|
+
setArchiving(false);
|
|
582
|
+
setArchiveError("Failed to update archive state. Check permissions.");
|
|
583
|
+
}
|
|
584
|
+
}
|
|
549
585
|
function handleOrgContextChange(newContext) {
|
|
550
586
|
setOwnerContext(newContext);
|
|
551
587
|
storeUIPrefs({ ownerContext: newContext });
|
|
@@ -836,13 +872,12 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
836
872
|
setConfirmFocus("cancel");
|
|
837
873
|
return;
|
|
838
874
|
}
|
|
839
|
-
if (key.return) {
|
|
840
|
-
if (confirmFocus === "delete") confirmDeleteNow();
|
|
841
|
-
else cancelDeleteModal();
|
|
842
|
-
return;
|
|
843
|
-
}
|
|
844
875
|
if (input && input.toUpperCase() === "Y") {
|
|
845
|
-
|
|
876
|
+
if (confirmFocus === "delete") {
|
|
877
|
+
confirmDeleteNow();
|
|
878
|
+
} else {
|
|
879
|
+
cancelDeleteModal();
|
|
880
|
+
}
|
|
846
881
|
return;
|
|
847
882
|
}
|
|
848
883
|
}
|
|
@@ -861,29 +896,12 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
861
896
|
setArchiveFocus("cancel");
|
|
862
897
|
return;
|
|
863
898
|
}
|
|
864
|
-
if (
|
|
899
|
+
if (input && input.toUpperCase() === "Y") {
|
|
865
900
|
if (archiveFocus === "cancel") {
|
|
866
901
|
closeArchiveModal();
|
|
867
902
|
return;
|
|
868
903
|
}
|
|
869
|
-
|
|
870
|
-
(async () => {
|
|
871
|
-
try {
|
|
872
|
-
setArchiving(true);
|
|
873
|
-
const isArchived = archiveTarget.isArchived;
|
|
874
|
-
const id = archiveTarget.id;
|
|
875
|
-
if (isArchived) await unarchiveRepositoryById(client, id);
|
|
876
|
-
else await archiveRepositoryById(client, id);
|
|
877
|
-
await updateCacheAfterArchive(token, id, !isArchived);
|
|
878
|
-
const updateRepo = (r) => r.id === id ? { ...r, isArchived: !isArchived } : r;
|
|
879
|
-
setItems((prev) => prev.map(updateRepo));
|
|
880
|
-
setSearchItems((prev) => prev.map(updateRepo));
|
|
881
|
-
closeArchiveModal();
|
|
882
|
-
} catch (e) {
|
|
883
|
-
setArchiving(false);
|
|
884
|
-
setArchiveError("Failed to update archive state. Check permissions.");
|
|
885
|
-
}
|
|
886
|
-
})();
|
|
904
|
+
executeArchive();
|
|
887
905
|
return;
|
|
888
906
|
}
|
|
889
907
|
return;
|
|
@@ -909,9 +927,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
909
927
|
}
|
|
910
928
|
return;
|
|
911
929
|
}
|
|
912
|
-
|
|
913
|
-
return;
|
|
914
|
-
}
|
|
930
|
+
return;
|
|
915
931
|
}
|
|
916
932
|
if (logoutMode) {
|
|
917
933
|
if (key.escape || input && input.toUpperCase() === "C") {
|
|
@@ -1366,7 +1382,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
1366
1382
|
/* @__PURE__ */ jsx6(Box5, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs5(Text6, { color: "gray", children: [
|
|
1367
1383
|
"Press Enter to ",
|
|
1368
1384
|
confirmFocus === "delete" ? "Delete" : "Cancel",
|
|
1369
|
-
"
|
|
1385
|
+
" | Y to Delete | C to Cancel"
|
|
1370
1386
|
] }) }),
|
|
1371
1387
|
/* @__PURE__ */ jsx6(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx6(
|
|
1372
1388
|
TextInput2,
|
|
@@ -1422,7 +1438,9 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
1422
1438
|
/* @__PURE__ */ jsx6(Box5, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs5(Text6, { color: "gray", children: [
|
|
1423
1439
|
"Press Enter to ",
|
|
1424
1440
|
archiveFocus === "confirm" ? archiveTarget.isArchived ? "Unarchive" : "Archive" : "Cancel",
|
|
1425
|
-
"
|
|
1441
|
+
" | Y to ",
|
|
1442
|
+
archiveTarget.isArchived ? "Unarchive" : "Archive",
|
|
1443
|
+
" | C to Cancel"
|
|
1426
1444
|
] }) }),
|
|
1427
1445
|
/* @__PURE__ */ jsx6(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx6(
|
|
1428
1446
|
TextInput2,
|
|
@@ -1432,23 +1450,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
1432
1450
|
},
|
|
1433
1451
|
onSubmit: () => {
|
|
1434
1452
|
if (archiveFocus === "confirm") {
|
|
1435
|
-
(
|
|
1436
|
-
try {
|
|
1437
|
-
setArchiving(true);
|
|
1438
|
-
const isArchived = archiveTarget.isArchived;
|
|
1439
|
-
const id = archiveTarget.id;
|
|
1440
|
-
if (isArchived) await unarchiveRepositoryById(client, id);
|
|
1441
|
-
else await archiveRepositoryById(client, id);
|
|
1442
|
-
await updateCacheAfterArchive(token, id, !isArchived);
|
|
1443
|
-
const updateRepo = (r) => r.id === id ? { ...r, isArchived: !isArchived } : r;
|
|
1444
|
-
setItems((prev) => prev.map(updateRepo));
|
|
1445
|
-
setSearchItems((prev) => prev.map(updateRepo));
|
|
1446
|
-
closeArchiveModal();
|
|
1447
|
-
} catch (e) {
|
|
1448
|
-
setArchiving(false);
|
|
1449
|
-
setArchiveError("Failed to update archive state. Check permissions.");
|
|
1450
|
-
}
|
|
1451
|
-
})();
|
|
1453
|
+
executeArchive();
|
|
1452
1454
|
} else {
|
|
1453
1455
|
closeArchiveModal();
|
|
1454
1456
|
}
|
|
@@ -1498,7 +1500,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
1498
1500
|
/* @__PURE__ */ jsx6(Box5, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs5(Text6, { color: "gray", children: [
|
|
1499
1501
|
"Press Enter to ",
|
|
1500
1502
|
syncFocus === "confirm" ? "Sync" : "Cancel",
|
|
1501
|
-
"
|
|
1503
|
+
" | Y to Sync | C to Cancel"
|
|
1502
1504
|
] }) }),
|
|
1503
1505
|
/* @__PURE__ */ jsx6(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx6(
|
|
1504
1506
|
TextInput2,
|
|
@@ -1551,7 +1553,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
|
|
|
1551
1553
|
/* @__PURE__ */ jsx6(Box5, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs5(Text6, { color: "gray", children: [
|
|
1552
1554
|
"Press Enter to ",
|
|
1553
1555
|
logoutFocus === "confirm" ? "Logout" : "Cancel",
|
|
1554
|
-
"
|
|
1556
|
+
" | Y to Logout | C to Cancel"
|
|
1555
1557
|
] }) })
|
|
1556
1558
|
] }) }) : orgSwitcherOpen ? /* @__PURE__ */ jsx6(Box5, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx6(
|
|
1557
1559
|
OrgSwitcher,
|
|
@@ -1764,6 +1766,7 @@ function App() {
|
|
|
1764
1766
|
if (!getStoredToken()) {
|
|
1765
1767
|
storeToken(token);
|
|
1766
1768
|
}
|
|
1769
|
+
setInput("");
|
|
1767
1770
|
setMode("ready");
|
|
1768
1771
|
} catch (e) {
|
|
1769
1772
|
clearTimeout(timeoutId);
|
|
@@ -1831,6 +1834,7 @@ function App() {
|
|
|
1831
1834
|
}
|
|
1832
1835
|
setToken(null);
|
|
1833
1836
|
setViewer(null);
|
|
1837
|
+
setInput("");
|
|
1834
1838
|
setMode("prompt");
|
|
1835
1839
|
};
|
|
1836
1840
|
useInput3((input2, key) => {
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gh-manager-cli",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.6",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Interactive CLI to manage your GitHub repos (personal) with Ink",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"bin": {
|
|
9
|
-
"gh-manager": "dist/index.js"
|
|
9
|
+
"gh-manager-cli": "dist/index.js"
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"dist/",
|
|
@@ -29,10 +29,12 @@
|
|
|
29
29
|
"build:binaries": "npm run build && pkg dist/index.js --targets node18-linux-x64,node18-macos-x64,node18-windows-x64 --out-path ./binaries",
|
|
30
30
|
"dev": "tsup --watch",
|
|
31
31
|
"start": "node dist/index.js",
|
|
32
|
-
"start:
|
|
33
|
-
"start:
|
|
34
|
-
"
|
|
35
|
-
"
|
|
32
|
+
"start:debug": "GH_MANAGER_DEBUG=1 node dist/index.js",
|
|
33
|
+
"start:dev": "REPOS_PER_FETCH=5 GH_MANAGER_DEBUG=1 node dist/index.js",
|
|
34
|
+
"prepublishOnly": "pnpm run build",
|
|
35
|
+
"test": "vitest run",
|
|
36
|
+
"test:watch": "vitest",
|
|
37
|
+
"test:coverage": "vitest run --coverage"
|
|
36
38
|
},
|
|
37
39
|
"engines": {
|
|
38
40
|
"node": ">=18"
|
|
@@ -55,10 +57,13 @@
|
|
|
55
57
|
"@semantic-release/git": "^10.0.1",
|
|
56
58
|
"@types/node": "^24.3.0",
|
|
57
59
|
"@types/react": "^19.1.12",
|
|
60
|
+
"ink-testing-library": "^3.0.0",
|
|
58
61
|
"pkg": "^5.8.1",
|
|
59
62
|
"semantic-release": "^24.2.7",
|
|
60
63
|
"tsup": "^8.5.0",
|
|
61
|
-
"typescript": "^5.9.2"
|
|
64
|
+
"typescript": "^5.9.2",
|
|
65
|
+
"vitest": "^2.1.3",
|
|
66
|
+
"@vitest/coverage-v8": "^2.1.3"
|
|
62
67
|
},
|
|
63
68
|
"repository": {
|
|
64
69
|
"type": "git",
|
|
@@ -92,18 +97,18 @@
|
|
|
92
97
|
{
|
|
93
98
|
"assets": [
|
|
94
99
|
{
|
|
95
|
-
"path": "binaries/gh-manager-linux-x64/gh-manager-linux-x64",
|
|
96
|
-
"name": "gh-manager-linux-x64",
|
|
100
|
+
"path": "binaries/gh-manager-cli-linux-x64/gh-manager-cli-linux-x64",
|
|
101
|
+
"name": "gh-manager-cli-linux-x64",
|
|
97
102
|
"label": "Linux x64 Binary"
|
|
98
103
|
},
|
|
99
104
|
{
|
|
100
|
-
"path": "binaries/gh-manager-macos-x64/gh-manager-macos-x64",
|
|
101
|
-
"name": "gh-manager-macos-x64",
|
|
105
|
+
"path": "binaries/gh-manager-cli-macos-x64/gh-manager-cli-macos-x64",
|
|
106
|
+
"name": "gh-manager-cli-macos-x64",
|
|
102
107
|
"label": "macOS x64 Binary"
|
|
103
108
|
},
|
|
104
109
|
{
|
|
105
|
-
"path": "binaries/gh-manager-windows-x64/gh-manager-windows-x64.exe",
|
|
106
|
-
"name": "gh-manager-windows-x64.exe",
|
|
110
|
+
"path": "binaries/gh-manager-cli-windows-x64/gh-manager-cli-windows-x64.exe",
|
|
111
|
+
"name": "gh-manager-cli-windows-x64.exe",
|
|
107
112
|
"label": "Windows x64 Binary"
|
|
108
113
|
}
|
|
109
114
|
]
|