lazyreview 0.1.4
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/.github/workflows/publish-npm.yml +51 -0
- package/.prettierrc +7 -0
- package/CLAUDE.md +50 -0
- package/README.md +119 -0
- package/dist/cli.js +3830 -0
- package/dist/cli.js.map +1 -0
- package/package.json +64 -0
- package/pnpm-workspace.yaml +5 -0
- package/src/app.tsx +235 -0
- package/src/cli.tsx +78 -0
- package/src/components/common/BorderedBox.tsx +41 -0
- package/src/components/common/Divider.tsx +31 -0
- package/src/components/common/EmptyState.tsx +35 -0
- package/src/components/common/FilterModal.tsx +117 -0
- package/src/components/common/LoadingIndicator.tsx +31 -0
- package/src/components/common/Modal.tsx +24 -0
- package/src/components/common/PaginationBar.tsx +56 -0
- package/src/components/common/SortModal.tsx +91 -0
- package/src/components/common/Spinner.tsx +28 -0
- package/src/components/common/index.ts +9 -0
- package/src/components/layout/HelpModal.tsx +61 -0
- package/src/components/layout/MainPanel.tsx +26 -0
- package/src/components/layout/Sidebar.tsx +71 -0
- package/src/components/layout/StatusBar.tsx +42 -0
- package/src/components/layout/TokenInputModal.tsx +92 -0
- package/src/components/layout/TopBar.tsx +44 -0
- package/src/components/layout/index.ts +6 -0
- package/src/components/pr/CommentsTab.tsx +92 -0
- package/src/components/pr/CommitsTab.tsx +142 -0
- package/src/components/pr/ConversationsTab.tsx +273 -0
- package/src/components/pr/FilesTab.tsx +532 -0
- package/src/components/pr/PRHeader.tsx +69 -0
- package/src/components/pr/PRListItem.tsx +92 -0
- package/src/components/pr/PRTabs.tsx +50 -0
- package/src/components/pr/index.ts +8 -0
- package/src/hooks/index.ts +12 -0
- package/src/hooks/useActivePanel.ts +54 -0
- package/src/hooks/useAppKeymap.ts +22 -0
- package/src/hooks/useAuth.ts +131 -0
- package/src/hooks/useConfig.ts +52 -0
- package/src/hooks/useFilter.ts +192 -0
- package/src/hooks/useGitHub.ts +260 -0
- package/src/hooks/useInputFocus.tsx +35 -0
- package/src/hooks/useListNavigation.ts +121 -0
- package/src/hooks/useLoading.ts +25 -0
- package/src/hooks/usePagination.ts +87 -0
- package/src/models/comment.ts +15 -0
- package/src/models/commit.ts +20 -0
- package/src/models/diff.ts +93 -0
- package/src/models/errors.ts +24 -0
- package/src/models/file-change.ts +22 -0
- package/src/models/index.ts +12 -0
- package/src/models/pull-request.ts +40 -0
- package/src/models/review.ts +17 -0
- package/src/models/user.ts +9 -0
- package/src/screens/InvolvedScreen.tsx +161 -0
- package/src/screens/MyPRsScreen.tsx +161 -0
- package/src/screens/PRDetailScreen.tsx +88 -0
- package/src/screens/PRListScreen.tsx +96 -0
- package/src/screens/ReviewRequestsScreen.tsx +161 -0
- package/src/screens/SettingsScreen.tsx +284 -0
- package/src/screens/ThisRepoScreen.tsx +175 -0
- package/src/screens/index.ts +7 -0
- package/src/services/Auth.ts +314 -0
- package/src/services/Config.ts +81 -0
- package/src/services/GitHubApi.ts +262 -0
- package/src/services/Loading.ts +54 -0
- package/src/services/index.ts +27 -0
- package/src/theme/index.ts +28 -0
- package/src/theme/themes.ts +84 -0
- package/src/theme/types.ts +28 -0
- package/src/utils/date.ts +28 -0
- package/src/utils/git.ts +67 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/terminal.ts +25 -0
- package/tsconfig.json +24 -0
- package/tsup.config.ts +13 -0
- package/vitest.config.ts +26 -0
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.tsx","../src/app.tsx","../src/theme/index.ts","../src/theme/themes.ts","../src/components/layout/TopBar.tsx","../src/components/layout/Sidebar.tsx","../src/components/layout/MainPanel.tsx","../src/components/layout/StatusBar.tsx","../src/components/common/Spinner.tsx","../src/hooks/useLoading.ts","../src/components/layout/HelpModal.tsx","../src/components/common/Divider.tsx","../src/components/common/Modal.tsx","../src/components/layout/TokenInputModal.tsx","../src/hooks/useInputFocus.tsx","../src/screens/PRDetailScreen.tsx","../src/hooks/useGitHub.ts","../src/services/GitHubApi.ts","../src/models/errors.ts","../src/models/pull-request.ts","../src/models/user.ts","../src/models/comment.ts","../src/models/review.ts","../src/models/file-change.ts","../src/models/commit.ts","../src/services/Auth.ts","../src/services/index.ts","../src/services/Config.ts","../src/services/Loading.ts","../src/components/pr/PRHeader.tsx","../src/utils/date.ts","../src/components/pr/PRTabs.tsx","../src/components/pr/FilesTab.tsx","../src/hooks/useListNavigation.ts","../src/models/diff.ts","../src/components/common/EmptyState.tsx","../src/components/pr/ConversationsTab.tsx","../src/components/pr/CommitsTab.tsx","../src/components/common/LoadingIndicator.tsx","../src/screens/MyPRsScreen.tsx","../src/hooks/usePagination.ts","../src/hooks/useFilter.ts","../src/components/pr/PRListItem.tsx","../src/components/common/PaginationBar.tsx","../src/components/common/FilterModal.tsx","../src/components/common/SortModal.tsx","../src/screens/ReviewRequestsScreen.tsx","../src/screens/SettingsScreen.tsx","../src/hooks/useConfig.ts","../src/hooks/useAuth.ts","../src/screens/InvolvedScreen.tsx","../src/screens/ThisRepoScreen.tsx","../src/hooks/useActivePanel.ts","../src/utils/git.ts"],"sourcesContent":["import React from 'react'\nimport { render } from 'ink'\nimport { App } from './app'\nimport { detectGitRepo } from './utils/git'\n\n// ANSI escape codes for alternate screen buffer\nconst ENTER_ALT_SCREEN = '\\x1b[?1049h'\nconst EXIT_ALT_SCREEN = '\\x1b[?1049l'\nconst CLEAR_SCREEN = '\\x1b[2J'\nconst CURSOR_HOME = '\\x1b[H'\nconst HIDE_CURSOR = '\\x1b[?25l'\nconst SHOW_CURSOR = '\\x1b[?25h'\n\ninterface RepoInfo {\n readonly owner: string | null\n readonly repo: string | null\n}\n\nfunction parseArgs(argv: string[]): RepoInfo | null {\n const repoArg = argv[2]\n\n if (repoArg && repoArg.includes('/')) {\n const [owner, repo] = repoArg.split('/')\n if (owner && repo) {\n return { owner, repo }\n }\n }\n\n return null\n}\n\n// Cleanup on exit\nfunction cleanup(): void {\n process.stdout.write(SHOW_CURSOR + EXIT_ALT_SCREEN)\n}\n\nasync function main(): Promise<void> {\n // Enter alternate screen buffer\n process.stdout.write(\n ENTER_ALT_SCREEN + CLEAR_SCREEN + CURSOR_HOME + HIDE_CURSOR,\n )\n\n process.on('exit', cleanup)\n process.on('SIGINT', () => {\n cleanup()\n process.exit(0)\n })\n process.on('SIGTERM', () => {\n cleanup()\n process.exit(0)\n })\n\n // Check for CLI args first\n const argsRepo = parseArgs(process.argv)\n\n // If no args, try to detect from current git repo\n let repoOwner: string | null = null\n let repoName: string | null = null\n\n if (argsRepo) {\n repoOwner = argsRepo.owner\n repoName = argsRepo.repo\n } else {\n const gitInfo = await detectGitRepo()\n if (gitInfo.isGitRepo && gitInfo.owner && gitInfo.repo) {\n repoOwner = gitInfo.owner\n repoName = gitInfo.repo\n }\n }\n\n render(<App repoOwner={repoOwner} repoName={repoName} />)\n}\n\nmain().catch((error) => {\n cleanup()\n console.error('Failed to start:', error)\n process.exit(1)\n})\n","import React, { useState, useCallback } from 'react'\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'\nimport { Box, useApp, useInput, useStdout } from 'ink'\nimport { ThemeProvider, getThemeByName } from './theme/index'\nimport type { ThemeName } from './theme/index'\nimport { TopBar } from './components/layout/TopBar'\nimport { Sidebar, SIDEBAR_ITEMS } from './components/layout/Sidebar'\nimport { MainPanel } from './components/layout/MainPanel'\nimport { StatusBar } from './components/layout/StatusBar'\nimport { HelpModal } from './components/layout/HelpModal'\nimport { TokenInputModal } from './components/layout/TokenInputModal'\nimport { PRDetailScreen } from './screens/PRDetailScreen'\nimport { MyPRsScreen } from './screens/MyPRsScreen'\nimport { ReviewRequestsScreen } from './screens/ReviewRequestsScreen'\nimport { SettingsScreen } from './screens/SettingsScreen'\nimport { InvolvedScreen } from './screens/InvolvedScreen'\nimport { ThisRepoScreen } from './screens/ThisRepoScreen'\nimport { Match } from 'effect'\nimport { useAuth } from './hooks/useAuth'\nimport { useConfig } from './hooks/useConfig'\nimport { useListNavigation } from './hooks/useListNavigation'\nimport { useActivePanel } from './hooks/useActivePanel'\nimport { InputFocusProvider, useInputFocus } from './hooks/useInputFocus'\nimport type { PullRequest } from './models/pull-request'\n\ntype AppScreen =\n | { readonly type: 'list' }\n | { readonly type: 'detail'; readonly pr: PullRequest }\n\ninterface AppContentProps {\n readonly repoOwner: string | null\n readonly repoName: string | null\n}\n\nfunction AppContent({\n repoOwner,\n repoName,\n}: AppContentProps): React.ReactElement {\n const { exit } = useApp()\n const { stdout } = useStdout()\n const { user, isAuthenticated, loading, saveToken, error } = useAuth()\n const [sidebarVisible, setSidebarVisible] = useState(true)\n const [currentScreen, setCurrentScreen] = useState<AppScreen>({\n type: 'list',\n })\n const [tokenError, setTokenError] = useState<string | null>(null)\n const [showHelp, setShowHelp] = useState(false)\n // Start with modal hidden, show only after auth check fails\n const [showTokenInput, setShowTokenInput] = useState(false)\n\n // Panel focus management\n const { activePanel, setActivePanel } = useActivePanel({\n hasSelection: currentScreen.type === 'detail',\n })\n\n // Input focus tracking (for disabling shortcuts when typing)\n const { isInputActive } = useInputFocus()\n\n // Sidebar navigation\n const { selectedIndex: sidebarIndex } = useListNavigation({\n itemCount: SIDEBAR_ITEMS.length,\n viewportHeight: SIDEBAR_ITEMS.length,\n isActive: activePanel === 'sidebar' && !showHelp && !showTokenInput,\n })\n\n // Show token modal when not authenticated (covers invalid token case)\n React.useEffect(() => {\n if (!loading && !isAuthenticated && !showTokenInput) {\n setShowTokenInput(true)\n } else if (isAuthenticated && showTokenInput) {\n setShowTokenInput(false)\n }\n }, [loading, isAuthenticated, showTokenInput])\n\n const handleTokenSubmit = useCallback(\n async (token: string) => {\n try {\n setTokenError(null)\n await saveToken(token)\n } catch (err) {\n setTokenError(String(err))\n }\n },\n [saveToken],\n )\n\n // Global keyboard shortcuts\n useInput(\n (input, key) => {\n // Handle modals first\n if (showHelp || showTokenInput) {\n if (key.escape || (showHelp && input === '?')) {\n setShowHelp(false)\n }\n return\n }\n\n if (input === 'b') {\n setSidebarVisible((prev) => !prev)\n } else if (input === '?') {\n setShowHelp(true)\n } else if (input === 'q') {\n if (currentScreen.type === 'detail') {\n setCurrentScreen({ type: 'list' })\n } else {\n exit()\n }\n } else if (key.return && activePanel === 'sidebar') {\n setActivePanel('list')\n }\n },\n { isActive: !showTokenInput && !isInputActive },\n )\n\n const handleSelectPR = useCallback((pr: PullRequest) => {\n setCurrentScreen({ type: 'detail', pr })\n }, [])\n\n const handleBackToList = useCallback(() => {\n setCurrentScreen({ type: 'list' })\n }, [])\n\n function renderScreen(): React.ReactElement {\n if (currentScreen.type === 'detail') {\n // Extract owner/repo from PR URL for detail view\n const prUrl = currentScreen.pr.html_url\n const match = prUrl.match(/github\\.com\\/([^/]+)\\/([^/]+)\\/pull/)\n const prOwner = match?.[1] ?? repoOwner ?? ''\n const prRepo = match?.[2] ?? repoName ?? ''\n\n return (\n <PRDetailScreen\n pr={currentScreen.pr}\n owner={prOwner}\n repo={prRepo}\n onBack={handleBackToList}\n />\n )\n }\n\n // Navigation:\n // 0 - Involved (all PRs user is involved in)\n // 1 - My PRs (PRs user created)\n // 2 - For Review (PRs requesting user's review)\n // 3 - This Repo (PRs from current git directory)\n // 4 - Settings\n return Match.value(sidebarIndex).pipe(\n Match.when(0, () => <InvolvedScreen onSelect={handleSelectPR} />),\n Match.when(1, () => <MyPRsScreen onSelect={handleSelectPR} />),\n Match.when(2, () => <ReviewRequestsScreen onSelect={handleSelectPR} />),\n Match.when(3, () => (\n <ThisRepoScreen\n owner={repoOwner}\n repo={repoName}\n onSelect={handleSelectPR}\n />\n )),\n Match.when(4, () => <SettingsScreen />),\n Match.orElse(() => <InvolvedScreen onSelect={handleSelectPR} />),\n )\n }\n\n const terminalHeight = stdout?.rows ?? 24\n\n const repoPath =\n repoOwner && repoName ? `${repoOwner}/${repoName}` : undefined\n\n return (\n <Box flexDirection=\"column\" height={terminalHeight}>\n <TopBar\n username={user?.login ?? 'anonymous'}\n provider=\"github\"\n repoPath={repoPath}\n />\n <Box flexDirection=\"row\" flexGrow={1}>\n <Sidebar\n selectedIndex={sidebarIndex}\n visible={sidebarVisible}\n isActive={activePanel === 'sidebar'}\n />\n <MainPanel isActive={activePanel === 'list'}>\n {renderScreen()}\n </MainPanel>\n </Box>\n <StatusBar activePanel={activePanel} />\n {showHelp && <HelpModal onClose={() => setShowHelp(false)} />}\n {showTokenInput && (\n <TokenInputModal\n onSubmit={handleTokenSubmit}\n onClose={() => setShowTokenInput(false)}\n error={tokenError ?? error}\n />\n )}\n </Box>\n )\n}\n\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 1000 * 60, // 1 minute\n retry: 1,\n },\n },\n})\n\ninterface AppProps {\n readonly repoOwner: string | null\n readonly repoName: string | null\n}\n\nfunction AppWithTheme({\n repoOwner,\n repoName,\n}: AppProps): React.ReactElement {\n const { config } = useConfig()\n const themeName = (config?.theme ?? 'tokyo-night') as ThemeName\n const theme = getThemeByName(themeName)\n\n return (\n <ThemeProvider theme={theme}>\n <AppContent repoOwner={repoOwner} repoName={repoName} />\n </ThemeProvider>\n )\n}\n\nexport function App({ repoOwner, repoName }: AppProps): React.ReactElement {\n return (\n <QueryClientProvider client={queryClient}>\n <InputFocusProvider>\n <AppWithTheme repoOwner={repoOwner} repoName={repoName} />\n </InputFocusProvider>\n </QueryClientProvider>\n )\n}\n","import React, { createContext, useContext } from 'react'\nimport type { Theme, ThemeName } from './types'\nimport { themes, defaultTheme } from './themes'\n\nexport type { Theme, ThemeColors, ThemeName } from './types'\nexport { themes, defaultTheme } from './themes'\n\nconst ThemeContext = createContext<Theme>(defaultTheme)\n\nexport interface ThemeProviderProps {\n readonly theme?: Theme\n readonly children: React.ReactNode\n}\n\nexport function ThemeProvider({\n theme = defaultTheme,\n children,\n}: ThemeProviderProps): React.ReactElement {\n return React.createElement(ThemeContext.Provider, { value: theme }, children)\n}\n\nexport function useTheme(): Theme {\n return useContext(ThemeContext)\n}\n\nexport function getThemeByName(name: ThemeName): Theme {\n return themes[name] ?? defaultTheme\n}\n","import type { Theme, ThemeName } from './types'\n\nconst tokyoNight: Theme = {\n name: 'tokyo-night',\n colors: {\n bg: '#1a1b26',\n text: '#c0caf5',\n accent: '#7aa2f7',\n muted: '#565f89',\n border: '#3b4261',\n primary: '#7aa2f7',\n secondary: '#bb9af7',\n\n success: '#9ece6a',\n error: '#f7768e',\n warning: '#e0af68',\n info: '#7dcfff',\n\n diffAdd: '#9ece6a',\n diffDel: '#f7768e',\n\n selection: '#283457',\n listSelectedFg: '#c0caf5',\n listSelectedBg: '#283457',\n },\n}\n\nconst dracula: Theme = {\n name: 'dracula',\n colors: {\n bg: '#282a36',\n text: '#f8f8f2',\n accent: '#bd93f9',\n muted: '#6272a4',\n border: '#44475a',\n primary: '#bd93f9',\n secondary: '#ff79c6',\n\n success: '#50fa7b',\n error: '#ff5555',\n warning: '#f1fa8c',\n info: '#8be9fd',\n\n diffAdd: '#50fa7b',\n diffDel: '#ff5555',\n\n selection: '#44475a',\n listSelectedFg: '#f8f8f2',\n listSelectedBg: '#44475a',\n },\n}\n\nconst catppuccinMocha: Theme = {\n name: 'catppuccin-mocha',\n colors: {\n bg: '#1e1e2e',\n text: '#cdd6f4',\n accent: '#89b4fa',\n muted: '#6c7086',\n border: '#313244',\n primary: '#89b4fa',\n secondary: '#cba6f7',\n\n success: '#a6e3a1',\n error: '#f38ba8',\n warning: '#f9e2af',\n info: '#89dceb',\n\n diffAdd: '#a6e3a1',\n diffDel: '#f38ba8',\n\n selection: '#313244',\n listSelectedFg: '#cdd6f4',\n listSelectedBg: '#313244',\n },\n}\n\nexport const themes: Record<ThemeName, Theme> = {\n 'tokyo-night': tokyoNight,\n dracula,\n 'catppuccin-mocha': catppuccinMocha,\n}\n\nexport const defaultTheme: Theme = tokyoNight\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport { useTheme } from '../../theme/index'\n\ninterface TopBarProps {\n readonly username: string\n readonly provider: string\n readonly repoPath?: string\n}\n\nexport function TopBar({\n username,\n provider,\n repoPath,\n}: TopBarProps): React.ReactElement {\n const theme = useTheme()\n\n return (\n <Box\n height={1}\n width=\"100%\"\n justifyContent=\"space-between\"\n paddingX={1}\n marginTop={0.6}\n >\n <Box gap={1}>\n <Text color={theme.colors.accent} bold>\n LazyReview\n </Text>\n {repoPath && (\n <>\n <Text color={theme.colors.muted}>│</Text>\n <Text color={theme.colors.text}>{repoPath}</Text>\n </>\n )}\n </Box>\n <Box gap={1}>\n <Text color={theme.colors.muted}>{provider}</Text>\n <Text color={theme.colors.muted}>│</Text>\n <Text color={theme.colors.secondary}>{username}</Text>\n </Box>\n </Box>\n )\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport { useTheme } from '../../theme/index'\n\nexport const SIDEBAR_ITEMS = [\n 'Involved',\n 'My PRs',\n 'For Review',\n 'This Repo',\n 'Settings',\n] as const\n\nexport type SidebarItem = (typeof SIDEBAR_ITEMS)[number]\n\nconst sidebarIcons: Record<SidebarItem, string> = {\n Involved: '◆',\n 'My PRs': '●',\n 'For Review': '◎',\n 'This Repo': '◈',\n Settings: '⚙',\n}\n\ninterface SidebarProps {\n readonly selectedIndex: number\n readonly visible: boolean\n readonly isActive: boolean\n}\n\nexport function Sidebar({\n selectedIndex,\n visible,\n isActive,\n}: SidebarProps): React.ReactElement | null {\n const theme = useTheme()\n\n if (!visible) return null\n\n return (\n <Box\n flexDirection=\"column\"\n width={24}\n borderStyle=\"single\"\n borderColor={isActive ? theme.colors.accent : theme.colors.border}\n >\n <Box paddingX={1} paddingY={0}>\n <Text color={theme.colors.accent} bold={isActive} dimColor={!isActive}>\n Navigation\n </Text>\n </Box>\n <Box flexDirection=\"column\" paddingTop={1}>\n {SIDEBAR_ITEMS.map((label, index) => {\n const isSelected = index === selectedIndex\n const icon = sidebarIcons[label]\n return (\n <Box key={label} paddingX={1}>\n <Text\n color={isSelected ? theme.colors.accent : theme.colors.text}\n backgroundColor={isSelected ? theme.colors.selection : undefined}\n bold={isSelected}\n dimColor={!isActive && !isSelected}\n >\n {isSelected ? '▸ ' : ' '}\n {icon} {label}\n </Text>\n </Box>\n )\n })}\n </Box>\n </Box>\n )\n}\n","import React from 'react'\nimport { Box } from 'ink'\nimport { useTheme } from '../../theme/index'\n\ninterface MainPanelProps {\n readonly children: React.ReactNode\n readonly isActive?: boolean\n}\n\nexport function MainPanel({\n children,\n isActive = false,\n}: MainPanelProps): React.ReactElement {\n const theme = useTheme()\n\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n borderStyle=\"single\"\n borderColor={isActive ? theme.colors.accent : theme.colors.border}\n >\n {children}\n </Box>\n )\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport { Spinner } from '../common/Spinner'\nimport { useTheme } from '../../theme/index'\nimport { useLoading } from '../../hooks/useLoading'\nimport type { Panel } from '../../hooks/useActivePanel'\n\nconst PANEL_HINTS: Record<Panel, string> = {\n sidebar: 'j/k:nav gg/G:top/bottom Enter:select Tab:list b:toggle ?:help q:quit',\n list: 'j/k:nav gg/G:top/bottom Enter:detail Esc:sidebar Tab:next ?:help q:quit',\n detail: 'j/k:scroll Tab:tabs Esc:list ?:help q:quit',\n}\n\ninterface StatusBarProps {\n readonly activePanel?: Panel\n}\n\nexport function StatusBar({ activePanel = 'sidebar' }: StatusBarProps): React.ReactElement {\n const theme = useTheme()\n const loadingState = useLoading()\n const hints = PANEL_HINTS[activePanel]\n\n return (\n <Box\n height={1}\n width=\"100%\"\n justifyContent=\"space-between\"\n paddingX={1}\n >\n <Box>\n {loadingState.isLoading ? (\n <Spinner label={loadingState.message ?? 'Loading...'} />\n ) : (\n <Text color={theme.colors.success}>Ready</Text>\n )}\n </Box>\n <Box gap={1}>\n <Text color={theme.colors.muted}>{hints}</Text>\n </Box>\n </Box>\n )\n}\n","import React, { useState, useEffect } from 'react'\nimport { Text } from 'ink'\nimport { useTheme } from '../../theme/index'\n\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']\n\ninterface SpinnerProps {\n readonly label?: string\n}\n\nexport function Spinner({ label }: SpinnerProps): React.ReactElement {\n const theme = useTheme()\n const [frame, setFrame] = useState(0)\n\n useEffect(() => {\n const timer = setInterval(() => {\n setFrame((prev) => (prev + 1) % SPINNER_FRAMES.length)\n }, 80)\n\n return () => clearInterval(timer)\n }, [])\n\n return (\n <Text color={theme.colors.accent}>\n {SPINNER_FRAMES[frame]} {label}\n </Text>\n )\n}\n","import { useSyncExternalStore } from 'react'\nimport type { LoadingState, LoadingService } from '../services/Loading'\n\nlet loadingService: LoadingService | null = null\n\nexport function setLoadingService(service: LoadingService): void {\n loadingService = service\n}\n\nexport function getLoadingService(): LoadingService | null {\n return loadingService\n}\n\nconst emptyState: LoadingState = { isLoading: false, message: null }\n\nexport function useLoading(): LoadingState {\n return useSyncExternalStore(\n (callback) => {\n if (!loadingService) return () => {}\n return loadingService.subscribe(callback)\n },\n () => loadingService?.getState() ?? emptyState,\n () => emptyState,\n )\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport { useTheme } from '../../theme/index'\nimport { Divider } from '../common/Divider'\nimport { Modal } from '../common/Modal'\n\ninterface HelpModalProps {\n readonly onClose: () => void\n}\n\nconst shortcuts = [\n { key: 'j / k', description: 'Move down / up' },\n { key: 'Enter', description: 'Select / Open' },\n { key: 'Tab', description: 'Switch focus panel' },\n { key: 'b', description: 'Toggle sidebar' },\n { key: '/', description: 'Search / Filter PRs' },\n { key: 's', description: 'Sort PRs' },\n { key: 'n / p', description: 'Next / Previous page' },\n { key: '1 / 2 / 3', description: 'Switch PR detail tabs' },\n { key: 'q', description: 'Back / Quit' },\n { key: '?', description: 'Toggle this help' },\n { key: 'Ctrl+c', description: 'Force quit' },\n]\n\nexport function HelpModal({ onClose }: HelpModalProps): React.ReactElement {\n const theme = useTheme()\n\n return (\n <Modal>\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.colors.accent}\n // @ts-ignore\n backgroundColor={theme.colors.bg}\n paddingX={2}\n paddingY={1}\n gap={1}\n >\n <Text color={theme.colors.accent} bold>\n Keyboard Shortcuts\n </Text>\n <Divider />\n <Box flexDirection=\"column\">\n {shortcuts.map((s) => (\n <Box key={s.key} gap={2}>\n <Box width={16}>\n <Text color={theme.colors.warning}>{s.key}</Text>\n </Box>\n <Text color={theme.colors.text}>{s.description}</Text>\n </Box>\n ))}\n </Box>\n <Divider />\n <Text color={theme.colors.muted} dimColor>\n Press ? to close\n </Text>\n </Box>\n </Modal>\n )\n}\n","import React from 'react'\nimport { Box, Text, useStdout } from 'ink'\nimport { useTheme } from '../../theme/index'\n\nconst DEFAULT_LINE_LENGTH = 36\n\nexport function Divider({ title }: { readonly title?: string }): React.ReactElement {\n const theme = useTheme()\n const { stdout } = useStdout()\n const cols = stdout?.columns ?? 80\n const len = Math.min(DEFAULT_LINE_LENGTH, Math.max(10, cols - 8))\n const line = '─'.repeat(len)\n\n if (title) {\n const pad = Math.max(0, len - title.length - 2)\n const left = Math.floor(pad / 2)\n const right = pad - left\n const text = '─'.repeat(left) + ` ${title} ` + '─'.repeat(right)\n return (\n <Box paddingY={0}>\n <Text color={theme.colors.border}>{text}</Text>\n </Box>\n )\n }\n\n return (\n <Box paddingY={0}>\n <Text color={theme.colors.border}>{line}</Text>\n </Box>\n )\n}\n","import React from 'react'\nimport { Box, useStdout } from 'ink'\n\ninterface ModalProps {\n readonly children: React.ReactNode\n}\n\nexport function Modal({ children }: ModalProps): React.ReactElement {\n const { stdout } = useStdout()\n const width = stdout?.columns ?? 80\n const height = stdout?.rows ?? 24\n\n return (\n <Box\n position=\"absolute\"\n width={width}\n height={height}\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n {children}\n </Box>\n )\n}\n","import React, { useState, useEffect } from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport { TextInput } from '@inkjs/ui'\nimport { useTheme } from '../../theme/index'\nimport { useInputFocus } from '../../hooks/useInputFocus'\nimport { Modal } from '../common/Modal'\n\ninterface TokenInputModalProps {\n readonly onClose: () => void\n readonly onSubmit: (token: string) => void\n readonly error?: string | null\n}\n\nexport function TokenInputModal({\n onSubmit,\n error,\n}: TokenInputModalProps): React.ReactElement {\n const theme = useTheme()\n const { setInputActive } = useInputFocus()\n const [value, setValue] = useState('')\n\n // Disable global shortcuts while this modal is open\n useEffect(() => {\n setInputActive(true)\n return () => setInputActive(false)\n }, [setInputActive])\n\n const handleSubmit = (): void => {\n const trimmed = value.trim()\n if (trimmed) {\n onSubmit(trimmed)\n }\n }\n\n useInput((_input, key) => {\n if (key.return) {\n handleSubmit()\n }\n })\n\n return (\n <Modal>\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.colors.accent}\n // @ts-ignore\n backgroundColor={theme.colors.bg}\n paddingX={2}\n paddingY={1}\n gap={1}\n >\n <Text color={theme.colors.accent} bold>\n GitHub Token Required\n </Text>\n <Box flexDirection=\"column\">\n <Text color={theme.colors.text}>\n No GitHub token found in your environment.\n </Text>\n <Text color={theme.colors.muted}>\n Please enter your GitHub Personal Access Token:\n </Text>\n </Box>\n {error && <Text color={theme.colors.error}>Error: {error}</Text>}\n <Box\n borderStyle=\"single\"\n borderColor={theme.colors.border}\n paddingX={1}\n width={50}\n >\n <TextInput defaultValue={value} onChange={setValue} />\n </Box>\n <Box flexDirection=\"column\">\n <Text color={theme.colors.muted} dimColor>\n The token will be saved to ~/.config/lazyreview/.token\n </Text>\n <Text color={theme.colors.muted} dimColor>\n Press Enter to submit, Ctrl+C to quit.\n </Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={theme.colors.info}>\n Get a token at: github.com/settings/tokens\n </Text>\n <Text color={theme.colors.muted}>\n Required scopes: repo, read:user\n </Text>\n </Box>\n </Box>\n </Modal>\n )\n}\n","import React, { createContext, useContext, useState, useCallback } from 'react'\n\ninterface InputFocusContextType {\n readonly isInputActive: boolean\n readonly setInputActive: (active: boolean) => void\n}\n\nconst InputFocusContext = createContext<InputFocusContextType>({\n isInputActive: false,\n setInputActive: () => {},\n})\n\ninterface InputFocusProviderProps {\n readonly children: React.ReactNode\n}\n\nexport function InputFocusProvider({\n children,\n}: InputFocusProviderProps): React.ReactElement {\n const [isInputActive, setIsInputActive] = useState(false)\n\n const setInputActive = useCallback((active: boolean) => {\n setIsInputActive(active)\n }, [])\n\n return React.createElement(\n InputFocusContext.Provider,\n { value: { isInputActive, setInputActive } },\n children,\n )\n}\n\nexport function useInputFocus(): InputFocusContextType {\n return useContext(InputFocusContext)\n}\n","import React, { useState } from 'react'\nimport { Box, useInput, useStdout } from 'ink'\nimport { Match } from 'effect'\nimport { usePRFiles, usePRComments, usePRReviews, usePRCommits } from '../hooks/useGitHub'\nimport { PRHeader } from '../components/pr/PRHeader'\nimport { PRTabs } from '../components/pr/PRTabs'\nimport { FilesTab } from '../components/pr/FilesTab'\nimport { ConversationsTab } from '../components/pr/ConversationsTab'\nimport { CommitsTab } from '../components/pr/CommitsTab'\nimport { LoadingIndicator } from '../components/common/LoadingIndicator'\nimport type { PullRequest } from '../models/pull-request'\n\ninterface PRDetailScreenProps {\n readonly pr: PullRequest\n readonly owner: string\n readonly repo: string\n readonly onBack: () => void\n}\n\nconst PR_DETAIL_RESERVED_LINES = 12\n\nexport function PRDetailScreen({\n pr,\n owner,\n repo,\n onBack,\n}: PRDetailScreenProps): React.ReactElement {\n const { stdout } = useStdout()\n const [currentTab, setCurrentTab] = useState(0)\n const contentHeight = Math.max(1, (stdout?.rows ?? 24) - PR_DETAIL_RESERVED_LINES)\n\n // Fetch all PR data\n const { data: files = [], isLoading: filesLoading } = usePRFiles(owner, repo, pr.number)\n const { data: comments = [], isLoading: commentsLoading } = usePRComments(owner, repo, pr.number)\n const { data: reviews = [], isLoading: reviewsLoading } = usePRReviews(owner, repo, pr.number)\n const { data: commits = [], isLoading: commitsLoading } = usePRCommits(owner, repo, pr.number)\n\n const isLoading = filesLoading || commentsLoading || reviewsLoading || commitsLoading\n\n useInput((input, key) => {\n if (input === '1') {\n setCurrentTab(0)\n } else if (input === '2') {\n setCurrentTab(1)\n } else if (input === '3') {\n setCurrentTab(2)\n } else if (input === 'q' || key.escape) {\n onBack()\n }\n })\n\n const renderTabContent = (): React.ReactElement => {\n if (isLoading) {\n return <LoadingIndicator message=\"Loading PR details...\" />\n }\n\n return Match.value(currentTab).pipe(\n Match.when(0, () => (\n <ConversationsTab\n pr={pr}\n comments={comments}\n reviews={reviews}\n isActive={true}\n />\n )),\n Match.when(1, () => <CommitsTab commits={commits} isActive={true} />),\n Match.when(2, () => <FilesTab files={files} isActive={true} />),\n Match.orElse(() => (\n <ConversationsTab\n pr={pr}\n comments={comments}\n reviews={reviews}\n isActive={true}\n />\n ))\n )\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <PRHeader pr={pr} />\n <PRTabs activeIndex={currentTab} onChange={setCurrentTab} />\n <Box height={contentHeight} overflow=\"hidden\" flexDirection=\"column\">\n {renderTabContent()}\n </Box>\n </Box>\n )\n}\n","import { useQuery } from '@tanstack/react-query'\nimport { Effect } from 'effect'\nimport { GitHubApi, type ListPRsOptions } from '../services/GitHubApi'\nimport { AppLayer } from '../services/index'\nimport type { PullRequest } from '../models/pull-request'\nimport type { FileChange } from '../models/file-change'\nimport type { Comment } from '../models/comment'\nimport type { Review } from '../models/review'\nimport type { Commit } from '../models/commit'\n\nfunction runEffect<A>(\n effect: Effect.Effect<A, unknown, unknown>,\n): Promise<A> {\n return Effect.runPromise(\n effect.pipe(Effect.provide(AppLayer)) as Effect.Effect<A, never, never>,\n )\n}\n\nexport function usePullRequests(\n owner: string,\n repo: string,\n options?: ListPRsOptions,\n) {\n return useQuery({\n queryKey: ['prs', owner, repo, options],\n queryFn: () =>\n runEffect(\n Effect.gen(function* () {\n const api = yield* GitHubApi\n return yield* api.listPullRequests(owner, repo, options)\n }),\n ),\n enabled: !!owner && !!repo,\n })\n}\n\nexport function usePullRequest(owner: string, repo: string, number: number) {\n return useQuery({\n queryKey: ['pr', owner, repo, number],\n queryFn: () =>\n runEffect(\n Effect.gen(function* () {\n const api = yield* GitHubApi\n return yield* api.getPullRequest(owner, repo, number)\n }),\n ),\n enabled: !!owner && !!repo && !!number,\n })\n}\n\nexport function usePRFiles(owner: string, repo: string, number: number) {\n return useQuery({\n queryKey: ['pr-files', owner, repo, number],\n queryFn: () =>\n runEffect(\n Effect.gen(function* () {\n const api = yield* GitHubApi\n return yield* api.getPullRequestFiles(owner, repo, number)\n }),\n ),\n enabled: !!owner && !!repo && !!number,\n })\n}\n\nexport function usePRComments(owner: string, repo: string, number: number) {\n return useQuery({\n queryKey: ['pr-comments', owner, repo, number],\n queryFn: () =>\n runEffect(\n Effect.gen(function* () {\n const api = yield* GitHubApi\n return yield* api.getPullRequestComments(owner, repo, number)\n }),\n ),\n enabled: !!owner && !!repo && !!number,\n })\n}\n\nexport function usePRReviews(owner: string, repo: string, number: number) {\n return useQuery({\n queryKey: ['pr-reviews', owner, repo, number],\n queryFn: () =>\n runEffect(\n Effect.gen(function* () {\n const api = yield* GitHubApi\n return yield* api.getPullRequestReviews(owner, repo, number)\n }),\n ),\n enabled: !!owner && !!repo && !!number,\n })\n}\n\nexport function usePRCommits(owner: string, repo: string, number: number) {\n return useQuery({\n queryKey: ['pr-commits', owner, repo, number],\n queryFn: () =>\n runEffect(\n Effect.gen(function* () {\n const api = yield* GitHubApi\n return yield* api.getPullRequestCommits(owner, repo, number)\n }),\n ),\n enabled: !!owner && !!repo && !!number,\n })\n}\n\nexport function useMyPRs() {\n return useQuery({\n queryKey: ['my-prs'],\n queryFn: () =>\n runEffect(\n Effect.gen(function* () {\n const api = yield* GitHubApi\n return yield* api.getMyPRs()\n }),\n ),\n })\n}\n\nexport function useReviewRequests() {\n return useQuery({\n queryKey: ['review-requests'],\n queryFn: () =>\n runEffect(\n Effect.gen(function* () {\n const api = yield* GitHubApi\n return yield* api.getReviewRequests()\n }),\n ),\n })\n}\n\nexport function useInvolvedPRs() {\n return useQuery({\n queryKey: ['involved-prs'],\n queryFn: () =>\n runEffect(\n Effect.gen(function* () {\n const api = yield* GitHubApi\n return yield* api.getInvolvedPRs()\n }),\n ),\n })\n}\n\n// Legacy hook for backwards compatibility during migration\ninterface UseGitHubReturn {\n readonly prs: readonly PullRequest[]\n readonly loading: boolean\n readonly error: string | null\n readonly fetchPRs: (\n owner: string,\n repo: string,\n options?: ListPRsOptions,\n ) => void\n readonly fetchPR: (\n owner: string,\n repo: string,\n number: number,\n ) => Promise<PullRequest | null>\n readonly fetchFiles: (\n owner: string,\n repo: string,\n number: number,\n ) => Promise<readonly FileChange[]>\n readonly fetchComments: (\n owner: string,\n repo: string,\n number: number,\n ) => Promise<readonly Comment[]>\n readonly fetchReviews: (\n owner: string,\n repo: string,\n number: number,\n ) => Promise<readonly Review[]>\n readonly fetchMyPRs: () => void\n readonly fetchReviewRequests: () => void\n}\n\nexport function useGitHub(): UseGitHubReturn {\n const { data: prs = [], isLoading, error } = usePullRequests('', '')\n\n return {\n prs,\n loading: isLoading,\n error: error ? String(error) : null,\n fetchPRs: (owner, repo, options) => {\n runEffect(\n Effect.gen(function* () {\n const api = yield* GitHubApi\n return yield* api.listPullRequests(owner, repo, options)\n }),\n )\n },\n fetchPR: async (owner, repo, number) => {\n try {\n return await runEffect(\n Effect.gen(function* () {\n const api = yield* GitHubApi\n return yield* api.getPullRequest(owner, repo, number)\n }),\n )\n } catch {\n return null\n }\n },\n fetchFiles: async (owner, repo, number) => {\n try {\n return await runEffect(\n Effect.gen(function* () {\n const api = yield* GitHubApi\n return yield* api.getPullRequestFiles(owner, repo, number)\n }),\n )\n } catch {\n return []\n }\n },\n fetchComments: async (owner, repo, number) => {\n try {\n return await runEffect(\n Effect.gen(function* () {\n const api = yield* GitHubApi\n return yield* api.getPullRequestComments(owner, repo, number)\n }),\n )\n } catch {\n return []\n }\n },\n fetchReviews: async (owner, repo, number) => {\n try {\n return await runEffect(\n Effect.gen(function* () {\n const api = yield* GitHubApi\n return yield* api.getPullRequestReviews(owner, repo, number)\n }),\n )\n } catch {\n return []\n }\n },\n fetchMyPRs: () => {\n runEffect(\n Effect.gen(function* () {\n const api = yield* GitHubApi\n return yield* api.getMyPRs()\n }),\n )\n },\n fetchReviewRequests: () => {\n runEffect(\n Effect.gen(function* () {\n const api = yield* GitHubApi\n return yield* api.getReviewRequests()\n }),\n )\n },\n }\n}\n","import { Context, Effect, Layer, Schema as S } from 'effect'\nimport { AuthError, GitHubError, NetworkError } from '../models/errors'\nimport { PullRequest } from '../models/pull-request'\nimport { Comment } from '../models/comment'\nimport { Review } from '../models/review'\nimport { FileChange } from '../models/file-change'\nimport { Commit } from '../models/commit'\nimport { Auth } from './Auth'\n\nconst BASE_URL = 'https://api.github.com'\n\nexport interface ListPRsOptions {\n readonly state?: 'open' | 'closed' | 'all'\n readonly sort?: 'created' | 'updated' | 'popularity' | 'long-running'\n readonly direction?: 'asc' | 'desc'\n readonly perPage?: number\n readonly page?: number\n}\n\ntype ApiError = GitHubError | NetworkError | AuthError\n\nexport interface GitHubApiService {\n readonly listPullRequests: (\n owner: string,\n repo: string,\n options?: ListPRsOptions,\n ) => Effect.Effect<readonly PullRequest[], ApiError>\n\n readonly getPullRequest: (\n owner: string,\n repo: string,\n number: number,\n ) => Effect.Effect<PullRequest, ApiError>\n\n readonly getPullRequestFiles: (\n owner: string,\n repo: string,\n number: number,\n ) => Effect.Effect<readonly FileChange[], ApiError>\n\n readonly getPullRequestComments: (\n owner: string,\n repo: string,\n number: number,\n ) => Effect.Effect<readonly Comment[], ApiError>\n\n readonly getPullRequestReviews: (\n owner: string,\n repo: string,\n number: number,\n ) => Effect.Effect<readonly Review[], ApiError>\n\n readonly getPullRequestCommits: (\n owner: string,\n repo: string,\n number: number,\n ) => Effect.Effect<readonly Commit[], ApiError>\n\n readonly getMyPRs: () => Effect.Effect<readonly PullRequest[], ApiError>\n\n readonly getReviewRequests: () => Effect.Effect<\n readonly PullRequest[],\n ApiError\n >\n\n readonly getInvolvedPRs: () => Effect.Effect<readonly PullRequest[], ApiError>\n}\n\nexport class GitHubApi extends Context.Tag('GitHubApi')<\n GitHubApi,\n GitHubApiService\n>() {}\n\nfunction fetchGitHub<A, I>(\n path: string,\n token: string,\n schema: S.Schema<A, I>,\n): Effect.Effect<A, GitHubError | NetworkError> {\n const url = `${BASE_URL}${path}`\n const decode = S.decodeUnknownSync(schema)\n\n return Effect.tryPromise({\n try: async () => {\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'application/vnd.github+json',\n 'X-GitHub-Api-Version': '2022-11-28',\n },\n })\n\n if (!response.ok) {\n const body = await response.text().catch(() => '')\n throw new GitHubError({\n message: `GitHub API error: ${response.status} ${response.statusText} - ${body}`,\n status: response.status,\n url,\n })\n }\n\n const data = await response.json()\n return decode(data)\n },\n catch: (error) => {\n if (error instanceof GitHubError) return error\n return new NetworkError({\n message: `Network request failed: ${String(error)}`,\n cause: error,\n })\n },\n })\n}\n\n// Schema for GitHub Search API response\nconst SearchResultSchema = S.Struct({\n total_count: S.Number,\n incomplete_results: S.Boolean,\n items: S.Array(PullRequest),\n})\n\nfunction fetchGitHubSearch(\n query: string,\n token: string,\n): Effect.Effect<readonly PullRequest[], GitHubError | NetworkError> {\n const url = `${BASE_URL}/search/issues?q=${encodeURIComponent(query)}&per_page=100`\n const decode = S.decodeUnknownSync(SearchResultSchema)\n\n return Effect.tryPromise({\n try: async () => {\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'application/vnd.github+json',\n 'X-GitHub-Api-Version': '2022-11-28',\n },\n })\n\n if (!response.ok) {\n const body = await response.text().catch(() => '')\n throw new GitHubError({\n message: `GitHub API error: ${response.status} ${response.statusText} - ${body}`,\n status: response.status,\n url,\n })\n }\n\n const data = await response.json()\n const result = decode(data)\n return result.items\n },\n catch: (error) => {\n if (error instanceof GitHubError) return error\n return new NetworkError({\n message: `Network request failed: ${String(error)}`,\n cause: error,\n })\n },\n })\n}\n\nfunction buildQueryString(options: ListPRsOptions): string {\n const params = new URLSearchParams()\n if (options.state) params.set('state', options.state)\n if (options.sort) params.set('sort', options.sort)\n if (options.direction) params.set('direction', options.direction)\n if (options.perPage) params.set('per_page', String(options.perPage))\n if (options.page) params.set('page', String(options.page))\n const qs = params.toString()\n return qs ? `?${qs}` : ''\n}\n\nexport const GitHubApiLive = Layer.effect(\n GitHubApi,\n Effect.gen(function* () {\n const auth = yield* Auth\n\n return GitHubApi.of({\n listPullRequests: (owner, repo, options = {}) =>\n Effect.gen(function* () {\n const token = yield* auth.getToken()\n const mergedOptions = { ...options, perPage: options.perPage ?? 100 }\n const qs = buildQueryString(mergedOptions)\n return yield* fetchGitHub(\n `/repos/${owner}/${repo}/pulls${qs}`,\n token,\n S.Array(PullRequest),\n )\n }),\n\n getPullRequest: (owner, repo, number) =>\n Effect.gen(function* () {\n const token = yield* auth.getToken()\n return yield* fetchGitHub(\n `/repos/${owner}/${repo}/pulls/${number}`,\n token,\n PullRequest,\n )\n }),\n\n getPullRequestFiles: (owner, repo, number) =>\n Effect.gen(function* () {\n const token = yield* auth.getToken()\n return yield* fetchGitHub(\n `/repos/${owner}/${repo}/pulls/${number}/files`,\n token,\n S.Array(FileChange),\n )\n }),\n\n getPullRequestComments: (owner, repo, number) =>\n Effect.gen(function* () {\n const token = yield* auth.getToken()\n return yield* fetchGitHub(\n `/repos/${owner}/${repo}/pulls/${number}/comments`,\n token,\n S.Array(Comment),\n )\n }),\n\n getPullRequestReviews: (owner, repo, number) =>\n Effect.gen(function* () {\n const token = yield* auth.getToken()\n return yield* fetchGitHub(\n `/repos/${owner}/${repo}/pulls/${number}/reviews`,\n token,\n S.Array(Review),\n )\n }),\n\n getPullRequestCommits: (owner, repo, number) =>\n Effect.gen(function* () {\n const token = yield* auth.getToken()\n return yield* fetchGitHub(\n `/repos/${owner}/${repo}/pulls/${number}/commits`,\n token,\n S.Array(Commit),\n )\n }),\n\n getMyPRs: () =>\n Effect.gen(function* () {\n const token = yield* auth.getToken()\n return yield* fetchGitHubSearch('is:pr is:open author:@me', token)\n }),\n\n getReviewRequests: () =>\n Effect.gen(function* () {\n const token = yield* auth.getToken()\n return yield* fetchGitHubSearch(\n 'is:pr is:open review-requested:@me',\n token,\n )\n }),\n\n getInvolvedPRs: () =>\n Effect.gen(function* () {\n const token = yield* auth.getToken()\n return yield* fetchGitHubSearch('is:pr is:open involves:@me', token)\n }),\n })\n }),\n)\n","import { Data } from 'effect'\n\nexport class GitHubError extends Data.TaggedError('GitHubError')<{\n readonly message: string\n readonly status?: number\n readonly url?: string\n}> {}\n\nexport class AuthError extends Data.TaggedError('AuthError')<{\n readonly message: string\n readonly reason: 'no_token' | 'invalid_token' | 'expired_token' | 'save_failed'\n}> {}\n\nexport class ConfigError extends Data.TaggedError('ConfigError')<{\n readonly message: string\n readonly path?: string\n}> {}\n\nexport class NetworkError extends Data.TaggedError('NetworkError')<{\n readonly message: string\n readonly cause?: unknown\n}> {}\n\nexport type AppError = GitHubError | AuthError | ConfigError | NetworkError\n","import { Schema as S } from 'effect'\nimport { User } from './user'\n\nexport class Label extends S.Class<Label>('Label')({\n id: S.Number,\n name: S.String,\n color: S.String,\n description: S.optionalWith(S.NullOr(S.String), { default: () => null }),\n}) {}\n\nexport class BranchRef extends S.Class<BranchRef>('BranchRef')({\n ref: S.optionalWith(S.String, { default: () => '' }),\n sha: S.optionalWith(S.String, { default: () => '' }),\n label: S.optional(S.String),\n}) {}\n\nexport class PullRequest extends S.Class<PullRequest>('PullRequest')({\n id: S.Number,\n number: S.Number,\n title: S.String,\n body: S.optionalWith(S.NullOr(S.String), { default: () => null }),\n state: S.Literal('open', 'closed'),\n draft: S.optionalWith(S.Boolean, { default: () => false }),\n merged: S.optionalWith(S.Boolean, { default: () => false }),\n user: User,\n labels: S.optionalWith(S.Array(Label), { default: () => [] }),\n created_at: S.String,\n updated_at: S.String,\n merged_at: S.optionalWith(S.NullOr(S.String), { default: () => null }),\n closed_at: S.optionalWith(S.NullOr(S.String), { default: () => null }),\n html_url: S.String,\n head: S.optionalWith(BranchRef, { default: () => new BranchRef({ ref: '', sha: '' }) }),\n base: S.optionalWith(BranchRef, { default: () => new BranchRef({ ref: '', sha: '' }) }),\n additions: S.optionalWith(S.Number, { default: () => 0 }),\n deletions: S.optionalWith(S.Number, { default: () => 0 }),\n changed_files: S.optionalWith(S.Number, { default: () => 0 }),\n comments: S.optionalWith(S.Number, { default: () => 0 }),\n review_comments: S.optionalWith(S.Number, { default: () => 0 }),\n requested_reviewers: S.optionalWith(S.Array(User), { default: () => [] }),\n}) {}\n","import { Schema as S } from 'effect'\n\nexport class User extends S.Class<User>('User')({\n login: S.String,\n id: S.Number,\n avatar_url: S.String,\n html_url: S.String,\n type: S.optionalWith(S.String, { default: () => 'User' }),\n}) {}\n","import { Schema as S } from 'effect'\nimport { User } from './user'\n\nexport class Comment extends S.Class<Comment>('Comment')({\n id: S.Number,\n body: S.String,\n user: User,\n created_at: S.String,\n updated_at: S.String,\n html_url: S.String,\n path: S.optional(S.String),\n line: S.optional(S.NullOr(S.Number)),\n side: S.optional(S.Literal('LEFT', 'RIGHT')),\n in_reply_to_id: S.optional(S.Number),\n}) {}\n","import { Schema as S } from 'effect'\nimport { User } from './user'\n\nexport class Review extends S.Class<Review>('Review')({\n id: S.Number,\n user: User,\n body: S.optionalWith(S.NullOr(S.String), { default: () => null }),\n state: S.Literal(\n 'APPROVED',\n 'CHANGES_REQUESTED',\n 'COMMENTED',\n 'DISMISSED',\n 'PENDING',\n ),\n submitted_at: S.optionalWith(S.NullOr(S.String), { default: () => null }),\n html_url: S.String,\n}) {}\n","import { Schema as S } from 'effect'\n\nexport class FileChange extends S.Class<FileChange>('FileChange')({\n sha: S.String,\n filename: S.String,\n status: S.Literal(\n 'added',\n 'removed',\n 'modified',\n 'renamed',\n 'copied',\n 'changed',\n 'unchanged',\n ),\n additions: S.Number,\n deletions: S.Number,\n changes: S.Number,\n patch: S.optional(S.String),\n previous_filename: S.optional(S.String),\n blob_url: S.optional(S.String),\n raw_url: S.optional(S.String),\n}) {}\n","import { Schema as S } from 'effect'\nimport { User } from './user'\n\nexport class CommitAuthor extends S.Class<CommitAuthor>('CommitAuthor')({\n name: S.String,\n email: S.String,\n date: S.String,\n}) {}\n\nexport class CommitDetails extends S.Class<CommitDetails>('CommitDetails')({\n message: S.String,\n author: CommitAuthor,\n}) {}\n\nexport class Commit extends S.Class<Commit>('Commit')({\n sha: S.String,\n commit: CommitDetails,\n author: S.optionalWith(S.NullOr(User), { default: () => null }),\n html_url: S.String,\n}) {}\n","import { Context, Effect, Layer, Schema as S } from 'effect'\nimport { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport { writeFile, readFile, mkdir, unlink } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { AuthError } from '../models/errors'\nimport { User } from '../models/user'\n\nconst execFileAsync = promisify(execFile)\n\nexport type TokenSource = 'manual' | 'env' | 'gh_cli' | 'none'\n\nexport interface TokenInfo {\n readonly source: TokenSource\n readonly token: string | null\n readonly maskedToken: string | null\n}\n\n// Config directory for storing token\nconst CONFIG_DIR = join(homedir(), '.config', 'lazyreview')\nconst TOKEN_FILE = join(CONFIG_DIR, '.token')\n\n// In-memory token storage for current session\nlet sessionToken: string | null = null\nlet preferredSource: TokenSource | null = null\n\n// Load saved token from file on startup\nasync function loadSavedToken(): Promise<string | null> {\n try {\n const token = await readFile(TOKEN_FILE, 'utf-8')\n return token.trim() || null\n } catch {\n return null\n }\n}\n\n// Save token to file for persistence\nasync function saveTokenToFile(token: string): Promise<void> {\n await mkdir(CONFIG_DIR, { recursive: true })\n await writeFile(TOKEN_FILE, token, { mode: 0o600 }) // Secure permissions\n}\n\n// Delete saved token file\nasync function deleteSavedToken(): Promise<void> {\n try {\n await unlink(TOKEN_FILE)\n } catch {\n // File might not exist\n }\n}\n\n// Initialize: load saved token on module load\nlet savedToken: string | null = null\nloadSavedToken().then((token) => {\n savedToken = token\n})\n\nfunction maskToken(token: string): string {\n if (token.length <= 8) return '****'\n return `${token.slice(0, 4)}...${token.slice(-4)}`\n}\n\nasync function tryGetGhToken(): Promise<string | null> {\n try {\n const { stdout } = await execFileAsync('gh', ['auth', 'token'])\n return stdout.trim() || null\n } catch {\n return null\n }\n}\n\nexport interface AuthService {\n readonly getToken: () => Effect.Effect<string, AuthError>\n readonly getUser: () => Effect.Effect<User, AuthError>\n readonly isAuthenticated: () => Effect.Effect<boolean, AuthError>\n readonly setToken: (token: string) => Effect.Effect<void, never>\n readonly getTokenInfo: () => Effect.Effect<TokenInfo, never>\n readonly setPreferredSource: (source: TokenSource) => Effect.Effect<void, never>\n readonly getAvailableSources: () => Effect.Effect<TokenSource[], never>\n readonly clearManualToken: () => Effect.Effect<void, never>\n}\n\nexport class Auth extends Context.Tag('Auth')<Auth, AuthService>() {}\n\nfunction resolveToken(): Effect.Effect<string, AuthError> {\n return Effect.gen(function* () {\n // If preferred source is set, use only that source\n if (preferredSource === 'manual') {\n const manualToken = sessionToken ?? savedToken\n if (manualToken) return manualToken\n return yield* Effect.fail(\n new AuthError({ message: 'No manual token found', reason: 'no_token' })\n )\n }\n\n if (preferredSource === 'env') {\n const envToken = process.env['LAZYREVIEW_GITHUB_TOKEN']\n if (envToken) return envToken\n return yield* Effect.fail(\n new AuthError({ message: 'LAZYREVIEW_GITHUB_TOKEN not set', reason: 'no_token' })\n )\n }\n\n if (preferredSource === 'gh_cli') {\n const ghToken = yield* Effect.tryPromise({\n try: tryGetGhToken,\n catch: () => new AuthError({ message: 'gh CLI failed', reason: 'no_token' }),\n })\n if (ghToken) return ghToken\n return yield* Effect.fail(\n new AuthError({ message: 'gh CLI token not available', reason: 'no_token' })\n )\n }\n\n // Default priority order:\n // 1. LAZYREVIEW_GITHUB_TOKEN env var (highest priority)\n const envToken = process.env['LAZYREVIEW_GITHUB_TOKEN']\n if (envToken) return envToken\n\n // 2. Manual/saved token (from settings or file)\n const manualToken = sessionToken ?? savedToken\n if (manualToken) return manualToken\n\n // 3. gh CLI fallback\n const ghResult = yield* Effect.tryPromise({\n try: tryGetGhToken,\n catch: () =>\n new AuthError({\n message: 'No GitHub token found. Set LAZYREVIEW_GITHUB_TOKEN or configure in Settings.',\n reason: 'no_token',\n }),\n })\n\n if (ghResult) return ghResult\n\n // 4. No token found - will show modal\n return yield* Effect.fail(\n new AuthError({\n message: 'No GitHub token found. Set LAZYREVIEW_GITHUB_TOKEN or configure in Settings.',\n reason: 'no_token',\n }),\n )\n })\n}\n\nfunction resolveTokenInfo(): Effect.Effect<TokenInfo, never> {\n return Effect.gen(function* () {\n // Check preferred source first\n if (preferredSource === 'manual') {\n const manualToken = sessionToken ?? savedToken\n if (manualToken) {\n return {\n source: 'manual' as TokenSource,\n token: manualToken,\n maskedToken: maskToken(manualToken),\n }\n }\n }\n\n if (preferredSource === 'env') {\n const envToken = process.env['LAZYREVIEW_GITHUB_TOKEN']\n if (envToken) {\n return {\n source: 'env' as TokenSource,\n token: envToken,\n maskedToken: maskToken(envToken),\n }\n }\n }\n\n if (preferredSource === 'gh_cli') {\n const ghToken = yield* Effect.promise(tryGetGhToken)\n if (ghToken) {\n return {\n source: 'gh_cli' as TokenSource,\n token: ghToken,\n maskedToken: maskToken(ghToken),\n }\n }\n }\n\n // Default: show what's currently being used (following priority order)\n // 1. LAZYREVIEW_GITHUB_TOKEN\n const envToken = process.env['LAZYREVIEW_GITHUB_TOKEN']\n if (envToken) {\n return {\n source: 'env' as TokenSource,\n token: envToken,\n maskedToken: maskToken(envToken),\n }\n }\n\n // 2. Manual/saved token\n const manualToken = sessionToken ?? savedToken\n if (manualToken) {\n return {\n source: 'manual' as TokenSource,\n token: manualToken,\n maskedToken: maskToken(manualToken),\n }\n }\n\n // 3. gh CLI\n const ghToken = yield* Effect.promise(tryGetGhToken)\n if (ghToken) {\n return {\n source: 'gh_cli' as TokenSource,\n token: ghToken,\n maskedToken: maskToken(ghToken),\n }\n }\n\n return {\n source: 'none' as TokenSource,\n token: null,\n maskedToken: null,\n }\n })\n}\n\nexport const AuthLive = Layer.succeed(\n Auth,\n Auth.of({\n getToken: resolveToken,\n\n getUser: () =>\n Effect.gen(function* () {\n const token = yield* resolveToken()\n\n const user = yield* Effect.tryPromise({\n try: async () => {\n const response = await fetch('https://api.github.com/user', {\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'application/vnd.github+json',\n },\n })\n\n if (!response.ok) {\n throw new Error(`GitHub API returned ${response.status}`)\n }\n\n const data = await response.json()\n return S.decodeUnknownSync(User)(data)\n },\n catch: (error) =>\n new AuthError({\n message: `Failed to get user: ${String(error)}`,\n reason: 'invalid_token',\n }),\n })\n\n return user\n }),\n\n isAuthenticated: () =>\n Effect.gen(function* () {\n const result = yield* Effect.either(resolveToken())\n return result._tag === 'Right'\n }),\n\n setToken: (token: string) =>\n Effect.gen(function* () {\n sessionToken = token\n savedToken = token\n preferredSource = 'manual'\n // Save to file for persistence across launches\n yield* Effect.promise(() => saveTokenToFile(token))\n }),\n\n getTokenInfo: resolveTokenInfo,\n\n setPreferredSource: (source: TokenSource) =>\n Effect.sync(() => {\n preferredSource = source === 'none' ? null : source\n }),\n\n getAvailableSources: () =>\n Effect.gen(function* () {\n const sources: TokenSource[] = []\n\n // Check LAZYREVIEW_GITHUB_TOKEN only\n const envToken = process.env['LAZYREVIEW_GITHUB_TOKEN']\n if (envToken) {\n sources.push('env')\n }\n\n // Check for manual token (session or saved)\n if (sessionToken || savedToken) {\n sources.push('manual')\n }\n\n // Check gh CLI\n const ghToken = yield* Effect.promise(tryGetGhToken)\n if (ghToken) {\n sources.push('gh_cli')\n }\n\n return sources\n }),\n\n clearManualToken: () =>\n Effect.gen(function* () {\n sessionToken = null\n savedToken = null\n if (preferredSource === 'manual') {\n preferredSource = null\n }\n // Delete the saved token file\n yield* Effect.promise(deleteSavedToken)\n }),\n }),\n)\n","import { Layer } from 'effect'\nimport { ConfigLive } from './Config'\nimport { AuthLive } from './Auth'\nimport { GitHubApiLive } from './GitHubApi'\nimport { LoadingLive } from './Loading'\n\nexport { Config, type AppConfig, type ConfigService } from './Config'\nexport { Auth, type AuthService } from './Auth'\nexport {\n GitHubApi,\n type GitHubApiService,\n type ListPRsOptions,\n} from './GitHubApi'\nexport {\n Loading,\n type LoadingService,\n type LoadingState,\n} from './Loading'\n\nconst GitHubApiFullLive = GitHubApiLive.pipe(Layer.provide(AuthLive))\n\nexport const AppLayer = Layer.mergeAll(\n ConfigLive,\n AuthLive,\n LoadingLive,\n GitHubApiFullLive,\n)\n","import { Context, Effect, Layer, Schema as S } from 'effect'\nimport { readFile, writeFile, mkdir } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { join, dirname } from 'node:path'\nimport { parse, stringify } from 'yaml'\nimport { ConfigError } from '../models/errors'\n\nconst KeybindingsSchema = S.Struct({\n toggleSidebar: S.optionalWith(S.String, { default: () => 'b' }),\n help: S.optionalWith(S.String, { default: () => '?' }),\n quit: S.optionalWith(S.String, { default: () => 'q' }),\n})\n\nexport class AppConfig extends S.Class<AppConfig>('AppConfig')({\n provider: S.optionalWith(S.Literal('github'), {\n default: () => 'github' as const,\n }),\n theme: S.optionalWith(S.String, { default: () => 'tokyo-night' }),\n defaultOwner: S.optional(S.String),\n defaultRepo: S.optional(S.String),\n pageSize: S.optionalWith(S.Number.pipe(S.int(), S.between(1, 100)), {\n default: () => 30,\n }),\n keybindings: S.optionalWith(KeybindingsSchema, {\n default: () => ({ toggleSidebar: 'b', help: '?', quit: 'q' }),\n }),\n}) {}\n\nconst defaultConfig = S.decodeUnknownSync(AppConfig)({})\n\nexport interface ConfigService {\n readonly load: () => Effect.Effect<AppConfig, ConfigError>\n readonly save: (config: AppConfig) => Effect.Effect<void, ConfigError>\n readonly getPath: () => string\n}\n\nexport class Config extends Context.Tag('Config')<Config, ConfigService>() {}\n\nfunction getConfigPath(): string {\n return join(homedir(), '.config', 'lazyreview', 'config.yaml')\n}\n\nexport const ConfigLive = Layer.succeed(\n Config,\n Config.of({\n getPath: getConfigPath,\n\n load: () =>\n Effect.tryPromise({\n try: async () => {\n const configPath = getConfigPath()\n try {\n const content = await readFile(configPath, 'utf-8')\n const parsed = parse(content)\n return S.decodeUnknownSync(AppConfig)(parsed)\n } catch {\n return defaultConfig\n }\n },\n catch: (error) =>\n new ConfigError({\n message: `Failed to load config: ${String(error)}`,\n path: getConfigPath(),\n }),\n }),\n\n save: (config: AppConfig) =>\n Effect.tryPromise({\n try: async () => {\n const configPath = getConfigPath()\n await mkdir(dirname(configPath), { recursive: true })\n await writeFile(configPath, stringify(config), 'utf-8')\n },\n catch: (error) =>\n new ConfigError({\n message: `Failed to save config: ${String(error)}`,\n path: getConfigPath(),\n }),\n }),\n }),\n)\n","import { Context, Layer } from 'effect'\n\nexport interface LoadingState {\n readonly isLoading: boolean\n readonly message: string | null\n}\n\ntype Listener = () => void\n\nexport interface LoadingService {\n readonly start: (message: string) => void\n readonly stop: () => void\n readonly getState: () => LoadingState\n readonly subscribe: (listener: Listener) => () => void\n}\n\nexport class Loading extends Context.Tag('Loading')<\n Loading,\n LoadingService\n>() {}\n\nfunction createLoadingService(): LoadingService {\n let state: LoadingState = { isLoading: false, message: null }\n const listeners = new Set<Listener>()\n\n function notify(): void {\n for (const listener of listeners) {\n listener()\n }\n }\n\n return {\n start: (message: string) => {\n state = { isLoading: true, message }\n notify()\n },\n\n stop: () => {\n state = { isLoading: false, message: null }\n notify()\n },\n\n getState: () => state,\n\n subscribe: (listener: Listener) => {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n }\n}\n\nexport const LoadingLive = Layer.sync(Loading, createLoadingService)\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport { useTheme } from '../../theme/index'\nimport type { PullRequest } from '../../models/pull-request'\nimport { timeAgo } from '../../utils/date'\n\ninterface PRHeaderProps {\n readonly pr: PullRequest\n}\n\nexport function PRHeader({ pr }: PRHeaderProps): React.ReactElement {\n const theme = useTheme()\n\n const stateColor = pr.draft\n ? theme.colors.muted\n : pr.state === 'open'\n ? theme.colors.success\n : theme.colors.error\n\n const stateLabel = pr.draft\n ? 'Draft'\n : pr.merged\n ? 'Merged'\n : pr.state === 'open'\n ? 'Open'\n : 'Closed'\n\n return (\n <Box flexDirection=\"column\" paddingX={1} paddingY={1}>\n <Box gap={1}>\n <Text color={stateColor} bold>\n [{stateLabel}]\n </Text>\n <Text color={theme.colors.accent} bold>\n #{pr.number}\n </Text>\n <Text color={theme.colors.text} bold>\n {pr.title}\n </Text>\n </Box>\n <Box gap={1} paddingLeft={2}>\n <Text color={theme.colors.secondary}>{pr.user.login}</Text>\n <Text color={theme.colors.muted}>wants to merge</Text>\n <Text color={theme.colors.info}>{pr.head.ref}</Text>\n <Text color={theme.colors.muted}>into</Text>\n <Text color={theme.colors.info}>{pr.base.ref}</Text>\n </Box>\n <Box gap={2} paddingLeft={2}>\n <Text color={theme.colors.muted}>\n opened {timeAgo(pr.created_at)}\n </Text>\n <Text color={theme.colors.diffAdd}>+{pr.additions}</Text>\n <Text color={theme.colors.diffDel}>-{pr.deletions}</Text>\n <Text color={theme.colors.muted}>\n {pr.changed_files} files changed\n </Text>\n </Box>\n {pr.labels.length > 0 && (\n <Box gap={1} paddingLeft={2}>\n {pr.labels.map((label) => (\n <Text key={label.id} color={`#${label.color}`}>\n [{label.name}]\n </Text>\n ))}\n </Box>\n )}\n </Box>\n )\n}\n","import { formatDistanceToNow, parseISO, format } from 'date-fns'\n\nexport function timeAgo(dateString: string): string {\n try {\n const date = parseISO(dateString)\n return formatDistanceToNow(date, { addSuffix: true })\n } catch {\n return dateString\n }\n}\n\nexport function formatDate(dateString: string): string {\n try {\n const date = parseISO(dateString)\n return format(date, 'MMM d, yyyy')\n } catch {\n return dateString\n }\n}\n\nexport function formatDateTime(dateString: string): string {\n try {\n const date = parseISO(dateString)\n return format(date, 'MMM d, yyyy h:mm a')\n } catch {\n return dateString\n }\n}\n","import React from 'react'\nimport { Box } from 'ink'\nimport { Tab, Tabs } from 'ink-tab'\nimport { useTheme } from '../../theme/index'\n\nexport const PR_TAB_NAMES = ['Conversations', 'Commits', 'Files'] as const\nexport type PRTabName = (typeof PR_TAB_NAMES)[number]\n\ninterface PRTabsProps {\n readonly activeIndex: number\n readonly onChange: (index: number) => void\n}\n\nexport function PRTabs({ activeIndex, onChange }: PRTabsProps): React.ReactElement {\n const theme = useTheme()\n\n return (\n <Box\n flexDirection=\"row\"\n paddingX={1}\n paddingY={1}\n borderStyle=\"single\"\n borderColor={theme.colors.border}\n >\n <Tabs\n key={activeIndex}\n defaultValue={PR_TAB_NAMES[activeIndex]}\n onChange={(name) => {\n const index = PR_TAB_NAMES.indexOf(name as PRTabName)\n if (index >= 0) onChange(index)\n }}\n showIndex={true}\n isFocused={true}\n colors={{\n activeTab: {\n color: theme.colors.accent,\n backgroundColor: theme.colors.bg,\n },\n }}\n keyMap={{ useNumbers: true, useTab: true }}\n >\n {PR_TAB_NAMES.map((name) => (\n <Tab key={name} name={name}>\n {name}\n </Tab>\n ))}\n </Tabs>\n </Box>\n )\n}\n","import React, { useEffect, useMemo, useRef, useState } from 'react'\nimport { Box, Text, useInput, useStdout } from 'ink'\nimport { UnorderedList } from '@inkjs/ui'\nimport { ScrollList, type ScrollListRef } from 'ink-scroll-list'\nimport SyntaxHighlight from 'ink-syntax-highlight'\nimport { useTheme } from '../../theme/index'\nimport { useListNavigation } from '../../hooks/useListNavigation'\nimport type { FileChange } from '../../models/file-change'\nimport type { Hunk, DiffLine } from '../../models/diff'\nimport { parseDiffPatch } from '../../models/diff'\nimport { EmptyState } from '../common/EmptyState'\n\ntype TreeNode =\n | { type: 'dir'; name: string; children: TreeNode[] }\n | { type: 'file'; file: FileChange }\n\ninterface DirNode {\n dirs: Record<string, DirNode>\n files: FileChange[]\n}\n\nfunction buildFileTree(files: readonly FileChange[]): TreeNode[] {\n const root: DirNode = { dirs: {}, files: [] }\n for (const file of files) {\n const parts = file.filename.split('/')\n let current = root\n for (let i = 0; i < parts.length - 1; i++) {\n const segment = parts[i]!\n if (!current.dirs[segment]) {\n current.dirs[segment] = { dirs: {}, files: [] }\n }\n current = current.dirs[segment]\n }\n const leafName = parts[parts.length - 1] ?? file.filename\n current.files.push(file)\n }\n\n function toTree(node: DirNode): TreeNode[] {\n const result: TreeNode[] = []\n const dirNames = Object.keys(node.dirs).sort((a, b) => a.localeCompare(b))\n const files = [...node.files].sort((a, b) =>\n a.filename.localeCompare(b.filename),\n )\n for (const name of dirNames) {\n result.push({\n type: 'dir',\n name,\n children: toTree(node.dirs[name]!),\n })\n }\n for (const file of files) {\n result.push({ type: 'file', file })\n }\n return result\n }\n\n return toTree(root)\n}\n\nfunction flattenTreeToFiles(nodes: TreeNode[]): FileChange[] {\n const out: FileChange[] = []\n function walk(n: TreeNode[]) {\n for (const node of n) {\n if (node.type === 'file') out.push(node.file)\n else walk(node.children)\n }\n }\n walk(nodes)\n return out\n}\n\ntype DisplayRow =\n | { indent: number; type: 'dir'; name: string }\n | {\n indent: number\n type: 'file'\n name: string\n file: FileChange\n fileIndex: number\n }\n\nfunction buildDisplayRows(\n nodes: TreeNode[],\n indent = 0,\n fileIndexRef: { current: number },\n): DisplayRow[] {\n const rows: DisplayRow[] = []\n for (const node of nodes) {\n if (node.type === 'file') {\n const parts = node.file.filename.split('/')\n const name = parts[parts.length - 1] ?? node.file.filename\n rows.push({\n indent,\n type: 'file',\n name,\n file: node.file,\n fileIndex: fileIndexRef.current,\n })\n fileIndexRef.current += 1\n } else {\n rows.push({ indent, type: 'dir', name: node.name })\n rows.push(...buildDisplayRows(node.children, indent + 1, fileIndexRef))\n }\n }\n return rows\n}\n\n\nfunction getLanguageFromFilename(filename: string): string | undefined {\n const ext = filename.split('.').pop()?.toLowerCase()\n const map: Record<string, string> = {\n ts: 'typescript',\n tsx: 'typescript',\n js: 'javascript',\n jsx: 'javascript',\n json: 'json',\n md: 'markdown',\n py: 'python',\n go: 'go',\n rs: 'rust',\n css: 'css',\n scss: 'scss',\n html: 'html',\n yaml: 'yaml',\n yml: 'yaml',\n }\n return ext ? map[ext] : undefined\n}\n\ninterface FilesTabProps {\n readonly files: readonly FileChange[]\n readonly isActive: boolean\n}\n\ntype FocusPanel = 'tree' | 'diff'\n\ninterface FileItemProps {\n readonly item: FileChange\n readonly isFocus: boolean\n readonly isSelected: boolean\n}\n\nfunction FileItem({\n item,\n isFocus,\n isSelected,\n}: FileItemProps): React.ReactElement {\n const theme = useTheme()\n\n const statusColor =\n item.status === 'added'\n ? theme.colors.diffAdd\n : item.status === 'removed'\n ? theme.colors.diffDel\n : theme.colors.warning\n\n const statusIcon =\n item.status === 'added'\n ? 'A'\n : item.status === 'removed'\n ? 'D'\n : item.status === 'renamed'\n ? 'R'\n : 'M'\n\n const parts = item.filename.split('/')\n const filename = parts[parts.length - 1] ?? item.filename\n\n return (\n <Box paddingX={0} gap={1} width=\"100%\">\n <Text color={statusColor} bold>\n {statusIcon}\n </Text>\n <Text\n color={\n isFocus\n ? theme.colors.listSelectedFg\n : isSelected\n ? theme.colors.accent\n : theme.colors.text\n }\n bold={isFocus || isSelected}\n inverse={isFocus}\n >\n {filename}\n </Text>\n </Box>\n )\n}\n\ninterface FileTreeProps {\n readonly nodes: TreeNode[]\n readonly fileIndexRef: { current: number }\n readonly treeSelectedIndex: number\n readonly selectedFileIndex: number\n readonly isPanelFocused: boolean\n}\n\nfunction FileTree({\n nodes,\n fileIndexRef,\n treeSelectedIndex,\n selectedFileIndex,\n isPanelFocused,\n}: FileTreeProps): React.ReactElement {\n const theme = useTheme()\n return (\n <UnorderedList>\n {nodes.map((node) => {\n if (node.type === 'file') {\n const idx = fileIndexRef.current\n fileIndexRef.current += 1\n const isFocus = isPanelFocused && idx === treeSelectedIndex\n const isSelected = idx === selectedFileIndex\n return (\n <UnorderedList.Item key={node.file.filename}>\n <FileItem\n item={node.file}\n isFocus={isFocus}\n isSelected={isSelected}\n />\n </UnorderedList.Item>\n )\n }\n return (\n <UnorderedList.Item key={node.name}>\n <Text color={theme.colors.muted}>{node.name}/</Text>\n <FileTree\n nodes={node.children}\n fileIndexRef={fileIndexRef}\n treeSelectedIndex={treeSelectedIndex}\n selectedFileIndex={selectedFileIndex}\n isPanelFocused={isPanelFocused}\n />\n </UnorderedList.Item>\n )\n })}\n </UnorderedList>\n )\n}\n\ninterface DiffLineViewProps {\n readonly line: DiffLine\n readonly lineNumber: number\n readonly isFocus: boolean\n readonly language?: string\n}\n\nfunction DiffLineView({\n line,\n lineNumber,\n isFocus,\n language,\n}: DiffLineViewProps): React.ReactElement {\n const theme = useTheme()\n\n const bgColor = isFocus ? theme.colors.selection : undefined\n\n const textColor =\n line.type === 'add'\n ? theme.colors.diffAdd\n : line.type === 'del'\n ? theme.colors.diffDel\n : line.type === 'header'\n ? theme.colors.info\n : theme.colors.text\n\n const prefix =\n line.type === 'add'\n ? '+'\n : line.type === 'del'\n ? '-'\n : line.type === 'header'\n ? ''\n : ' '\n\n const useSyntaxHighlight =\n line.type === 'context' && language && line.content.trim().length > 0\n\n return (\n // @ts-ignore\n <Box backgroundColor={bgColor}>\n <Box width={5}>\n <Text color={theme.colors.muted}>\n {line.type === 'header' ? '' : String(lineNumber).padStart(4, ' ')}\n </Text>\n </Box>\n {useSyntaxHighlight ? (\n <Box flexDirection=\"row\">\n <Text color={theme.colors.text}>{prefix}</Text>\n <SyntaxHighlight code={line.content} language={language} />\n </Box>\n ) : (\n <Text color={textColor} bold={isFocus} inverse={isFocus}>\n {prefix}\n {line.content}\n </Text>\n )}\n </Box>\n )\n}\n\ninterface DiffViewProps {\n readonly hunks: readonly Hunk[]\n readonly selectedLine: number\n readonly scrollOffset: number\n readonly viewportHeight: number\n readonly isActive: boolean\n readonly filename?: string\n}\n\nfunction DiffView({\n hunks,\n selectedLine,\n scrollOffset,\n viewportHeight,\n isActive,\n filename,\n}: DiffViewProps): React.ReactElement {\n const language = filename ? getLanguageFromFilename(filename) : undefined\n const theme = useTheme()\n\n if (hunks.length === 0) {\n return (\n <Box paddingX={1}>\n <Text color={theme.colors.muted}>No diff available</Text>\n </Box>\n )\n }\n\n // Flatten all lines with line numbers\n const allLines: { line: DiffLine; lineNumber: number; hunkIndex: number }[] =\n []\n let lineNumber = 1\n\n for (let hunkIndex = 0; hunkIndex < hunks.length; hunkIndex++) {\n const hunk = hunks[hunkIndex]\n for (const line of hunk.lines) {\n allLines.push({ line, lineNumber, hunkIndex })\n if (line.type !== 'header') {\n lineNumber++\n }\n }\n }\n\n const visibleLines = allLines.slice(\n scrollOffset,\n scrollOffset + viewportHeight,\n )\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n {visibleLines.map((item, index) => (\n <DiffLineView\n key={`${item.hunkIndex}-${scrollOffset + index}`}\n line={item.line}\n lineNumber={item.lineNumber}\n isFocus={isActive && scrollOffset + index === selectedLine}\n language={language}\n />\n ))}\n </Box>\n )\n}\n\nexport function FilesTab({\n files,\n isActive,\n}: FilesTabProps): React.ReactElement {\n const { stdout } = useStdout()\n const theme = useTheme()\n const viewportHeight = Math.max(1, (stdout?.rows ?? 24) - 10)\n\n const [focusPanel, setFocusPanel] = useState<FocusPanel>('tree')\n const [selectedFileIndex, setSelectedFileIndex] = useState(0)\n\n const tree = useMemo(() => buildFileTree(files), [files])\n const fileOrder = useMemo(() => flattenTreeToFiles(tree), [tree])\n const displayRows = useMemo(\n () => buildDisplayRows(tree, 0, { current: 0 }),\n [tree],\n )\n\n const { selectedIndex: treeSelectedIndex } = useListNavigation({\n itemCount: fileOrder.length,\n viewportHeight,\n isActive: isActive && focusPanel === 'tree',\n })\n\n const treeViewportHeight = viewportHeight - 2\n const fileTreeListRef = useRef<ScrollListRef>(null)\n const selectedRowIndex = displayRows.findIndex(\n (r) => r.type === 'file' && r.fileIndex === treeSelectedIndex,\n )\n const effectiveRowIndex = selectedRowIndex >= 0 ? selectedRowIndex : 0\n\n useEffect(() => {\n const handleResize = (): void => fileTreeListRef.current?.remeasure()\n stdout?.on('resize', handleResize)\n return () => {\n stdout?.off('resize', handleResize)\n }\n }, [stdout])\n\n React.useEffect(() => {\n if (focusPanel === 'tree') {\n setSelectedFileIndex(treeSelectedIndex)\n }\n }, [treeSelectedIndex, focusPanel])\n\n const selectedFile = fileOrder[selectedFileIndex] ?? fileOrder[0] ?? null\n const hunks = selectedFile?.patch ? parseDiffPatch(selectedFile.patch) : []\n\n const totalDiffLines = hunks.reduce((sum, hunk) => sum + hunk.lines.length, 0)\n\n const { selectedIndex: diffSelectedLine, scrollOffset: diffScrollOffset } =\n useListNavigation({\n itemCount: totalDiffLines,\n viewportHeight,\n isActive: isActive && focusPanel === 'diff',\n })\n\n useInput(\n (input, key) => {\n if (key.tab) {\n setFocusPanel((prev) => (prev === 'tree' ? 'diff' : 'tree'))\n } else if (input === 'h' || key.leftArrow) {\n setFocusPanel('tree')\n } else if (input === 'l' || key.rightArrow) {\n setFocusPanel('diff')\n }\n },\n { isActive },\n )\n\n if (files.length === 0) {\n return <EmptyState message=\"No files changed\" />\n }\n\n const isPanelFocused = focusPanel === 'tree' && isActive\n\n return (\n <Box flexDirection=\"row\" flexGrow={1}>\n <Box\n flexDirection=\"column\"\n width=\"30%\"\n borderStyle=\"single\"\n borderColor={\n focusPanel === 'tree' && isActive\n ? theme.colors.accent\n : theme.colors.border\n }\n >\n <Box paddingX={1} paddingY={0}>\n <Text color={theme.colors.accent} bold>\n Files ({files.length})\n </Text>\n </Box>\n <Box\n flexDirection=\"column\"\n paddingX={1}\n overflow=\"hidden\"\n height={treeViewportHeight}\n minHeight={treeViewportHeight}\n flexShrink={0}\n >\n <ScrollList\n ref={fileTreeListRef}\n selectedIndex={effectiveRowIndex}\n scrollAlignment=\"auto\"\n >\n {displayRows.map((row, rowIndex) =>\n row.type === 'dir' ? (\n <Box key={`row-${rowIndex}`} paddingLeft={row.indent * 2}>\n <Text color={theme.colors.muted}>{row.name}/</Text>\n </Box>\n ) : (\n <Box key={`row-${rowIndex}`} paddingLeft={row.indent * 2}>\n <FileItem\n item={row.file}\n isFocus={\n isPanelFocused && row.fileIndex === treeSelectedIndex\n }\n isSelected={row.fileIndex === selectedFileIndex}\n />\n </Box>\n ),\n )}\n </ScrollList>\n </Box>\n </Box>\n\n {/* Diff panel */}\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n borderStyle=\"single\"\n borderColor={\n focusPanel === 'diff' && isActive\n ? theme.colors.accent\n : theme.colors.border\n }\n >\n <Box paddingX={1} paddingY={0} gap={2}>\n <Text color={theme.colors.accent} bold>\n {selectedFile?.filename ?? 'No file selected'}\n </Text>\n {selectedFile && (\n <Box gap={1}>\n <Text color={theme.colors.diffAdd}>\n +{selectedFile.additions}\n </Text>\n <Text color={theme.colors.diffDel}>\n -{selectedFile.deletions}\n </Text>\n </Box>\n )}\n </Box>\n <Box flexDirection=\"column\" flexGrow={1} overflowY=\"hidden\">\n <DiffView\n hunks={hunks}\n selectedLine={diffSelectedLine}\n scrollOffset={diffScrollOffset}\n viewportHeight={viewportHeight - 2}\n isActive={isActive && focusPanel === 'diff'}\n filename={selectedFile?.filename}\n />\n </Box>\n </Box>\n </Box>\n )\n}\n","import { useInput } from 'ink'\nimport { useCallback, useEffect, useRef, useState } from 'react'\n\ninterface UseListNavigationOptions {\n readonly itemCount: number\n readonly viewportHeight: number\n readonly isActive?: boolean\n}\n\ninterface UseListNavigationResult {\n readonly selectedIndex: number\n readonly scrollOffset: number\n readonly setSelectedIndex: (index: number) => void\n}\n\nexport function useListNavigation({\n itemCount,\n viewportHeight,\n isActive = true,\n}: UseListNavigationOptions): UseListNavigationResult {\n const [selectedIndex, setSelectedIndex] = useState(0)\n const gPressedAt = useRef<number | null>(null)\n const prevItemCount = useRef(itemCount)\n\n // Auto-follow: if user was at the last item and a new one arrives, stay at bottom\n useEffect(() => {\n const wasAtEnd = selectedIndex === prevItemCount.current - 1\n prevItemCount.current = itemCount\n if (wasAtEnd && itemCount > 0) {\n setSelectedIndex(itemCount - 1)\n }\n }, [itemCount, selectedIndex])\n\n // Clamp selectedIndex if itemCount shrinks\n useEffect(() => {\n if (itemCount === 0) {\n setSelectedIndex(0)\n } else if (selectedIndex >= itemCount) {\n setSelectedIndex(itemCount - 1)\n }\n }, [itemCount, selectedIndex])\n\n const clamp = useCallback(\n (index: number) => Math.max(0, Math.min(index, itemCount - 1)),\n [itemCount],\n )\n\n useInput(\n (input, key) => {\n if (!isActive || itemCount === 0) return\n\n // j / ↓ — move down\n if (input === 'j' || key.downArrow) {\n setSelectedIndex((i) => clamp(i + 1))\n return\n }\n\n // k / ↑ — move up\n if (input === 'k' || key.upArrow) {\n setSelectedIndex((i) => clamp(i - 1))\n return\n }\n\n // G — jump to bottom\n if (input === 'G') {\n setSelectedIndex(itemCount - 1)\n return\n }\n\n // g — first press starts gg detection\n if (input === 'g') {\n const now = Date.now()\n if (gPressedAt.current !== null && now - gPressedAt.current < 500) {\n setSelectedIndex(0)\n gPressedAt.current = null\n } else {\n gPressedAt.current = now\n }\n return\n }\n\n // Ctrl+d — page down\n if (key.ctrl && input === 'd') {\n setSelectedIndex((i) => clamp(i + Math.floor(viewportHeight / 2)))\n return\n }\n\n // Ctrl+u — page up\n if (key.ctrl && input === 'u') {\n setSelectedIndex((i) => clamp(i - Math.floor(viewportHeight / 2)))\n return\n }\n\n // Any other key resets gg state\n gPressedAt.current = null\n },\n { isActive },\n )\n\n // Derive scroll offset to keep selectedIndex visible\n const scrollOffset = deriveScrollOffset(\n selectedIndex,\n viewportHeight,\n itemCount,\n )\n\n return { selectedIndex, scrollOffset, setSelectedIndex }\n}\n\nfunction deriveScrollOffset(\n selectedIndex: number,\n viewportHeight: number,\n itemCount: number,\n): number {\n if (itemCount <= viewportHeight) return 0\n\n let offset = selectedIndex - Math.floor(viewportHeight / 2)\n offset = Math.max(0, offset)\n offset = Math.min(offset, itemCount - viewportHeight)\n return offset\n}\n","export interface DiffLine {\n readonly type: 'add' | 'del' | 'context' | 'header'\n readonly content: string\n readonly oldLineNumber?: number\n readonly newLineNumber?: number\n}\n\nexport interface Hunk {\n readonly header: string\n readonly oldStart: number\n readonly oldCount: number\n readonly newStart: number\n readonly newCount: number\n readonly lines: readonly DiffLine[]\n}\n\nexport interface FileDiff {\n readonly filename: string\n readonly status: 'added' | 'removed' | 'modified' | 'renamed'\n readonly additions: number\n readonly deletions: number\n readonly hunks: readonly Hunk[]\n readonly previousFilename?: string\n}\n\nexport interface Diff {\n readonly files: readonly FileDiff[]\n readonly totalAdditions: number\n readonly totalDeletions: number\n}\n\nexport function parseDiffPatch(patch: string): readonly Hunk[] {\n const hunks: Hunk[] = []\n const lines = patch.split('\\n')\n let currentHunk: Hunk | null = null\n let currentLines: DiffLine[] = []\n let oldLine = 0\n let newLine = 0\n\n for (const line of lines) {\n const hunkMatch = line.match(\n /^@@\\s+-(\\d+)(?:,(\\d+))?\\s+\\+(\\d+)(?:,(\\d+))?\\s+@@/,\n )\n\n if (hunkMatch) {\n if (currentHunk) {\n hunks.push({ ...currentHunk, lines: currentLines })\n }\n\n oldLine = parseInt(hunkMatch[1]!, 10)\n newLine = parseInt(hunkMatch[3]!, 10)\n currentLines = [{ type: 'header', content: line }]\n currentHunk = {\n header: line,\n oldStart: oldLine,\n oldCount: parseInt(hunkMatch[2] ?? '1', 10),\n newStart: newLine,\n newCount: parseInt(hunkMatch[4] ?? '1', 10),\n lines: [],\n }\n continue\n }\n\n if (!currentHunk) continue\n\n if (line.startsWith('+')) {\n currentLines.push({\n type: 'add',\n content: line.slice(1),\n newLineNumber: newLine++,\n })\n } else if (line.startsWith('-')) {\n currentLines.push({\n type: 'del',\n content: line.slice(1),\n oldLineNumber: oldLine++,\n })\n } else if (line.startsWith(' ') || line === '') {\n currentLines.push({\n type: 'context',\n content: line.slice(1),\n oldLineNumber: oldLine++,\n newLineNumber: newLine++,\n })\n }\n }\n\n if (currentHunk) {\n hunks.push({ ...currentHunk, lines: currentLines })\n }\n\n return hunks\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport { useTheme } from '../../theme/index'\n\ninterface EmptyStateProps {\n readonly icon?: string\n readonly message: string\n readonly hint?: string\n}\n\nexport function EmptyState({\n icon = '~',\n message,\n hint,\n}: EmptyStateProps): React.ReactElement {\n const theme = useTheme()\n\n return (\n <Box\n flexDirection=\"column\"\n alignItems=\"center\"\n justifyContent=\"center\"\n flexGrow={1}\n paddingY={2}\n >\n <Text color={theme.colors.muted}>{icon}</Text>\n <Text color={theme.colors.muted}>{message}</Text>\n {hint && (\n <Text color={theme.colors.muted} dimColor>\n {hint}\n </Text>\n )}\n </Box>\n )\n}\n","import React, { useEffect, useRef } from 'react'\nimport { Box, Text, useStdout } from 'ink'\nimport { Match } from 'effect'\nimport { ScrollList, type ScrollListRef } from 'ink-scroll-list'\nimport { useTheme } from '../../theme/index'\nimport { Divider } from '../common/Divider'\nimport { useListNavigation } from '../../hooks/useListNavigation'\nimport type { PullRequest } from '../../models/pull-request'\nimport type { Comment } from '../../models/comment'\nimport type { Review } from '../../models/review'\nimport { timeAgo } from '../../utils/date'\n\ninterface ConversationsTabProps {\n readonly pr: PullRequest\n readonly comments: readonly Comment[]\n readonly reviews: readonly Review[]\n readonly isActive: boolean\n}\n\ninterface TimelineItem {\n readonly id: string\n readonly type: 'description' | 'review' | 'comment'\n readonly user: string\n readonly body: string | null\n readonly date: string\n readonly state?: string\n readonly path?: string\n readonly line?: number | null\n}\n\nfunction buildTimeline(\n pr: PullRequest,\n comments: readonly Comment[],\n reviews: readonly Review[],\n): TimelineItem[] {\n const items: TimelineItem[] = []\n\n // Add PR description first\n items.push({\n id: 'description',\n type: 'description',\n user: pr.user.login,\n body: pr.body,\n date: pr.created_at,\n })\n\n // Add reviews\n for (const review of reviews) {\n if (review.state !== 'PENDING') {\n items.push({\n id: `review-${review.id}`,\n type: 'review',\n user: review.user.login,\n body: review.body,\n date: review.submitted_at ?? pr.created_at,\n state: review.state,\n })\n }\n }\n\n // Add comments\n for (const comment of comments) {\n items.push({\n id: `comment-${comment.id}`,\n type: 'comment',\n user: comment.user.login,\n body: comment.body,\n date: comment.created_at,\n path: comment.path,\n line: comment.line,\n })\n }\n\n // Sort by date\n items.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime())\n\n return items\n}\n\nfunction TimelineItemView({\n item,\n isFocus,\n}: {\n readonly item: TimelineItem\n readonly isFocus: boolean\n}): React.ReactElement {\n const theme = useTheme()\n\n const getStateIcon = (state?: string): { icon: string; color: string } =>\n Match.value(state).pipe(\n Match.when('APPROVED', () => ({\n icon: '✓',\n color: theme.colors.success,\n })),\n Match.when('CHANGES_REQUESTED', () => ({\n icon: '✗',\n color: theme.colors.error,\n })),\n Match.when('COMMENTED', () => ({ icon: '💬', color: theme.colors.info })),\n Match.when('DISMISSED', () => ({ icon: '—', color: theme.colors.muted })),\n Match.orElse(() => ({ icon: '•', color: theme.colors.muted })),\n )\n\n const { icon, color } =\n item.type === 'review'\n ? getStateIcon(item.state)\n : item.type === 'description'\n ? { icon: '📝', color: theme.colors.accent }\n : { icon: '💬', color: theme.colors.info }\n\n const stateLabel =\n item.type === 'review' && item.state\n ? item.state.toLowerCase().replace('_', ' ')\n : ''\n const location =\n item.type === 'comment' && item.path\n ? ` on ${item.path}${item.line != null ? `:${item.line}` : ''}`\n : ''\n\n return (\n <Box\n flexDirection=\"column\"\n paddingX={1}\n paddingY={1}\n marginBottom={2}\n gap={1}\n >\n <Box flexDirection=\"row\">\n {isFocus && <Text color={theme.colors.accent}>{'▸ '}</Text>}\n <Text color={color}>{icon}</Text>\n <Text> </Text>\n <Text color={theme.colors.secondary} bold>\n {item.user}\n </Text>\n {stateLabel ? (\n <>\n <Text> </Text>\n <Text color={color}>{stateLabel}</Text>\n </>\n ) : null}\n {location ? <Text color={theme.colors.muted}>{location}</Text> : null}\n <Text color={theme.colors.muted}> · {timeAgo(item.date)}</Text>\n </Box>\n {item.body ? (\n <Box paddingLeft={isFocus ? 3 : 2} marginTop={0} width=\"80%\">\n <Text color={theme.colors.text} wrap=\"wrap\">\n {item.body}\n </Text>\n </Box>\n ) : null}\n </Box>\n )\n}\n\nfunction PRInfoSection({\n pr,\n}: {\n readonly pr: PullRequest\n}): React.ReactElement {\n const theme = useTheme()\n\n return (\n <Box\n flexDirection=\"column\"\n paddingX={1}\n paddingY={1}\n borderStyle=\"single\"\n borderColor={theme.colors.border}\n >\n <Box flexDirection=\"row\">\n <Text color={theme.colors.muted}>Author: </Text>\n <Text color={theme.colors.secondary} bold>\n {pr.user.login}\n </Text>\n </Box>\n {pr.requested_reviewers.length > 0 ? (\n <Box flexDirection=\"row\" marginTop={0}>\n <Text color={theme.colors.muted}>Reviewers: </Text>\n <Text color={theme.colors.text}>\n {pr.requested_reviewers.map((r) => r.login).join(', ')}\n </Text>\n </Box>\n ) : null}\n {pr.labels.length > 0 ? (\n <Box flexDirection=\"row\" marginTop={0}>\n <Text color={theme.colors.muted}>Labels: </Text>\n {pr.labels.map((label) => (\n <Text key={label.id} color={`#${label.color}`}>\n [{label.name}]{' '}\n </Text>\n ))}\n </Box>\n ) : null}\n <Box paddingY={0}>\n <Divider />\n </Box>\n <Box flexDirection=\"row\" marginTop={0}>\n <Text color={theme.colors.diffAdd}>+{pr.additions}</Text>\n <Text> </Text>\n <Text color={theme.colors.diffDel}>-{pr.deletions}</Text>\n <Text color={theme.colors.muted}>\n {' '}\n {pr.changed_files} files changed\n </Text>\n </Box>\n </Box>\n )\n}\n\nconst CONVERSATIONS_RESERVED_LINES = 18\n\nexport function ConversationsTab({\n pr,\n comments,\n reviews,\n isActive,\n}: ConversationsTabProps): React.ReactElement {\n const theme = useTheme()\n const { stdout } = useStdout()\n const listRef = useRef<ScrollListRef>(null)\n const timeline = buildTimeline(pr, comments, reviews)\n const viewportHeight = Math.max(1, (stdout?.rows ?? 24) - CONVERSATIONS_RESERVED_LINES)\n\n const { selectedIndex } = useListNavigation({\n itemCount: timeline.length,\n viewportHeight,\n isActive,\n })\n\n useEffect(() => {\n const handleResize = (): void => {\n listRef.current?.remeasure()\n }\n stdout?.on('resize', handleResize)\n return () => {\n stdout?.off('resize', handleResize)\n }\n }, [stdout])\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <PRInfoSection pr={pr} />\n\n <Box flexDirection=\"row\" paddingX={1} paddingY={0} marginBottom={1}>\n <Text color={theme.colors.accent} bold>\n Timeline ({timeline.length} items)\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" flexGrow={1} overflow=\"hidden\" height={viewportHeight}>\n {timeline.length === 0 ? (\n <Box paddingX={1}>\n <Text color={theme.colors.muted}>No conversations yet</Text>\n </Box>\n ) : (\n <ScrollList\n ref={listRef}\n selectedIndex={selectedIndex}\n scrollAlignment=\"auto\"\n >\n {timeline.map((item, index) => (\n <TimelineItemView\n key={item.id}\n item={item}\n isFocus={index === selectedIndex}\n />\n ))}\n </ScrollList>\n )}\n </Box>\n </Box>\n )\n}\n","import React, { useEffect, useRef } from 'react'\nimport { Box, Text, useStdout } from 'ink'\nimport { ScrollList, type ScrollListRef } from 'ink-scroll-list'\nimport { useTheme } from '../../theme/index'\nimport { useListNavigation } from '../../hooks/useListNavigation'\nimport type { Commit } from '../../models/commit'\nimport { timeAgo } from '../../utils/date'\nimport { EmptyState } from '../common/EmptyState'\n\ninterface CommitsTabProps {\n readonly commits: readonly Commit[]\n readonly isActive: boolean\n}\n\nfunction CommitItem({\n commit,\n isFocus,\n}: {\n readonly commit: Commit\n readonly isFocus: boolean\n}): React.ReactElement {\n const theme = useTheme()\n\n const shortSha = commit.sha.slice(0, 7)\n const message = commit.commit.message.split('\\n')[0] ?? ''\n const author = commit.author?.login ?? commit.commit.author.name\n const date = commit.commit.author.date\n\n return (\n <Box\n paddingX={1}\n paddingY={0}\n gap={1}\n // @ts-ignore\n backgroundColor={isFocus ? theme.colors.selection : undefined}\n >\n <Box width={10}>\n <Text color={theme.colors.warning} bold={isFocus}>\n {shortSha}\n </Text>\n </Box>\n <Box flexGrow={1} flexShrink={1}>\n <Text\n color={isFocus ? theme.colors.listSelectedFg : theme.colors.text}\n bold={isFocus}\n wrap=\"truncate\"\n >\n {message}\n </Text>\n </Box>\n <Box width={16}>\n <Text color={theme.colors.secondary}>{author}</Text>\n </Box>\n <Box width={14}>\n <Text color={theme.colors.muted}>{timeAgo(date)}</Text>\n </Box>\n </Box>\n )\n}\n\nexport function CommitsTab({\n commits,\n isActive,\n}: CommitsTabProps): React.ReactElement {\n const { stdout } = useStdout()\n const theme = useTheme()\n const viewportHeight = Math.max(1, (stdout?.rows ?? 24) - 10)\n\n const listRef = useRef<ScrollListRef>(null)\n const { selectedIndex } = useListNavigation({\n itemCount: commits.length,\n viewportHeight,\n isActive,\n })\n\n useEffect(() => {\n const handleResize = (): void => listRef.current?.remeasure()\n stdout?.on('resize', handleResize)\n return () => {\n stdout?.off('resize', handleResize)\n }\n }, [stdout])\n\n if (commits.length === 0) {\n return <EmptyState message=\"No commits found\" />\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box paddingX={1} paddingY={1} gap={1}>\n <Text color={theme.colors.accent} bold>\n Commits\n </Text>\n <Text color={theme.colors.muted}>({commits.length})</Text>\n </Box>\n\n <Box\n paddingX={1}\n paddingBottom={1}\n gap={1}\n borderStyle=\"single\"\n borderColor={theme.colors.border}\n borderTop={false}\n borderLeft={false}\n borderRight={false}\n >\n <Box width={10}>\n <Text color={theme.colors.muted} bold>\n SHA\n </Text>\n </Box>\n <Box flexGrow={1}>\n <Text color={theme.colors.muted} bold>\n Message\n </Text>\n </Box>\n <Box width={16}>\n <Text color={theme.colors.muted} bold>\n Author\n </Text>\n </Box>\n <Box width={14}>\n <Text color={theme.colors.muted} bold>\n Date\n </Text>\n </Box>\n </Box>\n\n <Box flexDirection=\"column\" overflow=\"hidden\" height={viewportHeight}>\n <ScrollList ref={listRef} selectedIndex={selectedIndex} scrollAlignment=\"auto\">\n {commits.map((commit, index) => (\n <CommitItem\n key={commit.sha}\n commit={commit}\n isFocus={index === selectedIndex}\n />\n ))}\n </ScrollList>\n </Box>\n </Box>\n )\n}\n","import React from 'react'\nimport { Box, Text, useStdout } from 'ink'\nimport { Spinner } from '@inkjs/ui'\nimport { useTheme } from '../../theme/index'\n\ninterface LoadingIndicatorProps {\n readonly message?: string\n}\n\nexport function LoadingIndicator({\n message = 'Loading...',\n}: LoadingIndicatorProps): React.ReactElement {\n const theme = useTheme()\n const { stdout } = useStdout()\n const height = stdout?.rows ?? 24\n\n return (\n <Box\n flexDirection=\"column\"\n justifyContent=\"center\"\n alignItems=\"center\"\n height={height - 4}\n flexGrow={1}\n >\n <Box gap={1}>\n <Spinner />\n <Text color={theme.colors.accent}>{message}</Text>\n </Box>\n </Box>\n )\n}\n","import React, { useState } from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport { useTheme } from '../theme/index'\nimport { useMyPRs } from '../hooks/useGitHub'\nimport { useListNavigation } from '../hooks/useListNavigation'\nimport { usePagination } from '../hooks/usePagination'\nimport { useFilter } from '../hooks/useFilter'\nimport { PRListItem } from '../components/pr/PRListItem'\nimport { EmptyState } from '../components/common/EmptyState'\nimport { LoadingIndicator } from '../components/common/LoadingIndicator'\nimport { PaginationBar } from '../components/common/PaginationBar'\nimport { FilterModal } from '../components/common/FilterModal'\nimport { SortModal } from '../components/common/SortModal'\nimport type { PullRequest } from '../models/pull-request'\n\ninterface MyPRsScreenProps {\n readonly onSelect: (pr: PullRequest) => void\n}\n\nexport function MyPRsScreen({\n onSelect,\n}: MyPRsScreenProps): React.ReactElement {\n const theme = useTheme()\n const { data: prs = [], isLoading, error } = useMyPRs()\n const [showFilter, setShowFilter] = useState(false)\n const [showSort, setShowSort] = useState(false)\n\n const {\n filter,\n filteredItems,\n setSearch,\n setRepo,\n setAuthor,\n setLabel,\n setSortBy,\n toggleSortDirection,\n clearFilters,\n hasActiveFilters,\n availableRepos,\n availableAuthors,\n availableLabels,\n } = useFilter(prs)\n\n const {\n currentPage,\n totalPages,\n pageItems,\n hasNextPage,\n hasPrevPage,\n nextPage,\n prevPage,\n startIndex,\n endIndex,\n } = usePagination(filteredItems, { pageSize: 18 })\n\n const { selectedIndex } = useListNavigation({\n itemCount: pageItems.length,\n viewportHeight: pageItems.length,\n isActive: !showFilter && !showSort,\n })\n\n useInput(\n (input, key) => {\n if (key.return && pageItems[selectedIndex]) {\n onSelect(pageItems[selectedIndex])\n } else if (input === 'n' && hasNextPage) {\n nextPage()\n } else if (input === 'p' && hasPrevPage) {\n prevPage()\n } else if (input === '/') {\n setShowFilter(true)\n } else if (input === 's') {\n setShowSort(true)\n }\n },\n { isActive: !showFilter && !showSort },\n )\n\n if (isLoading && prs.length === 0) {\n return <LoadingIndicator message=\"Loading your PRs...\" />\n }\n\n if (error) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Text color={theme.colors.error}>Error: {String(error)}</Text>\n </Box>\n )\n }\n\n if (prs.length === 0) {\n return <EmptyState message=\"You have no open pull requests\" />\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box paddingX={1} justifyContent=\"space-between\">\n <Box gap={2}>\n <Text color={theme.colors.accent} bold>\n My Pull Requests\n </Text>\n {hasActiveFilters && (\n <Text color={theme.colors.warning}>(filtered)</Text>\n )}\n <Text color={theme.colors.muted}>/ filter s sort</Text>\n </Box>\n <PaginationBar\n currentPage={currentPage}\n totalPages={totalPages}\n totalItems={filteredItems.length}\n startIndex={startIndex}\n endIndex={endIndex}\n hasNextPage={hasNextPage}\n hasPrevPage={hasPrevPage}\n />\n </Box>\n <Box flexDirection=\"column\">\n {pageItems.length === 0 ? (\n <Box padding={1}>\n <Text color={theme.colors.muted}>\n No PRs match the current filters\n </Text>\n </Box>\n ) : (\n pageItems.map((pr, index) => (\n <PRListItem\n key={pr.id}\n item={pr}\n isFocus={index === selectedIndex}\n />\n ))\n )}\n </Box>\n {showFilter && (\n <FilterModal\n filter={filter}\n availableRepos={availableRepos}\n availableAuthors={availableAuthors}\n availableLabels={availableLabels}\n onSearchChange={setSearch}\n onRepoChange={setRepo}\n onAuthorChange={setAuthor}\n onLabelChange={setLabel}\n onSortChange={setSortBy}\n onSortDirectionToggle={toggleSortDirection}\n onClear={clearFilters}\n onClose={() => setShowFilter(false)}\n />\n )}\n {showSort && (\n <SortModal\n currentSort={filter.sortBy}\n sortDirection={filter.sortDirection}\n onSortChange={setSortBy}\n onSortDirectionToggle={toggleSortDirection}\n onClose={() => setShowSort(false)}\n />\n )}\n </Box>\n )\n}\n","import { useState, useMemo, useCallback, useEffect, useRef } from 'react'\n\ninterface UsePaginationOptions {\n readonly pageSize?: number\n}\n\ninterface UsePaginationResult<T> {\n readonly currentPage: number\n readonly totalPages: number\n readonly pageItems: readonly T[]\n readonly hasNextPage: boolean\n readonly hasPrevPage: boolean\n readonly nextPage: () => void\n readonly prevPage: () => void\n readonly goToPage: (page: number) => void\n readonly startIndex: number\n readonly endIndex: number\n}\n\nexport function usePagination<T>(\n items: readonly T[],\n options: UsePaginationOptions = {},\n): UsePaginationResult<T> {\n const pageSize = options.pageSize ?? 18\n const [currentPage, setCurrentPage] = useState(1)\n const prevItemsLengthRef = useRef(items.length)\n\n const totalPages = useMemo(\n () => Math.max(1, Math.ceil(items.length / pageSize)),\n [items.length, pageSize],\n )\n\n // Reset to page 1 when items change (e.g., filter applied)\n useEffect(() => {\n if (items.length !== prevItemsLengthRef.current) {\n setCurrentPage(1)\n prevItemsLengthRef.current = items.length\n }\n }, [items.length])\n\n // Ensure current page is within bounds\n const safePage = Math.min(currentPage, totalPages)\n\n const startIndex = (safePage - 1) * pageSize\n const endIndex = Math.min(startIndex + pageSize, items.length)\n\n const pageItems = useMemo(\n () => items.slice(startIndex, endIndex),\n [items, startIndex, endIndex],\n )\n\n const hasNextPage = safePage < totalPages\n const hasPrevPage = safePage > 1\n\n const nextPage = useCallback(() => {\n if (hasNextPage) {\n setCurrentPage((p) => p + 1)\n }\n }, [hasNextPage])\n\n const prevPage = useCallback(() => {\n if (hasPrevPage) {\n setCurrentPage((p) => p - 1)\n }\n }, [hasPrevPage])\n\n const goToPage = useCallback(\n (page: number) => {\n const clampedPage = Math.max(1, Math.min(page, totalPages))\n setCurrentPage(clampedPage)\n },\n [totalPages],\n )\n\n return {\n currentPage: safePage,\n totalPages,\n pageItems,\n hasNextPage,\n hasPrevPage,\n nextPage,\n prevPage,\n goToPage,\n startIndex,\n endIndex,\n }\n}\n","import { useState, useMemo, useCallback } from 'react'\nimport type { PullRequest } from '../models/pull-request'\n\nexport type SortField = 'updated' | 'created' | 'repo' | 'author' | 'title'\nexport type SortDirection = 'asc' | 'desc'\n\nexport interface FilterState {\n readonly search: string\n readonly repo: string | null\n readonly author: string | null\n readonly label: string | null\n readonly sortBy: SortField\n readonly sortDirection: SortDirection\n}\n\nconst defaultFilter: FilterState = {\n search: '',\n repo: null,\n author: null,\n label: null,\n sortBy: 'updated',\n sortDirection: 'desc',\n}\n\nfunction extractRepoFromUrl(url: string): string | null {\n const match = url.match(/github\\.com\\/([^/]+\\/[^/]+)\\/pull/)\n return match?.[1] ?? null\n}\n\nfunction matchesSearch(pr: PullRequest, search: string): boolean {\n if (!search) return true\n const lowerSearch = search.toLowerCase()\n return (\n pr.title.toLowerCase().includes(lowerSearch) ||\n pr.user.login.toLowerCase().includes(lowerSearch) ||\n String(pr.number).includes(lowerSearch)\n )\n}\n\nfunction matchesRepo(pr: PullRequest, repo: string | null): boolean {\n if (!repo) return true\n const prRepo = extractRepoFromUrl(pr.html_url)\n return prRepo?.toLowerCase().includes(repo.toLowerCase()) ?? false\n}\n\nfunction matchesAuthor(pr: PullRequest, author: string | null): boolean {\n if (!author) return true\n return pr.user.login.toLowerCase().includes(author.toLowerCase())\n}\n\nfunction matchesLabel(pr: PullRequest, label: string | null): boolean {\n if (!label) return true\n const lowerLabel = label.toLowerCase()\n return pr.labels.some((l) => l.name.toLowerCase().includes(lowerLabel))\n}\n\nfunction comparePRs(\n a: PullRequest,\n b: PullRequest,\n sortBy: SortField,\n sortDirection: SortDirection,\n): number {\n let comparison = 0\n\n switch (sortBy) {\n case 'updated':\n comparison =\n new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime()\n break\n case 'created':\n comparison =\n new Date(b.created_at).getTime() - new Date(a.created_at).getTime()\n break\n case 'repo': {\n const repoA = extractRepoFromUrl(a.html_url) ?? ''\n const repoB = extractRepoFromUrl(b.html_url) ?? ''\n comparison = repoA.localeCompare(repoB)\n break\n }\n case 'author':\n comparison = a.user.login.localeCompare(b.user.login)\n break\n case 'title':\n comparison = a.title.localeCompare(b.title)\n break\n }\n\n return sortDirection === 'asc' ? -comparison : comparison\n}\n\ninterface UseFilterResult {\n readonly filter: FilterState\n readonly filteredItems: readonly PullRequest[]\n readonly setSearch: (search: string) => void\n readonly setRepo: (repo: string | null) => void\n readonly setAuthor: (author: string | null) => void\n readonly setLabel: (label: string | null) => void\n readonly setSortBy: (sortBy: SortField) => void\n readonly toggleSortDirection: () => void\n readonly clearFilters: () => void\n readonly hasActiveFilters: boolean\n readonly availableRepos: readonly string[]\n readonly availableAuthors: readonly string[]\n readonly availableLabels: readonly string[]\n}\n\nexport function useFilter(items: readonly PullRequest[]): UseFilterResult {\n const [filter, setFilter] = useState<FilterState>(defaultFilter)\n\n const availableRepos = useMemo(() => {\n const repos = new Set<string>()\n items.forEach((pr) => {\n const repo = extractRepoFromUrl(pr.html_url)\n if (repo) repos.add(repo)\n })\n return Array.from(repos).sort()\n }, [items])\n\n const availableAuthors = useMemo(() => {\n const authors = new Set<string>()\n items.forEach((pr) => authors.add(pr.user.login))\n return Array.from(authors).sort()\n }, [items])\n\n const availableLabels = useMemo(() => {\n const labels = new Set<string>()\n items.forEach((pr) => pr.labels.forEach((l) => labels.add(l.name)))\n return Array.from(labels).sort()\n }, [items])\n\n const filteredItems = useMemo(() => {\n return items\n .filter((pr) => matchesSearch(pr, filter.search))\n .filter((pr) => matchesRepo(pr, filter.repo))\n .filter((pr) => matchesAuthor(pr, filter.author))\n .filter((pr) => matchesLabel(pr, filter.label))\n .sort((a, b) => comparePRs(a, b, filter.sortBy, filter.sortDirection))\n }, [items, filter])\n\n const setSearch = useCallback((search: string) => {\n setFilter((prev) => ({ ...prev, search }))\n }, [])\n\n const setRepo = useCallback((repo: string | null) => {\n setFilter((prev) => ({ ...prev, repo }))\n }, [])\n\n const setAuthor = useCallback((author: string | null) => {\n setFilter((prev) => ({ ...prev, author }))\n }, [])\n\n const setLabel = useCallback((label: string | null) => {\n setFilter((prev) => ({ ...prev, label }))\n }, [])\n\n const setSortBy = useCallback((sortBy: SortField) => {\n setFilter((prev) => ({ ...prev, sortBy }))\n }, [])\n\n const toggleSortDirection = useCallback(() => {\n setFilter((prev) => ({\n ...prev,\n sortDirection: prev.sortDirection === 'asc' ? 'desc' : 'asc',\n }))\n }, [])\n\n const clearFilters = useCallback(() => {\n setFilter(defaultFilter)\n }, [])\n\n const hasActiveFilters =\n filter.search !== '' ||\n filter.repo !== null ||\n filter.author !== null ||\n filter.label !== null\n\n return {\n filter,\n filteredItems,\n setSearch,\n setRepo,\n setAuthor,\n setLabel,\n setSortBy,\n toggleSortDirection,\n clearFilters,\n hasActiveFilters,\n availableRepos,\n availableAuthors,\n availableLabels,\n }\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport { useTheme } from '../../theme/index'\nimport type { PullRequest } from '../../models/pull-request'\nimport { timeAgo } from '../../utils/date'\n\ninterface PRListItemProps {\n readonly item: PullRequest\n readonly isFocus: boolean\n}\n\nfunction extractRepoFromUrl(url: string): string | null {\n const match = url.match(/github\\.com\\/([^/]+\\/[^/]+)\\/pull/)\n return match?.[1] ?? null\n}\n\nexport function PRListItem({\n item,\n isFocus,\n}: PRListItemProps): React.ReactElement {\n const theme = useTheme()\n\n const stateColor = item.draft\n ? theme.colors.muted\n : item.state === 'open'\n ? theme.colors.success\n : theme.colors.error\n\n const stateIcon = item.draft ? 'D' : item.state === 'open' ? 'O' : 'C'\n const repoName = extractRepoFromUrl(item.html_url)\n\n return (\n <Box flexDirection=\"column\" paddingX={1}>\n <Box gap={1}>\n <Text color={stateColor} bold>\n {stateIcon}\n </Text>\n <Text\n color={isFocus ? theme.colors.listSelectedFg : theme.colors.text}\n bold={isFocus}\n inverse={isFocus}\n >\n #{item.number}\n </Text>\n <Text\n color={isFocus ? theme.colors.listSelectedFg : theme.colors.text}\n bold={isFocus}\n inverse={isFocus}\n >\n {item.title}\n </Text>\n </Box>\n <Box gap={1} paddingLeft={3}>\n {repoName && (\n <>\n <Text color={theme.colors.secondary}>{repoName}</Text>\n <Text color={theme.colors.muted}>|</Text>\n </>\n )}\n <Text color={theme.colors.muted}>{item.user.login}</Text>\n <Text color={theme.colors.muted}>|</Text>\n <Text color={theme.colors.muted}>{timeAgo(item.created_at)}</Text>\n {item.requested_reviewers.length > 0 && (\n <>\n <Text color={theme.colors.muted}>|</Text>\n <Text color={theme.colors.info}>\n {item.requested_reviewers.map((r) => r.login).join(', ')}\n </Text>\n </>\n )}\n {item.comments > 0 && (\n <>\n <Text color={theme.colors.muted}>|</Text>\n <Text color={theme.colors.muted}>{item.comments} comments</Text>\n </>\n )}\n {item.labels.length > 0 && (\n <>\n <Text color={theme.colors.muted}>|</Text>\n {item.labels.map(\n (label: { id: number; name: string; color: string }) => (\n <Text key={label.id} color={`#${label.color}`}>\n [{label.name}]\n </Text>\n ),\n )}\n </>\n )}\n </Box>\n </Box>\n )\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport { useTheme } from '../../theme/index'\n\ninterface PaginationBarProps {\n readonly currentPage: number\n readonly totalPages: number\n readonly totalItems: number\n readonly startIndex: number\n readonly endIndex: number\n readonly hasNextPage: boolean\n readonly hasPrevPage: boolean\n}\n\nexport function PaginationBar({\n currentPage,\n totalPages,\n totalItems,\n startIndex,\n endIndex,\n hasNextPage,\n hasPrevPage,\n}: PaginationBarProps): React.ReactElement {\n const theme = useTheme()\n\n if (totalPages <= 1) {\n return (\n <Box paddingX={1}>\n <Text color={theme.colors.muted}>\n {totalItems} item{totalItems !== 1 ? 's' : ''}\n </Text>\n </Box>\n )\n }\n\n return (\n <Box paddingX={1} gap={2}>\n <Text color={theme.colors.muted}>\n {startIndex + 1}-{endIndex} of {totalItems}\n </Text>\n <Box gap={1}>\n <Text color={hasPrevPage ? theme.colors.accent : theme.colors.muted}>\n {hasPrevPage ? '← [p]rev' : '← prev'}\n </Text>\n <Text color={theme.colors.muted}>│</Text>\n <Text color={theme.colors.text}>\n Page {currentPage}/{totalPages}\n </Text>\n <Text color={theme.colors.muted}>│</Text>\n <Text color={hasNextPage ? theme.colors.accent : theme.colors.muted}>\n {hasNextPage ? '[n]ext →' : 'next →'}\n </Text>\n </Box>\n </Box>\n )\n}\n","import React, { useState, useEffect } from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport { TextInput } from '@inkjs/ui'\nimport { useTheme } from '../../theme/index'\nimport { useInputFocus } from '../../hooks/useInputFocus'\nimport { Modal } from './Modal'\nimport type { FilterState, SortField } from '../../hooks/useFilter'\n\ninterface FilterModalProps {\n readonly filter: FilterState\n readonly availableRepos: readonly string[]\n readonly availableAuthors: readonly string[]\n readonly availableLabels: readonly string[]\n readonly onSearchChange: (search: string) => void\n readonly onRepoChange: (repo: string | null) => void\n readonly onAuthorChange: (author: string | null) => void\n readonly onLabelChange: (label: string | null) => void\n readonly onSortChange: (sortBy: SortField) => void\n readonly onSortDirectionToggle: () => void\n readonly onClear: () => void\n readonly onClose: () => void\n}\n\nexport function FilterModal({\n filter,\n onSearchChange,\n onClear,\n onClose,\n}: FilterModalProps): React.ReactElement {\n const theme = useTheme()\n const { setInputActive } = useInputFocus()\n const [searchValue, setSearchValue] = useState(filter.search)\n const [showClearConfirm, setShowClearConfirm] = useState(false)\n\n useEffect(() => {\n setInputActive(true)\n return () => setInputActive(false)\n }, [setInputActive])\n\n useInput((input, key) => {\n if (showClearConfirm) {\n if (input === 'y' || input === 'Y') {\n onClear()\n onClose()\n } else if (input === 'n' || input === 'N' || key.escape) {\n setShowClearConfirm(false)\n }\n return\n }\n\n if (key.escape) {\n onClose()\n } else if (key.return) {\n onSearchChange(searchValue)\n onClose()\n } else if (input === 'c' && filter.search) {\n setShowClearConfirm(true)\n }\n })\n\n if (showClearConfirm) {\n return (\n <Modal>\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.colors.accent}\n // @ts-ignore\n backgroundColor={theme.colors.bg}\n paddingX={2}\n paddingY={1}\n gap={1}\n >\n <Text color={theme.colors.accent} bold>\n Clear all filters?\n </Text>\n <Text color={theme.colors.text}>y: Yes, n: No</Text>\n </Box>\n </Modal>\n )\n }\n\n return (\n <Modal>\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.colors.accent}\n // @ts-ignore\n backgroundColor={theme.colors.bg}\n paddingX={2}\n paddingY={1}\n gap={1}\n >\n <Text color={theme.colors.accent} bold>\n Search PRs\n </Text>\n\n <Text color={theme.colors.muted}>\n Filter by title, number, or author\n </Text>\n\n <Box>\n <TextInput\n defaultValue={searchValue}\n onChange={setSearchValue}\n placeholder=\"Type to search...\"\n />\n </Box>\n\n <Text color={theme.colors.muted} dimColor>\n Enter: apply | Esc: cancel{filter.search ? ' | c: clear' : ''}\n </Text>\n </Box>\n </Modal>\n )\n}\n","import React, { useMemo } from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport SelectInput from 'ink-select-input'\nimport { useTheme } from '../../theme/index'\nimport { Modal } from './Modal'\nimport type { SortField, SortDirection } from '../../hooks/useFilter'\n\nconst SORT_OPTIONS: readonly { key: SortField; label: string }[] = [\n { key: 'updated', label: 'Last Updated' },\n { key: 'created', label: 'Created Date' },\n { key: 'repo', label: 'Repository' },\n { key: 'author', label: 'Author' },\n { key: 'title', label: 'Title' },\n]\n\ninterface SortModalProps {\n readonly currentSort: SortField\n readonly sortDirection: SortDirection\n readonly onSortChange: (sortBy: SortField) => void\n readonly onSortDirectionToggle: () => void\n readonly onClose: () => void\n}\n\nexport function SortModal({\n currentSort,\n sortDirection,\n onSortChange,\n onSortDirectionToggle,\n onClose,\n}: SortModalProps): React.ReactElement {\n const theme = useTheme()\n\n useInput((input, key) => {\n if (key.escape || input === 's') {\n onClose()\n }\n })\n\n const items = useMemo(\n () =>\n SORT_OPTIONS.map((option) => ({\n label: `${option.label}${option.key === currentSort ? (sortDirection === 'desc' ? ' ↓' : ' ↑') : ''}`,\n value: option.key,\n })),\n [currentSort, sortDirection],\n )\n\n const initialIndex = Math.max(\n 0,\n SORT_OPTIONS.findIndex((o) => o.key === currentSort),\n )\n\n const handleSelect = (item: { label: string; value: SortField }) => {\n if (item.value === currentSort) {\n onSortDirectionToggle()\n } else {\n onSortChange(item.value)\n }\n onClose()\n }\n\n return (\n <Modal>\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={theme.colors.accent}\n // @ts-ignore\n backgroundColor={theme.colors.bg}\n paddingX={2}\n paddingY={1}\n gap={1}\n >\n <Text color={theme.colors.accent} bold>\n Sort by\n </Text>\n\n <SelectInput\n items={items}\n initialIndex={initialIndex}\n onSelect={handleSelect}\n isFocused={true}\n />\n\n <Text color={theme.colors.muted} dimColor>\n j/k: move | Enter: select | Esc: close\n </Text>\n </Box>\n </Modal>\n )\n}\n","import React, { useState } from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport { useTheme } from '../theme/index'\nimport { useReviewRequests } from '../hooks/useGitHub'\nimport { useListNavigation } from '../hooks/useListNavigation'\nimport { usePagination } from '../hooks/usePagination'\nimport { useFilter } from '../hooks/useFilter'\nimport { PRListItem } from '../components/pr/PRListItem'\nimport { EmptyState } from '../components/common/EmptyState'\nimport { LoadingIndicator } from '../components/common/LoadingIndicator'\nimport { PaginationBar } from '../components/common/PaginationBar'\nimport { FilterModal } from '../components/common/FilterModal'\nimport { SortModal } from '../components/common/SortModal'\nimport type { PullRequest } from '../models/pull-request'\n\ninterface ReviewRequestsScreenProps {\n readonly onSelect: (pr: PullRequest) => void\n}\n\nexport function ReviewRequestsScreen({\n onSelect,\n}: ReviewRequestsScreenProps): React.ReactElement {\n const theme = useTheme()\n const { data: prs = [], isLoading, error } = useReviewRequests()\n const [showFilter, setShowFilter] = useState(false)\n const [showSort, setShowSort] = useState(false)\n\n const {\n filter,\n filteredItems,\n setSearch,\n setRepo,\n setAuthor,\n setLabel,\n setSortBy,\n toggleSortDirection,\n clearFilters,\n hasActiveFilters,\n availableRepos,\n availableAuthors,\n availableLabels,\n } = useFilter(prs)\n\n const {\n currentPage,\n totalPages,\n pageItems,\n hasNextPage,\n hasPrevPage,\n nextPage,\n prevPage,\n startIndex,\n endIndex,\n } = usePagination(filteredItems, { pageSize: 18 })\n\n const { selectedIndex } = useListNavigation({\n itemCount: pageItems.length,\n viewportHeight: pageItems.length,\n isActive: !showFilter && !showSort,\n })\n\n useInput(\n (input, key) => {\n if (key.return && pageItems[selectedIndex]) {\n onSelect(pageItems[selectedIndex])\n } else if (input === 'n' && hasNextPage) {\n nextPage()\n } else if (input === 'p' && hasPrevPage) {\n prevPage()\n } else if (input === '/') {\n setShowFilter(true)\n } else if (input === 's') {\n setShowSort(true)\n }\n },\n { isActive: !showFilter && !showSort },\n )\n\n if (isLoading && prs.length === 0) {\n return <LoadingIndicator message=\"Loading review requests...\" />\n }\n\n if (error) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Text color={theme.colors.error}>Error: {String(error)}</Text>\n </Box>\n )\n }\n\n if (prs.length === 0) {\n return <EmptyState message=\"No review requests\" />\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box paddingX={1} justifyContent=\"space-between\">\n <Box gap={2}>\n <Text color={theme.colors.accent} bold>\n For Review\n </Text>\n {hasActiveFilters && (\n <Text color={theme.colors.warning}>(filtered)</Text>\n )}\n <Text color={theme.colors.muted}>/ filter s sort</Text>\n </Box>\n <PaginationBar\n currentPage={currentPage}\n totalPages={totalPages}\n totalItems={filteredItems.length}\n startIndex={startIndex}\n endIndex={endIndex}\n hasNextPage={hasNextPage}\n hasPrevPage={hasPrevPage}\n />\n </Box>\n <Box flexDirection=\"column\">\n {pageItems.length === 0 ? (\n <Box padding={1}>\n <Text color={theme.colors.muted}>\n No PRs match the current filters\n </Text>\n </Box>\n ) : (\n pageItems.map((pr, index) => (\n <PRListItem\n key={pr.id}\n item={pr}\n isFocus={index === selectedIndex}\n />\n ))\n )}\n </Box>\n {showFilter && (\n <FilterModal\n filter={filter}\n availableRepos={availableRepos}\n availableAuthors={availableAuthors}\n availableLabels={availableLabels}\n onSearchChange={setSearch}\n onRepoChange={setRepo}\n onAuthorChange={setAuthor}\n onLabelChange={setLabel}\n onSortChange={setSortBy}\n onSortDirectionToggle={toggleSortDirection}\n onClear={clearFilters}\n onClose={() => setShowFilter(false)}\n />\n )}\n {showSort && (\n <SortModal\n currentSort={filter.sortBy}\n sortDirection={filter.sortDirection}\n onSortChange={setSortBy}\n onSortDirectionToggle={toggleSortDirection}\n onClose={() => setShowSort(false)}\n />\n )}\n </Box>\n )\n}\n","import React, { useState } from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport { TextInput } from '@inkjs/ui'\nimport { useTheme } from '../theme/index'\nimport { useConfig } from '../hooks/useConfig'\nimport { useAuth } from '../hooks/useAuth'\nimport { Divider } from '../components/common/Divider'\nimport { LoadingIndicator } from '../components/common/LoadingIndicator'\nimport type { TokenSource } from '../services/Auth'\n\nfunction SettingRow({\n label,\n value,\n isSelected,\n isEditing,\n}: {\n readonly label: string\n readonly value: string\n readonly isSelected?: boolean\n readonly isEditing?: boolean\n}): React.ReactElement {\n const theme = useTheme()\n\n return (\n <Box gap={2} paddingX={2}>\n <Box width={20}>\n <Text\n color={isSelected ? theme.colors.accent : theme.colors.muted}\n bold={isSelected}\n >\n {isSelected ? '> ' : ' '}\n {label}\n </Text>\n </Box>\n <Text\n color={isEditing ? theme.colors.accent : theme.colors.text}\n inverse={isEditing}\n >\n {value}\n </Text>\n </Box>\n )\n}\n\nfunction TokenSourceLabel({ source }: { readonly source: TokenSource }): React.ReactElement {\n const theme = useTheme()\n\n const labels: Record<TokenSource, { text: string; color: string }> = {\n manual: { text: 'Manual Token', color: theme.colors.warning },\n env: { text: 'Environment Variable', color: theme.colors.success },\n gh_cli: { text: 'GitHub CLI (gh)', color: theme.colors.info },\n none: { text: 'Not configured', color: theme.colors.error },\n }\n\n const { text, color } = labels[source]\n return <Text color={color}>{text}</Text>\n}\n\ntype SettingsItem = 'token_source' | 'new_token' | 'theme' | 'page_size'\n\nexport function SettingsScreen(): React.ReactElement {\n const theme = useTheme()\n const { config, loading: configLoading, error: configError } = useConfig()\n const {\n tokenInfo,\n availableSources,\n setPreferredSource,\n saveToken,\n loading: authLoading,\n } = useAuth()\n\n const [selectedItem, setSelectedItem] = useState<SettingsItem>('token_source')\n const [isEditingToken, setIsEditingToken] = useState(false)\n const [newTokenValue, setNewTokenValue] = useState('')\n const [tokenMessage, setTokenMessage] = useState<string | null>(null)\n\n const settingsItems: SettingsItem[] = ['token_source', 'new_token', 'theme', 'page_size']\n\n useInput(\n (input, key) => {\n if (isEditingToken) {\n if (key.escape) {\n setIsEditingToken(false)\n setNewTokenValue('')\n } else if (key.return && newTokenValue.trim()) {\n saveToken(newTokenValue.trim())\n .then(() => {\n setTokenMessage('Token saved successfully!')\n setIsEditingToken(false)\n setNewTokenValue('')\n setTimeout(() => setTokenMessage(null), 3000)\n })\n .catch((err) => {\n setTokenMessage(`Error: ${String(err)}`)\n })\n }\n return\n }\n\n if (input === 'j' || key.downArrow) {\n const currentIndex = settingsItems.indexOf(selectedItem)\n const nextIndex = Math.min(currentIndex + 1, settingsItems.length - 1)\n setSelectedItem(settingsItems[nextIndex]!)\n } else if (input === 'k' || key.upArrow) {\n const currentIndex = settingsItems.indexOf(selectedItem)\n const prevIndex = Math.max(currentIndex - 1, 0)\n setSelectedItem(settingsItems[prevIndex]!)\n } else if (key.return) {\n if (selectedItem === 'token_source') {\n // Cycle through available sources\n const currentSource = tokenInfo?.source ?? 'none'\n const sourceOrder: TokenSource[] = ['gh_cli', 'env', 'manual']\n const availableInOrder = sourceOrder.filter((s) => availableSources.includes(s))\n\n if (availableInOrder.length > 0) {\n const currentIndex = availableInOrder.indexOf(currentSource)\n const nextIndex = (currentIndex + 1) % availableInOrder.length\n setPreferredSource(availableInOrder[nextIndex]!)\n }\n } else if (selectedItem === 'new_token') {\n setIsEditingToken(true)\n }\n }\n },\n { isActive: true },\n )\n\n if (configLoading || authLoading) {\n return <LoadingIndicator message=\"Loading settings...\" />\n }\n\n if (configError) {\n return (\n <Box padding={1}>\n <Text color={theme.colors.error}>Error: {configError}</Text>\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box paddingX={1} paddingY={1}>\n <Text color={theme.colors.accent} bold>\n Settings\n </Text>\n </Box>\n <Box paddingX={1}>\n <Divider />\n </Box>\n\n {/* Token Section */}\n <Box flexDirection=\"column\" paddingX={1} marginBottom={1}>\n <Text color={theme.colors.secondary} bold>\n Authentication\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" gap={0}>\n <Box gap={2} paddingX={2}>\n <Box width={20}>\n <Text\n color={selectedItem === 'token_source' ? theme.colors.accent : theme.colors.muted}\n bold={selectedItem === 'token_source'}\n >\n {selectedItem === 'token_source' ? '> ' : ' '}\n Token Source\n </Text>\n </Box>\n <TokenSourceLabel source={tokenInfo?.source ?? 'none'} />\n {availableSources.length > 1 && selectedItem === 'token_source' && (\n <Text color={theme.colors.muted} dimColor>\n (Enter to switch)\n </Text>\n )}\n </Box>\n\n <Box gap={2} paddingX={2}>\n <Box width={20}>\n <Text color={theme.colors.muted}> Token</Text>\n </Box>\n <Text color={theme.colors.text}>\n {tokenInfo?.maskedToken ?? '(none)'}\n </Text>\n </Box>\n\n <Box gap={2} paddingX={2}>\n <Box width={20}>\n <Text color={theme.colors.muted}> Available</Text>\n </Box>\n <Text color={theme.colors.muted}>\n {availableSources.length > 0\n ? availableSources.join(', ')\n : 'none'}\n </Text>\n </Box>\n\n <Box gap={2} paddingX={2} marginTop={1}>\n <Box width={20}>\n <Text\n color={selectedItem === 'new_token' ? theme.colors.accent : theme.colors.muted}\n bold={selectedItem === 'new_token'}\n >\n {selectedItem === 'new_token' ? '> ' : ' '}\n Set New Token\n </Text>\n </Box>\n {isEditingToken ? (\n <Box borderStyle=\"single\" borderColor={theme.colors.accent} paddingX={1} width={40}>\n <TextInput\n defaultValue={newTokenValue}\n onChange={setNewTokenValue}\n placeholder=\"ghp_xxxx...\"\n />\n </Box>\n ) : (\n <Text color={theme.colors.muted} dimColor>\n (Enter to add)\n </Text>\n )}\n </Box>\n\n {tokenMessage && (\n <Box paddingX={4} marginTop={1}>\n <Text\n color={tokenMessage.startsWith('Error') ? theme.colors.error : theme.colors.success}\n >\n {tokenMessage}\n </Text>\n </Box>\n )}\n </Box>\n\n <Box paddingX={1} marginTop={1}>\n <Divider title=\"Configuration\" />\n </Box>\n {/* Config Section */}\n <Box flexDirection=\"column\" paddingX={1} marginTop={0} marginBottom={1}>\n <Text color={theme.colors.secondary} bold>\n Configuration\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" gap={0}>\n <SettingRow\n label=\"Theme\"\n value={config?.theme ?? 'tokyo-night'}\n isSelected={selectedItem === 'theme'}\n />\n <SettingRow\n label=\"Page Size\"\n value={String(config?.pageSize ?? 30)}\n isSelected={selectedItem === 'page_size'}\n />\n <SettingRow\n label=\"Provider\"\n value={config?.provider ?? 'github'}\n />\n <SettingRow\n label=\"Default Owner\"\n value={config?.defaultOwner ?? '(not set)'}\n />\n <SettingRow\n label=\"Default Repo\"\n value={config?.defaultRepo ?? '(not set)'}\n />\n </Box>\n\n <Box paddingX={1} paddingTop={2} flexDirection=\"column\">\n <Text color={theme.colors.muted} dimColor>\n Config: ~/.config/lazyreview/config.yaml\n </Text>\n <Text color={theme.colors.muted} dimColor>\n Token: ~/.config/lazyreview/.token\n </Text>\n </Box>\n\n <Box paddingX={1} paddingTop={1}>\n <Text color={theme.colors.muted} dimColor>\n j/k: navigate | Enter: select/toggle | Esc: cancel\n </Text>\n </Box>\n </Box>\n )\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { Effect } from 'effect'\nimport { Config, ConfigLive, type AppConfig } from '../services/Config'\n\ninterface UseConfigReturn {\n readonly config: AppConfig | null\n readonly error: string | null\n readonly loading: boolean\n readonly updateConfig: (updates: Partial<AppConfig>) => void\n}\n\nexport function useConfig(): UseConfigReturn {\n const queryClient = useQueryClient()\n\n const { data, error, isLoading } = useQuery({\n queryKey: ['config'],\n queryFn: () =>\n Effect.runPromise(\n Effect.gen(function* () {\n const configService = yield* Config\n return yield* configService.load()\n }).pipe(Effect.provide(ConfigLive)),\n ),\n })\n\n const mutation = useMutation({\n mutationFn: (newConfig: AppConfig) =>\n Effect.runPromise(\n Effect.gen(function* () {\n const configService = yield* Config\n yield* configService.save(newConfig)\n }).pipe(Effect.provide(ConfigLive)),\n ),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['config'] })\n },\n })\n\n const updateConfig = (updates: Partial<AppConfig>) => {\n if (!data) return\n const newConfig = { ...data, ...updates } as AppConfig\n queryClient.setQueryData(['config'], newConfig)\n mutation.mutate(newConfig)\n }\n\n return {\n config: data ?? null,\n error: error ? String(error) : null,\n loading: isLoading,\n updateConfig,\n }\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { Effect } from 'effect'\nimport { Auth, AuthLive } from '../services/Auth'\nimport type { TokenSource, TokenInfo } from '../services/Auth'\nimport type { User } from '../models/user'\n\ninterface UseAuthReturn {\n readonly user: User | null\n readonly isAuthenticated: boolean\n readonly error: string | null\n readonly loading: boolean\n readonly saveToken: (token: string) => Promise<void>\n readonly isSavingToken: boolean\n readonly tokenInfo: TokenInfo | null\n readonly availableSources: TokenSource[]\n readonly setPreferredSource: (source: TokenSource) => Promise<void>\n readonly clearManualToken: () => Promise<void>\n readonly refetch: () => void\n}\n\nexport function useAuth(): UseAuthReturn {\n const queryClient = useQueryClient()\n\n const { data, error, isLoading, refetch } = useQuery({\n queryKey: ['auth'],\n queryFn: () =>\n Effect.runPromise(\n Effect.gen(function* () {\n const auth = yield* Auth\n const authenticated = yield* auth.isAuthenticated()\n\n if (!authenticated) {\n return { user: null, isAuthenticated: false }\n }\n\n const currentUser = yield* auth.getUser()\n return { user: currentUser, isAuthenticated: true }\n }).pipe(Effect.provide(AuthLive)),\n ),\n staleTime: Infinity,\n })\n\n const { data: tokenInfoData } = useQuery({\n queryKey: ['tokenInfo'],\n queryFn: () =>\n Effect.runPromise(\n Effect.gen(function* () {\n const auth = yield* Auth\n return yield* auth.getTokenInfo()\n }).pipe(Effect.provide(AuthLive)),\n ),\n staleTime: 0, // Always refetch\n })\n\n const { data: availableSourcesData } = useQuery({\n queryKey: ['availableSources'],\n queryFn: () =>\n Effect.runPromise(\n Effect.gen(function* () {\n const auth = yield* Auth\n return yield* auth.getAvailableSources()\n }).pipe(Effect.provide(AuthLive)),\n ),\n staleTime: 0,\n })\n\n const saveTokenMutation = useMutation({\n mutationFn: async (token: string) => {\n await Effect.runPromise(\n Effect.gen(function* () {\n const auth = yield* Auth\n yield* auth.setToken(token)\n }).pipe(Effect.provide(AuthLive)),\n )\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['auth'] })\n queryClient.invalidateQueries({ queryKey: ['tokenInfo'] })\n queryClient.invalidateQueries({ queryKey: ['availableSources'] })\n },\n })\n\n const setPreferredSourceMutation = useMutation({\n mutationFn: async (source: TokenSource) => {\n await Effect.runPromise(\n Effect.gen(function* () {\n const auth = yield* Auth\n yield* auth.setPreferredSource(source)\n }).pipe(Effect.provide(AuthLive)),\n )\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['auth'] })\n queryClient.invalidateQueries({ queryKey: ['tokenInfo'] })\n },\n })\n\n const clearManualTokenMutation = useMutation({\n mutationFn: async () => {\n await Effect.runPromise(\n Effect.gen(function* () {\n const auth = yield* Auth\n yield* auth.clearManualToken()\n }).pipe(Effect.provide(AuthLive)),\n )\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['auth'] })\n queryClient.invalidateQueries({ queryKey: ['tokenInfo'] })\n queryClient.invalidateQueries({ queryKey: ['availableSources'] })\n },\n })\n\n return {\n user: data?.user ?? null,\n isAuthenticated: data?.isAuthenticated ?? false,\n error: error ? String(error) : null,\n loading: isLoading,\n saveToken: saveTokenMutation.mutateAsync,\n isSavingToken: saveTokenMutation.isPending,\n tokenInfo: tokenInfoData ?? null,\n availableSources: availableSourcesData ?? [],\n setPreferredSource: setPreferredSourceMutation.mutateAsync,\n clearManualToken: clearManualTokenMutation.mutateAsync,\n refetch: () => {\n refetch()\n queryClient.invalidateQueries({ queryKey: ['tokenInfo'] })\n queryClient.invalidateQueries({ queryKey: ['availableSources'] })\n },\n }\n}\n","import React, { useState } from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport { useTheme } from '../theme/index'\nimport { useInvolvedPRs } from '../hooks/useGitHub'\nimport { useListNavigation } from '../hooks/useListNavigation'\nimport { usePagination } from '../hooks/usePagination'\nimport { useFilter } from '../hooks/useFilter'\nimport { PRListItem } from '../components/pr/PRListItem'\nimport { EmptyState } from '../components/common/EmptyState'\nimport { LoadingIndicator } from '../components/common/LoadingIndicator'\nimport { PaginationBar } from '../components/common/PaginationBar'\nimport { FilterModal } from '../components/common/FilterModal'\nimport { SortModal } from '../components/common/SortModal'\nimport type { PullRequest } from '../models/pull-request'\n\ninterface InvolvedScreenProps {\n readonly onSelect: (pr: PullRequest) => void\n}\n\nexport function InvolvedScreen({\n onSelect,\n}: InvolvedScreenProps): React.ReactElement {\n const theme = useTheme()\n const { data: prs = [], isLoading, error } = useInvolvedPRs()\n const [showFilter, setShowFilter] = useState(false)\n const [showSort, setShowSort] = useState(false)\n\n const {\n filter,\n filteredItems,\n setSearch,\n setRepo,\n setAuthor,\n setLabel,\n setSortBy,\n toggleSortDirection,\n clearFilters,\n hasActiveFilters,\n availableRepos,\n availableAuthors,\n availableLabels,\n } = useFilter(prs)\n\n const {\n currentPage,\n totalPages,\n pageItems,\n hasNextPage,\n hasPrevPage,\n nextPage,\n prevPage,\n startIndex,\n endIndex,\n } = usePagination(filteredItems, { pageSize: 18 })\n\n const { selectedIndex } = useListNavigation({\n itemCount: pageItems.length,\n viewportHeight: pageItems.length,\n isActive: !showFilter && !showSort,\n })\n\n useInput(\n (input, key) => {\n if (key.return && pageItems[selectedIndex]) {\n onSelect(pageItems[selectedIndex])\n } else if (input === 'n' && hasNextPage) {\n nextPage()\n } else if (input === 'p' && hasPrevPage) {\n prevPage()\n } else if (input === '/') {\n setShowFilter(true)\n } else if (input === 's') {\n setShowSort(true)\n }\n },\n { isActive: !showFilter && !showSort },\n )\n\n if (isLoading && prs.length === 0) {\n return <LoadingIndicator message=\"Loading involved PRs...\" />\n }\n\n if (error) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Text color={theme.colors.error}>Error: {String(error)}</Text>\n </Box>\n )\n }\n\n if (prs.length === 0) {\n return <EmptyState message=\"No pull requests you're involved in\" />\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box paddingX={1} justifyContent=\"space-between\">\n <Box gap={2}>\n <Text color={theme.colors.accent} bold>\n Involved Pull Requests\n </Text>\n {hasActiveFilters && (\n <Text color={theme.colors.warning}>(filtered)</Text>\n )}\n <Text color={theme.colors.muted}>/ filter s sort</Text>\n </Box>\n <PaginationBar\n currentPage={currentPage}\n totalPages={totalPages}\n totalItems={filteredItems.length}\n startIndex={startIndex}\n endIndex={endIndex}\n hasNextPage={hasNextPage}\n hasPrevPage={hasPrevPage}\n />\n </Box>\n <Box flexDirection=\"column\">\n {pageItems.length === 0 ? (\n <Box padding={1}>\n <Text color={theme.colors.muted}>\n No PRs match the current filters\n </Text>\n </Box>\n ) : (\n pageItems.map((pr, index) => (\n <PRListItem\n key={pr.id}\n item={pr}\n isFocus={index === selectedIndex}\n />\n ))\n )}\n </Box>\n {showFilter && (\n <FilterModal\n filter={filter}\n availableRepos={availableRepos}\n availableAuthors={availableAuthors}\n availableLabels={availableLabels}\n onSearchChange={setSearch}\n onRepoChange={setRepo}\n onAuthorChange={setAuthor}\n onLabelChange={setLabel}\n onSortChange={setSortBy}\n onSortDirectionToggle={toggleSortDirection}\n onClear={clearFilters}\n onClose={() => setShowFilter(false)}\n />\n )}\n {showSort && (\n <SortModal\n currentSort={filter.sortBy}\n sortDirection={filter.sortDirection}\n onSortChange={setSortBy}\n onSortDirectionToggle={toggleSortDirection}\n onClose={() => setShowSort(false)}\n />\n )}\n </Box>\n )\n}\n","import React, { useState } from 'react'\nimport { Box, Text, useInput } from 'ink'\nimport { useTheme } from '../theme/index'\nimport { usePullRequests } from '../hooks/useGitHub'\nimport { useListNavigation } from '../hooks/useListNavigation'\nimport { usePagination } from '../hooks/usePagination'\nimport { useFilter } from '../hooks/useFilter'\nimport { PRListItem } from '../components/pr/PRListItem'\nimport { EmptyState } from '../components/common/EmptyState'\nimport { LoadingIndicator } from '../components/common/LoadingIndicator'\nimport { PaginationBar } from '../components/common/PaginationBar'\nimport { FilterModal } from '../components/common/FilterModal'\nimport { SortModal } from '../components/common/SortModal'\nimport type { PullRequest } from '../models/pull-request'\n\ninterface ThisRepoScreenProps {\n readonly owner: string | null\n readonly repo: string | null\n readonly onSelect: (pr: PullRequest) => void\n}\n\nexport function ThisRepoScreen({\n owner,\n repo,\n onSelect,\n}: ThisRepoScreenProps): React.ReactElement {\n const theme = useTheme()\n const {\n data: prs = [],\n isLoading,\n error,\n } = usePullRequests(owner ?? '', repo ?? '', { state: 'open' })\n const [showFilter, setShowFilter] = useState(false)\n const [showSort, setShowSort] = useState(false)\n\n const {\n filter,\n filteredItems,\n setSearch,\n setRepo: setRepoFilter,\n setAuthor,\n setLabel,\n setSortBy,\n toggleSortDirection,\n clearFilters,\n hasActiveFilters,\n availableRepos,\n availableAuthors,\n availableLabels,\n } = useFilter(prs)\n\n const {\n currentPage,\n totalPages,\n pageItems,\n hasNextPage,\n hasPrevPage,\n nextPage,\n prevPage,\n startIndex,\n endIndex,\n } = usePagination(filteredItems, { pageSize: 18 })\n\n const { selectedIndex } = useListNavigation({\n itemCount: pageItems.length,\n viewportHeight: pageItems.length,\n isActive: !showFilter && !showSort,\n })\n\n useInput(\n (input, key) => {\n if (key.return && pageItems[selectedIndex]) {\n onSelect(pageItems[selectedIndex])\n } else if (input === 'n' && hasNextPage) {\n nextPage()\n } else if (input === 'p' && hasPrevPage) {\n prevPage()\n } else if (input === '/') {\n setShowFilter(true)\n } else if (input === 's') {\n setShowSort(true)\n }\n },\n { isActive: !showFilter && !showSort },\n )\n\n if (!owner || !repo) {\n return (\n <EmptyState message=\"Not in a git repository or remote not detected\" />\n )\n }\n\n if (isLoading && prs.length === 0) {\n return <LoadingIndicator message={`Loading PRs for ${owner}/${repo}...`} />\n }\n\n if (error) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Text color={theme.colors.error}>Error: {String(error)}</Text>\n </Box>\n )\n }\n\n if (prs.length === 0) {\n return <EmptyState message={`No open PRs in ${owner}/${repo}`} />\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box paddingX={1} justifyContent=\"space-between\">\n <Box gap={2}>\n <Text color={theme.colors.accent} bold>\n {owner}/{repo}\n </Text>\n {hasActiveFilters && (\n <Text color={theme.colors.warning}>(filtered)</Text>\n )}\n <Text color={theme.colors.muted}>/ filter s sort</Text>\n </Box>\n <PaginationBar\n currentPage={currentPage}\n totalPages={totalPages}\n totalItems={filteredItems.length}\n startIndex={startIndex}\n endIndex={endIndex}\n hasNextPage={hasNextPage}\n hasPrevPage={hasPrevPage}\n />\n </Box>\n <Box flexDirection=\"column\">\n {pageItems.length === 0 ? (\n <Box padding={1}>\n <Text color={theme.colors.muted}>\n No PRs match the current filters\n </Text>\n </Box>\n ) : (\n pageItems.map((pr, index) => (\n <PRListItem\n key={pr.id}\n item={pr}\n isFocus={index === selectedIndex}\n />\n ))\n )}\n </Box>\n {showFilter && (\n <FilterModal\n filter={filter}\n availableRepos={availableRepos}\n availableAuthors={availableAuthors}\n availableLabels={availableLabels}\n onSearchChange={setSearch}\n onRepoChange={setRepoFilter}\n onAuthorChange={setAuthor}\n onLabelChange={setLabel}\n onSortChange={setSortBy}\n onSortDirectionToggle={toggleSortDirection}\n onClear={clearFilters}\n onClose={() => setShowFilter(false)}\n />\n )}\n {showSort && (\n <SortModal\n currentSort={filter.sortBy}\n sortDirection={filter.sortDirection}\n onSortChange={setSortBy}\n onSortDirectionToggle={toggleSortDirection}\n onClose={() => setShowSort(false)}\n />\n )}\n </Box>\n )\n}\n","import { useInput } from 'ink'\nimport { useCallback, useEffect, useState } from 'react'\n\nexport type Panel = 'sidebar' | 'list' | 'detail'\n\ninterface UseActivePanelOptions {\n readonly hasSelection: boolean\n}\n\ninterface UseActivePanelResult {\n readonly activePanel: Panel\n readonly setActivePanel: (panel: Panel) => void\n}\n\nexport function useActivePanel({\n hasSelection,\n}: UseActivePanelOptions): UseActivePanelResult {\n const [activePanel, setActivePanel] = useState<Panel>('sidebar')\n\n // Reset to list when selection is lost\n useEffect(() => {\n if (!hasSelection && activePanel === 'detail') {\n setActivePanel('list')\n }\n }, [hasSelection, activePanel])\n\n const handleEscape = useCallback(() => {\n if (activePanel === 'detail') {\n setActivePanel('list')\n } else if (activePanel === 'list') {\n setActivePanel('sidebar')\n }\n }, [activePanel])\n\n const handleTab = useCallback(() => {\n if (activePanel === 'sidebar') {\n setActivePanel('list')\n } else if (activePanel === 'list' && hasSelection) {\n setActivePanel('detail')\n } else if (activePanel === 'detail') {\n setActivePanel('sidebar')\n }\n }, [activePanel, hasSelection])\n\n useInput((_input, key) => {\n if (key.escape) {\n handleEscape()\n } else if (key.tab) {\n handleTab()\n }\n })\n\n return { activePanel, setActivePanel }\n}\n","import { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\n\nconst execFileAsync = promisify(execFile)\n\nexport interface GitRepoInfo {\n readonly isGitRepo: boolean\n readonly owner: string | null\n readonly repo: string | null\n readonly remoteUrl: string | null\n}\n\n/**\n * Detect if current directory is a git repo and extract owner/repo from remote\n */\nexport async function detectGitRepo(): Promise<GitRepoInfo> {\n try {\n // Check if we're in a git repo\n await execFileAsync('git', ['rev-parse', '--git-dir'])\n\n // Get the remote URL\n const { stdout } = await execFileAsync('git', [\n 'remote',\n 'get-url',\n 'origin',\n ])\n const remoteUrl = stdout.trim()\n\n // Parse owner/repo from URL\n // Supports: git@github.com:owner/repo.git, https://github.com/owner/repo.git\n const parsed = parseGitHubUrl(remoteUrl)\n\n return {\n isGitRepo: true,\n owner: parsed?.owner ?? null,\n repo: parsed?.repo ?? null,\n remoteUrl,\n }\n } catch {\n return {\n isGitRepo: false,\n owner: null,\n repo: null,\n remoteUrl: null,\n }\n }\n}\n\nfunction parseGitHubUrl(\n url: string,\n): { owner: string; repo: string } | null {\n // SSH format: git@github.com:owner/repo.git\n const sshMatch = url.match(/git@github\\.com:([^/]+)\\/([^/.]+)(?:\\.git)?/)\n if (sshMatch) {\n return { owner: sshMatch[1]!, repo: sshMatch[2]! }\n }\n\n // HTTPS format: https://github.com/owner/repo.git\n const httpsMatch = url.match(\n /https?:\\/\\/github\\.com\\/([^/]+)\\/([^/.]+)(?:\\.git)?/,\n )\n if (httpsMatch) {\n return { owner: httpsMatch[1]!, repo: httpsMatch[2]! }\n }\n\n return null\n}\n"],"mappings":"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","names":["React","useState","useCallback","Box","useInput","useStdout","Box","Text","jsx","jsxs","Box","Text","Box","jsx","Box","Box","Text","Text","jsxs","Text","jsx","jsxs","Box","Text","Box","Text","Box","Text","jsx","Box","Text","Box","useStdout","jsx","jsx","jsxs","Box","Text","useState","useEffect","Box","Text","React","createContext","useContext","useState","jsx","jsxs","useState","useEffect","Box","Text","useState","Box","useInput","useStdout","Match","Effect","Context","Effect","Layer","S","S","S","S","S","S","S","S","S","S","S","manualToken","envToken","ghToken","S","Context","S","Effect","Layer","Layer","Context","Effect","Layer","S","readFile","writeFile","mkdir","homedir","join","S","Context","join","homedir","Layer","Effect","readFile","mkdir","writeFile","Context","Layer","Layer","Effect","Effect","Box","Text","jsx","jsxs","Box","Text","Box","jsx","Box","React","useEffect","useRef","useState","Box","Text","useInput","useStdout","useInput","useCallback","useEffect","useState","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","files","Box","Text","jsxs","Box","jsx","Text","useStdout","useState","useRef","useEffect","React","useInput","useEffect","useRef","Box","Text","useStdout","ScrollList","Fragment","jsx","jsxs","Box","Text","useStdout","useRef","useEffect","ScrollList","useEffect","useRef","Box","Text","useStdout","ScrollList","jsx","jsxs","Box","Text","useStdout","useRef","useEffect","ScrollList","Box","Text","useStdout","Spinner","jsx","jsxs","useStdout","Box","Spinner","Text","jsx","jsxs","useStdout","useState","useInput","Match","Box","useState","Box","Text","useInput","useState","useMemo","useCallback","useEffect","useRef","useState","useMemo","useCallback","Box","Text","Fragment","jsx","jsxs","extractRepoFromUrl","Box","Text","Box","Text","jsx","jsxs","Box","Text","useState","useEffect","Box","Text","useInput","TextInput","jsx","jsxs","useState","useEffect","useInput","Box","Text","TextInput","useMemo","Box","Text","useInput","jsx","jsxs","useInput","useMemo","Box","Text","jsx","jsxs","useState","useInput","Box","Text","useState","Box","Text","useInput","jsx","jsxs","useState","useInput","Box","Text","useState","Box","Text","useInput","TextInput","useQuery","Effect","queryClient","useQuery","Effect","useQuery","useMutation","useQueryClient","Effect","queryClient","useQueryClient","useQuery","Effect","useMutation","jsx","jsxs","Box","Text","useState","useInput","TextInput","useState","Box","Text","useInput","jsx","jsxs","useState","useInput","Box","Text","useState","Box","Text","useInput","jsx","jsxs","useState","useInput","Box","Text","Match","useInput","useCallback","useEffect","useState","jsx","jsxs","useStdout","useState","React","useCallback","useInput","Match","Box","execFile","promisify","execFileAsync","jsx"]}
|