gh-manager-cli 1.19.2 → 1.21.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,17 @@
1
+ # [1.21.0](https://github.com/wiiiimm/gh-manager-cli/compare/v1.20.0...v1.21.0) (2025-09-03)
2
+
3
+
4
+ ### Features
5
+
6
+ * add repository URL copying modal with interactive selection ([#24](https://github.com/wiiiimm/gh-manager-cli/issues/24)) ([45998e9](https://github.com/wiiiimm/gh-manager-cli/commit/45998e966805da7277a5fa6506e2b94c0d8dde39))
7
+
8
+ # [1.20.0](https://github.com/wiiiimm/gh-manager-cli/compare/v1.19.2...v1.20.0) (2025-09-03)
9
+
10
+
11
+ ### Features
12
+
13
+ * add repository rename functionality ([#23](https://github.com/wiiiimm/gh-manager-cli/issues/23)) ([4f25a7d](https://github.com/wiiiimm/gh-manager-cli/commit/4f25a7d080f678a91f846dddf78734d02fa69b91))
14
+
1
15
  ## [1.19.2](https://github.com/wiiiimm/gh-manager-cli/compare/v1.19.1...v1.19.2) (2025-09-03)
2
16
 
3
17
 
package/README.md CHANGED
@@ -60,8 +60,10 @@ On first run, you'll be prompted to authenticate with GitHub (OAuth recommended)
60
60
  - **Repository Actions**:
61
61
  - View detailed info (`I`) - Shows repository metadata, language, size, and timestamps
62
62
  - Open in browser (Enter/`O`)
63
+ - Copy repository URLs (`C`) - Interactive modal to copy SSH or HTTPS clone URLs with keyboard navigation
63
64
  - Delete repository (`Del` or `Backspace`) with secure two-step confirmation
64
65
  - Archive/unarchive repositories (`Ctrl+A`) with confirmation prompts
66
+ - Rename repository (`Ctrl+R`) with real-time validation
65
67
  - Change repository visibility (`Ctrl+V`) - Switch between Public, Private, and Internal (enterprise only)
66
68
  - Sync forks with upstream (`Ctrl+S`) with automatic conflict detection
67
69
 
@@ -257,7 +259,15 @@ Launch the app, then use the keys below:
257
259
  ### Repository Actions
258
260
  - **Repository info**: `I` to view detailed metadata (size, language, timestamps)
259
261
  - **Cache info**: `K` to inspect Apollo cache status
262
+ - **Copy URLs**: `C` to open interactive modal for copying SSH or HTTPS clone URLs
263
+ - SSH selected by default with visual indicators (▶)
264
+ - Up/Down arrows to select between SSH and HTTPS
265
+ - Enter to copy selected URL, or use `S`/`H` shortcuts
266
+ - Multiple close options: Esc, Q, C
260
267
  - **Archive/Unarchive**: `Ctrl+A` with confirmation prompt
268
+ - **Rename repository**: `Ctrl+R` to rename (with real-time validation)
269
+ - Enter new name → confirm (Enter)
270
+ - Cancel: press Esc
261
271
  - **Change visibility**: `Ctrl+V` to change repository visibility (Public/Private/Internal)
262
272
  - **Delete repository**: `Del` or `Backspace` (with two-step confirmation modal)
263
273
  - Type confirmation code → confirm (Y/Enter)
@@ -306,7 +316,7 @@ Project layout:
306
316
  - `src/ui/App.tsx` — token bootstrap, renders `RepoList`
307
317
  - `src/ui/RepoList.tsx` — main list UI with modal management
308
318
  - `src/ui/components/` — modular components (modals, repo, common)
309
- - `modals/` — DeleteModal, ArchiveModal, SyncModal, InfoModal, LogoutModal
319
+ - `modals/` — DeleteModal, ArchiveModal, RenameModal, SyncModal, InfoModal, LogoutModal
310
320
  - `repo/` — RepoRow, FilterInput, RepoListHeader
311
321
  - `common/` — SlowSpinner and shared UI elements
312
322
  - `src/ui/OrgSwitcher.tsx` — organization switching component
@@ -407,7 +417,7 @@ APOLLO_TTL_MS=1800000 npx gh-manager-cli
407
417
  GH_MANAGER_DEBUG=1 npx gh-manager-cli
408
418
 
409
419
  # Combine multiple environment variables
410
- REPOS_PER_FETCH=5 GH_MANAGER_DEBUG=1 npx gh-manager-cli-cli
420
+ REPOS_PER_FETCH=5 GH_MANAGER_DEBUG=1 npx gh-manager-cli
411
421
  ```
412
422
 
413
423
  ## Troubleshooting
@@ -423,7 +433,9 @@ For the up-to-date task board, see [TODOs.md](./TODOs.md).
423
433
  Recently implemented:
424
434
  - ✅ OAuth login flow as an alternative to Personal Access Token
425
435
  - ✅ Density toggle for row spacing (compact/cozy/comfy)
426
- - ✅ Repo actions (archive/unarchive, delete, change visibility) with confirmations
436
+ - ✅ Repo actions (archive/unarchive, delete, rename, change visibility) with confirmations
437
+ - ✅ Repository renaming with real-time validation (`Ctrl+R`)
438
+ - ✅ Repository URL copying modal (`C`) with interactive SSH/HTTPS selection
427
439
  - ✅ Organization support and switching (press `W`) with enterprise detection
428
440
  - ✅ Enhanced server-side search with improved UX and organization context support
429
441
  - ✅ Smart infinite scroll with 80% prefetch trigger
@@ -435,7 +447,6 @@ Recently implemented:
435
447
  Highlights on deck:
436
448
  - Optional OS keychain storage via `keytar`
437
449
  - Bulk selection and actions
438
- - Repository renaming
439
450
 
440
451
  ## License
441
452
 
@@ -1211,6 +1211,54 @@ async function updateCacheWithRepository(token, repository) {
1211
1211
  } catch {
1212
1212
  }
1213
1213
  }
1214
+ async function updateCacheAfterRename(token, repositoryId, newName, nameWithOwner) {
1215
+ try {
1216
+ const ap = await makeApolloClient(token);
1217
+ if (!ap || !ap.client) return;
1218
+ ap.client.cache.modify({
1219
+ id: `Repository:${repositoryId}`,
1220
+ fields: {
1221
+ name: () => newName,
1222
+ nameWithOwner: () => nameWithOwner
1223
+ }
1224
+ });
1225
+ } catch {
1226
+ }
1227
+ }
1228
+ async function renameRepositoryById(client, repositoryId, newName) {
1229
+ logger.info("Renaming repository", {
1230
+ repositoryId,
1231
+ newName
1232
+ });
1233
+ const mutation = (
1234
+ /* GraphQL */
1235
+ `
1236
+ mutation RenameRepo($repositoryId: ID!, $name: String!) {
1237
+ updateRepository(input: { repositoryId: $repositoryId, name: $name }) {
1238
+ repository {
1239
+ id
1240
+ name
1241
+ nameWithOwner
1242
+ }
1243
+ }
1244
+ }
1245
+ `
1246
+ );
1247
+ try {
1248
+ const result = await client(mutation, { repositoryId, name: newName });
1249
+ logger.info("Repository renamed successfully", {
1250
+ repositoryId,
1251
+ newName: result?.updateRepository?.repository?.name
1252
+ });
1253
+ } catch (error) {
1254
+ logger.error("Failed to rename repository", {
1255
+ repositoryId,
1256
+ newName,
1257
+ error: error.message
1258
+ });
1259
+ throw error;
1260
+ }
1261
+ }
1214
1262
  async function inspectCacheStatus() {
1215
1263
  try {
1216
1264
  const fs3 = await import("fs");
@@ -1279,5 +1327,7 @@ export {
1279
1327
  updateCacheAfterArchive,
1280
1328
  updateCacheAfterVisibilityChange,
1281
1329
  updateCacheWithRepository,
1330
+ updateCacheAfterRename,
1331
+ renameRepositoryById,
1282
1332
  inspectCacheStatus
1283
1333
  };
@@ -13,14 +13,16 @@ import {
13
13
  inspectCacheStatus,
14
14
  makeClient,
15
15
  purgeApolloCacheFiles,
16
+ renameRepositoryById,
16
17
  searchRepositoriesUnified,
17
18
  syncForkWithUpstream,
18
19
  unarchiveRepositoryById,
19
20
  updateCacheAfterArchive,
20
21
  updateCacheAfterDelete,
22
+ updateCacheAfterRename,
21
23
  updateCacheAfterVisibilityChange,
22
24
  updateCacheWithRepository
23
- } from "./chunk-FPJS7YJW.js";
25
+ } from "./chunk-RI2B33OX.js";
24
26
  export {
25
27
  archiveRepositoryById,
26
28
  changeRepositoryVisibility,
@@ -35,11 +37,13 @@ export {
35
37
  inspectCacheStatus,
36
38
  makeClient,
37
39
  purgeApolloCacheFiles,
40
+ renameRepositoryById,
38
41
  searchRepositoriesUnified,
39
42
  syncForkWithUpstream,
40
43
  unarchiveRepositoryById,
41
44
  updateCacheAfterArchive,
42
45
  updateCacheAfterDelete,
46
+ updateCacheAfterRename,
43
47
  updateCacheAfterVisibilityChange,
44
48
  updateCacheWithRepository
45
49
  };