gh-manager-cli 1.43.0 → 1.45.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 +7 -0
- package/README.md +12 -2
- package/dist/{chunk-MKIUBPVD.js → chunk-WHX6IOTW.js} +81 -0
- package/dist/{github-6HD7I2UI.js → github-72MPRF5W.js} +5 -1
- package/dist/index.js +899 -441
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [1.45.0](https://github.com/wiiiimm/gh-manager-cli/compare/v1.44.0...v1.45.0) (2026-06-07)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* add repository creation (Ctrl+N) and transfer (Shift+M) ([#60](https://github.com/wiiiimm/gh-manager-cli/issues/60)) ([2e9c271](https://github.com/wiiiimm/gh-manager-cli/commit/2e9c2711b985be9373a94483e0bd0b420dc48aec))
|
|
7
|
+
|
|
1
8
|
# [1.43.0](https://github.com/wiiiimm/gh-manager-cli/compare/v1.42.0...v1.43.0) (2026-06-05)
|
|
2
9
|
|
|
3
10
|
|
package/README.md
CHANGED
|
@@ -84,7 +84,9 @@ On first run, you'll be prompted to authenticate with GitHub (OAuth recommended)
|
|
|
84
84
|
- View detailed info (`I`) - Shows repository metadata, language, size, and timestamps
|
|
85
85
|
- Open in browser (Enter/`O`) — for forks a chooser lets you open this repo or the upstream
|
|
86
86
|
- Jump to upstream (`P`) — moves cursor to the parent if loaded; otherwise fetches and shows it
|
|
87
|
+
- Create new repository (`Ctrl+N`) — prompts for a name (with the personal/organisation slug shown in front), choose visibility with `Tab`, and surfaces GitHub errors inline
|
|
87
88
|
- Rename repository (`Ctrl+R`) with inline validation and automatic cache update
|
|
89
|
+
- Transfer repository to another owner (`Shift+M`) — prompts for the destination owner, requires a verification code, shows a final confirmation, and surfaces GitHub errors inline
|
|
88
90
|
- Copy repository URL to clipboard (`C`) with SSH/HTTPS options
|
|
89
91
|
- Delete repository (`Del` or `Backspace`) with secure two-step confirmation
|
|
90
92
|
- Archive/unarchive repositories (`Ctrl+A`) with confirmation prompts
|
|
@@ -95,7 +97,7 @@ On first run, you'll be prompted to authenticate with GitHub (OAuth recommended)
|
|
|
95
97
|
### User Interface & Experience
|
|
96
98
|
- **Keyboard Navigation**: Full keyboard control (arrow keys, PageUp/Down, `Ctrl+G`/`G`)
|
|
97
99
|
- **Display Density**: Toggle between compact/cozy/comfy spacing (`T`)
|
|
98
|
-
- **Colour Themes**: Four themes (Default, Ocean, Forest, Monochrome) cycled with `Shift+T`, persisted across restarts
|
|
100
|
+
- **Colour Themes**: Four themes (Default, Ocean, Forest, Monochrome) cycled with `Shift+T`, persisted across restarts; the selected-row highlight is theme-aware and tuned per theme for readable contrast
|
|
99
101
|
- **Visual Indicators**: Fork status, private/internal/archived badges, language colors, visibility status
|
|
100
102
|
- **Enterprise Support**: Full support for GitHub Enterprise with Internal repository visibility
|
|
101
103
|
- **Organization Context**: Switch between personal and organization accounts with ENT badge for enterprise orgs
|
|
@@ -272,7 +274,7 @@ Launch the app, then use the keys below:
|
|
|
272
274
|
- Stars: Number of stars
|
|
273
275
|
- **Sort Direction**: `D` to open sort direction modal (ascending/descending)
|
|
274
276
|
- **Display Density**: `T` to toggle compact/cozy/comfy
|
|
275
|
-
- **Colour Theme**: `Shift+T` to cycle themes (Default → Ocean → Forest → Monochrome); selection persists across restarts
|
|
277
|
+
- **Colour Theme**: `Shift+T` to cycle themes (Default → Ocean → Forest → Monochrome); selection persists across restarts. Each theme defines its own selected-row highlight (a darker on-theme background) so the highlighted repository stays high-contrast
|
|
276
278
|
- **Fork Status**: Always enabled — shows commits **ahead** and **behind** upstream once enrichment completes (see below)
|
|
277
279
|
- **Visibility Filter**: `V` opens modal (All, Public, Private/Internal for enterprise)
|
|
278
280
|
- **Archive Filter**: `A` toggles archive filter (All → Unarchived → Archived)
|
|
@@ -288,6 +290,10 @@ Launch the app, then use the keys below:
|
|
|
288
290
|
- **Quit**: `Q`
|
|
289
291
|
|
|
290
292
|
### Repository Actions
|
|
293
|
+
- **Create repository**: `Ctrl+N` to create a new repository in the current context (personal or organisation)
|
|
294
|
+
- Prompts for a name with the owner slug (`owner/`) shown in front
|
|
295
|
+
- `Tab` cycles visibility (Private/Public, plus Internal for enterprise organisations)
|
|
296
|
+
- Enter to create; GitHub errors (e.g. name already exists) are shown inline
|
|
291
297
|
- **Repository info**: `I` to view detailed metadata (size, language, timestamps)
|
|
292
298
|
- **Cache info**: `K` to inspect Apollo cache status
|
|
293
299
|
- **Archive/Unarchive**: `Ctrl+A` with confirmation prompt
|
|
@@ -298,6 +304,10 @@ Launch the app, then use the keys below:
|
|
|
298
304
|
- **Star/Unstar**: `Ctrl+S` to toggle star status for any repository
|
|
299
305
|
- **Sync fork**: `Ctrl+F` (for forks only, shows ahead/behind counts and handles conflicts)
|
|
300
306
|
- **Rename repository**: `Ctrl+R` with inline validation
|
|
307
|
+
- **Transfer repository**: `Shift+M` (Move) to transfer ownership to another user or organisation
|
|
308
|
+
- Prompts for the destination owner (`new-owner/<repo>` preview)
|
|
309
|
+
- Requires typing a randomly generated verification code (like delete), then a final confirmation before transferring
|
|
310
|
+
- GitHub errors (e.g. insufficient permissions) are shown inline
|
|
301
311
|
- **Copy URL**: `C` to copy repository URL to clipboard (SSH/HTTPS options)
|
|
302
312
|
|
|
303
313
|
### General
|
|
@@ -811,6 +811,85 @@ async function deleteRepositoryRest(token, owner, repo) {
|
|
|
811
811
|
});
|
|
812
812
|
throw new Error(msg);
|
|
813
813
|
}
|
|
814
|
+
async function parseGitHubRestError(res, defaultMessage) {
|
|
815
|
+
let msg = defaultMessage;
|
|
816
|
+
try {
|
|
817
|
+
const errBody = await res.json();
|
|
818
|
+
if (errBody?.message) msg = errBody.message;
|
|
819
|
+
if (Array.isArray(errBody?.errors) && errBody.errors.length > 0) {
|
|
820
|
+
const details = errBody.errors.map((e) => e.message || (e.field ? `${e.field}: ${e.code}` : e.code)).filter(Boolean).join("; ");
|
|
821
|
+
if (details) msg += ` (${details})`;
|
|
822
|
+
}
|
|
823
|
+
} catch {
|
|
824
|
+
}
|
|
825
|
+
return msg;
|
|
826
|
+
}
|
|
827
|
+
async function createRepositoryRest(token, options) {
|
|
828
|
+
const { name, visibility, description, org } = options;
|
|
829
|
+
const url = org ? `https://api.github.com/orgs/${org}/repos` : `https://api.github.com/user/repos`;
|
|
830
|
+
const body = { name };
|
|
831
|
+
if (visibility === "INTERNAL") {
|
|
832
|
+
body.visibility = "internal";
|
|
833
|
+
} else {
|
|
834
|
+
body.private = visibility === "PRIVATE";
|
|
835
|
+
}
|
|
836
|
+
if (description) body.description = description;
|
|
837
|
+
logger.info("Creating repository", { name, visibility, org: org ?? null, url });
|
|
838
|
+
let res;
|
|
839
|
+
try {
|
|
840
|
+
res = await fetch(url, {
|
|
841
|
+
method: "POST",
|
|
842
|
+
headers: {
|
|
843
|
+
"Authorization": `token ${token}`,
|
|
844
|
+
"Accept": "application/vnd.github+json",
|
|
845
|
+
"Content-Type": "application/json",
|
|
846
|
+
"User-Agent": "gh-manager-cli"
|
|
847
|
+
},
|
|
848
|
+
body: JSON.stringify(body)
|
|
849
|
+
});
|
|
850
|
+
} catch (networkError) {
|
|
851
|
+
logger.error("Network error during repository creation", { error: networkError.message, name, org: org ?? null });
|
|
852
|
+
throw new Error(`Network error whilst creating repository: ${networkError.message}`);
|
|
853
|
+
}
|
|
854
|
+
if (res.status === 201) {
|
|
855
|
+
const data = await res.json();
|
|
856
|
+
logger.info("Successfully created repository", {
|
|
857
|
+
nameWithOwner: data.full_name,
|
|
858
|
+
url: data.html_url
|
|
859
|
+
});
|
|
860
|
+
return { nameWithOwner: data.full_name, url: data.html_url };
|
|
861
|
+
}
|
|
862
|
+
const msg = await parseGitHubRestError(res, `Failed to create repository (status ${res.status})`);
|
|
863
|
+
logger.error("Failed to create repository", { status: res.status, error: msg, name, org: org ?? null });
|
|
864
|
+
throw new Error(msg);
|
|
865
|
+
}
|
|
866
|
+
async function transferRepositoryRest(token, owner, repo, newOwner) {
|
|
867
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/transfer`;
|
|
868
|
+
logger.info("Transferring repository", { owner, repo, newOwner, url });
|
|
869
|
+
let res;
|
|
870
|
+
try {
|
|
871
|
+
res = await fetch(url, {
|
|
872
|
+
method: "POST",
|
|
873
|
+
headers: {
|
|
874
|
+
"Authorization": `token ${token}`,
|
|
875
|
+
"Accept": "application/vnd.github+json",
|
|
876
|
+
"Content-Type": "application/json",
|
|
877
|
+
"User-Agent": "gh-manager-cli"
|
|
878
|
+
},
|
|
879
|
+
body: JSON.stringify({ new_owner: newOwner })
|
|
880
|
+
});
|
|
881
|
+
} catch (networkError) {
|
|
882
|
+
logger.error("Network error during repository transfer", { error: networkError.message, owner, repo, newOwner });
|
|
883
|
+
throw new Error(`Network error whilst transferring repository: ${networkError.message}`);
|
|
884
|
+
}
|
|
885
|
+
if (res.status === 202 || res.status === 200) {
|
|
886
|
+
logger.info("Successfully initiated repository transfer", { owner, repo, newOwner, status: res.status });
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
const msg = await parseGitHubRestError(res, `Failed to transfer repository (status ${res.status})`);
|
|
890
|
+
logger.error("Failed to transfer repository", { status: res.status, error: msg, owner, repo, newOwner });
|
|
891
|
+
throw new Error(msg);
|
|
892
|
+
}
|
|
814
893
|
async function getStarredRepositories(client, first, after) {
|
|
815
894
|
logger.info("Fetching starred repositories", {
|
|
816
895
|
first,
|
|
@@ -1607,6 +1686,8 @@ export {
|
|
|
1607
1686
|
fetchViewerReposPageUnified,
|
|
1608
1687
|
searchRepositoriesUnified,
|
|
1609
1688
|
deleteRepositoryRest,
|
|
1689
|
+
createRepositoryRest,
|
|
1690
|
+
transferRepositoryRest,
|
|
1610
1691
|
getStarredRepositories,
|
|
1611
1692
|
starRepository,
|
|
1612
1693
|
unstarRepository,
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
archiveRepositoryById,
|
|
4
4
|
changeRepositoryVisibility,
|
|
5
5
|
checkOrganizationIsEnterprise,
|
|
6
|
+
createRepositoryRest,
|
|
6
7
|
deleteRepositoryRest,
|
|
7
8
|
enrichForksWithAheadBehind,
|
|
8
9
|
fetchRepositoryById,
|
|
@@ -21,6 +22,7 @@ import {
|
|
|
21
22
|
searchRepositoriesUnified,
|
|
22
23
|
starRepository,
|
|
23
24
|
syncForkWithUpstream,
|
|
25
|
+
transferRepositoryRest,
|
|
24
26
|
unarchiveRepositoryById,
|
|
25
27
|
unstarRepository,
|
|
26
28
|
updateCacheAfterArchive,
|
|
@@ -28,11 +30,12 @@ import {
|
|
|
28
30
|
updateCacheAfterRename,
|
|
29
31
|
updateCacheAfterVisibilityChange,
|
|
30
32
|
updateCacheWithRepository
|
|
31
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-WHX6IOTW.js";
|
|
32
34
|
export {
|
|
33
35
|
archiveRepositoryById,
|
|
34
36
|
changeRepositoryVisibility,
|
|
35
37
|
checkOrganizationIsEnterprise,
|
|
38
|
+
createRepositoryRest,
|
|
36
39
|
deleteRepositoryRest,
|
|
37
40
|
enrichForksWithAheadBehind,
|
|
38
41
|
fetchRepositoryById,
|
|
@@ -51,6 +54,7 @@ export {
|
|
|
51
54
|
searchRepositoriesUnified,
|
|
52
55
|
starRepository,
|
|
53
56
|
syncForkWithUpstream,
|
|
57
|
+
transferRepositoryRest,
|
|
54
58
|
unarchiveRepositoryById,
|
|
55
59
|
unstarRepository,
|
|
56
60
|
updateCacheAfterArchive,
|