gh-manager-cli 1.13.2 → 1.15.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/dist/index.js CHANGED
@@ -3,6 +3,8 @@ import {
3
3
  __commonJS,
4
4
  __toESM,
5
5
  archiveRepositoryById,
6
+ changeRepositoryVisibility,
7
+ checkOrganizationIsEnterprise,
6
8
  deleteRepositoryRest,
7
9
  fetchViewerOrganizations,
8
10
  fetchViewerReposPageUnified,
@@ -16,15 +18,16 @@ 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
 
22
25
  // package.json
23
26
  var require_package = __commonJS({
24
27
  "package.json"(exports, module) {
25
28
  module.exports = {
26
29
  name: "gh-manager-cli",
27
- version: "1.13.2",
30
+ version: "1.15.0",
28
31
  private: false,
29
32
  description: "Interactive CLI to manage your GitHub repos (personal) with Ink",
30
33
  license: "MIT",
@@ -59,7 +62,8 @@ var require_package = __commonJS({
59
62
  test: "vitest run",
60
63
  "test:watch": "vitest",
61
64
  "test:coverage": "vitest run --coverage",
62
- "brew:sha": "bash scripts/brew-sha.sh"
65
+ "brew:sha": "bash scripts/brew-sha.sh",
66
+ "assets:png": "bash scripts/convert-svg-to-png.sh"
63
67
  },
64
68
  engines: {
65
69
  node: ">=18"
@@ -75,6 +79,7 @@ var require_package = __commonJS({
75
79
  ink: "^6.2.3",
76
80
  "ink-spinner": "^5.0.0",
77
81
  "ink-text-input": "^6.0.0",
82
+ open: "^10.1.0",
78
83
  react: "^19.1.1"
79
84
  },
80
85
  devDependencies: {
@@ -82,13 +87,13 @@ var require_package = __commonJS({
82
87
  "@semantic-release/git": "^10.0.1",
83
88
  "@types/node": "^24.3.0",
84
89
  "@types/react": "^19.1.12",
90
+ "@vitest/coverage-v8": "^2.1.3",
85
91
  "ink-testing-library": "^3.0.0",
86
92
  pkg: "^5.8.1",
87
93
  "semantic-release": "^24.2.7",
88
94
  tsup: "^8.5.0",
89
95
  typescript: "^5.9.2",
90
- vitest: "^2.1.3",
91
- "@vitest/coverage-v8": "^2.1.3"
96
+ vitest: "^2.1.3"
92
97
  },
93
98
  repository: {
94
99
  type: "git",
@@ -147,13 +152,13 @@ var require_package = __commonJS({
147
152
 
148
153
  // src/index.tsx
149
154
  var import_package = __toESM(require_package(), 1);
150
- import { render, Box as Box14, Text as Text15 } from "ink";
155
+ import { render, Box as Box17, Text as Text18 } from "ink";
151
156
  import "dotenv/config";
152
157
 
153
158
  // src/ui/App.tsx
154
- import { useEffect as useEffect7, useMemo as useMemo2, useState as useState10 } from "react";
155
- import { Box as Box13, Text as Text14, useApp as useApp2, useStdout as useStdout2, useInput as useInput10 } from "ink";
156
- import TextInput4 from "ink-text-input";
159
+ import { useEffect as useEffect8, useMemo as useMemo2, useState as useState12 } from "react";
160
+ import { Box as Box16, Text as Text17, useApp as useApp2, useStdout as useStdout2, useInput as useInput12 } from "ink";
161
+ import TextInput5 from "ink-text-input";
157
162
 
158
163
  // src/config.ts
159
164
  import fs from "fs";
@@ -189,15 +194,19 @@ function getStoredToken() {
189
194
  const cfg = readConfig();
190
195
  return cfg.token;
191
196
  }
192
- function storeToken(token) {
197
+ function storeToken(token, source = "pat") {
193
198
  const existing = readConfig();
194
- writeConfig({ ...existing, token, tokenVersion: 1 });
199
+ writeConfig({ ...existing, token, tokenVersion: 1, tokenSource: source });
195
200
  }
196
201
  function clearStoredToken() {
197
202
  const existing = readConfig();
198
- const { token, tokenVersion, ...rest } = existing;
203
+ const { token, tokenVersion, tokenSource, ...rest } = existing;
199
204
  writeConfig({ ...rest });
200
205
  }
206
+ function getTokenSource() {
207
+ const cfg = readConfig();
208
+ return cfg.tokenSource || "pat";
209
+ }
201
210
  function getUIPrefs() {
202
211
  const cfg = readConfig();
203
212
  return cfg.ui || {};
@@ -208,11 +217,196 @@ function storeUIPrefs(patch) {
208
217
  writeConfig({ ...existing, ui: mergedUI });
209
218
  }
210
219
 
220
+ // src/oauth.ts
221
+ import open from "open";
222
+
223
+ // src/constants.ts
224
+ var OAUTH_CONFIG = {
225
+ // GitHub OAuth App Client ID (public, safe to include in client)
226
+ // You'll need to register an OAuth App on GitHub and replace this with your client ID
227
+ // Note: Device flow doesn't use callback URLs, but GitHub requires one during app setup
228
+ CLIENT_ID: "Ov23li1pOAO5GZmxBF1L",
229
+ // gh-manager-cli OAuth App
230
+ // GitHub Device Authorization Grant endpoints
231
+ DEVICE_CODE_URL: "https://github.com/login/device/code",
232
+ TOKEN_URL: "https://github.com/login/oauth/access_token",
233
+ // Required OAuth scopes for the application
234
+ // Comprehensive scopes for full functionality:
235
+ // 'repo' - Full control of private repositories (includes repo:status, repo_deployment, public_repo, repo:invite)
236
+ // 'read:org' - Read organisation data including teams and membership
237
+ // 'user' - Read user profile data (includes user:email, user:follow)
238
+ // 'delete_repo' - Delete repositories
239
+ // 'workflow' - Update GitHub Actions workflow files
240
+ // 'write:packages' - Upload packages to GitHub Package Registry
241
+ // 'read:packages' - Download packages from GitHub Package Registry
242
+ SCOPES: [
243
+ "repo",
244
+ // Full repository access (private and public)
245
+ "read:org",
246
+ // Read organisation information
247
+ "user",
248
+ // Read user profile data
249
+ "delete_repo",
250
+ // Delete repositories
251
+ "workflow",
252
+ // Manage GitHub Actions workflows
253
+ "write:packages",
254
+ // Write to package registry
255
+ "read:packages"
256
+ // Read from package registry
257
+ ],
258
+ // Device flow configuration
259
+ DEVICE_FLOW_TIMEOUT_MS: 9e5,
260
+ // 15 minutes (GitHub's maximum)
261
+ POLLING_INTERVAL_MS: 5e3
262
+ // 5 seconds (GitHub's default)
263
+ };
264
+
265
+ // src/oauth.ts
266
+ async function pollForAccessToken(deviceCodeResponse) {
267
+ try {
268
+ const token = await pollForToken(deviceCodeResponse);
269
+ if (token) {
270
+ try {
271
+ const client = makeClient(token);
272
+ const login = await getViewerLogin(client);
273
+ return {
274
+ success: true,
275
+ token,
276
+ login
277
+ };
278
+ } catch (error) {
279
+ return {
280
+ success: false,
281
+ error: `Token validation failed: ${error.message}`
282
+ };
283
+ }
284
+ }
285
+ return {
286
+ success: false,
287
+ error: "Failed to obtain access token"
288
+ };
289
+ } catch (error) {
290
+ return {
291
+ success: false,
292
+ error: `Polling failed: ${error.message}`
293
+ };
294
+ }
295
+ }
296
+ async function requestDeviceCode() {
297
+ const response = await fetch(OAUTH_CONFIG.DEVICE_CODE_URL, {
298
+ method: "POST",
299
+ headers: {
300
+ "Accept": "application/json",
301
+ "Content-Type": "application/json"
302
+ },
303
+ body: JSON.stringify({
304
+ client_id: OAUTH_CONFIG.CLIENT_ID,
305
+ scope: OAUTH_CONFIG.SCOPES.join(" ")
306
+ })
307
+ });
308
+ if (!response.ok) {
309
+ throw new Error(`HTTP error ${response.status}: ${await response.text()}`);
310
+ }
311
+ const data = await response.json();
312
+ if (data.error) {
313
+ throw new Error(`${data.error}: ${data.error_description || "Unknown error"}`);
314
+ }
315
+ return data;
316
+ }
317
+ async function pollForToken(deviceCodeResponse) {
318
+ const startTime = Date.now();
319
+ const timeout = OAUTH_CONFIG.DEVICE_FLOW_TIMEOUT_MS;
320
+ const interval = Math.max(deviceCodeResponse.interval || 5, 5) * 1e3;
321
+ if (process.env.GH_MANAGER_DEBUG) {
322
+ console.log(`\u{1F504} Starting polling with interval ${interval}ms, timeout ${timeout}ms`);
323
+ }
324
+ while (Date.now() - startTime < timeout) {
325
+ await sleep(interval);
326
+ try {
327
+ if (process.env.GH_MANAGER_DEBUG) {
328
+ console.log("\u{1F504} Polling GitHub for access token...");
329
+ }
330
+ const response = await fetch(OAUTH_CONFIG.TOKEN_URL, {
331
+ method: "POST",
332
+ headers: {
333
+ "Accept": "application/json",
334
+ "Content-Type": "application/json"
335
+ },
336
+ body: JSON.stringify({
337
+ client_id: OAUTH_CONFIG.CLIENT_ID,
338
+ device_code: deviceCodeResponse.device_code,
339
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code"
340
+ })
341
+ });
342
+ if (!response.ok) {
343
+ const errorText = await response.text();
344
+ if (process.env.GH_MANAGER_DEBUG) {
345
+ console.log(`\u274C HTTP error ${response.status}: ${errorText}`);
346
+ }
347
+ throw new Error(`HTTP error ${response.status}: ${errorText}`);
348
+ }
349
+ const data = await response.json();
350
+ if (process.env.GH_MANAGER_DEBUG) {
351
+ console.log("\u{1F4E8} GitHub response:", JSON.stringify(data, null, 2));
352
+ }
353
+ if (data.access_token) {
354
+ if (process.env.GH_MANAGER_DEBUG) {
355
+ console.log("\u2705 Authorization successful! Token received.");
356
+ }
357
+ return data.access_token;
358
+ }
359
+ if (data.error) {
360
+ if (process.env.GH_MANAGER_DEBUG) {
361
+ console.log(`\u26A0\uFE0F GitHub error: ${data.error}`);
362
+ }
363
+ switch (data.error) {
364
+ case "authorization_pending":
365
+ continue;
366
+ case "slow_down":
367
+ if (process.env.GH_MANAGER_DEBUG) {
368
+ console.log("\u{1F40C} GitHub requested slow down, waiting extra 5 seconds");
369
+ }
370
+ await sleep(5e3);
371
+ continue;
372
+ case "expired_token":
373
+ throw new Error("The device code has expired. Please try again.");
374
+ case "access_denied":
375
+ throw new Error("Authorization was denied.");
376
+ default:
377
+ throw new Error(`${data.error}: ${data.error_description || "Unknown error"}`);
378
+ }
379
+ }
380
+ if (process.env.GH_MANAGER_DEBUG) {
381
+ console.log("\u{1F914} Unexpected response format, continuing to poll...");
382
+ }
383
+ } catch (error) {
384
+ if (process.env.GH_MANAGER_DEBUG) {
385
+ console.log("\u274C Polling error:", error.message);
386
+ }
387
+ if (error.message.includes("access_denied") || error.message.includes("expired_token")) {
388
+ throw error;
389
+ }
390
+ if (process.env.GH_MANAGER_DEBUG) {
391
+ console.log("\u{1F504} Continuing to poll despite error...");
392
+ }
393
+ }
394
+ }
395
+ throw new Error("OAuth flow timed out. Please try again.");
396
+ }
397
+ function sleep(ms) {
398
+ return new Promise((resolve) => setTimeout(resolve, ms));
399
+ }
400
+ async function openGitHubAuthorizationPage() {
401
+ const authUrl = `https://github.com/settings/connections/applications/${OAUTH_CONFIG.CLIENT_ID}`;
402
+ await open(authUrl);
403
+ }
404
+
211
405
  // src/ui/RepoList.tsx
212
- import React9, { useEffect as useEffect6, useMemo, useState as useState9, useRef } from "react";
213
- import { Box as Box12, Text as Text13, useApp, useInput as useInput9, useStdout } from "ink";
214
- import TextInput3 from "ink-text-input";
215
- import chalk10 from "chalk";
406
+ import React10, { useEffect as useEffect7, useMemo, useState as useState10, useRef } from "react";
407
+ import { Box as Box13, Text as Text14, useApp, useInput as useInput10, useStdout } from "ink";
408
+ import TextInput4 from "ink-text-input";
409
+ import chalk11 from "chalk";
216
410
 
217
411
  // src/apolloMeta.ts
218
412
  import fs2 from "fs";
@@ -282,34 +476,60 @@ function OrgSwitcher({ token, currentContext, onSelect, onClose }) {
282
476
  const [loading, setLoading] = useState(true);
283
477
  const [error, setError] = useState(null);
284
478
  const [cursor, setCursor] = useState(0);
479
+ const [enterpriseOrgs, setEnterpriseOrgs] = useState(/* @__PURE__ */ new Set());
480
+ const [showReauthorizeOption, setShowReauthorizeOption] = useState(false);
481
+ const [refreshing, setRefreshing] = useState(false);
285
482
  const isPersonalContext = currentContext === "personal";
286
- useEffect(() => {
287
- const loadOrgs = async () => {
288
- try {
289
- setLoading(true);
290
- const client = await import("./github-GO2ZQWZN.js").then((m) => m.makeClient(token));
291
- const orgs = await fetchViewerOrganizations(client);
292
- setOrganizations(orgs);
293
- if (!isPersonalContext) {
294
- const orgLogin2 = currentContext.login;
295
- const index = orgs.findIndex((org) => org.login === orgLogin2);
296
- if (index !== -1) {
297
- setCursor(index + 1);
298
- }
483
+ const loadOrgs = async () => {
484
+ try {
485
+ setLoading(true);
486
+ setError(null);
487
+ const client = await import("./github-YDCON2PN.js").then((m) => m.makeClient(token));
488
+ const orgs = await fetchViewerOrganizations(client);
489
+ setOrganizations(orgs);
490
+ const entOrgs = /* @__PURE__ */ new Set();
491
+ for (const org of orgs) {
492
+ const isEnt = await checkOrganizationIsEnterprise(client, org.login);
493
+ if (isEnt) {
494
+ entOrgs.add(org.login);
299
495
  }
300
- } catch (e) {
301
- setError(e.message || "Failed to load organizations");
302
- } finally {
303
- setLoading(false);
304
496
  }
305
- };
497
+ setEnterpriseOrgs(entOrgs);
498
+ if (!isPersonalContext) {
499
+ const orgLogin2 = currentContext.login;
500
+ const index = orgs.findIndex((org) => org.login === orgLogin2);
501
+ if (index !== -1) {
502
+ setCursor(index + 1);
503
+ }
504
+ }
505
+ } catch (e) {
506
+ setError(e.message || "Failed to load organisations");
507
+ } finally {
508
+ setLoading(false);
509
+ setRefreshing(false);
510
+ }
511
+ };
512
+ useEffect(() => {
306
513
  loadOrgs();
307
- }, [token, currentContext, isPersonalContext]);
514
+ }, []);
308
515
  useInput((input, key) => {
309
516
  if (key.escape) {
310
517
  onClose();
311
518
  return;
312
519
  }
520
+ if (input?.toLowerCase() === "r" && !refreshing && !loading) {
521
+ setRefreshing(true);
522
+ loadOrgs();
523
+ return;
524
+ }
525
+ if (key.ctrl && input === "w") {
526
+ process.nextTick(() => {
527
+ openGitHubAuthorizationPage().catch((err) => {
528
+ setError("Failed to open GitHub authorisation page");
529
+ });
530
+ });
531
+ return;
532
+ }
313
533
  if (key.return) {
314
534
  if (cursor === 0) {
315
535
  onSelect("personal");
@@ -330,14 +550,30 @@ function OrgSwitcher({ token, currentContext, onSelect, onClose }) {
330
550
  }
331
551
  });
332
552
  const totalItems = organizations.length + 1;
333
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 3, paddingY: 2, width: 60, children: [
334
- /* @__PURE__ */ jsx(Text, { bold: true, children: "Switch Account/Organization" }),
335
- loading ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: "Loading organizations..." }) : error ? /* @__PURE__ */ jsx(Text, { color: "red", children: error }) : /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
336
- /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { children: cursor === 0 ? chalk.bgCyan.black(" \u2192 ") + " " + chalk.bold("Personal Account") : " " + chalk.gray("Personal Account") }) }),
337
- organizations.map((org, index) => /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { children: cursor === index + 1 ? chalk.bgCyan.black(" \u2192 ") + " " + chalk.bold(org.name || org.login) + chalk.gray(` (@${org.login})`) : " " + chalk.gray(org.name || org.login) + chalk.gray(` (@${org.login})`) }) }, org.id)),
338
- organizations.length === 0 && /* @__PURE__ */ jsx(Text, { color: "gray", dimColor: true, children: "No organizations found" })
553
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, width: 50, children: [
554
+ /* @__PURE__ */ jsxs(Text, { bold: true, children: [
555
+ "Switch Account ",
556
+ refreshing && /* @__PURE__ */ jsx(Text, { color: "yellow", children: "(Refreshing...)" })
339
557
  ] }),
340
- /* @__PURE__ */ jsx(Box, { marginTop: 2, children: /* @__PURE__ */ jsx(Text, { color: "gray", children: "\u2191/\u2193 Navigate \u2022 Enter Select \u2022 Esc Cancel" }) })
558
+ loading && !refreshing ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: "Loading..." }) : error ? /* @__PURE__ */ jsx(Text, { color: "red", children: error }) : /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
559
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { children: cursor === 0 ? chalk.bgCyan.black(" \u2192 ") + " " + chalk.bold("Personal Account") + (isPersonalContext ? chalk.green(" \u2713") : "") : " " + chalk.gray("Personal Account") + (isPersonalContext ? chalk.green(" \u2713") : "") }) }),
560
+ organizations.map((org, index) => {
561
+ const isEnterprise = enterpriseOrgs.has(org.login);
562
+ const isCurrent = cursor === index + 1;
563
+ const isActiveContext = !isPersonalContext && currentContext.login === org.login;
564
+ return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { children: isCurrent ? chalk.bgCyan.black(" \u2192 ") + " " + chalk.bold(org.name || org.login) + (isEnterprise ? chalk.yellow(" (ENT)") : "") + chalk.gray(` (@${org.login})`) + (isActiveContext ? chalk.green(" \u2713") : "") : " " + chalk.gray(org.name || org.login) + (isEnterprise ? chalk.gray(" (ENT)") : "") + chalk.gray(` (@${org.login})`) + (isActiveContext ? chalk.green(" \u2713") : "") }) }, org.id);
565
+ }),
566
+ organizations.length === 0 && /* @__PURE__ */ jsx(Text, { color: "gray", dimColor: true, children: "No organisations found" })
567
+ ] }),
568
+ /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
569
+ /* @__PURE__ */ jsx(Text, { color: "gray", dimColor: true, children: "\u2191\u2193/Enter \u2022 R Refresh \u2022 Esc" }),
570
+ /* @__PURE__ */ jsx(Box, { height: 1, children: /* @__PURE__ */ jsx(Text, { children: " " }) }),
571
+ /* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
572
+ "Not seeing your organisations? Press ",
573
+ /* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "Ctrl+W" }),
574
+ " to manage GitHub access"
575
+ ] })
576
+ ] })
341
577
  ] });
342
578
  }
343
579
 
@@ -416,11 +652,11 @@ import chalk7 from "chalk";
416
652
  import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
417
653
  function VisibilityModal({
418
654
  currentFilter,
419
- hasInternalRepos,
655
+ isEnterprise,
420
656
  onSelect,
421
657
  onCancel
422
658
  }) {
423
- const options = hasInternalRepos ? ["all", "public", "private", "internal"] : ["all", "public", "private"];
659
+ const options = ["all", "public", "private"];
424
660
  const [selectedIndex, setSelectedIndex] = useState7(0);
425
661
  const [focusedOption, setFocusedOption] = useState7("all");
426
662
  useEffect4(() => {
@@ -488,8 +724,6 @@ function VisibilityModal({
488
724
  onSelect("public");
489
725
  } else if (upperInput === "R") {
490
726
  onSelect("private");
491
- } else if (upperInput === "I" && hasInternalRepos) {
492
- onSelect("internal");
493
727
  }
494
728
  }
495
729
  });
@@ -500,9 +734,7 @@ function VisibilityModal({
500
734
  case "public":
501
735
  return "Public Only";
502
736
  case "private":
503
- return "Private Only";
504
- case "internal":
505
- return "Internal Only";
737
+ return isEnterprise ? "Private/Internal" : "Private Only";
506
738
  }
507
739
  };
508
740
  const getButtonColor = (filter) => {
@@ -511,45 +743,20 @@ function VisibilityModal({
511
743
  }
512
744
  return focusedOption === filter ? "cyan" : "gray";
513
745
  };
514
- return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 3, paddingY: 2, width: 60, children: [
746
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, width: 45, children: [
515
747
  /* @__PURE__ */ jsx8(Text8, { bold: true, children: "Visibility Filter" }),
516
- /* @__PURE__ */ jsx8(Box7, { height: 1, children: /* @__PURE__ */ jsx8(Text8, { children: " " }) }),
517
- /* @__PURE__ */ jsx8(Text8, { color: "gray", children: "Select which repositories to display:" }),
518
- /* @__PURE__ */ jsx8(Box7, { height: 1, children: /* @__PURE__ */ jsx8(Text8, { children: " " }) }),
519
- /* @__PURE__ */ jsx8(Box7, { flexDirection: "column", gap: 1, children: options.map((option) => /* @__PURE__ */ jsx8(
520
- Box7,
521
- {
522
- borderStyle: focusedOption === option ? "round" : "single",
523
- borderColor: getButtonColor(option),
524
- paddingX: 2,
525
- paddingY: 1,
526
- width: "100%",
527
- children: /* @__PURE__ */ jsxs7(Box7, { flexDirection: "row", justifyContent: "space-between", children: [
528
- /* @__PURE__ */ jsx8(Text8, { color: focusedOption === option ? "white" : void 0, children: focusedOption === option ? chalk7[getButtonColor(option)].bold(getButtonLabel(option)) : chalk7[getButtonColor(option)](getButtonLabel(option)) }),
529
- option === currentFilter && /* @__PURE__ */ jsx8(Text8, { color: "green", children: " \u2713 Current" })
530
- ] })
531
- },
532
- option
533
- )) }),
534
- /* @__PURE__ */ jsx8(Box7, { height: 1, children: /* @__PURE__ */ jsx8(Text8, { children: " " }) }),
535
- /* @__PURE__ */ jsx8(
536
- Box7,
537
- {
538
- borderStyle: focusedOption === "cancel" ? "round" : "single",
539
- borderColor: focusedOption === "cancel" ? "white" : "gray",
540
- paddingX: 2,
541
- paddingY: 1,
542
- width: "100%",
543
- justifyContent: "center",
544
- children: /* @__PURE__ */ jsx8(Text8, { children: focusedOption === "cancel" ? chalk7.white.bold("Cancel") : chalk7.gray("Cancel") })
545
- }
546
- ),
547
- /* @__PURE__ */ jsx8(Box7, { height: 1, children: /* @__PURE__ */ jsx8(Text8, { children: " " }) }),
548
- /* @__PURE__ */ jsx8(Box7, { flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs7(Text8, { color: "gray", children: [
549
- "\u2191\u2193 Navigate \u2022 Enter Select \u2022 A All \u2022 P Public \u2022 R Private",
550
- hasInternalRepos && " \u2022 I Internal",
551
- " \u2022 C/Esc Cancel"
552
- ] }) })
748
+ /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", marginTop: 1, children: [
749
+ options.map((option) => /* @__PURE__ */ jsx8(Box7, { paddingX: 1, children: /* @__PURE__ */ jsxs7(Text8, { children: [
750
+ focusedOption === option ? chalk7.bgCyan.black(" \u2192 ") : " ",
751
+ focusedOption === option ? chalk7[getButtonColor(option)].bold(getButtonLabel(option)) : chalk7[getButtonColor(option)](getButtonLabel(option)),
752
+ option === currentFilter && chalk7.green(" \u2713")
753
+ ] }) }, option)),
754
+ /* @__PURE__ */ jsx8(Box7, { paddingX: 1, children: /* @__PURE__ */ jsxs7(Text8, { children: [
755
+ focusedOption === "cancel" ? chalk7.bgWhite.black(" \u2192 ") : " ",
756
+ focusedOption === "cancel" ? chalk7.white.bold("Cancel") : chalk7.gray("Cancel")
757
+ ] }) })
758
+ ] }),
759
+ /* @__PURE__ */ jsx8(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text8, { color: "gray", dimColor: true, children: "\u2191\u2193/Enter \u2022 A/P/R \u2022 Esc" }) })
553
760
  ] });
