gh-manager-cli 1.13.1 → 1.14.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 CHANGED
@@ -1,3 +1,27 @@
1
+ # [1.14.0](https://github.com/wiiiimm/gh-manager-cli/compare/v1.13.2...v1.14.0) (2025-09-02)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * correct TextInput import from ink-text-input package ([1040eca](https://github.com/wiiiimm/gh-manager-cli/commit/1040ecac07b0976eaf916ee5593d0bc867590eda))
7
+ * update both visibility and isPrivate fields when changing visibility ([4b96234](https://github.com/wiiiimm/gh-manager-cli/commit/4b962345a1e490b3a675575c8726e7040e0c0ed3))
8
+ * use REST API for changing repository visibility ([0bd1475](https://github.com/wiiiimm/gh-manager-cli/commit/0bd1475f22d5802d919491ad507d4b38f158da5e))
9
+
10
+
11
+ ### Features
12
+
13
+ * add enterprise support with Internal visibility and Ctrl+V visibility change ([9f457af](https://github.com/wiiiimm/gh-manager-cli/commit/9f457af4558458a23f321c14b42f0701fefecc0f))
14
+ * add repository visibility change with Ctrl+V ([d51b5e8](https://github.com/wiiiimm/gh-manager-cli/commit/d51b5e8b28c78f6ba58056a3254fc1aa218d9838))
15
+ * add support for Internal visibility in enterprise accounts ([781575a](https://github.com/wiiiimm/gh-manager-cli/commit/781575aee55a70f869aad7d724fd50b6bd052221))
16
+ * respect visibility filter when changing repository visibility ([25c963c](https://github.com/wiiiimm/gh-manager-cli/commit/25c963ca89038c84e0c8711f69d71785eb3a7355))
17
+
18
+ ## [1.13.2](https://github.com/wiiiimm/gh-manager-cli/compare/v1.13.1...v1.13.2) (2025-09-01)
19
+
20
+
21
+ ### Bug Fixes
22
+
23
+ * add authentication to Homebrew tap update in workflow ([31ec056](https://github.com/wiiiimm/gh-manager-cli/commit/31ec056a95bfbd696d8bb4d884fee0213c52257a))
24
+
1
25
  ## [1.13.1](https://github.com/wiiiimm/gh-manager-cli/compare/v1.13.0...v1.13.1) (2025-09-01)
2
26
 
3
27
 
package/README.md CHANGED
@@ -51,24 +51,26 @@ On first run, you'll be prompted for a GitHub Personal Access Token.
51
51
  - **Live Pagination**: Infinite scroll with automatic page prefetching
52
52
  - **Interactive Sorting**: Modal-based sort selection (updated, pushed, name, stars) with direction toggle
53
53
  - **Smart Search**: Server-side search through repository names and descriptions (3+ characters)
54
- - **Visibility Filtering**: Modal-based visibility filter (All, Public, Private, Internal for enterprise) with server-side filtering
54
+ - **Visibility Filtering**: Modal-based visibility filter (All, Public, Private/Internal for enterprise) with smart filtering
55
55
  - **Fork Status Tracking**: Toggle display of commits behind upstream for forked repositories
56
56
  - **Repository Actions**:
57
57
  - View detailed info (`I`) - Shows repository metadata, language, size, and timestamps
58
58
  - Open in browser (Enter/`O`)
59
59
  - Delete repository (`Del` or `Backspace`) with secure two-step confirmation
60
60
  - Archive/unarchive repositories (`Ctrl+A`) with confirmation prompts
61
+ - Change repository visibility (`Ctrl+V`) - Switch between Public, Private, and Internal (enterprise only)
61
62
  - Sync forks with upstream (`Ctrl+S`) with automatic conflict detection
62
63
 
63
64
  ### User Interface & Experience
64
65
  - **Keyboard Navigation**: Full keyboard control (arrow keys, PageUp/Down, `Ctrl+G`/`G`)
65
66
  - **Display Density**: Toggle between compact/cozy/comfy spacing (`T`)
66
- - **Visual Indicators**: Fork status, private/archived badges, language colors, visibility status
67
- - **Interactive Modals**: Sort selection, visibility filtering, and organization switching via modal dialogs
67
+ - **Visual Indicators**: Fork status, private/internal/archived badges, language colors, visibility status
68
+ - **Enterprise Support**: Full support for GitHub Enterprise with Internal repository visibility
69
+ - **Organization Context**: Switch between personal and organization accounts with ENT badge for enterprise orgs
70
+ - **Interactive Modals**: Sort selection, visibility filtering, organization switching, and visibility change dialogs
68
71
  - **Balanced Layout**: Repository items with spacing above and below for better visual hierarchy
69
72
  - **Loading States**: Contextual loading screens for sorting and refreshing operations
70
73
  - **Rate Limit Monitoring**: Live API usage display with visual warnings
71
- - **Improved Layout**: Balanced spacing above and below repository items for better visual hierarchy
72
74
 
73
75
  ### Technical Features
74
76
  - **Preference Persistence**: UI settings (sort, density, visibility filter, fork tracking) saved between sessions
@@ -192,7 +194,7 @@ Launch the app, then use the keys below:
192
194
  - **Sort Direction**: `D` to toggle ascending/descending
193
195
  - **Display Density**: `T` to toggle compact/cozy/comfy
194
196
  - **Fork Status**: `F` to toggle showing commits behind upstream
195
- - **Visibility Filter**: `V` opens modal (All, Public, Private, Internal for enterprise)
197
+ - **Visibility Filter**: `V` opens modal (All, Public, Private/Internal for enterprise)
196
198
 
197
199
  ### Navigation & Account
198
200
  - **Open in browser**: Enter or `O`
@@ -205,6 +207,7 @@ Launch the app, then use the keys below:
205
207
  - **Repository info**: `I` to view detailed metadata (size, language, timestamps)
206
208
  - **Cache info**: `K` to inspect Apollo cache status
207
209
  - **Archive/Unarchive**: `Ctrl+A` with confirmation prompt
210
+ - **Change visibility**: `Ctrl+V` to change repository visibility (Public/Private/Internal)
208
211
  - **Delete repository**: `Del` or `Backspace` (with two-step confirmation modal)
209
212
  - Type confirmation code → confirm (Y/Enter)
210
213
  - Cancel: press `C` or Esc
@@ -330,12 +333,14 @@ For the up-to-date task board, see [TODOs.md](./TODOs.md).
330
333
 
331
334
  Recently implemented:
332
335
  - ✅ Density toggle for row spacing (compact/cozy/comfy)
333
- - ✅ Repo actions (archive/unarchive, delete) with confirmations
334
- - ✅ Organization support and switching (press `W`)
335
- - ✅ Enhanced server-side search with improved UX
336
+ - ✅ Repo actions (archive/unarchive, delete, change visibility) with confirmations
337
+ - ✅ Organization support and switching (press `W`) with enterprise detection
338
+ - ✅ Enhanced server-side search with improved UX and organization context support
336
339
  - ✅ Smart infinite scroll with 80% prefetch trigger
337
340
  - ✅ Modal-based sort and visibility filtering
338
- - ✅ Server-side visibility filtering for accurate pagination
341
+ - ✅ GitHub Enterprise support with Internal repository visibility
342
+ - ✅ Change repository visibility modal (`Ctrl+V`)
343
+ - ✅ Compact filter modals for better screen space utilization
339
344
 
340
345
  Highlights on deck:
341
346
  - Optional OS keychain storage via `keytar`
@@ -139,6 +139,26 @@ async function fetchViewerOrganizations(client) {
139
139
  const res = await client(query);
140
140
  return res.viewer.organizations.nodes;
141
141
  }
142
+ async function checkOrganizationIsEnterprise(client, orgLogin) {
143
+ try {
144
+ const query = (
145
+ /* GraphQL */
146
+ `
147
+ query CheckOrgEnterprise($orgLogin: String!) {
148
+ organization(login: $orgLogin) {
149
+ enterpriseOwners(first: 1) {
150
+ totalCount
151
+ }
152
+ }
153
+ }
154
+ `
155
+ );
156
+ const res = await client(query, { orgLogin });
157
+ return res.organization?.enterpriseOwners?.totalCount > 0;
158
+ } catch (error) {
159
+ return false;
160
+ }
161
+ }
142
162
  async function fetchViewerReposPage(client, first, after, orderBy, includeForkTracking = true, ownerAffiliations = ["OWNER"], organizationLogin, privacy) {
143
163
  const sortField = orderBy?.field || "UPDATED_AT";
144
164
  const sortDirection = orderBy?.direction || "DESC";
@@ -453,8 +473,9 @@ async function fetchViewerReposPageUnified(token, first, after, orderBy, include
453
473
  const octo = makeClient(token);
454
474
  return fetchViewerReposPage(octo, first, after, orderBy, includeForkTracking, ownerAffiliations, organizationLogin, privacy);
455
475
  }
456
- async function searchRepositoriesUnified(token, viewer, text, first, after, sortKey = "UPDATED_AT", sortDir = "DESC", includeForkTracking = true, fetchPolicy = "network-only") {
457
- const q = `${text} user:${viewer} in:name,description fork:true`;
476
+ async function searchRepositoriesUnified(token, viewer, text, first, after, sortKey = "UPDATED_AT", sortDir = "DESC", includeForkTracking = true, fetchPolicy = "network-only", organizationLogin) {
477
+ const searchContext = organizationLogin ? `org:${organizationLogin}` : `user:${viewer}`;
478
+ const q = `${text} ${searchContext} in:name,description fork:true`;
458
479
  try {
459
480
  const ap = await makeApolloClient(token);
460
481
  const queryDoc = ap.gql`
@@ -565,6 +586,48 @@ async function unarchiveRepositoryById(client, repositoryId) {
565
586
  );
566
587
  await client(mutation, { repositoryId });
567
588
  }
589
+ async function changeRepositoryVisibility(client, repositoryId, visibility, token) {
590
+ const query = (
591
+ /* GraphQL */
592
+ `
593
+ query GetRepoDetails($id: ID!) {
594
+ node(id: $id) {
595
+ ... on Repository {
596
+ nameWithOwner
597
+ owner {
598
+ login
599
+ }
600
+ name
601
+ }
602
+ }
603
+ }
604
+ `
605
+ );
606
+ const result = await client(query, { id: repositoryId });
607
+ const repo = result.node;
608
+ if (!repo || !repo.nameWithOwner) {
609
+ throw new Error("Repository not found");
610
+ }
611
+ const [owner, name] = repo.nameWithOwner.split("/");
612
+ const response = await fetch(`https://api.github.com/repos/${owner}/${name}`, {
613
+ method: "PATCH",
614
+ headers: {
615
+ "Authorization": `token ${token}`,
616
+ "Accept": "application/vnd.github+json",
617
+ "Content-Type": "application/json",
618
+ "User-Agent": "gh-manager-cli"
619
+ },
620
+ body: JSON.stringify({
621
+ visibility: visibility.toLowerCase()
622
+ // API expects lowercase
623
+ })
624
+ });
625
+ if (!response.ok) {
626
+ const error = await response.text();
627
+ throw new Error(`Failed to change visibility: ${error}`);
628
+ }
629
+ return { nameWithOwner: repo.nameWithOwner };
630
+ }
568
631
  async function getRepositoryFromCache(token, repositoryId) {
569
632
  try {
570
633
  const ap = await makeApolloClient(token);
@@ -755,6 +818,21 @@ async function updateCacheAfterArchive(token, repositoryId, isArchived) {
755
818
  } catch {
756
819
  }
757
820
  }
821
+ async function updateCacheAfterVisibilityChange(token, repositoryId, visibility) {
822
+ try {
823
+ const ap = await makeApolloClient(token);
824
+ if (!ap || !ap.client) return;
825
+ const isPrivate = visibility === "PRIVATE";
826
+ ap.client.cache.modify({
827
+ id: `Repository:${repositoryId}`,
828
+ fields: {
829
+ visibility: () => visibility,
830
+ isPrivate: () => isPrivate
831
+ }
832
+ });
833
+ } catch {
834
+ }
835
+ }
758
836
  async function updateCacheWithRepository(token, repository) {
759
837
  try {
760
838
  const ap = await makeApolloClient(token);
@@ -860,18 +938,21 @@ export {
860
938
  makeClient,
861
939
  getViewerLogin,
862
940
  fetchViewerOrganizations,
941
+ checkOrganizationIsEnterprise,
863
942
  fetchViewerReposPage,
864
943
  fetchViewerReposPageUnified,
865
944
  searchRepositoriesUnified,
866
945
  deleteRepositoryRest,
867
946
  archiveRepositoryById,
868
947
  unarchiveRepositoryById,
948
+ changeRepositoryVisibility,
869
949
  getRepositoryFromCache,
870
950
  fetchRepositoryById,
871
951
  syncForkWithUpstream,
872
952
  purgeApolloCacheFiles,
873
953
  updateCacheAfterDelete,
874
954
  updateCacheAfterArchive,
955
+ updateCacheAfterVisibilityChange,
875
956
  updateCacheWithRepository,
876
957
  inspectCacheStatus
877
958
  };
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  archiveRepositoryById,
4
+ changeRepositoryVisibility,
5
+ checkOrganizationIsEnterprise,
4
6
  deleteRepositoryRest,
5
7
  fetchRepositoryById,
6
8
  fetchViewerOrganizations,
@@ -16,10 +18,13 @@ import {
16
18
  unarchiveRepositoryById,
17
19
  updateCacheAfterArchive,
18
20
  updateCacheAfterDelete,
21
+ updateCacheAfterVisibilityChange,
19
22
  updateCacheWithRepository
20
- } from "./chunk-BOS4OCY4.js";
23
+ } from "./chunk-OKP742N4.js";
21
24
  export {
22
25
  archiveRepositoryById,
26
+ changeRepositoryVisibility,
27
+ checkOrganizationIsEnterprise,
23
28
  deleteRepositoryRest,
24
29
  fetchRepositoryById,
25
30
  fetchViewerOrganizations,
@@ -35,5 +40,6 @@ export {
35
40
  unarchiveRepositoryById,
36
41
  updateCacheAfterArchive,
37
42
  updateCacheAfterDelete,
43
+ updateCacheAfterVisibilityChange,
38
44
  updateCacheWithRepository
39
45
  };