554
761
  }
555
762
 
@@ -666,51 +873,235 @@ function SortModal({
666
873
  }
667
874
  return focusedOption === sort ? "cyan" : "gray";
668
875
  };
669
- return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 3, paddingY: 2, width: 60, children: [
876
+ return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, width: 40, children: [
670
877
  /* @__PURE__ */ jsx9(Text9, { bold: true, children: "Sort By" }),
671
- /* @__PURE__ */ jsx9(Box8, { height: 1, children: /* @__PURE__ */ jsx9(Text9, { children: " " }) }),
672
- /* @__PURE__ */ jsx9(Text9, { color: "gray", children: "Select how to sort repositories:" }),
673
- /* @__PURE__ */ jsx9(Box8, { height: 1, children: /* @__PURE__ */ jsx9(Text9, { children: " " }) }),
674
- /* @__PURE__ */ jsx9(Box8, { flexDirection: "column", gap: 1, children: options.map((option) => /* @__PURE__ */ jsx9(
675
- Box8,
676
- {
677
- borderStyle: focusedOption === option ? "round" : "single",
678
- borderColor: getButtonColor(option),
679
- paddingX: 2,
680
- paddingY: 1,
681
- width: "100%",
682
- children: /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
683
- /* @__PURE__ */ jsxs8(Box8, { flexDirection: "row", justifyContent: "space-between", children: [
684
- /* @__PURE__ */ jsx9(Text9, { color: focusedOption === option ? "white" : void 0, children: focusedOption === option ? chalk8[getButtonColor(option)].bold(getButtonLabel(option)) : chalk8[getButtonColor(option)](getButtonLabel(option)) }),
685
- option === currentSort && /* @__PURE__ */ jsx9(Text9, { color: "green", children: " \u2713 Current" })
686
- ] }),
687
- /* @__PURE__ */ jsx9(Text9, { color: "gray", dimColor: true, children: getButtonDescription(option) })
688
- ] })
689
- },
690
- option
691
- )) }),
692
- /* @__PURE__ */ jsx9(Box8, { height: 1, children: /* @__PURE__ */ jsx9(Text9, { children: " " }) }),
693
- /* @__PURE__ */ jsx9(
694
- Box8,
695
- {
696
- borderStyle: focusedOption === "cancel" ? "round" : "single",
697
- borderColor: focusedOption === "cancel" ? "white" : "gray",
698
- paddingX: 2,
699
- paddingY: 1,
700
- width: "100%",
701
- justifyContent: "center",
702
- children: /* @__PURE__ */ jsx9(Text9, { children: focusedOption === "cancel" ? chalk8.white.bold("Cancel") : chalk8.gray("Cancel") })
703
- }
704
- ),
705
- /* @__PURE__ */ jsx9(Box8, { height: 1, children: /* @__PURE__ */ jsx9(Text9, { children: " " }) }),
706
- /* @__PURE__ */ jsx9(Box8, { flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsx9(Text9, { color: "gray", children: "\u2191\u2193 Navigate \u2022 Enter Select \u2022 U Updated \u2022 P Pushed \u2022 N Name \u2022 S Stars \u2022 C/Esc Cancel" }) })
878
+ /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginTop: 1, children: [
879
+ options.map((option) => /* @__PURE__ */ jsx9(Box8, { paddingX: 1, children: /* @__PURE__ */ jsxs8(Text9, { children: [
880
+ focusedOption === option ? chalk8.bgCyan.black(" \u2192 ") : " ",
881
+ focusedOption === option ? chalk8[getButtonColor(option)].bold(getButtonLabel(option)) : chalk8[getButtonColor(option)](getButtonLabel(option)),
882
+ option === currentSort && chalk8.green(" \u2713")
883
+ ] }) }, option)),
884
+ /* @__PURE__ */ jsx9(Box8, { paddingX: 1, children: /* @__PURE__ */ jsxs8(Text9, { children: [
885
+ focusedOption === "cancel" ? chalk8.bgWhite.black(" \u2192 ") : " ",
886
+ focusedOption === "cancel" ? chalk8.white.bold("Cancel") : chalk8.gray("Cancel")
887
+ ] }) })
888
+ ] }),
889
+ /* @__PURE__ */ jsx9(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text9, { color: "gray", dimColor: true, children: "\u2191\u2193/Enter \u2022 U/P/N/S \u2022 Esc" }) })
707
890
  ] });
708
891
  }
709
892
 
710
- // src/ui/components/repo/RepoRow.tsx
711
- import { Box as Box9, Text as Text10 } from "ink";
893
+ // src/ui/components/modals/ChangeVisibilityModal.tsx
894
+ import { useState as useState9, useEffect as useEffect6 } from "react";
895
+ import { Box as Box9, Text as Text10, useInput as useInput9 } from "ink";
896
+ import TextInput2 from "ink-text-input";
712
897
  import chalk9 from "chalk";
713
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
898
+ import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
899
+ var ChangeVisibilityModal = ({
900
+ isOpen,
901
+ repoName,
902
+ currentVisibility,
903
+ isFork = false,
904
+ isEnterprise = false,
905
+ onVisibilityChange,
906
+ onClose,
907
+ changing: externalChanging,
908
+ error: externalError
909
+ }) => {
910
+ const getAvailableOptions = () => {
911
+ if (currentVisibility === "PUBLIC") {
912
+ return isEnterprise ? ["PRIVATE", "INTERNAL"] : ["PRIVATE"];
913
+ } else if (currentVisibility === "PRIVATE") {
914
+ return isEnterprise ? ["PUBLIC", "INTERNAL"] : ["PUBLIC"];
915
+ } else if (currentVisibility === "INTERNAL") {
916
+ return ["PUBLIC", "PRIVATE"];
917
+ }
918
+ return ["PUBLIC"];
919
+ };
920
+ const availableOptions = getAvailableOptions();
921
+ const [selectedOptionIndex, setSelectedOptionIndex] = useState9(0);
922
+ const [focusedButton, setFocusedButton] = useState9(isFork ? "cancel" : "option");
923
+ const changing = externalChanging ?? false;
924
+ const error = externalError ?? null;
925
+ useEffect6(() => {
926
+ if (isOpen) {
927
+ setSelectedOptionIndex(0);
928
+ setFocusedButton(isFork ? "cancel" : "option");
929
+ }
930
+ }, [isOpen, isFork]);
931
+ useInput9((input, key) => {
932
+ if (!isOpen) return;
933
+ if (key.escape || input?.toLowerCase() === "c") {
934
+ onClose();
935
+ return;
936
+ }
937
+ if (!isFork) {
938
+ if (key.leftArrow) {
939
+ if (focusedButton === "cancel") {
940
+ setFocusedButton("option");
941
+ } else if (availableOptions.length > 1 && selectedOptionIndex > 0) {
942
+ setSelectedOptionIndex(selectedOptionIndex - 1);
943
+ }
944
+ return;
945
+ }
946
+ if (key.rightArrow) {
947
+ if (focusedButton === "option") {
948
+ if (selectedOptionIndex < availableOptions.length - 1) {
949
+ setSelectedOptionIndex(selectedOptionIndex + 1);
950
+ } else {
951
+ setFocusedButton("cancel");
952
+ }
953
+ }
954
+ return;
955
+ }
956
+ if (key.upArrow || key.downArrow) {
957
+ if (focusedButton === "option" && availableOptions.length > 1) {
958
+ setSelectedOptionIndex((selectedOptionIndex + 1) % availableOptions.length);
959
+ }
960
+ return;
961
+ }
962
+ if (input?.toLowerCase() === "y") {
963
+ if (focusedButton === "cancel") {
964
+ onClose();
965
+ return;
966
+ }
967
+ handleChange();
968
+ return;
969
+ }
970
+ }
971
+ });
972
+ const handleChange = () => {
973
+ if (isFork) return;
974
+ const newVisibility = availableOptions[selectedOptionIndex];
975
+ onVisibilityChange(newVisibility);
976
+ };
977
+ if (!isOpen) return null;
978
+ const getVisibilityLabel = (vis) => {
979
+ switch (vis) {
980
+ case "PUBLIC":
981
+ return "Public";
982
+ case "PRIVATE":
983
+ return "Private";
984
+ case "INTERNAL":
985
+ return "Internal";
986
+ default:
987
+ return vis;
988
+ }
989
+ };
990
+ const getVisibilityColor = (vis) => {
991
+ switch (vis) {
992
+ case "PUBLIC":
993
+ return "green";
994
+ case "PRIVATE":
995
+ return "yellow";
996
+ case "INTERNAL":
997
+ return "cyan";
998
+ default:
999
+ return "white";
1000
+ }
1001
+ };
1002
+ const borderColor = isFork ? "red" : getVisibilityColor(currentVisibility);
1003
+ return /* @__PURE__ */ jsxs9(
1004
+ Box9,
1005
+ {
1006
+ flexDirection: "column",
1007
+ borderStyle: "round",
1008
+ borderColor,
1009
+ paddingX: 3,
1010
+ paddingY: 2,
1011
+ width: 80,
1012
+ children: [
1013
+ /* @__PURE__ */ jsx10(Text10, { bold: true, children: isFork ? "Visibility Change Not Available" : "Change Repository Visibility" }),
1014
+ isFork ? /* @__PURE__ */ jsxs9(Fragment4, { children: [
1015
+ /* @__PURE__ */ jsx10(Text10, { color: "red", children: "\u26A0\uFE0F Cannot change visibility of forked repositories" }),
1016
+ /* @__PURE__ */ jsx10(Box9, { height: 1, children: /* @__PURE__ */ jsx10(Text10, { children: " " }) }),
1017
+ /* @__PURE__ */ jsx10(Text10, { children: repoName }),
1018
+ /* @__PURE__ */ jsx10(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text10, { children: "GitHub does not allow changing the visibility of forked repositories. The fork must have the same visibility as its parent repository." }) }),
1019
+ /* @__PURE__ */ jsx10(Box9, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsx10(
1020
+ Box9,
1021
+ {
1022
+ borderStyle: "round",
1023
+ borderColor: "white",
1024
+ height: 3,
1025
+ width: 20,
1026
+ alignItems: "center",
1027
+ justifyContent: "center",
1028
+ flexDirection: "column",
1029
+ children: /* @__PURE__ */ jsx10(Text10, { children: chalk9.bgGray.white.bold(" Cancel ") })
1030
+ }
1031
+ ) }),
1032
+ /* @__PURE__ */ jsx10(Box9, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsx10(Text10, { color: "gray", children: "Press Enter to Cancel \u2022 C to cancel" }) })
1033
+ ] }) : /* @__PURE__ */ jsxs9(Fragment4, { children: [
1034
+ /* @__PURE__ */ jsx10(Text10, { color: borderColor, children: "\u26A0\uFE0F Change repository visibility?" }),
1035
+ /* @__PURE__ */ jsx10(Box9, { height: 1, children: /* @__PURE__ */ jsx10(Text10, { children: " " }) }),
1036
+ /* @__PURE__ */ jsx10(Text10, { children: repoName }),
1037
+ /* @__PURE__ */ jsx10(Box9, { marginTop: 1, children: /* @__PURE__ */ jsxs9(Text10, { children: [
1038
+ "Current visibility:",
1039
+ " ",
1040
+ /* @__PURE__ */ jsx10(Text10, { color: getVisibilityColor(currentVisibility), children: getVisibilityLabel(currentVisibility) })
1041
+ ] }) }),
1042
+ /* @__PURE__ */ jsx10(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text10, { children: "Change to:" }) }),
1043
+ /* @__PURE__ */ jsxs9(Box9, { marginTop: 1, flexDirection: "row", justifyContent: "center", gap: 3, children: [
1044
+ availableOptions.map((option, index) => /* @__PURE__ */ jsx10(
1045
+ Box9,
1046
+ {
1047
+ borderStyle: "round",
1048
+ borderColor: focusedButton === "option" && selectedOptionIndex === index ? getVisibilityColor(option) : "gray",
1049
+ height: 3,
1050
+ width: 18,
1051
+ alignItems: "center",
1052
+ justifyContent: "center",
1053
+ flexDirection: "column",
1054
+ children: /* @__PURE__ */ jsx10(Text10, { children: focusedButton === "option" && selectedOptionIndex === index ? chalk9[`bg${getVisibilityLabel(option) === "Public" ? "Green" : getVisibilityLabel(option) === "Private" ? "Yellow" : "Cyan"}`].black.bold(` ${getVisibilityLabel(option)} `) : chalk9[getVisibilityColor(option)](getVisibilityLabel(option)) })
1055
+ },
1056
+ option
1057
+ )),
1058
+ /* @__PURE__ */ jsx10(
1059
+ Box9,
1060
+ {
1061
+ borderStyle: "round",
1062
+ borderColor: focusedButton === "cancel" ? "white" : "gray",
1063
+ height: 3,
1064
+ width: 18,
1065
+ alignItems: "center",
1066
+ justifyContent: "center",
1067
+ flexDirection: "column",
1068
+ children: /* @__PURE__ */ jsx10(Text10, { children: focusedButton === "cancel" ? chalk9.bgGray.white.bold(" Cancel ") : chalk9.gray.bold("Cancel") })
1069
+ }
1070
+ )
1071
+ ] }),
1072
+ /* @__PURE__ */ jsx10(Box9, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs9(Text10, { color: "gray", children: [
1073
+ availableOptions.length > 1 ? "\u2191\u2193 Select Option \u2022 " : "",
1074
+ "\u2190 \u2192 Navigate \u2022 Press Enter to ",
1075
+ focusedButton === "option" ? "Change" : "Cancel",
1076
+ " \u2022 Y to confirm \u2022 C to cancel"
1077
+ ] }) })
1078
+ ] }),
1079
+ /* @__PURE__ */ jsx10(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx10(
1080
+ TextInput2,
1081
+ {
1082
+ value: "",
1083
+ onChange: () => {
1084
+ },
1085
+ onSubmit: () => {
1086
+ if (isFork || focusedButton === "cancel") {
1087
+ onClose();
1088
+ } else {
1089
+ handleChange();
1090
+ }
1091
+ }
1092
+ }
1093
+ ) }),
1094
+ error && /* @__PURE__ */ jsx10(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text10, { color: "magenta", children: error }) }),
1095
+ changing && /* @__PURE__ */ jsx10(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text10, { color: "yellow", children: "Changing visibility..." }) })
1096
+ ]
1097
+ }
1098
+ );
1099
+ };
1100
+
1101
+ // src/ui/components/repo/RepoRow.tsx
1102
+ import { Box as Box10, Text as Text11 } from "ink";
1103
+ import chalk10 from "chalk";
1104
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
714
1105
  function RepoRow({
715
1106
  repo,
716
1107
  selected,
@@ -726,46 +1117,50 @@ function RepoRow({
726
1117
  const commitsBehind = hasCommitData ? repo.parent.defaultBranchRef.target.history.totalCount - repo.defaultBranchRef.target.history.totalCount : 0;
727
1118
  const showCommitsBehind = forkTracking && hasCommitData;
728
1119
  let line1 = "";
729
- const numColor = selected ? chalk9.cyan : chalk9.gray;
730
- const nameColor = selected ? chalk9.cyan.bold : chalk9.white;
1120
+ const numColor = selected ? chalk10.cyan : chalk10.gray;
1121
+ const nameColor = selected ? chalk10.cyan.bold : chalk10.white;
731
1122
  line1 += numColor(`${String(index).padStart(3, " ")}.`);
732
1123
  line1 += nameColor(` ${repo.nameWithOwner}`);
733
- if (repo.isPrivate) line1 += chalk9.yellow(" Private");
734
- if (repo.isArchived) line1 += " " + chalk9.bgGray.whiteBright(" Archived ") + " ";
1124
+ if (repo.visibility === "INTERNAL") {
1125
+ line1 += chalk10.magenta(" Internal");
1126
+ } else if (repo.visibility === "PRIVATE" || repo.isPrivate && !repo.visibility) {
1127
+ line1 += chalk10.yellow(" Private");
1128
+ }
1129
+ if (repo.isArchived) line1 += " " + chalk10.bgGray.whiteBright(" Archived ") + " ";
735
1130
  if (repo.isFork && repo.parent) {
736
- line1 += chalk9.blue(` Fork of ${repo.parent.nameWithOwner}`);
1131
+ line1 += chalk10.blue(` Fork of ${repo.parent.nameWithOwner}`);
737
1132
  if (showCommitsBehind) {
738
1133
  if (commitsBehind > 0) {
739
- line1 += chalk9.yellow(` (${commitsBehind} behind)`);
1134
+ line1 += chalk10.yellow(` (${commitsBehind} behind)`);
740
1135
  } else {
741
- line1 += chalk9.green(` (0 behind)`);
1136
+ line1 += chalk10.green(` (0 behind)`);
742
1137
  }
743
1138
  }
744
1139
  }
745
1140
  let line2 = " ";
746
- const metaColor = selected ? chalk9.white : chalk9.gray;
747
- if (langName) line2 += chalk9.hex(langColor)("\u25CF ") + metaColor(`${langName} `);
1141
+ const metaColor = selected ? chalk10.white : chalk10.gray;
1142
+ if (langName) line2 += chalk10.hex(langColor)("\u25CF ") + metaColor(`${langName} `);
748
1143
  line2 += metaColor(`\u2605 ${repo.stargazerCount} \u2442 ${repo.forkCount} Updated ${formatDate(repo.updatedAt)}`);
749
1144
  const line3 = repo.description ? ` ${truncate(repo.description, Math.max(30, maxWidth - 10))}` : null;
750
1145
  let fullText = line1 + "\n" + line2;
751
1146
  if (line3) fullText += "\n" + metaColor(line3);
752
1147
  const spacingAbove = Math.floor(spacingLines / 2);
753
1148
  const spacingBelow = spacingLines - spacingAbove;
754
- return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", backgroundColor: selected ? "gray" : void 0, children: [
755
- spacingAbove > 0 && /* @__PURE__ */ jsx10(Box9, { height: spacingAbove, children: /* @__PURE__ */ jsx10(Text10, { children: " " }) }),
756
- /* @__PURE__ */ jsx10(Text10, { children: dim ? chalk9.dim(fullText) : fullText }),
757
- spacingBelow > 0 && /* @__PURE__ */ jsx10(Box9, { height: spacingBelow, children: /* @__PURE__ */ jsx10(Text10, { children: " " }) })
1149
+ return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", backgroundColor: selected ? "gray" : void 0, children: [
1150
+ spacingAbove > 0 && /* @__PURE__ */ jsx11(Box10, { height: spacingAbove, children: /* @__PURE__ */ jsx11(Text11, { children: " " }) }),
1151
+ /* @__PURE__ */ jsx11(Text11, { children: dim ? chalk10.dim(fullText) : fullText }),
1152
+ spacingBelow > 0 && /* @__PURE__ */ jsx11(Box10, { height: spacingBelow, children: /* @__PURE__ */ jsx11(Text11, { children: " " }) })
758
1153
  ] });
759
1154
  }
760
1155
 
761
1156
  // src/ui/components/repo/FilterInput.tsx
762
- import { Box as Box10, Text as Text11 } from "ink";
763
- import TextInput2 from "ink-text-input";
764
- import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
1157
+ import { Box as Box11, Text as Text12 } from "ink";
1158
+ import TextInput3 from "ink-text-input";
1159
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
765
1160
 
766
1161
  // src/ui/components/repo/RepoListHeader.tsx
767
- import { Box as Box11, Text as Text12 } from "ink";
768
- import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
1162
+ import { Box as Box12, Text as Text13 } from "ink";
1163
+ import { Fragment as Fragment5, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
769
1164
  function RepoListHeader({
770
1165
  ownerContext,
771
1166
  sortKey,
@@ -774,37 +1169,40 @@ function RepoListHeader({
774
1169
  filter,
775
1170
  searchActive,
776
1171
  searchLoading,
777
- visibilityFilter = "all"
1172
+ visibilityFilter = "all",
1173
+ isEnterprise = false
778
1174
  }) {
779
- return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "row", gap: 2, marginBottom: 1, children: [
780
- /* @__PURE__ */ jsx12(Text12, { color: "cyan", bold: true, children: ownerContext === "personal" ? "Personal Account" : `Organization: ${ownerContext.name || ownerContext.login}` }),
781
- /* @__PURE__ */ jsxs11(Text12, { color: "gray", dimColor: true, children: [
1175
+ const contextLabel = ownerContext === "personal" ? "Personal Account" : ownerContext?.type === "organization" ? `Organization: ${ownerContext.name ?? ownerContext.login}` : "";
1176
+ const visibilityLabel = visibilityFilter === "public" ? "Public" : visibilityFilter === "private" ? isEnterprise ? "Private/Internal" : "Private" : visibilityFilter === "internal" ? "Internal" : "";
1177
+ return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", gap: 2, marginBottom: 1, children: [
1178
+ contextLabel && /* @__PURE__ */ jsx13(Text13, { children: contextLabel }),
1179
+ /* @__PURE__ */ jsxs12(Text13, { color: "gray", dimColor: true, children: [
782
1180
  "Sort: ",
783
1181
  sortKey,
784
1182
  " ",
785
1183
  sortDir === "asc" ? "\u2191" : "\u2193"
786
1184
  ] }),
787
- /* @__PURE__ */ jsxs11(Text12, { color: "gray", dimColor: true, children: [
1185
+ /* @__PURE__ */ jsxs12(Text13, { color: "gray", dimColor: true, children: [
788
1186
  "Fork Status - Commits Behind: ",
789
1187
  forkTracking ? "ON" : "OFF"
790
1188
  ] }),
791
- visibilityFilter !== "all" && /* @__PURE__ */ jsxs11(Text12, { color: "yellow", children: [
1189
+ !!visibilityLabel && /* @__PURE__ */ jsxs12(Text13, { color: "yellow", children: [
792
1190
  "Visibility: ",
793
- visibilityFilter === "public" ? "Public" : visibilityFilter === "private" ? "Private" : "Internal"
1191
+ visibilityLabel
794
1192
  ] }),
795
- filter && !searchActive && /* @__PURE__ */ jsxs11(Text12, { color: "cyan", children: [
1193
+ filter && !searchActive && /* @__PURE__ */ jsxs12(Text13, { color: "cyan", children: [
796
1194
  'Filter: "',
797
1195
  filter,
798
1196
  '"'
799
1197
  ] }),
800
- searchActive && /* @__PURE__ */ jsxs11(Fragment4, { children: [
801
- /* @__PURE__ */ jsxs11(Text12, { color: "cyan", children: [
1198
+ searchActive && /* @__PURE__ */ jsxs12(Fragment5, { children: [
1199
+ /* @__PURE__ */ jsxs12(Text13, { color: "cyan", children: [
802
1200
  'Search: "',
803
1201
  filter.trim(),
804
1202
  '"'
805
1203
  ] }),
806
- searchLoading && /* @__PURE__ */ jsx12(Box11, { marginLeft: 1, children: /* @__PURE__ */ jsxs11(Text12, { color: "cyan", children: [
807
- /* @__PURE__ */ jsx12(SlowSpinner, {}),
1204
+ searchLoading && /* @__PURE__ */ jsx13(Box12, { marginLeft: 1, children: /* @__PURE__ */ jsxs12(Text13, { color: "cyan", children: [
1205
+ /* @__PURE__ */ jsx13(SlowSpinner, {}),
808
1206
  " Searching\u2026"
809
1207
  ] }) })
810
1208
  ] })
@@ -812,7 +1210,7 @@ function RepoListHeader({
812
1210
  }
813
1211
 
814
1212
  // src/ui/RepoList.tsx
815
- import { Fragment as Fragment5, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1213
+ import { Fragment as Fragment6, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
816
1214
  var getPageSize = () => {
817
1215
  const envValue = process.env.REPOS_PER_FETCH;
818
1216
  if (envValue) {
@@ -828,66 +1226,70 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
828
1226
  const { exit } = useApp();
829
1227
  const { stdout } = useStdout();
830
1228
  const client = useMemo(() => makeClient(token), [token]);
831
- const [debugMessages, setDebugMessages] = useState9([]);
1229
+ const [debugMessages, setDebugMessages] = useState10([]);
832
1230
  const addDebugMessage = (msg) => {
833
1231
  if (process.env.GH_MANAGER_DEBUG === "1") {
834
1232
  setDebugMessages((prev) => [...prev.slice(-9), msg]);
835
1233
  }
836
1234
  };
837
- React9.useEffect(() => {
1235
+ React10.useEffect(() => {
838
1236
  addDebugMessage(`[RepoList] Component mounted`);
839
1237
  }, []);
840
1238
  const terminalWidth = stdout?.columns ?? 80;
841
1239
  const availableHeight = maxVisibleRows ?? 20;
842
- const [items, setItems] = useState9([]);
843
- const [cursor, setCursor] = useState9(0);
844
- const [endCursor, setEndCursor] = useState9(null);
845
- const [hasNextPage, setHasNextPage] = useState9(false);
846
- const [totalCount, setTotalCount] = useState9(0);
847
- const [loading, setLoading] = useState9(true);
848
- const [sortingLoading, setSortingLoading] = useState9(false);
849
- const [refreshing, setRefreshing] = useState9(false);
850
- const [loadingMore, setLoadingMore] = useState9(false);
851
- const [error, setError] = useState9(null);
852
- const [rateLimit, setRateLimit] = useState9(void 0);
853
- const [prevRateLimit, setPrevRateLimit] = useState9(void 0);
854
- const [density, setDensity] = useState9(2);
855
- const [prefsLoaded, setPrefsLoaded] = useState9(false);
856
- const [ownerContext, setOwnerContext] = useState9("personal");
857
- const [ownerAffiliations, setOwnerAffiliations] = useState9(["OWNER"]);
858
- const [orgSwitcherOpen, setOrgSwitcherOpen] = useState9(false);
859
- const [searchItems, setSearchItems] = useState9([]);
860
- const [searchEndCursor, setSearchEndCursor] = useState9(null);
861
- const [searchHasNextPage, setSearchHasNextPage] = useState9(false);
862
- const [searchTotalCount, setSearchTotalCount] = useState9(0);
863
- const [searchLoading, setSearchLoading] = useState9(false);
864
- const [deleteMode, setDeleteMode] = useState9(false);
865
- const [deleteTarget, setDeleteTarget] = useState9(null);
866
- const [deleteCode, setDeleteCode] = useState9("");
867
- const [typedCode, setTypedCode] = useState9("");
868
- const [deleting, setDeleting] = useState9(false);
869
- const [deleteError, setDeleteError] = useState9(null);
870
- const [deleteConfirmStage, setDeleteConfirmStage] = useState9(false);
871
- const [confirmFocus, setConfirmFocus] = useState9("delete");
872
- const [archiveMode, setArchiveMode] = useState9(false);
873
- const [archiveTarget, setArchiveTarget] = useState9(null);
874
- const [archiving, setArchiving] = useState9(false);
875
- const [archiveError, setArchiveError] = useState9(null);
876
- const [archiveFocus, setArchiveFocus] = useState9("confirm");
877
- const [syncMode, setSyncMode] = useState9(false);
878
- const [syncTarget, setSyncTarget] = useState9(null);
879
- const [syncing, setSyncing] = useState9(false);
880
- const [syncError, setSyncError] = useState9(null);
881
- const [syncFocus, setSyncFocus] = useState9("confirm");
882
- const [syncTrigger, setSyncTrigger] = useState9(false);
883
- const [infoMode, setInfoMode] = useState9(false);
884
- const [infoRepo, setInfoRepo] = useState9(null);
885
- const [logoutMode, setLogoutMode] = useState9(false);
886
- const [logoutFocus, setLogoutFocus] = useState9("confirm");
887
- const [logoutError, setLogoutError] = useState9(null);
888
- const [visibilityMode, setVisibilityMode] = useState9(false);
889
- const [hasInternalRepos, setHasInternalRepos] = useState9(false);
890
- const [sortMode, setSortMode] = useState9(false);
1240
+ const [items, setItems] = useState10([]);
1241
+ const [cursor, setCursor] = useState10(0);
1242
+ const [endCursor, setEndCursor] = useState10(null);
1243
+ const [hasNextPage, setHasNextPage] = useState10(false);
1244
+ const [totalCount, setTotalCount] = useState10(0);
1245
+ const [loading, setLoading] = useState10(true);
1246
+ const [sortingLoading, setSortingLoading] = useState10(false);
1247
+ const [refreshing, setRefreshing] = useState10(false);
1248
+ const [loadingMore, setLoadingMore] = useState10(false);
1249
+ const [error, setError] = useState10(null);
1250
+ const [rateLimit, setRateLimit] = useState10(void 0);
1251
+ const [prevRateLimit, setPrevRateLimit] = useState10(void 0);
1252
+ const [density, setDensity] = useState10(2);
1253
+ const [prefsLoaded, setPrefsLoaded] = useState10(false);
1254
+ const [ownerContext, setOwnerContext] = useState10("personal");
1255
+ const [ownerAffiliations, setOwnerAffiliations] = useState10(["OWNER"]);
1256
+ const [orgSwitcherOpen, setOrgSwitcherOpen] = useState10(false);
1257
+ const [searchItems, setSearchItems] = useState10([]);
1258
+ const [searchEndCursor, setSearchEndCursor] = useState10(null);
1259
+ const [searchHasNextPage, setSearchHasNextPage] = useState10(false);
1260
+ const [searchTotalCount, setSearchTotalCount] = useState10(0);
1261
+ const [searchLoading, setSearchLoading] = useState10(false);
1262
+ const [deleteMode, setDeleteMode] = useState10(false);
1263
+ const [deleteTarget, setDeleteTarget] = useState10(null);
1264
+ const [deleteCode, setDeleteCode] = useState10("");
1265
+ const [typedCode, setTypedCode] = useState10("");
1266
+ const [deleting, setDeleting] = useState10(false);
1267
+ const [deleteError, setDeleteError] = useState10(null);
1268
+ const [deleteConfirmStage, setDeleteConfirmStage] = useState10(false);
1269
+ const [confirmFocus, setConfirmFocus] = useState10("delete");
1270
+ const [archiveMode, setArchiveMode] = useState10(false);
1271
+ const [archiveTarget, setArchiveTarget] = useState10(null);
1272
+ const [archiving, setArchiving] = useState10(false);
1273
+ const [archiveError, setArchiveError] = useState10(null);
1274
+ const [archiveFocus, setArchiveFocus] = useState10("confirm");
1275
+ const [syncMode, setSyncMode] = useState10(false);
1276
+ const [syncTarget, setSyncTarget] = useState10(null);
1277
+ const [syncing, setSyncing] = useState10(false);
1278
+ const [syncError, setSyncError] = useState10(null);
1279
+ const [syncFocus, setSyncFocus] = useState10("confirm");
1280
+ const [syncTrigger, setSyncTrigger] = useState10(false);
1281
+ const [infoMode, setInfoMode] = useState10(false);
1282
+ const [infoRepo, setInfoRepo] = useState10(null);
1283
+ const [logoutMode, setLogoutMode] = useState10(false);
1284
+ const [logoutFocus, setLogoutFocus] = useState10("confirm");
1285
+ const [logoutError, setLogoutError] = useState10(null);
1286
+ const [visibilityMode, setVisibilityMode] = useState10(false);
1287
+ const [isEnterpriseOrg, setIsEnterpriseOrg] = useState10(false);
1288
+ const [changeVisibilityMode, setChangeVisibilityMode] = useState10(false);
1289
+ const [changeVisibilityTarget, setChangeVisibilityTarget] = useState10(null);
1290
+ const [changingVisibility, setChangingVisibility] = useState10(false);
1291
+ const [changeVisibilityError, setChangeVisibilityError] = useState10(null);
1292
+ const [sortMode, setSortMode] = useState10(false);
891
1293
  function closeArchiveModal() {
892
1294
  setArchiveMode(false);
893
1295
  setArchiveTarget(null);
@@ -895,6 +1297,12 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
895
1297
  setArchiveError(null);
896
1298
  setArchiveFocus("confirm");
897
1299
  }
1300
+ function closeChangeVisibilityModal() {
1301
+ setChangeVisibilityMode(false);
1302
+ setChangeVisibilityTarget(null);
1303
+ setChangingVisibility(false);
1304
+ setChangeVisibilityError(null);
1305
+ }
898
1306
  function closeSyncModal() {
899
1307
  setSyncMode(false);
900
1308
  setSyncTarget(null);
@@ -963,14 +1371,54 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
963
1371
  setArchiveError("Failed to update archive state. Check permissions.");
964
1372
  }
965
1373
  }
966
- function handleOrgContextChange(newContext) {
1374
+ async function handleVisibilityChange(newVisibility) {
1375
+ if (!changeVisibilityTarget || changingVisibility) return;
1376
+ try {
1377
+ setChangingVisibility(true);
1378
+ const id = changeVisibilityTarget.id;
1379
+ await changeRepositoryVisibility(client, id, newVisibility, token);
1380
+ await updateCacheAfterVisibilityChange(token, id, newVisibility);
1381
+ const shouldRemove = visibilityFilter === "public" && newVisibility !== "PUBLIC" || visibilityFilter === "private" && newVisibility !== "PRIVATE" && newVisibility !== "INTERNAL";
1382
+ if (shouldRemove) {
1383
+ setItems((prev) => prev.filter((r) => r.id !== id));
1384
+ setSearchItems((prev) => prev.filter((r) => r.id !== id));
1385
+ setTotalCount((c) => Math.max(0, c - 1));
1386
+ if (searchActive) {
1387
+ setSearchTotalCount((c) => Math.max(0, c - 1));
1388
+ }
1389
+ const currentItemsLength = searchActive ? searchItems.length : items.length;
1390
+ setCursor((c) => Math.max(0, Math.min(c, currentItemsLength - 2)));
1391
+ } else {
1392
+ const isPrivate = newVisibility === "PRIVATE";
1393
+ const updateRepo = (r) => r.id === id ? { ...r, visibility: newVisibility, isPrivate } : r;
1394
+ setItems((prev) => prev.map(updateRepo));
1395
+ setSearchItems((prev) => prev.map(updateRepo));
1396
+ }
1397
+ closeChangeVisibilityModal();
1398
+ } catch (e) {
1399
+ setChangingVisibility(false);
1400
+ setChangeVisibilityError(e.message || "Failed to change visibility. Check permissions.");
1401
+ }
1402
+ }
1403
+ async function handleOrgContextChange(newContext) {
967
1404
  setOwnerContext(newContext);
968
- storeUIPrefs({ ownerContext: newContext });
969
1405
  setCursor(0);
970
1406
  setOrgSwitcherOpen(false);
1407
+ setVisibilityFilter("all");
971
1408
  const newAffiliations = newContext === "personal" ? ["OWNER"] : ["ORGANIZATION_MEMBER"];
972
1409
  setOwnerAffiliations(newAffiliations);
973
- storeUIPrefs({ ownerAffiliations: newAffiliations });
1410
+ if (newContext !== "personal") {
1411
+ const client2 = makeClient(token);
1412
+ const isEnt = await checkOrganizationIsEnterprise(client2, newContext.login);
1413
+ setIsEnterpriseOrg(isEnt);
1414
+ } else {
1415
+ setIsEnterpriseOrg(false);
1416
+ }
1417
+ storeUIPrefs({
1418
+ ownerContext: newContext,
1419
+ ownerAffiliations: newAffiliations,
1420
+ visibilityFilter: "all"
1421
+ });
974
1422
  if (onOrgContextChange) {
975
1423
  onOrgContextChange(newContext);
976
1424
  }
@@ -1010,12 +1458,12 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1010
1458
  setDeleteError("Failed to delete repository. Ensure delete_repo scope and admin permissions.");
1011
1459
  }
1012
1460
  }
1013
- const [filter, setFilter] = useState9("");
1014
- const [filterMode, setFilterMode] = useState9(false);
1015
- const [sortKey, setSortKey] = useState9("updated");
1016
- const [sortDir, setSortDir] = useState9("desc");
1017
- const [forkTracking, setForkTracking] = useState9(true);
1018
- const [visibilityFilter, setVisibilityFilter] = useState9("all");
1461
+ const [filter, setFilter] = useState10("");
1462
+ const [filterMode, setFilterMode] = useState10(false);
1463
+ const [sortKey, setSortKey] = useState10("updated");
1464
+ const [sortDir, setSortDir] = useState10("desc");
1465
+ const [forkTracking, setForkTracking] = useState10(true);
1466
+ const [visibilityFilter, setVisibilityFilter] = useState10("all");
1019
1467
  const previousVisibilityFilter = useRef("all");
1020
1468
  const sortFieldMap = {
1021
1469
  "updated": "UPDATED_AT",
@@ -1058,6 +1506,12 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1058
1506
  if (page.nodes.some((repo) => repo.visibility === "INTERNAL")) {
1059
1507
  setHasInternalRepos(true);
1060
1508
  }
1509
+ if (!after && orgLogin2) {
1510
+ const client2 = makeClient(token);
1511
+ checkOrganizationIsEnterprise(client2, orgLogin2).then((isEnt) => {
1512
+ setIsEnterpriseOrg(isEnt);
1513
+ });
1514
+ }
1061
1515
  if (!after) {
1062
1516
  try {
1063
1517
  const key = makeApolloKey({
@@ -1097,7 +1551,8 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1097
1551
  setSearchLoading(true);
1098
1552
  try {
1099
1553
  const orderBy = { field: sortFieldMap[sortKey], direction: sortDir.toUpperCase() };
1100
- addDebugMessage(`[fetchSearchPage] Calling API with viewer="${viewerLogin}", query="${query.trim()}"`);
1554
+ const orgLogin2 = ownerContext !== "personal" ? ownerContext.login : void 0;
1555
+ addDebugMessage(`[fetchSearchPage] Calling API with viewer="${viewerLogin}", orgLogin="${orgLogin2 || "none"}", query="${query.trim()}"`);
1101
1556
  const page = await searchRepositoriesUnified(
1102
1557
  token,
1103
1558
  viewerLogin,
@@ -1107,7 +1562,8 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1107
1562
  orderBy.field,
1108
1563
  orderBy.direction,
1109
1564
  forkTracking,
1110
- policy ?? (after ? "network-only" : "cache-first")
1565
+ policy ?? (after ? "network-only" : "cache-first"),
1566
+ orgLogin2
1111
1567
  );
1112
1568
  addDebugMessage(`[fetchSearchPage] API returned ${page.nodes.length} results, totalCount=${page.totalCount}`);
1113
1569
  if (page.nodes.length > 0) {
@@ -1143,7 +1599,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1143
1599
  setSearchLoading(false);
1144
1600
  }
1145
1601
  };
1146
- useEffect6(() => {
1602
+ useEffect7(() => {
1147
1603
  const ui = getUIPrefs();
1148
1604
  if (ui.density !== void 0) setDensity(ui.density);
1149
1605
  if (ui.sortKey && ["updated", "pushed", "name", "stars"].includes(ui.sortKey)) {
@@ -1162,13 +1618,19 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1162
1618
  if (onOrgContextChange) {
1163
1619
  onOrgContextChange(ui.ownerContext);
1164
1620
  }
1621
+ if (ui.ownerContext !== "personal") {
1622
+ const client2 = makeClient(token);
1623
+ checkOrganizationIsEnterprise(client2, ui.ownerContext.login).then((isEnt) => {
1624
+ setIsEnterpriseOrg(isEnt);
1625
+ });
1626
+ }
1165
1627
  }
1166
1628
  if (ui.ownerAffiliations && Array.isArray(ui.ownerAffiliations)) {
1167
1629
  setOwnerAffiliations(ui.ownerAffiliations);
1168
1630
  }
1169
1631
  setPrefsLoaded(true);
1170
1632
  }, [onOrgContextChange]);
1171
- useEffect6(() => {
1633
+ useEffect7(() => {
1172
1634
  if (!prefsLoaded) return;
1173
1635
  let policy = "cache-first";
1174
1636
  const orgLogin2 = ownerContext !== "personal" ? ownerContext.login : void 0;
@@ -1188,7 +1650,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1188
1650
  setCursor(0);
1189
1651
  fetchPage(null, true, false, void 0, policy);
1190
1652
  }, [client, prefsLoaded, ownerContext, ownerAffiliations]);
1191
- useEffect6(() => {
1653
+ useEffect7(() => {
1192
1654
  if (!searchActive) {
1193
1655
  if (items.length > 0) {
1194
1656
  let policy = "cache-first";
@@ -1227,7 +1689,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1227
1689
  }
1228
1690
  }
1229
1691
  }, [sortKey, sortDir]);
1230
- useEffect6(() => {
1692
+ useEffect7(() => {
1231
1693
  if (visibilityFilter !== "all" || previousVisibilityFilter.current && previousVisibilityFilter.current !== visibilityFilter) {
1232
1694
  if (!searchActive) {
1233
1695
  if (items.length > 0) {
@@ -1244,7 +1706,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1244
1706
  }
1245
1707
  previousVisibilityFilter.current = visibilityFilter;
1246
1708
  }, [visibilityFilter]);
1247
- useEffect6(() => {
1709
+ useEffect7(() => {
1248
1710
  if (viewerLogin && searchActive && !searchLoading && searchItems.length === 0) {
1249
1711
  let policy = "cache-first";
1250
1712
  try {
@@ -1264,7 +1726,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1264
1726
  fetchSearchPage(null, true, policy);
1265
1727
  }
1266
1728
  }, [viewerLogin]);
1267
- useInput9((input, key) => {
1729
+ useInput10((input, key) => {
1268
1730
  if (orgSwitcherOpen) {
1269
1731
  return;
1270
1732
  }
@@ -1379,6 +1841,9 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1379
1841
  if (visibilityMode) {
1380
1842
  return;
1381
1843
  }
1844
+ if (changeVisibilityMode) {
1845
+ return;
1846
+ }
1382
1847
  if (sortMode) {
1383
1848
  return;
1384
1849
  }
@@ -1481,6 +1946,14 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1481
1946
  }
1482
1947
  return;
1483
1948
  }
1949
+ if (key.ctrl && (input === "v" || input === "V")) {
1950
+ const repo = visibleItems[cursor];
1951
+ if (repo) {
1952
+ setChangeVisibilityTarget(repo);
1953
+ setChangeVisibilityMode(true);
1954
+ }
1955
+ return;
1956
+ }
1484
1957
  if (key.ctrl && (input === "s" || input === "S")) {
1485
1958
  const repo = visibleItems[cursor];
1486
1959
  if (repo && repo.isFork && repo.parent) {
@@ -1582,8 +2055,8 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1582
2055
  });
1583
2056
  const filtered = useMemo(() => {
1584
2057
  let result = items;
1585
- if (visibilityFilter === "internal") {
1586
- result = result.filter((r) => r.visibility === "INTERNAL");
2058
+ if (visibilityFilter === "private") {
2059
+ result = result.filter((r) => r.visibility === "PRIVATE" || r.visibility === "INTERNAL");
1587
2060
  }
1588
2061
  const q = filter.trim().toLowerCase();
1589
2062
  if (q) {
@@ -1614,13 +2087,22 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1614
2087
  return arr;
1615
2088
  }, [filtered, sortKey, sortDir]);
1616
2089
  const searchActive = filter.trim().length >= 3;
1617
- const visibleItems = searchActive ? searchItems : filteredAndSorted;
1618
- useEffect6(() => {
2090
+ const filteredSearchItems = useMemo(() => {
2091
+ let result = searchItems;
2092
+ if (visibilityFilter === "private") {
2093
+ result = result.filter((r) => r.visibility === "PRIVATE" || r.visibility === "INTERNAL");
2094
+ } else if (visibilityFilter === "public") {
2095
+ result = result.filter((r) => r.visibility === "PUBLIC");
2096
+ }
2097
+ return result;
2098
+ }, [searchItems, visibilityFilter]);
2099
+ const visibleItems = searchActive ? filteredSearchItems : filteredAndSorted;
2100
+ useEffect7(() => {
1619
2101
  if (searchActive) {
1620
2102
  addDebugMessage(`[State] searchActive=${searchActive}, searchItems=${searchItems.length}, visibleItems=${visibleItems.length}, filter="${filter}"`);
1621
2103
  }
1622
2104
  }, [searchActive, searchItems.length, visibleItems.length, filter]);
1623
- useEffect6(() => {
2105
+ useEffect7(() => {
1624
2106
  setCursor((c) => Math.min(c, Math.max(0, (searchActive ? searchItems.length : items.length) - 1)));
1625
2107
  }, [searchActive, searchItems.length, items.length]);
1626
2108
  const headerHeight = 2;
@@ -1641,7 +2123,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1641
2123
  const end = Math.min(total, start + visibleRepos + buffer);
1642
2124
  return { start, end };
1643
2125
  }, [visibleItems.length, cursor, listHeight, spacingLines]);
1644
- useEffect6(() => {
2126
+ useEffect7(() => {
1645
2127
  const prefetchThreshold = Math.floor(visibleItems.length * 0.8);
1646
2128
  const nearEnd = visibleItems.length > 0 && cursor >= prefetchThreshold;
1647
2129
  if (searchActive) {
@@ -1663,88 +2145,94 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1663
2145
  }
1664
2146
  const lowRate = rateLimit && rateLimit.remaining <= Math.ceil(rateLimit.limit * 0.1);
1665
2147
  const modalOpen = deleteMode || archiveMode || syncMode || logoutMode || infoMode || visibilityMode;
1666
- const headerBar = useMemo(() => /* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", justifyContent: "space-between", height: 1, marginBottom: 1, children: [
1667
- /* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", gap: 1, children: [
1668
- /* @__PURE__ */ jsx13(Text13, { bold: true, color: modalOpen ? "gray" : void 0, dimColor: modalOpen ? true : void 0, children: " Repositories" }),
1669
- /* @__PURE__ */ jsxs12(Text13, { color: "gray", children: [
2148
+ const headerBar = useMemo(() => /* @__PURE__ */ jsxs13(Box13, { flexDirection: "row", justifyContent: "space-between", height: 1, marginBottom: 1, children: [
2149
+ /* @__PURE__ */ jsxs13(Box13, { flexDirection: "row", gap: 1, children: [
2150
+ /* @__PURE__ */ jsxs13(Text14, { color: "cyan", bold: !modalOpen, dimColor: modalOpen, children: [
2151
+ " ",
2152
+ ownerContext === "personal" ? "Personal" : ownerContext.name || ownerContext.login,
2153
+ ownerContext !== "personal" && isEnterpriseOrg && " (ENT)"
2154
+ ] }),
2155
+ /* @__PURE__ */ jsx14(Text14, { bold: true, color: modalOpen ? "gray" : void 0, dimColor: modalOpen ? true : void 0, children: "Repositories" }),
2156
+ /* @__PURE__ */ jsxs13(Text14, { color: "gray", children: [
1670
2157
  "(",
1671
2158
  visibleItems.length,
1672
2159
  "/",
1673
2160
  searchActive ? searchTotalCount : totalCount,
1674
2161
  ")"
1675
2162
  ] }),
1676
- (loading || searchLoading) && /* @__PURE__ */ jsx13(Box12, { width: 2, flexShrink: 0, flexGrow: 0, marginLeft: 1, children: /* @__PURE__ */ jsx13(Text13, { color: "yellow", children: /* @__PURE__ */ jsx13(SlowSpinner, {}) }) })
2163
+ (loading || searchLoading) && /* @__PURE__ */ jsx14(Box13, { width: 2, flexShrink: 0, flexGrow: 0, marginLeft: 1, children: /* @__PURE__ */ jsx14(Text14, { color: "yellow", children: /* @__PURE__ */ jsx14(SlowSpinner, {}) }) })
1677
2164
  ] }),
1678
- rateLimit && /* @__PURE__ */ jsxs12(Text13, { color: lowRate ? "yellow" : "gray", children: [
2165
+ rateLimit && /* @__PURE__ */ jsxs13(Text14, { color: lowRate ? "yellow" : "gray", children: [
1679
2166
  "API: ",
1680
2167
  rateLimit.remaining,
1681
2168
  "/",
1682
2169
  rateLimit.limit,
1683
- prevRateLimit !== void 0 && prevRateLimit !== rateLimit.remaining && /* @__PURE__ */ jsx13(Text13, { color: rateLimit.remaining < prevRateLimit ? "red" : "green", children: ` (${rateLimit.remaining - prevRateLimit > 0 ? "+" : ""}${rateLimit.remaining - prevRateLimit})` })
2170
+ prevRateLimit !== void 0 && prevRateLimit !== rateLimit.remaining && /* @__PURE__ */ jsx14(Text14, { color: rateLimit.remaining < prevRateLimit ? "red" : "green", children: ` (${rateLimit.remaining - prevRateLimit > 0 ? "+" : ""}${rateLimit.remaining - prevRateLimit})` }),
2171
+ " "
1684
2172
  ] })
1685
- ] }), [visibleItems.length, searchActive, searchTotalCount, totalCount, loading, searchLoading, rateLimit, lowRate, modalOpen, prevRateLimit]);
2173
+ ] }), [visibleItems.length, searchActive, searchTotalCount, totalCount, loading, searchLoading, rateLimit, lowRate, modalOpen, prevRateLimit, ownerContext, isEnterpriseOrg]);
1686
2174
  if (error) {
1687
- return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", height: availableHeight, children: [
1688
- /* @__PURE__ */ jsx13(Box12, { flexDirection: "row", justifyContent: "space-between", height: 1, marginBottom: 1, children: /* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", gap: 1, children: [
1689
- /* @__PURE__ */ jsx13(Text13, { bold: true, children: " Repositories" }),
1690
- /* @__PURE__ */ jsx13(Text13, { color: "red", children: "(Error)" })
2175
+ return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", height: availableHeight, children: [
2176
+ /* @__PURE__ */ jsx14(Box13, { flexDirection: "row", justifyContent: "space-between", height: 1, marginBottom: 1, children: /* @__PURE__ */ jsxs13(Box13, { flexDirection: "row", gap: 1, children: [
2177
+ /* @__PURE__ */ jsx14(Text14, { bold: true, children: " Repositories" }),
2178
+ /* @__PURE__ */ jsx14(Text14, { color: "red", children: "(Error)" })
1691
2179
  ] }) }),
1692
- /* @__PURE__ */ jsx13(Box12, { borderStyle: "single", borderColor: "red", paddingX: 1, paddingY: 1, marginX: 1, height: contentHeight + containerPadding + 2, flexDirection: "column", children: /* @__PURE__ */ jsx13(Box12, { height: contentHeight, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", alignItems: "center", children: [
1693
- /* @__PURE__ */ jsx13(Text13, { color: "red", children: error }),
1694
- /* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text13, { color: "gray", dimColor: true, children: "Press 'r' to retry or 'q' to quit" }) })
2180
+ /* @__PURE__ */ jsx14(Box13, { borderStyle: "single", borderColor: "red", paddingX: 1, paddingY: 1, marginX: 1, height: contentHeight + containerPadding + 2, flexDirection: "column", children: /* @__PURE__ */ jsx14(Box13, { height: contentHeight, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", alignItems: "center", children: [
2181
+ /* @__PURE__ */ jsx14(Text14, { color: "red", children: error }),
2182
+ /* @__PURE__ */ jsx14(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text14, { color: "gray", dimColor: true, children: "Press 'r' to retry or 'q' to quit" }) })
1695
2183
  ] }) }) }),
1696
- /* @__PURE__ */ jsx13(Box12, { marginTop: 1, paddingX: 1, children: /* @__PURE__ */ jsx13(Text13, { color: "gray", children: "Press 'r' to retry \u2022 'q' to quit" }) })
2184
+ /* @__PURE__ */ jsx14(Box13, { marginTop: 1, paddingX: 1, children: /* @__PURE__ */ jsx14(Text14, { color: "gray", children: "Press 'r' to retry \u2022 'q' to quit" }) })
1697
2185
  ] });
1698
2186
  }
1699
2187
  if (loading && items.length === 0 || sortingLoading) {
1700
- return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", height: availableHeight, children: [
1701
- /* @__PURE__ */ jsx13(Box12, { flexDirection: "row", justifyContent: "space-between", height: 1, marginBottom: 1, children: /* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", gap: 1, children: [
1702
- /* @__PURE__ */ jsx13(Text13, { bold: true, children: " Repositories" }),
1703
- /* @__PURE__ */ jsx13(Text13, { color: "gray", children: "(Loading...)" })
2188
+ return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", height: availableHeight, children: [
2189
+ /* @__PURE__ */ jsx14(Box13, { flexDirection: "row", justifyContent: "space-between", height: 1, marginBottom: 1, children: /* @__PURE__ */ jsxs13(Box13, { flexDirection: "row", gap: 1, children: [
2190
+ /* @__PURE__ */ jsx14(Text14, { bold: true, children: " Repositories" }),
2191
+ /* @__PURE__ */ jsx14(Text14, { color: "gray", children: "(Loading...)" })
1704
2192
  ] }) }),
1705
- /* @__PURE__ */ jsx13(Box12, { borderStyle: "single", borderColor: "yellow", paddingX: 1, paddingY: 1, marginX: 1, height: contentHeight + containerPadding + 2, flexDirection: "column", children: /* @__PURE__ */ jsx13(Box12, { height: contentHeight, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsx13(Box12, { flexDirection: "column", alignItems: "center", children: /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", alignItems: "center", children: [
1706
- /* @__PURE__ */ jsxs12(Box12, { height: 1, flexDirection: "row", children: [
1707
- /* @__PURE__ */ jsx13(Box12, { width: 2, flexShrink: 0, flexGrow: 0, children: /* @__PURE__ */ jsx13(Text13, { color: "cyan", children: /* @__PURE__ */ jsx13(SlowSpinner, {}) }) }),
1708
- /* @__PURE__ */ jsx13(Text13, { color: "cyan", children: refreshing ? "Refreshing..." : sortingLoading ? "Applying sort..." : "Loading repositories..." })
2193
+ /* @__PURE__ */ jsx14(Box13, { borderStyle: "single", borderColor: "yellow", paddingX: 1, paddingY: 1, marginX: 1, height: contentHeight + containerPadding + 2, flexDirection: "column", children: /* @__PURE__ */ jsx14(Box13, { height: contentHeight, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsx14(Box13, { flexDirection: "column", alignItems: "center", children: /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", alignItems: "center", children: [
2194
+ /* @__PURE__ */ jsxs13(Box13, { height: 1, flexDirection: "row", children: [
2195
+ /* @__PURE__ */ jsx14(Box13, { width: 2, flexShrink: 0, flexGrow: 0, children: /* @__PURE__ */ jsx14(Text14, { color: "cyan", children: /* @__PURE__ */ jsx14(SlowSpinner, {}) }) }),
2196
+ /* @__PURE__ */ jsx14(Text14, { color: "cyan", children: refreshing ? "Refreshing..." : sortingLoading ? "Applying sort..." : "Loading repositories..." })
1709
2197
  ] }),
1710
- /* @__PURE__ */ jsx13(Box12, { height: 1, marginTop: 1, children: /* @__PURE__ */ jsx13(Text13, { color: "gray", children: refreshing ? "Fetching latest repository data" : sortingLoading ? `Sorting by ${sortKey} (${sortDir === "asc" ? "ascending" : "descending"})` : "Fetching your GitHub repositories" }) })
2198
+ /* @__PURE__ */ jsx14(Box13, { height: 1, marginTop: 1, children: /* @__PURE__ */ jsx14(Text14, { color: "gray", children: refreshing ? "Fetching latest repository data" : sortingLoading ? `Sorting by ${sortKey} (${sortDir === "asc" ? "ascending" : "descending"})` : "Fetching your GitHub repositories" }) })
1711
2199
  ] }) }) }) }),
1712
- /* @__PURE__ */ jsx13(Box12, { marginTop: 1, paddingX: 1, children: /* @__PURE__ */ jsx13(Text13, { color: "gray", children: "Please wait..." }) })
2200
+ /* @__PURE__ */ jsx14(Box13, { marginTop: 1, paddingX: 1, children: /* @__PURE__ */ jsx14(Text14, { color: "gray", children: "Please wait..." }) })
1713
2201
  ] });
1714
2202
  }
1715
- return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", height: availableHeight, children: [
2203
+ return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", height: availableHeight, children: [
1716
2204
  headerBar,
1717
- /* @__PURE__ */ jsx13(Box12, { borderStyle: "single", borderColor: modalOpen ? "gray" : "yellow", paddingX: 1, paddingY: 1, marginX: 1, height: contentHeight + containerPadding + 2, flexDirection: "column", children: deleteMode && deleteTarget ? (
2205
+ /* @__PURE__ */ jsx14(Box13, { borderStyle: "single", borderColor: modalOpen ? "gray" : "yellow", paddingX: 1, paddingY: 1, marginX: 1, height: contentHeight + containerPadding + 2, flexDirection: "column", children: deleteMode && deleteTarget ? (
1718
2206
  // Centered modal; hide list content while modal is open
1719
- /* @__PURE__ */ jsx13(Box12, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 3, paddingY: 2, width: Math.min(terminalWidth - 8, 80), children: [
1720
- /* @__PURE__ */ jsx13(Text13, { bold: true, children: "Delete Confirmation" }),
1721
- /* @__PURE__ */ jsx13(Text13, { color: "red", children: "\u26A0\uFE0F Delete repository?" }),
1722
- /* @__PURE__ */ jsx13(Box12, { height: 2, children: /* @__PURE__ */ jsx13(Text13, { children: " " }) }),
2207
+ /* @__PURE__ */ jsx14(Box13, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 3, paddingY: 2, width: Math.min(terminalWidth - 8, 80), children: [
2208
+ /* @__PURE__ */ jsx14(Text14, { bold: true, children: "Delete Confirmation" }),
2209
+ /* @__PURE__ */ jsx14(Text14, { color: "red", children: "\u26A0\uFE0F Delete repository?" }),
2210
+ /* @__PURE__ */ jsx14(Box13, { height: 2, children: /* @__PURE__ */ jsx14(Text14, { children: " " }) }),
1723
2211
  (() => {
1724
2212
  const langName = deleteTarget.primaryLanguage?.name || "";
1725
2213
  const langColor = deleteTarget.primaryLanguage?.color || "#666666";
1726
2214
  let line1 = "";
1727
- line1 += chalk10.white(deleteTarget.nameWithOwner);
1728
- if (deleteTarget.isPrivate) line1 += chalk10.yellow(" Private");
1729
- if (deleteTarget.isArchived) line1 += chalk10.gray.dim(" Archived");
1730
- if (deleteTarget.isFork && deleteTarget.parent) line1 += chalk10.blue(` Fork of ${deleteTarget.parent.nameWithOwner}`);
2215
+ line1 += chalk11.white(deleteTarget.nameWithOwner);
2216
+ if (deleteTarget.isPrivate) line1 += chalk11.yellow(" Private");
2217
+ if (deleteTarget.isArchived) line1 += chalk11.gray.dim(" Archived");
2218
+ if (deleteTarget.isFork && deleteTarget.parent) line1 += chalk11.blue(` Fork of ${deleteTarget.parent.nameWithOwner}`);
1731
2219
  let line2 = "";
1732
- if (langName) line2 += chalk10.hex(langColor)("\u25CF ") + chalk10.gray(`${langName} `);
1733
- line2 += chalk10.gray(`\u2605 ${deleteTarget.stargazerCount} \u2442 ${deleteTarget.forkCount} Updated ${formatDate(deleteTarget.updatedAt)}`);
1734
- return /* @__PURE__ */ jsxs12(Fragment5, { children: [
1735
- /* @__PURE__ */ jsx13(Text13, { children: line1 }),
1736
- /* @__PURE__ */ jsx13(Text13, { children: line2 })
2220
+ if (langName) line2 += chalk11.hex(langColor)("\u25CF ") + chalk11.gray(`${langName} `);
2221
+ line2 += chalk11.gray(`\u2605 ${deleteTarget.stargazerCount} \u2442 ${deleteTarget.forkCount} Updated ${formatDate(deleteTarget.updatedAt)}`);
2222
+ return /* @__PURE__ */ jsxs13(Fragment6, { children: [
2223
+ /* @__PURE__ */ jsx14(Text14, { children: line1 }),
2224
+ /* @__PURE__ */ jsx14(Text14, { children: line2 })
1737
2225
  ] });
1738
2226
  })(),
1739
- /* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsxs12(Text13, { children: [
2227
+ /* @__PURE__ */ jsx14(Box13, { marginTop: 1, children: /* @__PURE__ */ jsxs13(Text14, { children: [
1740
2228
  "Type ",
1741
- /* @__PURE__ */ jsx13(Text13, { color: "yellow", bold: true, children: deleteCode }),
2229
+ /* @__PURE__ */ jsx14(Text14, { color: "yellow", bold: true, children: deleteCode }),
1742
2230
  " to confirm."
1743
2231
  ] }) }),
1744
- !deleteConfirmStage && /* @__PURE__ */ jsxs12(Box12, { marginTop: 1, children: [
1745
- /* @__PURE__ */ jsx13(Text13, { children: "Confirm code: " }),
1746
- /* @__PURE__ */ jsx13(
1747
- TextInput3,
2232
+ !deleteConfirmStage && /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, children: [
2233
+ /* @__PURE__ */ jsx14(Text14, { children: "Confirm code: " }),
2234
+ /* @__PURE__ */ jsx14(
2235
+ TextInput4,
1748
2236
  {
1749
2237
  value: typedCode,
1750
2238
  onChange: (v) => {
@@ -1770,11 +2258,11 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1770
2258
  }
1771
2259
  )
1772
2260
  ] }),
1773
- deleteConfirmStage && /* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "column", children: [
1774
- /* @__PURE__ */ jsx13(Text13, { color: "red", children: "This action will permanently delete the repository. This cannot be undone." }),
1775
- /* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "row", justifyContent: "center", gap: 6, children: [
1776
- /* @__PURE__ */ jsx13(
1777
- Box12,
2261
+ deleteConfirmStage && /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "column", children: [
2262
+ /* @__PURE__ */ jsx14(Text14, { color: "red", children: "This action will permanently delete the repository. This cannot be undone." }),
2263
+ /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "row", justifyContent: "center", gap: 6, children: [
2264
+ /* @__PURE__ */ jsx14(
2265
+ Box13,
1778
2266
  {
1779
2267
  borderStyle: "round",
1780
2268
  borderColor: "red",
@@ -1783,11 +2271,11 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1783
2271
  alignItems: "center",
1784
2272
  justifyContent: "center",
1785
2273
  flexDirection: "column",
1786
- children: /* @__PURE__ */ jsx13(Text13, { children: confirmFocus === "delete" ? chalk10.bgRed.white.bold(" Delete ") : chalk10.red.bold("Delete") })
2274
+ children: /* @__PURE__ */ jsx14(Text14, { children: confirmFocus === "delete" ? chalk11.bgRed.white.bold(" Delete ") : chalk11.red.bold("Delete") })
1787
2275
  }
1788
2276
  ),
1789
- /* @__PURE__ */ jsx13(
1790
- Box12,
2277
+ /* @__PURE__ */ jsx14(
2278
+ Box13,
1791
2279
  {
1792
2280
  borderStyle: "round",
1793
2281
  borderColor: confirmFocus === "cancel" ? "white" : "gray",
@@ -1796,17 +2284,17 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1796
2284
  alignItems: "center",
1797
2285
  justifyContent: "center",
1798
2286
  flexDirection: "column",
1799
- children: /* @__PURE__ */ jsx13(Text13, { children: confirmFocus === "cancel" ? chalk10.bgGray.white.bold(" Cancel ") : chalk10.gray.bold("Cancel") })
2287
+ children: /* @__PURE__ */ jsx14(Text14, { children: confirmFocus === "cancel" ? chalk11.bgGray.white.bold(" Cancel ") : chalk11.gray.bold("Cancel") })
1800
2288
  }
1801
2289
  )
1802
2290
  ] }),
1803
- /* @__PURE__ */ jsx13(Box12, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs12(Text13, { color: "gray", children: [
2291
+ /* @__PURE__ */ jsx14(Box13, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs13(Text14, { color: "gray", children: [
1804
2292
  "Press Enter to ",
1805
2293
  confirmFocus === "delete" ? "Delete" : "Cancel",
1806
2294
  " | Y to Delete | C to Cancel"
1807
2295
  ] }) }),
1808
- /* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(
1809
- TextInput3,
2296
+ /* @__PURE__ */ jsx14(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx14(
2297
+ TextInput4,
1810
2298
  {
1811
2299
  value: "",
1812
2300
  onChange: () => {
@@ -1819,18 +2307,18 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1819
2307
  }
1820
2308
  ) })
1821
2309
  ] }),
1822
- deleteError && /* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text13, { color: "magenta", children: deleteError }) }),
1823
- deleting && /* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text13, { color: "yellow", children: "Deleting..." }) })
2310
+ deleteError && /* @__PURE__ */ jsx14(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text14, { color: "magenta", children: deleteError }) }),
2311
+ deleting && /* @__PURE__ */ jsx14(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text14, { color: "yellow", children: "Deleting..." }) })
1824
2312
  ] }) })
1825
- ) : archiveMode && archiveTarget ? /* @__PURE__ */ jsx13(Box12, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: archiveTarget.isArchived ? "green" : "yellow", paddingX: 3, paddingY: 2, width: Math.min(terminalWidth - 8, 80), children: [
1826
- /* @__PURE__ */ jsx13(Text13, { bold: true, children: archiveTarget.isArchived ? "Unarchive Confirmation" : "Archive Confirmation" }),
1827
- /* @__PURE__ */ jsx13(Text13, { color: archiveTarget.isArchived ? "green" : "yellow", children: archiveTarget.isArchived ? "\u21BA Unarchive repository?" : "\u26A0\uFE0F Archive repository?" }),
1828
- /* @__PURE__ */ jsx13(Box12, { height: 1, children: /* @__PURE__ */ jsx13(Text13, { children: " " }) }),
1829
- /* @__PURE__ */ jsx13(Text13, { children: archiveTarget.nameWithOwner }),
1830
- /* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text13, { children: archiveTarget.isArchived ? "This will make the repository active again." : "This will make the repository read-only." }) }),
1831
- /* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "row", justifyContent: "center", gap: 6, children: [
1832
- /* @__PURE__ */ jsx13(
1833
- Box12,
2313
+ ) : archiveMode && archiveTarget ? /* @__PURE__ */ jsx14(Box13, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", borderStyle: "round", borderColor: archiveTarget.isArchived ? "green" : "yellow", paddingX: 3, paddingY: 2, width: Math.min(terminalWidth - 8, 80), children: [
2314
+ /* @__PURE__ */ jsx14(Text14, { bold: true, children: archiveTarget.isArchived ? "Unarchive Confirmation" : "Archive Confirmation" }),
2315
+ /* @__PURE__ */ jsx14(Text14, { color: archiveTarget.isArchived ? "green" : "yellow", children: archiveTarget.isArchived ? "\u21BA Unarchive repository?" : "\u26A0\uFE0F Archive repository?" }),
2316
+ /* @__PURE__ */ jsx14(Box13, { height: 1, children: /* @__PURE__ */ jsx14(Text14, { children: " " }) }),
2317
+ /* @__PURE__ */ jsx14(Text14, { children: archiveTarget.nameWithOwner }),
2318
+ /* @__PURE__ */ jsx14(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text14, { children: archiveTarget.isArchived ? "This will make the repository active again." : "This will make the repository read-only." }) }),
2319
+ /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "row", justifyContent: "center", gap: 6, children: [
2320
+ /* @__PURE__ */ jsx14(
2321
+ Box13,
1834
2322
  {
1835
2323
  borderStyle: "round",
1836
2324
  borderColor: archiveTarget.isArchived ? "green" : "yellow",
@@ -1839,11 +2327,11 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1839
2327
  alignItems: "center",
1840
2328
  justifyContent: "center",
1841
2329
  flexDirection: "column",
1842
- children: /* @__PURE__ */ jsx13(Text13, { children: archiveFocus === "confirm" ? chalk10.bgGreen.white.bold(` ${archiveTarget.isArchived ? "Unarchive" : "Archive"} `) : chalk10.bold[archiveTarget.isArchived ? "green" : "yellow"](archiveTarget.isArchived ? "Unarchive" : "Archive") })
2330
+ children: /* @__PURE__ */ jsx14(Text14, { children: archiveFocus === "confirm" ? chalk11.bgGreen.white.bold(` ${archiveTarget.isArchived ? "Unarchive" : "Archive"} `) : chalk11.bold[archiveTarget.isArchived ? "green" : "yellow"](archiveTarget.isArchived ? "Unarchive" : "Archive") })
1843
2331
  }
1844
2332
  ),
1845
- /* @__PURE__ */ jsx13(
1846
- Box12,
2333
+ /* @__PURE__ */ jsx14(
2334
+ Box13,
1847
2335
  {
1848
2336
  borderStyle: "round",
1849
2337
  borderColor: archiveFocus === "cancel" ? "white" : "gray",
@@ -1852,19 +2340,19 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1852
2340
  alignItems: "center",
1853
2341
  justifyContent: "center",
1854
2342
  flexDirection: "column",
1855
- children: /* @__PURE__ */ jsx13(Text13, { children: archiveFocus === "cancel" ? chalk10.bgGray.white.bold(" Cancel ") : chalk10.gray.bold("Cancel") })
2343
+ children: /* @__PURE__ */ jsx14(Text14, { children: archiveFocus === "cancel" ? chalk11.bgGray.white.bold(" Cancel ") : chalk11.gray.bold("Cancel") })
1856
2344
  }
1857
2345
  )
1858
2346
  ] }),
1859
- /* @__PURE__ */ jsx13(Box12, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs12(Text13, { color: "gray", children: [
2347
+ /* @__PURE__ */ jsx14(Box13, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs13(Text14, { color: "gray", children: [
1860
2348
  "Press Enter to ",
1861
2349
  archiveFocus === "confirm" ? archiveTarget.isArchived ? "Unarchive" : "Archive" : "Cancel",
1862
2350
  " | Y to ",
1863
2351
  archiveTarget.isArchived ? "Unarchive" : "Archive",
1864
2352
  " | C to Cancel"
1865
2353
  ] }) }),
1866
- /* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(
1867
- TextInput3,
2354
+ /* @__PURE__ */ jsx14(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx14(
2355
+ TextInput4,
1868
2356
  {
1869
2357
  value: "",
1870
2358
  onChange: () => {
@@ -1878,21 +2366,21 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1878
2366
  }
1879
2367
  }
1880
2368
  ) }),
1881
- archiveError && /* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text13, { color: "magenta", children: archiveError }) }),
1882
- archiving && /* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text13, { color: "yellow", children: archiveTarget.isArchived ? "Unarchiving..." : "Archiving..." }) })
1883
- ] }) }) : syncMode && syncTarget ? /* @__PURE__ */ jsx13(Box12, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: "blue", paddingX: 3, paddingY: 2, width: Math.min(terminalWidth - 8, 80), children: [
1884
- /* @__PURE__ */ jsx13(Text13, { bold: true, children: "Sync Fork Confirmation" }),
1885
- /* @__PURE__ */ jsx13(Text13, { color: "blue", children: "\u27F2 Sync fork with upstream?" }),
1886
- /* @__PURE__ */ jsx13(Box12, { height: 1, children: /* @__PURE__ */ jsx13(Text13, { children: " " }) }),
1887
- /* @__PURE__ */ jsx13(Text13, { children: syncTarget.nameWithOwner }),
1888
- syncTarget.parent && /* @__PURE__ */ jsxs12(Text13, { color: "gray", children: [
2369
+ archiveError && /* @__PURE__ */ jsx14(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text14, { color: "magenta", children: archiveError }) }),
2370
+ archiving && /* @__PURE__ */ jsx14(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text14, { color: "yellow", children: archiveTarget.isArchived ? "Unarchiving..." : "Archiving..." }) })
2371
+ ] }) }) : syncMode && syncTarget ? /* @__PURE__ */ jsx14(Box13, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", borderStyle: "round", borderColor: "blue", paddingX: 3, paddingY: 2, width: Math.min(terminalWidth - 8, 80), children: [
2372
+ /* @__PURE__ */ jsx14(Text14, { bold: true, children: "Sync Fork Confirmation" }),
2373
+ /* @__PURE__ */ jsx14(Text14, { color: "blue", children: "\u27F2 Sync fork with upstream?" }),
2374
+ /* @__PURE__ */ jsx14(Box13, { height: 1, children: /* @__PURE__ */ jsx14(Text14, { children: " " }) }),
2375
+ /* @__PURE__ */ jsx14(Text14, { children: syncTarget.nameWithOwner }),
2376
+ syncTarget.parent && /* @__PURE__ */ jsxs13(Text14, { color: "gray", children: [
1889
2377
  "Upstream: ",
1890
2378
  syncTarget.parent.nameWithOwner
1891
2379
  ] }),
1892
- /* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text13, { children: "This will merge upstream changes into your fork." }) }),
1893
- /* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "row", justifyContent: "center", gap: 6, children: [
1894
- /* @__PURE__ */ jsx13(
1895
- Box12,
2380
+ /* @__PURE__ */ jsx14(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text14, { children: "This will merge upstream changes into your fork." }) }),
2381
+ /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "row", justifyContent: "center", gap: 6, children: [
2382
+ /* @__PURE__ */ jsx14(
2383
+ Box13,
1896
2384
  {
1897
2385
  borderStyle: "round",
1898
2386
  borderColor: "blue",
@@ -1901,11 +2389,11 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1901
2389
  alignItems: "center",
1902
2390
  justifyContent: "center",
1903
2391
  flexDirection: "column",
1904
- children: /* @__PURE__ */ jsx13(Text13, { children: syncFocus === "confirm" ? chalk10.bgBlue.white.bold(" Sync ") : chalk10.blue.bold("Sync") })
2392
+ children: /* @__PURE__ */ jsx14(Text14, { children: syncFocus === "confirm" ? chalk11.bgBlue.white.bold(" Sync ") : chalk11.blue.bold("Sync") })
1905
2393
  }
1906
2394
  ),
1907
- /* @__PURE__ */ jsx13(
1908
- Box12,
2395
+ /* @__PURE__ */ jsx14(
2396
+ Box13,
1909
2397
  {
1910
2398
  borderStyle: "round",
1911
2399
  borderColor: syncFocus === "cancel" ? "white" : "gray",
@@ -1914,17 +2402,17 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1914
2402
  alignItems: "center",
1915
2403
  justifyContent: "center",
1916
2404
  flexDirection: "column",
1917
- children: /* @__PURE__ */ jsx13(Text13, { children: syncFocus === "cancel" ? chalk10.bgGray.white.bold(" Cancel ") : chalk10.gray.bold("Cancel") })
2405
+ children: /* @__PURE__ */ jsx14(Text14, { children: syncFocus === "cancel" ? chalk11.bgGray.white.bold(" Cancel ") : chalk11.gray.bold("Cancel") })
1918
2406
  }
1919
2407
  )
1920
2408
  ] }),
1921
- /* @__PURE__ */ jsx13(Box12, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs12(Text13, { color: "gray", children: [
2409
+ /* @__PURE__ */ jsx14(Box13, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs13(Text14, { color: "gray", children: [
1922
2410
  "Press Enter to ",
1923
2411
  syncFocus === "confirm" ? "Sync" : "Cancel",
1924
2412
  " | Y to Sync | C to Cancel"
1925
2413
  ] }) }),
1926
- /* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(
1927
- TextInput3,
2414
+ /* @__PURE__ */ jsx14(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx14(
2415
+ TextInput4,
1928
2416
  {
1929
2417
  value: "",
1930
2418
  onChange: () => {
@@ -1938,14 +2426,14 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1938
2426
  }
1939
2427
  }
1940
2428
  ) }),
1941
- syncError && /* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text13, { color: "magenta", children: syncError }) }),
1942
- syncing && /* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text13, { color: "yellow", children: "Syncing..." }) })
1943
- ] }) }) : logoutMode ? /* @__PURE__ */ jsx13(Box12, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 3, paddingY: 2, width: Math.min(terminalWidth - 8, 80), children: [
1944
- /* @__PURE__ */ jsx13(Text13, { bold: true, children: "Logout Confirmation" }),
1945
- /* @__PURE__ */ jsx13(Text13, { color: "cyan", children: "Are you sure you want to log out?" }),
1946
- /* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "row", justifyContent: "center", gap: 6, children: [
1947
- /* @__PURE__ */ jsx13(
1948
- Box12,
2429
+ syncError && /* @__PURE__ */ jsx14(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text14, { color: "magenta", children: syncError }) }),
2430
+ syncing && /* @__PURE__ */ jsx14(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text14, { color: "yellow", children: "Syncing..." }) })
2431
+ ] }) }) : logoutMode ? /* @__PURE__ */ jsx14(Box13, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 3, paddingY: 2, width: Math.min(terminalWidth - 8, 80), children: [
2432
+ /* @__PURE__ */ jsx14(Text14, { bold: true, children: "Logout Confirmation" }),
2433
+ /* @__PURE__ */ jsx14(Text14, { color: "cyan", children: "Are you sure you want to log out?" }),
2434
+ /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "row", justifyContent: "center", gap: 6, children: [
2435
+ /* @__PURE__ */ jsx14(
2436
+ Box13,
1949
2437
  {
1950
2438
  borderStyle: "round",
1951
2439
  borderColor: "cyan",
@@ -1954,11 +2442,11 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1954
2442
  alignItems: "center",
1955
2443
  justifyContent: "center",
1956
2444
  flexDirection: "column",
1957
- children: /* @__PURE__ */ jsx13(Text13, { children: logoutFocus === "confirm" ? chalk10.bgCyan.white.bold(" Logout ") : chalk10.cyan.bold("Logout") })
2445
+ children: /* @__PURE__ */ jsx14(Text14, { children: logoutFocus === "confirm" ? chalk11.bgCyan.white.bold(" Logout ") : chalk11.cyan.bold("Logout") })
1958
2446
  }
1959
2447
  ),
1960
- /* @__PURE__ */ jsx13(
1961
- Box12,
2448
+ /* @__PURE__ */ jsx14(
2449
+ Box13,
1962
2450
  {
1963
2451
  borderStyle: "round",
1964
2452
  borderColor: logoutFocus === "cancel" ? "white" : "gray",
@@ -1967,16 +2455,16 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1967
2455
  alignItems: "center",
1968
2456
  justifyContent: "center",
1969
2457
  flexDirection: "column",
1970
- children: /* @__PURE__ */ jsx13(Text13, { children: logoutFocus === "cancel" ? chalk10.bgGray.white.bold(" Cancel ") : chalk10.gray.bold("Cancel") })
2458
+ children: /* @__PURE__ */ jsx14(Text14, { children: logoutFocus === "cancel" ? chalk11.bgGray.white.bold(" Cancel ") : chalk11.gray.bold("Cancel") })
1971
2459
  }
1972
2460
  )
1973
2461
  ] }),
1974
- /* @__PURE__ */ jsx13(Box12, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs12(Text13, { color: "gray", children: [
2462
+ /* @__PURE__ */ jsx14(Box13, { marginTop: 1, flexDirection: "row", justifyContent: "center", children: /* @__PURE__ */ jsxs13(Text14, { color: "gray", children: [
1975
2463
  "Press Enter to ",
1976
2464
  logoutFocus === "confirm" ? "Logout" : "Cancel",
1977
2465
  " | Y to Logout | C to Cancel"
1978
2466
  ] }) })
1979
- ] }) }) : orgSwitcherOpen ? /* @__PURE__ */ jsx13(Box12, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx13(
2467
+ ] }) }) : orgSwitcherOpen ? /* @__PURE__ */ jsx14(Box13, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx14(
1980
2468
  OrgSwitcher,
1981
2469
  {
1982
2470
  token,
@@ -1984,49 +2472,49 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
1984
2472
  onSelect: handleOrgContextChange,
1985
2473
  onClose: () => setOrgSwitcherOpen(false)
1986
2474
  }
1987
- ) }) : infoMode ? /* @__PURE__ */ jsx13(Box12, { height: contentHeight, alignItems: "center", justifyContent: "center", children: (() => {
2475
+ ) }) : infoMode ? /* @__PURE__ */ jsx14(Box13, { height: contentHeight, alignItems: "center", justifyContent: "center", children: (() => {
1988
2476
  const repo = infoRepo || visibleItems[cursor];
1989
- if (!repo) return /* @__PURE__ */ jsx13(Text13, { color: "red", children: "No repository selected." });
2477
+ if (!repo) return /* @__PURE__ */ jsx14(Text14, { color: "red", children: "No repository selected." });
1990
2478
  const langName = repo.primaryLanguage?.name || "N/A";
1991
2479
  const langColor = repo.primaryLanguage?.color || "#666666";
1992
- return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 3, paddingY: 2, width: Math.min(terminalWidth - 8, 90), children: [
1993
- /* @__PURE__ */ jsxs12(Text13, { bold: true, children: [
2480
+ return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 3, paddingY: 2, width: Math.min(terminalWidth - 8, 90), children: [
2481
+ /* @__PURE__ */ jsxs13(Text14, { bold: true, children: [
1994
2482
  "Repository Info ",
1995
- infoRepo ? chalk10.dim("(cached)") : ""
2483
+ infoRepo ? chalk11.dim("(cached)") : ""
1996
2484
  ] }),
1997
- /* @__PURE__ */ jsx13(Box12, { height: 1, children: /* @__PURE__ */ jsx13(Text13, { children: " " }) }),
1998
- /* @__PURE__ */ jsx13(Text13, { children: chalk10.bold(repo.nameWithOwner) }),
1999
- repo.description && /* @__PURE__ */ jsx13(Text13, { color: "gray", children: repo.description }),
2000
- /* @__PURE__ */ jsx13(Box12, { height: 1, children: /* @__PURE__ */ jsx13(Text13, { children: " " }) }),
2001
- /* @__PURE__ */ jsxs12(Text13, { children: [
2002
- repo.visibility === "PRIVATE" ? chalk10.yellow("Private") : repo.visibility === "INTERNAL" ? chalk10.cyan("Internal") : chalk10.green("Public"),
2003
- repo.isArchived ? chalk10.gray(" Archived") : "",
2004
- repo.isFork ? chalk10.blue(" Fork") : ""
2485
+ /* @__PURE__ */ jsx14(Box13, { height: 1, children: /* @__PURE__ */ jsx14(Text14, { children: " " }) }),
2486
+ /* @__PURE__ */ jsx14(Text14, { children: chalk11.bold(repo.nameWithOwner) }),
2487
+ repo.description && /* @__PURE__ */ jsx14(Text14, { color: "gray", children: repo.description }),
2488
+ /* @__PURE__ */ jsx14(Box13, { height: 1, children: /* @__PURE__ */ jsx14(Text14, { children: " " }) }),
2489
+ /* @__PURE__ */ jsxs13(Text14, { children: [
2490
+ repo.visibility === "PRIVATE" ? chalk11.yellow("Private") : repo.visibility === "INTERNAL" ? chalk11.magenta("Internal") : chalk11.green("Public"),
2491
+ repo.isArchived ? chalk11.gray(" Archived") : "",
2492
+ repo.isFork ? chalk11.blue(" Fork") : ""
2005
2493
  ] }),
2006
- /* @__PURE__ */ jsx13(Text13, { children: chalk10.gray(`\u2605 ${repo.stargazerCount} \u2442 ${repo.forkCount}`) }),
2007
- /* @__PURE__ */ jsxs12(Text13, { children: [
2008
- chalk10.hex(langColor)(`\u25CF `),
2009
- chalk10.gray(`${langName}`)
2494
+ /* @__PURE__ */ jsx14(Text14, { children: chalk11.gray(`\u2605 ${repo.stargazerCount} \u2442 ${repo.forkCount}`) }),
2495
+ /* @__PURE__ */ jsxs13(Text14, { children: [
2496
+ chalk11.hex(langColor)(`\u25CF `),
2497
+ chalk11.gray(`${langName}`)
2010
2498
  ] }),
2011
- /* @__PURE__ */ jsxs12(Text13, { color: "gray", children: [
2499
+ /* @__PURE__ */ jsxs13(Text14, { color: "gray", children: [
2012
2500
  "Updated: ",
2013
2501
  formatDate(repo.updatedAt),
2014
2502
  " \u2022 Pushed: ",
2015
2503
  formatDate(repo.pushedAt)
2016
2504
  ] }),
2017
- /* @__PURE__ */ jsxs12(Text13, { color: "gray", children: [
2505
+ /* @__PURE__ */ jsxs13(Text14, { color: "gray", children: [
2018
2506
  "Size: ",
2019
2507
  repo.diskUsage,
2020
2508
  " KB"
2021
2509
  ] }),
2022
- /* @__PURE__ */ jsx13(Box12, { height: 1, children: /* @__PURE__ */ jsx13(Text13, { children: " " }) }),
2023
- /* @__PURE__ */ jsx13(Text13, { color: "gray", children: "Press Esc or I to close" })
2510
+ /* @__PURE__ */ jsx14(Box13, { height: 1, children: /* @__PURE__ */ jsx14(Text14, { children: " " }) }),
2511
+ /* @__PURE__ */ jsx14(Text14, { color: "gray", children: "Press Esc or I to close" })
2024
2512
  ] });
2025
- })() }) : visibilityMode ? /* @__PURE__ */ jsx13(Box12, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx13(
2513
+ })() }) : visibilityMode ? /* @__PURE__ */ jsx14(Box13, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx14(
2026
2514
  VisibilityModal,
2027
2515
  {
2028
2516
  currentFilter: visibilityFilter,
2029
- hasInternalRepos,
2517
+ isEnterprise: isEnterpriseOrg,
2030
2518
  onSelect: (filter2) => {
2031
2519
  setVisibilityFilter(filter2);
2032
2520
  setVisibilityMode(false);
@@ -2035,7 +2523,7 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
2035
2523
  },
2036
2524
  onCancel: () => setVisibilityMode(false)
2037
2525
  }
2038
- ) }) : sortMode ? /* @__PURE__ */ jsx13(Box12, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx13(
2526
+ ) }) : sortMode ? /* @__PURE__ */ jsx14(Box13, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx14(
2039
2527
  SortModal,
2040
2528
  {
2041
2529
  currentSort: sortKey,
@@ -2047,8 +2535,21 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
2047
2535
  },
2048
2536
  onCancel: () => setSortMode(false)
2049
2537
  }
2050
- ) }) : /* @__PURE__ */ jsxs12(Fragment5, { children: [
2051
- /* @__PURE__ */ jsx13(
2538
+ ) }) : changeVisibilityMode && changeVisibilityTarget ? /* @__PURE__ */ jsx14(Box13, { height: contentHeight, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsx14(
2539
+ ChangeVisibilityModal,
2540
+ {
2541
+ isOpen: changeVisibilityMode,
2542
+ repoName: changeVisibilityTarget.nameWithOwner,
2543
+ currentVisibility: changeVisibilityTarget.visibility,
2544
+ isFork: changeVisibilityTarget.isFork,
2545
+ isEnterprise: isEnterpriseOrg,
2546
+ onVisibilityChange: handleVisibilityChange,
2547
+ onClose: closeChangeVisibilityModal,
2548
+ changing: changingVisibility,
2549
+ error: changeVisibilityError
2550
+ }
2551
+ ) }) : /* @__PURE__ */ jsxs13(Fragment6, { children: [
2552
+ /* @__PURE__ */ jsx14(
2052
2553
  RepoListHeader,
2053
2554
  {
2054
2555
  ownerContext,
@@ -2058,13 +2559,14 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
2058
2559
  filter,
2059
2560
  searchActive,
2060
2561
  searchLoading,
2061
- visibilityFilter
2562
+ visibilityFilter,
2563
+ isEnterprise: isEnterpriseOrg
2062
2564
  }
2063
2565
  ),
2064
- filterMode && /* @__PURE__ */ jsxs12(Box12, { marginBottom: 1, children: [
2065
- /* @__PURE__ */ jsx13(Text13, { children: "Filter: " }),
2066
- /* @__PURE__ */ jsx13(
2067
- TextInput3,
2566
+ filterMode && /* @__PURE__ */ jsxs13(Box13, { marginBottom: 1, children: [
2567
+ /* @__PURE__ */ jsx14(Text14, { children: "Search: " }),
2568
+ /* @__PURE__ */ jsx14(
2569
+ TextInput4,
2068
2570
  {
2069
2571
  value: filter,
2070
2572
  onChange: (val) => {
@@ -2103,10 +2605,10 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
2103
2605
  }
2104
2606
  )
2105
2607
  ] }),
2106
- /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", height: listHeight, children: [
2107
- filterMode && filter.trim().length > 0 && filter.trim().length < 3 ? /* @__PURE__ */ jsx13(Box12, { justifyContent: "center", alignItems: "center", flexGrow: 1, children: /* @__PURE__ */ jsx13(Text13, { color: "gray", dimColor: true, children: "Type at least 3 characters to search" }) }) : visibleItems.slice(windowed.start, windowed.end).map((repo, i) => {
2608
+ /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", height: listHeight, children: [
2609
+ filterMode && filter.trim().length > 0 && filter.trim().length < 3 ? /* @__PURE__ */ jsx14(Box13, { justifyContent: "center", alignItems: "center", flexGrow: 1, children: /* @__PURE__ */ jsx14(Text14, { color: "gray", dimColor: true, children: "Type at least 3 characters to search" }) }) : visibleItems.slice(windowed.start, windowed.end).map((repo, i) => {
2108
2610
  const idx = windowed.start + i;
2109
- return /* @__PURE__ */ jsx13(
2611
+ return /* @__PURE__ */ jsx14(
2110
2612
  RepoRow,
2111
2613
  {
2112
2614
  repo,
@@ -2119,45 +2621,189 @@ function RepoList({ token, maxVisibleRows, onLogout, viewerLogin, onOrgContextCh
2119
2621
  repo.nameWithOwner
2120
2622
  );
2121
2623
  }),
2122
- loadingMore && hasNextPage && /* @__PURE__ */ jsx13(Box12, { justifyContent: "center", alignItems: "center", marginTop: 1, children: /* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", children: [
2123
- /* @__PURE__ */ jsx13(Box12, { width: 2, flexShrink: 0, flexGrow: 0, marginRight: 1, children: /* @__PURE__ */ jsx13(Text13, { color: "cyan", children: /* @__PURE__ */ jsx13(SlowSpinner, {}) }) }),
2124
- /* @__PURE__ */ jsx13(Text13, { color: "cyan", children: "Loading more repositories..." })
2624
+ loadingMore && hasNextPage && /* @__PURE__ */ jsx14(Box13, { justifyContent: "center", alignItems: "center", marginTop: 1, children: /* @__PURE__ */ jsxs13(Box13, { flexDirection: "row", children: [
2625
+ /* @__PURE__ */ jsx14(Box13, { width: 2, flexShrink: 0, flexGrow: 0, marginRight: 1, children: /* @__PURE__ */ jsx14(Text14, { color: "cyan", children: /* @__PURE__ */ jsx14(SlowSpinner, {}) }) }),
2626
+ /* @__PURE__ */ jsx14(Text14, { color: "cyan", children: "Loading more repositories..." })
2125
2627
  ] }) }),
2126
- !loading && !searchLoading && visibleItems.length === 0 && /* @__PURE__ */ jsx13(Box12, { justifyContent: "center", alignItems: "center", flexGrow: 1, children: /* @__PURE__ */ jsx13(Text13, { color: "gray", dimColor: true, children: searchActive ? "No repositories match your search" : filter ? "No repositories match your filter" : "No repositories found" }) })
2628
+ !loading && !searchLoading && visibleItems.length === 0 && /* @__PURE__ */ jsx14(Box13, { justifyContent: "center", alignItems: "center", flexGrow: 1, children: /* @__PURE__ */ jsx14(Text14, { color: "gray", dimColor: true, children: searchActive ? "No repositories match your search" : filter ? "No repositories match your filter" : "No repositories found" }) })
2127
2629
  ] })
2128
2630
  ] }) }),
2129
- /* @__PURE__ */ jsxs12(Box12, { marginTop: 1, paddingX: 1, flexDirection: "column", children: [
2130
- /* @__PURE__ */ jsx13(Box12, { width: terminalWidth, justifyContent: "center", children: /* @__PURE__ */ jsx13(Text13, { color: "gray", dimColor: modalOpen ? true : void 0, children: "\u2191\u2193 Navigate \u2022 \u23CE/O Open \u2022 R Refresh \u2022 W Org Switch \u2022 Ctrl+L Logout \u2022 Q Quit" }) }),
2131
- /* @__PURE__ */ jsx13(Box12, { width: terminalWidth, justifyContent: "center", children: /* @__PURE__ */ jsx13(Text13, { color: "gray", dimColor: modalOpen ? true : void 0, children: "Ctrl+G Top \u2022 G Bottom \u2022 / Search \u2022 S Sort \u2022 D Direction \u2022 T Density \u2022 F Fork Status \u2022 V Visibility" }) }),
2132
- /* @__PURE__ */ jsx13(Box12, { width: terminalWidth, justifyContent: "center", children: /* @__PURE__ */ jsx13(Text13, { color: "gray", dimColor: modalOpen ? true : void 0, children: "I Info \u2022 K Cache Info \u2022 Ctrl+A Un/Archive \u2022 Del/Backspace Delete \u2022 Ctrl+S Sync Fork" }) })
2631
+ /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, paddingX: 1, flexDirection: "column", children: [
2632
+ /* @__PURE__ */ jsx14(Box13, { width: terminalWidth, justifyContent: "center", children: /* @__PURE__ */ jsx14(Text14, { color: "gray", dimColor: modalOpen ? true : void 0, children: "\u2191\u2193 Navigate \u2022 \u23CE/O Open \u2022 R Refresh \u2022 W Org Switch \u2022 Ctrl+L Logout \u2022 Q Quit" }) }),
2633
+ /* @__PURE__ */ jsx14(Box13, { width: terminalWidth, justifyContent: "center", children: /* @__PURE__ */ jsx14(Text14, { color: "gray", dimColor: modalOpen ? true : void 0, children: "Ctrl+G Top \u2022 G Bottom \u2022 / Search \u2022 S Sort \u2022 D Direction \u2022 T Density \u2022 F Fork Status \u2022 V Visibility" }) }),
2634
+ /* @__PURE__ */ jsx14(Box13, { width: terminalWidth, justifyContent: "center", children: /* @__PURE__ */ jsx14(Text14, { color: "gray", dimColor: modalOpen ? true : void 0, children: "I Info \u2022 K Cache Info \u2022 Ctrl+A Un/Archive \u2022 Ctrl+V Change Visibility \u2022 Del/Backspace Delete \u2022 Ctrl+S Sync Fork" }) })
2133
2635
  ] }),
2134
- process.env.GH_MANAGER_DEBUG === "1" && /* @__PURE__ */ jsxs12(Box12, { marginTop: 1, borderStyle: "single", borderColor: "yellow", paddingX: 1, flexDirection: "column", children: [
2135
- /* @__PURE__ */ jsx13(Text13, { bold: true, color: "yellow", children: "Debug Messages:" }),
2136
- debugMessages.length === 0 ? /* @__PURE__ */ jsx13(Text13, { color: "gray", children: "No debug messages yet..." }) : debugMessages.map((msg, i) => /* @__PURE__ */ jsx13(Text13, { color: "gray", children: msg }, i))
2636
+ process.env.GH_MANAGER_DEBUG === "1" && /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, borderStyle: "single", borderColor: "yellow", paddingX: 1, flexDirection: "column", children: [
2637
+ /* @__PURE__ */ jsx14(Text14, { bold: true, color: "yellow", children: "Debug Messages:" }),
2638
+ debugMessages.length === 0 ? /* @__PURE__ */ jsx14(Text14, { color: "gray", children: "No debug messages yet..." }) : debugMessages.map((msg, i) => /* @__PURE__ */ jsx14(Text14, { color: "gray", children: msg }, i))
2137
2639
  ] })
2138
2640
  ] });
2139
2641
  }
2140
2642
 
2643
+ // src/ui/components/auth/AuthMethodSelector.tsx
2644
+ import { useState as useState11 } from "react";
2645
+ import { Box as Box14, Text as Text15, useInput as useInput11 } from "ink";
2646
+ import chalk12 from "chalk";
2647
+ import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
2648
+ function AuthMethodSelector({ onSelect, onQuit }) {
2649
+ const [selectedIndex, setSelectedIndex] = useState11(0);
2650
+ const methods = [
2651
+ {
2652
+ key: "oauth",
2653
+ label: "GitHub OAuth",
2654
+ description: "Login via GitHub in your browser (recommended)"
2655
+ },
2656
+ {
2657
+ key: "pat",
2658
+ label: "Personal Access Token",
2659
+ description: "Manually enter a GitHub Personal Access Token"
2660
+ }
2661
+ ];
2662
+ useInput11((input, key) => {
2663
+ if (key.escape || input?.toLowerCase() === "q") {
2664
+ if (onQuit) {
2665
+ onQuit();
2666
+ } else {
2667
+ process.exit(0);
2668
+ }
2669
+ } else if (key.upArrow) {
2670
+ setSelectedIndex((prev) => Math.max(0, prev - 1));
2671
+ } else if (key.downArrow) {
2672
+ setSelectedIndex((prev) => Math.min(methods.length - 1, prev + 1));
2673
+ } else if (key.return) {
2674
+ onSelect(methods[selectedIndex].key);
2675
+ } else if (input === "1") {
2676
+ onSelect("oauth");
2677
+ } else if (input === "2") {
2678
+ onSelect("pat");
2679
+ }
2680
+ });
2681
+ return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", paddingX: 2, paddingY: 1, children: [
2682
+ /* @__PURE__ */ jsx15(Text15, { bold: true, marginBottom: 1, children: "Choose Authentication Method" }),
2683
+ /* @__PURE__ */ jsx15(Box14, { flexDirection: "column", marginY: 1, children: methods.map((method, index) => {
2684
+ const isSelected = index === selectedIndex;
2685
+ const prefix = isSelected ? chalk12.cyan("\u203A") : " ";
2686
+ const numberPrefix = `${index + 1}.`;
2687
+ return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", marginBottom: 1, children: [
2688
+ /* @__PURE__ */ jsx15(Text15, { children: /* @__PURE__ */ jsxs14(Text15, { color: isSelected ? "cyan" : void 0, bold: isSelected, children: [
2689
+ prefix,
2690
+ " ",
2691
+ numberPrefix,
2692
+ " ",
2693
+ method.label
2694
+ ] }) }),
2695
+ /* @__PURE__ */ jsxs14(Text15, { color: "gray", dimColor: true, children: [
2696
+ " ",
2697
+ method.description
2698
+ ] })
2699
+ ] }, method.key);
2700
+ }) }),
2701
+ /* @__PURE__ */ jsx15(Text15, { color: "gray", dimColor: true, marginTop: 1, children: "Use arrow keys to navigate, Enter to select, or press 1/2 \u2022 Q/Esc to quit" })
2702
+ ] });
2703
+ }
2704
+
2705
+ // src/ui/components/auth/OAuthProgress.tsx
2706
+ import { Box as Box15, Text as Text16 } from "ink";
2707
+ import Spinner from "ink-spinner";
2708
+ import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
2709
+ function OAuthProgress({ status, error, deviceCode }) {
2710
+ const statusMessages = {
2711
+ initializing: {
2712
+ message: "Initializing GitHub Device Flow...",
2713
+ showSpinner: true
2714
+ },
2715
+ device_code_requested: {
2716
+ message: "Requesting device authorization code...",
2717
+ showSpinner: true
2718
+ },
2719
+ browser_opening: {
2720
+ message: "Opening browser for GitHub authentication...",
2721
+ showSpinner: true
2722
+ },
2723
+ waiting_for_authorization: {
2724
+ message: "Waiting for you to authorize in your browser...",
2725
+ showSpinner: true
2726
+ },
2727
+ polling_for_token: {
2728
+ message: "Polling GitHub for access token...",
2729
+ showSpinner: true
2730
+ },
2731
+ validating_token: {
2732
+ message: "Validating token with GitHub...",
2733
+ showSpinner: true
2734
+ },
2735
+ success: {
2736
+ message: "Authentication successful!",
2737
+ showSpinner: false
2738
+ },
2739
+ error: {
2740
+ message: "Authentication failed",
2741
+ showSpinner: false
2742
+ }
2743
+ };
2744
+ const { message, showSpinner } = statusMessages[status];
2745
+ return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", borderStyle: "single", borderColor: status === "error" ? "red" : "cyan", paddingX: 2, paddingY: 1, children: [
2746
+ /* @__PURE__ */ jsx16(Text16, { bold: true, marginBottom: 1, children: "GitHub OAuth Authentication" }),
2747
+ /* @__PURE__ */ jsx16(Box15, { marginY: 1, children: showSpinner ? /* @__PURE__ */ jsxs15(Box15, { children: [
2748
+ /* @__PURE__ */ jsx16(Text16, { color: "green", children: /* @__PURE__ */ jsx16(Spinner, { type: "dots" }) }),
2749
+ /* @__PURE__ */ jsxs15(Text16, { children: [
2750
+ " ",
2751
+ message
2752
+ ] })
2753
+ ] }) : /* @__PURE__ */ jsxs15(Text16, { color: status === "error" ? "red" : "green", children: [
2754
+ status === "error" ? "\u2717" : "\u2713",
2755
+ " ",
2756
+ message
2757
+ ] }) }),
2758
+ (status === "waiting_for_authorization" || status === "polling_for_token") && deviceCode && /* @__PURE__ */ jsxs15(Box15, { marginY: 1, flexDirection: "column", children: [
2759
+ /* @__PURE__ */ jsx16(Text16, { bold: true, color: "cyan", marginBottom: 1, children: "\u{1F4CB} Please complete these steps:" }),
2760
+ /* @__PURE__ */ jsxs15(Box15, { marginBottom: 1, children: [
2761
+ /* @__PURE__ */ jsx16(Text16, { children: "1. Visit: " }),
2762
+ /* @__PURE__ */ jsx16(Text16, { bold: true, color: "blue", children: deviceCode.verification_uri })
2763
+ ] }),
2764
+ /* @__PURE__ */ jsxs15(Box15, { marginBottom: 1, flexDirection: "column", children: [
2765
+ /* @__PURE__ */ jsx16(Text16, { children: "2. Enter this code:" }),
2766
+ /* @__PURE__ */ jsx16(Box15, { borderStyle: "single", borderColor: "yellow", paddingX: 2, paddingY: 1, marginTop: 1, children: /* @__PURE__ */ jsx16(Text16, { bold: true, color: "yellow", children: deviceCode.user_code }) })
2767
+ ] }),
2768
+ status === "waiting_for_authorization" && /* @__PURE__ */ jsx16(Text16, { color: "gray", marginTop: 1, children: "Your browser should open automatically." }),
2769
+ status === "polling_for_token" && /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", marginTop: 1, children: [
2770
+ /* @__PURE__ */ jsx16(Text16, { color: "gray", children: "Waiting for you to complete authorization in your browser..." }),
2771
+ /* @__PURE__ */ jsx16(Text16, { color: "gray", dimColor: true, marginTop: 1, children: "This will timeout in 15 minutes. Press Esc to cancel." })
2772
+ ] })
2773
+ ] }),
2774
+ status === "error" && error && /* @__PURE__ */ jsxs15(Box15, { marginY: 1, flexDirection: "column", children: [
2775
+ /* @__PURE__ */ jsx16(Text16, { color: "red", children: error }),
2776
+ /* @__PURE__ */ jsx16(Text16, { color: "gray", marginTop: 1, children: "Press Esc to go back and try again." })
2777
+ ] }),
2778
+ status === "success" && /* @__PURE__ */ jsx16(Text16, { color: "gray", marginTop: 1, children: "Returning to application..." })
2779
+ ] });
2780
+ }
2781
+
2141
2782
  // src/ui/App.tsx
2142
- import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
2783
+ import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
2143
2784
  var packageJson = require_package();
2144
2785
  function App() {
2145
2786
  const { exit } = useApp2();
2146
2787
  const { stdout } = useStdout2();
2147
- const [mode, setMode] = useState10("checking");
2148
- const [token, setToken] = useState10(null);
2149
- const [input, setInput] = useState10("");
2150
- const [error, setError] = useState10(null);
2151
- const [viewer, setViewer] = useState10(null);
2152
- const [rateLimitReset, setRateLimitReset] = useState10(null);
2153
- const [wasRateLimited, setWasRateLimited] = useState10(false);
2154
- const [orgContext, setOrgContext] = useState10("personal");
2155
- const [dims, setDims] = useState10(() => {
2788
+ const [mode, setMode] = useState12("checking");
2789
+ const [token, setToken] = useState12(null);
2790
+ const [input, setInput] = useState12("");
2791
+ const [error, setError] = useState12(null);
2792
+ const [viewer, setViewer] = useState12(null);
2793
+ const [rateLimitReset, setRateLimitReset] = useState12(null);
2794
+ const [wasRateLimited, setWasRateLimited] = useState12(false);
2795
+ const [orgContext, setOrgContext] = useState12("personal");
2796
+ const [authMethod, setAuthMethod] = useState12("pat");
2797
+ const [oauthStatus, setOAuthStatus] = useState12("initializing");
2798
+ const [tokenSource, setTokenSource] = useState12("pat");
2799
+ const [deviceCodeResponse, setDeviceCodeResponse] = useState12(null);
2800
+ const [oauthDeviceCode, setOauthDeviceCode] = useState12(null);
2801
+ const [dims, setDims] = useState12(() => {
2156
2802
  const cols = stdout?.columns ?? 100;
2157
2803
  const rows = stdout?.rows ?? 30;
2158
2804
  return { cols, rows };
2159
2805
  });
2160
- useEffect7(() => {
2806
+ useEffect8(() => {
2161
2807
  if (!stdout) return;
2162
2808
  const onResize = () => {
2163
2809
  const cols = stdout.columns ?? 100;
@@ -2169,9 +2815,11 @@ function App() {
2169
2815
  stdout.off?.("resize", onResize);
2170
2816
  };
2171
2817
  }, [stdout]);
2172
- useEffect7(() => {
2818
+ useEffect8(() => {
2173
2819
  const env = getTokenFromEnv();
2174
2820
  const stored = getStoredToken();
2821
+ const source = getTokenSource();
2822
+ setTokenSource(source);
2175
2823
  if (env) {
2176
2824
  setToken(env);
2177
2825
  setMode("validating");
@@ -2179,15 +2827,66 @@ function App() {
2179
2827
  setToken(stored);
2180
2828
  setMode("validating");
2181
2829
  } else {
2182
- setMode("prompt");
2830
+ setMode("auth_method_selection");
2183
2831
  }
2184
2832
  }, []);
2185
- useEffect7(() => {
2833
+ useEffect8(() => {
2834
+ if (mode !== "oauth_flow") return;
2835
+ (async () => {
2836
+ try {
2837
+ setOAuthStatus("initializing");
2838
+ await new Promise((resolve) => setTimeout(resolve, 500));
2839
+ setOAuthStatus("device_code_requested");
2840
+ const deviceCodeResp = await requestDeviceCode();
2841
+ setDeviceCodeResponse(deviceCodeResp);
2842
+ setOauthDeviceCode({
2843
+ user_code: deviceCodeResp.user_code,
2844
+ verification_uri: deviceCodeResp.verification_uri
2845
+ });
2846
+ await new Promise((resolve) => setTimeout(resolve, 500));
2847
+ setOAuthStatus("browser_opening");
2848
+ const open2 = (await import("open")).default;
2849
+ await open2(deviceCodeResp.verification_uri);
2850
+ setOAuthStatus("waiting_for_authorization");
2851
+ await new Promise((resolve) => setTimeout(resolve, 2e3));
2852
+ setOAuthStatus("polling_for_token");
2853
+ const tokenResult = await pollForAccessToken(deviceCodeResp);
2854
+ if (tokenResult.success && tokenResult.token) {
2855
+ setOAuthStatus("validating_token");
2856
+ storeToken(tokenResult.token, "oauth");
2857
+ setToken(tokenResult.token);
2858
+ setTokenSource("oauth");
2859
+ if (tokenResult.login) {
2860
+ setViewer(tokenResult.login);
2861
+ setOAuthStatus("success");
2862
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
2863
+ setMode("ready");
2864
+ } else {
2865
+ throw new Error("Failed to get user login from token");
2866
+ }
2867
+ } else {
2868
+ throw new Error(tokenResult.error || "Failed to obtain access token");
2869
+ }
2870
+ } catch (error2) {
2871
+ setOAuthStatus("error");
2872
+ setError(error2.message);
2873
+ }
2874
+ })();
2875
+ }, [mode]);
2876
+ const handleAuthMethodSelect = (method) => {
2877
+ setAuthMethod(method);
2878
+ if (method === "pat") {
2879
+ setMode("prompt");
2880
+ } else if (method === "oauth") {
2881
+ setMode("oauth_flow");
2882
+ }
2883
+ };
2884
+ useEffect8(() => {
2186
2885
  (async () => {
2187
2886
  if (mode !== "validating" || !token) return;
2188
2887
  const timeoutId = setTimeout(() => {
2189
2888
  setError("Token validation timed out. Please check your network connection.");
2190
- setMode("prompt");
2889
+ setMode("auth_method_selection");
2191
2890
  setToken(null);
2192
2891
  }, 15e3);
2193
2892
  try {
@@ -2251,8 +2950,9 @@ function App() {
2251
2950
  } else {
2252
2951
  setError(errorMessage);
2253
2952
  setInput("");
2254
- setMode("prompt");
2255
2953
  setToken(null);
2954
+ clearStoredToken();
2955
+ setMode("auth_method_selection");
2256
2956
  }
2257
2957
  }
2258
2958
  })();
@@ -2260,6 +2960,7 @@ function App() {
2260
2960
  const onSubmitToken = async () => {
2261
2961
  if (!input.trim()) return;
2262
2962
  setToken(input.trim());
2963
+ setTokenSource("pat");
2263
2964
  setError(null);
2264
2965
  setMode("validating");
2265
2966
  };
@@ -2272,12 +2973,20 @@ function App() {
2272
2973
  setToken(null);
2273
2974
  setViewer(null);
2274
2975
  setInput("");
2275
- setMode("prompt");
2976
+ setTokenSource("pat");
2977
+ setMode("auth_method_selection");
2276
2978
  };
2277
- useInput10((input2, key) => {
2278
- if (mode === "prompt" && key.escape) {
2979
+ useInput12((input2, key) => {
2980
+ if ((mode === "prompt" || mode === "auth_method_selection") && key.escape) {
2279
2981
  exit();
2280
2982
  }
2983
+ if (mode === "oauth_flow" && key.escape) {
2984
+ setMode("auth_method_selection");
2985
+ setError(null);
2986
+ setOAuthStatus("initializing");
2987
+ setOauthDeviceCode(null);
2988
+ setDeviceCodeResponse(null);
2989
+ }
2281
2990
  if (mode === "rate_limited") {
2282
2991
  const ch = (input2 || "").toLowerCase();
2283
2992
  if (key.escape || ch === "q") {
@@ -2289,29 +2998,29 @@ function App() {
2289
2998
  }
2290
2999
  }
2291
3000
  if (mode === "validating" && key.escape) {
2292
- if (wasRateLimited) {
3001
+ if (wasRateLimited || rateLimitReset) {
2293
3002
  setMode("rate_limited");
2294
3003
  } else {
2295
- setMode("prompt");
2296
- setToken(null);
2297
- setInput("");
3004
+ setMode("auth_method_selection");
2298
3005
  }
3006
+ setToken(null);
3007
+ setInput("");
2299
3008
  }
2300
3009
  });
2301
3010
  const verticalPadding = Math.floor(dims.rows * 0.15);
2302
- const header = useMemo2(() => /* @__PURE__ */ jsxs13(Box13, { flexDirection: "row", justifyContent: "space-between", marginBottom: 1, children: [
2303
- /* @__PURE__ */ jsxs13(Box13, { flexDirection: "row", gap: 1, children: [
2304
- /* @__PURE__ */ jsxs13(Text14, { bold: true, color: "cyan", children: [
3011
+ const header = useMemo2(() => /* @__PURE__ */ jsxs16(Box16, { flexDirection: "row", justifyContent: "space-between", marginBottom: 1, children: [
3012
+ /* @__PURE__ */ jsxs16(Box16, { flexDirection: "row", gap: 1, children: [
3013
+ /* @__PURE__ */ jsxs16(Text17, { bold: true, color: "cyan", children: [
2305
3014
  " ",
2306
3015
  "GitHub Repository Manager"
2307
3016
  ] }),
2308
- /* @__PURE__ */ jsxs13(Text14, { color: "gray", dimColor: true, children: [
3017
+ /* @__PURE__ */ jsxs16(Text17, { color: "gray", dimColor: true, children: [
2309
3018
  "v",
2310
3019
  packageJson.version
2311
3020
  ] }),
2312
- process.env.GH_MANAGER_DEBUG === "1" && /* @__PURE__ */ jsx14(Text14, { backgroundColor: "blue", color: "white", children: " debug mode " })
3021
+ process.env.GH_MANAGER_DEBUG === "1" && /* @__PURE__ */ jsx17(Text17, { backgroundColor: "blue", color: "white", children: " debug mode " })
2313
3022
  ] }),
2314
- viewer && /* @__PURE__ */ jsx14(Text14, { color: "gray", children: orgContext !== "personal" && orgContext.login ? `${orgContext.login}/@${viewer} ` : `@${viewer} ` })
3023
+ viewer && /* @__PURE__ */ jsx17(Text17, { color: "gray", children: orgContext !== "personal" && orgContext.login ? `${orgContext.login}/@${viewer} ` : `@${viewer} ` })
2315
3024
  ] }), [viewer, orgContext]);
2316
3025
  if (mode === "rate_limited") {
2317
3026
  const formatResetTime = (resetTime) => {
@@ -2334,56 +3043,71 @@ function App() {
2334
3043
  return "Unknown";
2335
3044
  }
2336
3045
  };
2337
- return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
3046
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
2338
3047
  header,
2339
- /* @__PURE__ */ jsx14(Box13, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsxs13(Box13, { borderStyle: "single", borderColor: "yellow", paddingX: 3, paddingY: 2, flexDirection: "column", width: Math.min(dims.cols - 8, 80), children: [
2340
- /* @__PURE__ */ jsx14(Text14, { bold: true, color: "yellow", marginBottom: 1, children: "\u26A0\uFE0F Rate Limit Exceeded" }),
2341
- /* @__PURE__ */ jsx14(Text14, { color: "gray", marginBottom: 1, children: "You've hit GitHub's API rate limit for your token." }),
2342
- /* @__PURE__ */ jsx14(Text14, { color: "gray", marginBottom: 1, children: "This happens when you make too many requests in a short time." }),
2343
- rateLimitReset && /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, marginBottom: 1, children: [
2344
- /* @__PURE__ */ jsxs13(Text14, { children: [
2345
- /* @__PURE__ */ jsx14(Text14, { color: "cyan", children: "Reset in:" }),
3048
+ /* @__PURE__ */ jsx17(Box16, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsxs16(Box16, { borderStyle: "single", borderColor: "yellow", paddingX: 3, paddingY: 2, flexDirection: "column", width: Math.min(dims.cols - 8, 80), children: [
3049
+ /* @__PURE__ */ jsx17(Text17, { bold: true, color: "yellow", marginBottom: 1, children: "\u26A0\uFE0F Rate Limit Exceeded" }),
3050
+ /* @__PURE__ */ jsx17(Text17, { color: "gray", marginBottom: 1, children: "You've hit GitHub's API rate limit for your token." }),
3051
+ /* @__PURE__ */ jsx17(Text17, { color: "gray", marginBottom: 1, children: "This happens when you make too many requests in a short time." }),
3052
+ rateLimitReset && /* @__PURE__ */ jsxs16(Box16, { marginTop: 1, marginBottom: 1, children: [
3053
+ /* @__PURE__ */ jsxs16(Text17, { children: [
3054
+ /* @__PURE__ */ jsx17(Text17, { color: "cyan", children: "Reset in:" }),
2346
3055
  " ",
2347
- /* @__PURE__ */ jsx14(Text14, { bold: true, children: formatResetTime(rateLimitReset) })
3056
+ /* @__PURE__ */ jsx17(Text17, { bold: true, children: formatResetTime(rateLimitReset) })
2348
3057
  ] }),
2349
- /* @__PURE__ */ jsxs13(Text14, { color: "gray", dimColor: true, children: [
3058
+ /* @__PURE__ */ jsxs16(Text17, { color: "gray", dimColor: true, children: [
2350
3059
  "(",
2351
3060
  new Date(rateLimitReset).toLocaleTimeString(),
2352
3061
  ")"
2353
3062
  ] })
2354
3063
  ] }),
2355
- /* @__PURE__ */ jsxs13(Box13, { marginTop: 2, flexDirection: "column", gap: 1, children: [
2356
- /* @__PURE__ */ jsx14(Text14, { bold: true, children: "What would you like to do?" }),
2357
- /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", paddingLeft: 2, children: [
2358
- /* @__PURE__ */ jsxs13(Text14, { children: [
2359
- /* @__PURE__ */ jsx14(Text14, { color: "cyan", bold: true, children: "R" }),
3064
+ /* @__PURE__ */ jsxs16(Box16, { marginTop: 2, flexDirection: "column", gap: 1, children: [
3065
+ /* @__PURE__ */ jsx17(Text17, { bold: true, children: "What would you like to do?" }),
3066
+ /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", paddingLeft: 2, children: [
3067
+ /* @__PURE__ */ jsxs16(Text17, { children: [
3068
+ /* @__PURE__ */ jsx17(Text17, { color: "cyan", bold: true, children: "R" }),
2360
3069
  " - Retry now ",
2361
3070
  rateLimitReset && formatResetTime(rateLimitReset) !== "Now (should be reset)" ? "(likely to fail until reset)" : "(should work now)"
2362
3071
  ] }),
2363
- /* @__PURE__ */ jsxs13(Text14, { children: [
2364
- /* @__PURE__ */ jsx14(Text14, { color: "cyan", bold: true, children: "L" }),
2365
- " - Logout and use a different token"
3072
+ /* @__PURE__ */ jsxs16(Text17, { children: [
3073
+ /* @__PURE__ */ jsx17(Text17, { color: "cyan", bold: true, children: "L" }),
3074
+ " - Logout and choose authentication method"
2366
3075
  ] }),
2367
- /* @__PURE__ */ jsxs13(Text14, { children: [
2368
- /* @__PURE__ */ jsx14(Text14, { color: "gray", bold: true, children: "Q/Esc" }),
3076
+ /* @__PURE__ */ jsxs16(Text17, { children: [
3077
+ /* @__PURE__ */ jsx17(Text17, { color: "gray", bold: true, children: "Q/Esc" }),
2369
3078
  " - Quit application"
2370
3079
  ] })
2371
3080
  ] })
2372
3081
  ] }),
2373
- /* @__PURE__ */ jsx14(Text14, { color: "gray", dimColor: true, marginTop: 2, children: "Tip: Using multiple tokens or waiting between requests can help avoid rate limits." })
3082
+ /* @__PURE__ */ jsx17(Text17, { color: "gray", dimColor: true, marginTop: 2, children: "Tip: Using multiple tokens or waiting between requests can help avoid rate limits." })
2374
3083
  ] }) })
2375
3084
  ] });
2376
3085
  }
3086
+ if (mode === "auth_method_selection") {
3087
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
3088
+ header,
3089
+ /* @__PURE__ */ jsx17(Box16, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", alignItems: "center", children: [
3090
+ /* @__PURE__ */ jsx17(AuthMethodSelector, { onSelect: handleAuthMethodSelect }),
3091
+ error && /* @__PURE__ */ jsx17(Text17, { color: "red", marginTop: 1, children: error })
3092
+ ] }) })
3093
+ ] });
3094
+ }
3095
+ if (mode === "oauth_flow") {
3096
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
3097
+ header,
3098
+ /* @__PURE__ */ jsx17(Box16, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsx17(OAuthProgress, { status: oauthStatus, error: error || void 0, deviceCode: oauthDeviceCode || void 0 }) })
3099
+ ] });
3100
+ }
2377
3101
  if (mode === "prompt") {
2378
- return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
3102
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
2379
3103
  header,
2380
- /* @__PURE__ */ jsx14(Box13, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsxs13(Box13, { borderStyle: "single", borderColor: "cyan", paddingX: 2, paddingY: 1, flexDirection: "column", children: [
2381
- /* @__PURE__ */ jsx14(Text14, { bold: true, marginBottom: 1, children: "Authentication Required" }),
2382
- /* @__PURE__ */ jsx14(Text14, { color: "gray", marginBottom: 1, children: "Enter your GitHub Personal Access Token" }),
2383
- /* @__PURE__ */ jsxs13(Box13, { children: [
2384
- /* @__PURE__ */ jsx14(Text14, { children: "Token: " }),
2385
- /* @__PURE__ */ jsx14(
2386
- TextInput4,
3104
+ /* @__PURE__ */ jsx17(Box16, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsxs16(Box16, { borderStyle: "single", borderColor: "cyan", paddingX: 2, paddingY: 1, flexDirection: "column", children: [
3105
+ /* @__PURE__ */ jsx17(Text17, { bold: true, marginBottom: 1, children: "Authentication Required" }),
3106
+ /* @__PURE__ */ jsx17(Text17, { color: "gray", marginBottom: 1, children: "Enter your GitHub Personal Access Token" }),
3107
+ /* @__PURE__ */ jsxs16(Box16, { children: [
3108
+ /* @__PURE__ */ jsx17(Text17, { children: "Token: " }),
3109
+ /* @__PURE__ */ jsx17(
3110
+ TextInput5,
2387
3111
  {
2388
3112
  value: input,
2389
3113
  onChange: setInput,
@@ -2392,30 +3116,30 @@ function App() {
2392
3116
  }
2393
3117
  )
2394
3118
  ] }),
2395
- error && /* @__PURE__ */ jsx14(Text14, { color: "red", marginTop: 1, children: error }),
2396
- /* @__PURE__ */ jsx14(Text14, { color: "gray", dimColor: true, marginTop: 1, children: "The token will be stored securely in your local config" }),
2397
- /* @__PURE__ */ jsx14(Text14, { color: "gray", dimColor: true, marginTop: 1, children: "Press Esc to quit" })
3119
+ error && /* @__PURE__ */ jsx17(Text17, { color: "red", marginTop: 1, children: error }),
3120
+ /* @__PURE__ */ jsx17(Text17, { color: "gray", dimColor: true, marginTop: 1, children: "The token will be stored securely in your local config" }),
3121
+ /* @__PURE__ */ jsx17(Text17, { color: "gray", dimColor: true, marginTop: 1, children: "Press Esc to go back" })
2398
3122
  ] }) })
2399
3123
  ] });
2400
3124
  }
2401
3125
  if (mode === "validating" || mode === "checking") {
2402
- return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
3126
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
2403
3127
  header,
2404
- /* @__PURE__ */ jsx14(Box13, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", alignItems: "center", children: [
2405
- /* @__PURE__ */ jsx14(Text14, { color: "yellow", children: "Validating token..." }),
2406
- mode === "validating" && /* @__PURE__ */ jsx14(Text14, { color: "gray", dimColor: true, marginTop: 1, children: "Press Esc to cancel" })
3128
+ /* @__PURE__ */ jsx17(Box16, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", alignItems: "center", children: [
3129
+ /* @__PURE__ */ jsx17(Text17, { color: "yellow", children: "Validating token..." }),
3130
+ mode === "validating" && /* @__PURE__ */ jsx17(Text17, { color: "gray", dimColor: true, marginTop: 1, children: "Press Esc to cancel" })
2407
3131
  ] }) })
2408
3132
  ] });
2409
3133
  }
2410
3134
  if (mode === "error") {
2411
- return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
3135
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
2412
3136
  header,
2413
- /* @__PURE__ */ jsx14(Box13, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsx14(Text14, { color: "red", children: error ?? "Unexpected error" }) })
3137
+ /* @__PURE__ */ jsx17(Box16, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsx17(Text17, { color: "red", children: error ?? "Unexpected error" }) })
2414
3138
  ] });
2415
3139
  }
2416
- return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
3140
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", height: dims.rows, paddingX: 2, paddingTop: verticalPadding, paddingBottom: verticalPadding, children: [
2417
3141
  header,
2418
- /* @__PURE__ */ jsx14(
3142
+ /* @__PURE__ */ jsx17(
2419
3143
  RepoList,
2420
3144
  {
2421
3145
  token,
@@ -2429,7 +3153,7 @@ function App() {
2429
3153
  }
2430
3154
 
2431
3155
  // src/index.tsx
2432
- import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
3156
+ import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
2433
3157
  var argv = process.argv.slice(2);
2434
3158
  if (argv.includes("--version") || argv.includes("-v")) {
2435
3159
  const version = import_package.default?.version || "0.0.0";
@@ -2464,8 +3188,8 @@ process.on("unhandledRejection", (reason) => {
2464
3188
  process.exit(1);
2465
3189
  });
2466
3190
  render(
2467
- /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", children: [
2468
- /* @__PURE__ */ jsx15(App, {}),
2469
- /* @__PURE__ */ jsx15(Text15, { color: "gray" })
3191
+ /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
3192
+ /* @__PURE__ */ jsx18(App, {}),
3193
+ /* @__PURE__ */ jsx18(Text18, { color: "gray" })
2470
3194
  ] })
2471
3195
  );