git-tidy-cli 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -343,6 +343,7 @@ function BranchSelectStep({
343
343
  onBack
344
344
  }) {
345
345
  const [selectedValues, setSelectedValues] = useState2([]);
346
+ const [selectKey, setSelectKey] = useState2(0);
346
347
  const options2 = useMemo(() => {
347
348
  return branches.map((branch) => {
348
349
  const location = branch.isLocal && branch.isRemote ? "local+remote" : branch.isLocal ? "local" : "remote";
@@ -367,13 +368,16 @@ function BranchSelectStep({
367
368
  }
368
369
  if (input === "a") {
369
370
  setSelectedValues(branches.map((b) => b.name));
371
+ setSelectKey((k) => k + 1);
370
372
  }
371
373
  if (input === "n") {
372
374
  setSelectedValues([]);
375
+ setSelectKey((k) => k + 1);
373
376
  }
374
377
  if (input === "i") {
375
378
  const inverted = branches.filter((b) => !selectedValues.includes(b.name)).map((b) => b.name);
376
379
  setSelectedValues(inverted);
380
+ setSelectKey((k) => k + 1);
377
381
  }
378
382
  });
379
383
  const handleChange = (values) => {
@@ -413,7 +417,8 @@ function BranchSelectStep({
413
417
  options: options2,
414
418
  defaultValue: selectedValues,
415
419
  onChange: handleChange
416
- }
420
+ },
421
+ selectKey
417
422
  ) }),
418
423
  /* @__PURE__ */ jsx4(Box4, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx4(Text4, { color: "gray", dimColor: true, children: "\u2191\u2193 navigate, Space toggle, Enter confirm, Esc back" }) }),
419
424
  /* @__PURE__ */ jsxs4(Box4, { marginTop: 1, children: [
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx","../src/app.tsx","../src/components/Header.tsx","../src/components/ScopeStep.tsx","../src/components/CriteriaStep.tsx","../src/utils/config.ts","../src/components/BranchSelectStep.tsx","../src/utils/date.ts","../src/components/ConfirmStep.tsx","../src/components/ExecutionStep.tsx","../src/services/git.ts","../src/components/SummaryStep.tsx","../src/hooks/useWizard.ts","../src/services/github.ts","../src/services/branch-analyzer.ts","../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport React from 'react';\nimport { render } from 'ink';\nimport { App } from './app.js';\nimport { createCLI } from './cli.js';\n\n// Parse CLI arguments\nconst options = createCLI();\n\n// Render the app\nrender(<App options={options} />);\n","import React, { useState, useEffect, useCallback } from 'react';\nimport { Box, Text } from 'ink';\nimport { Spinner } from '@inkjs/ui';\n\nimport { Header } from './components/Header.js';\nimport { ScopeStep } from './components/ScopeStep.js';\nimport { CriteriaStep } from './components/CriteriaStep.js';\nimport { BranchSelectStep } from './components/BranchSelectStep.js';\nimport { ConfirmStep } from './components/ConfirmStep.js';\nimport { ExecutionStep } from './components/ExecutionStep.js';\nimport { SummaryStep } from './components/SummaryStep.js';\n\nimport { useWizard } from './hooks/useWizard.js';\nimport { initGit, isGitRepo, getRepoInfo } from './services/git.js';\nimport { initGitHub, getDefaultBranch } from './services/github.js';\nimport { fetchBranches, filterBranches } from './services/branch-analyzer.js';\n\nimport type {\n RepoInfo,\n BranchScope,\n FilterOptions,\n Branch,\n DeletionSummary,\n CLIOptions,\n} from './types/index.js';\nimport { DEFAULT_STALE_DAYS, DEFAULT_AGE_DAYS } from './utils/config.js';\n\ninterface AppProps {\n options: CLIOptions;\n}\n\nexport function App({ options }: AppProps) {\n const { step, goToStep } = useWizard('init');\n\n // State\n const [repoInfo, setRepoInfo] = useState<RepoInfo | null>(null);\n const [scope, setScope] = useState<BranchScope>('both');\n const [filters, setFilters] = useState<FilterOptions>({\n merged: false,\n stale: false,\n staleDays: DEFAULT_STALE_DAYS,\n pattern: false,\n patternValue: '',\n age: false,\n ageDays: DEFAULT_AGE_DAYS,\n });\n const [allBranches, setAllBranches] = useState<Branch[]>([]);\n const [filteredBranches, setFilteredBranches] = useState<Branch[]>([]);\n const [selectedBranches, setSelectedBranches] = useState<Branch[]>([]);\n const [deletionSummary, setDeletionSummary] = useState<DeletionSummary | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [loadingMessage, setLoadingMessage] = useState('Initializing...');\n const [executeForReal, setExecuteForReal] = useState(false);\n\n // Initialize on mount\n useEffect(() => {\n const initialize = async () => {\n try {\n // Initialize git\n initGit();\n\n // Check if we're in a git repo\n const isRepo = await isGitRepo();\n if (!isRepo) {\n setError('Not a git repository. Please run this command in a git repository.');\n return;\n }\n\n // Initialize GitHub if token is provided\n if (options.token || process.env.GITHUB_TOKEN) {\n initGitHub(options.token);\n }\n\n // Get repo info\n setLoadingMessage('Detecting repository...');\n let info = await getRepoInfo();\n\n if (info?.isGitHub && (options.token || process.env.GITHUB_TOKEN)) {\n // Get default branch from GitHub API\n setLoadingMessage('Fetching repository info from GitHub...');\n const defaultBranch = await getDefaultBranch(info.owner, info.repo);\n info = { ...info, defaultBranch };\n }\n\n setRepoInfo(info);\n goToStep('scope');\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Unknown error occurred');\n }\n };\n\n initialize();\n }, [options.token, goToStep]);\n\n // Handle scope selection\n const handleScopeSelect = useCallback((selectedScope: BranchScope) => {\n setScope(selectedScope);\n goToStep('criteria');\n }, [goToStep]);\n\n // Handle criteria selection\n const handleCriteriaSelect = useCallback(async (selectedFilters: FilterOptions) => {\n setFilters(selectedFilters);\n goToStep('loading');\n setLoadingMessage('Fetching branches...');\n\n try {\n if (!repoInfo) {\n throw new Error('Repository info not available');\n }\n\n // Fetch branches\n const branches = await fetchBranches(\n scope,\n repoInfo.defaultBranch,\n repoInfo.currentBranch\n );\n setAllBranches(branches);\n\n // Apply filters\n setLoadingMessage('Analyzing branches...');\n const filtered = filterBranches(branches, selectedFilters);\n setFilteredBranches(filtered);\n\n goToStep('select');\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to fetch branches');\n }\n }, [repoInfo, scope, goToStep]);\n\n // Handle branch selection\n const handleBranchSelect = useCallback((selected: Branch[]) => {\n setSelectedBranches(selected);\n goToStep('confirm');\n }, [goToStep]);\n\n // Handle confirmation\n const handleConfirm = useCallback(() => {\n goToStep('execute');\n }, [goToStep]);\n\n // Handle deletion complete\n const handleDeletionComplete = useCallback((summary: DeletionSummary) => {\n setDeletionSummary(summary);\n goToStep('summary');\n }, [goToStep]);\n\n // Handle delete for real after dry run\n const handleDeleteForReal = useCallback(() => {\n setExecuteForReal(true);\n setDeletionSummary(null);\n goToStep('execute');\n }, [goToStep]);\n\n // Handle cancel/back\n const handleBack = useCallback(() => {\n switch (step) {\n case 'criteria':\n goToStep('scope');\n break;\n case 'select':\n goToStep('criteria');\n break;\n case 'confirm':\n goToStep('select');\n break;\n default:\n break;\n }\n }, [step, goToStep]);\n\n // Render error state\n if (error) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Text color=\"red\" bold>\n Error: {error}\n </Text>\n </Box>\n );\n }\n\n // Render based on current step\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Header repoInfo={repoInfo} />\n\n {step === 'init' && (\n <Box gap={1}>\n <Spinner label={loadingMessage} />\n </Box>\n )}\n\n {step === 'loading' && (\n <Box gap={1}>\n <Spinner label={loadingMessage} />\n </Box>\n )}\n\n {step === 'scope' && <ScopeStep onSelect={handleScopeSelect} />}\n\n {step === 'criteria' && (\n <CriteriaStep onSelect={handleCriteriaSelect} onBack={handleBack} />\n )}\n\n {step === 'select' && (\n <BranchSelectStep\n branches={filteredBranches}\n onSelect={handleBranchSelect}\n onBack={handleBack}\n />\n )}\n\n {step === 'confirm' && (\n <ConfirmStep\n branches={selectedBranches}\n isDryRun={!options.execute}\n onConfirm={handleConfirm}\n onCancel={handleBack}\n />\n )}\n\n {step === 'execute' && (\n <ExecutionStep\n branches={selectedBranches}\n isDryRun={!options.execute && !executeForReal}\n onComplete={handleDeletionComplete}\n />\n )}\n\n {step === 'summary' && deletionSummary && (\n <SummaryStep\n summary={deletionSummary}\n isDryRun={!options.execute && !executeForReal}\n onDeleteForReal={handleDeleteForReal}\n />\n )}\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport type { RepoInfo } from '../types/index.js';\n\ninterface HeaderProps {\n repoInfo: RepoInfo | null;\n}\n\nexport function Header({ repoInfo }: HeaderProps) {\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor=\"cyan\"\n paddingX={2}\n paddingY={0}\n marginBottom={1}\n >\n <Box>\n <Text color=\"cyan\" bold>\n git-tidy\n </Text>\n <Text color=\"gray\"> - Branch Cleanup Tool</Text>\n </Box>\n\n {repoInfo && (\n <Box gap={2}>\n <Text color=\"gray\">\n Repository:{' '}\n <Text color=\"white\">\n {repoInfo.owner}/{repoInfo.repo}\n </Text>\n </Text>\n <Text color=\"gray\">\n Branch:{' '}\n <Text color=\"green\">{repoInfo.currentBranch}</Text>\n </Text>\n <Text color=\"gray\">\n Default:{' '}\n <Text color=\"yellow\">{repoInfo.defaultBranch}</Text>\n </Text>\n </Box>\n )}\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport { Select } from '@inkjs/ui';\nimport type { BranchScope } from '../types/index.js';\n\ninterface ScopeStepProps {\n onSelect: (scope: BranchScope) => void;\n}\n\nexport function ScopeStep({ onSelect }: ScopeStepProps) {\n const options = [\n {\n label: 'Both local and remote branches',\n value: 'both' as BranchScope,\n },\n {\n label: 'Local branches only',\n value: 'local' as BranchScope,\n },\n {\n label: 'Remote branches only',\n value: 'remote' as BranchScope,\n },\n ];\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text color=\"cyan\" bold>\n Step 1:\n </Text>\n <Text> What would you like to clean up?</Text>\n </Box>\n\n <Box marginLeft={2}>\n <Select\n options={options}\n onChange={(value) => onSelect(value as BranchScope)}\n />\n </Box>\n\n <Box marginTop={1}>\n <Text color=\"gray\" dimColor>\n Use ↑↓ to navigate, Enter to select\n </Text>\n </Box>\n </Box>\n );\n}\n","import React, { useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { MultiSelect, TextInput } from '@inkjs/ui';\nimport type { FilterOptions, FilterCriteria } from '../types/index.js';\nimport { DEFAULT_STALE_DAYS, DEFAULT_AGE_DAYS } from '../utils/config.js';\n\ninterface CriteriaStepProps {\n onSelect: (filters: FilterOptions) => void;\n onBack: () => void;\n}\n\ntype InputMode = 'select' | 'staleDays' | 'ageDays' | 'pattern';\n\nexport function CriteriaStep({ onSelect, onBack }: CriteriaStepProps) {\n const [selectedCriteria, setSelectedCriteria] = useState<FilterCriteria[]>([]);\n const [inputMode, setInputMode] = useState<InputMode>('select');\n const [staleDays, setStaleDays] = useState(String(DEFAULT_STALE_DAYS));\n const [ageDays, setAgeDays] = useState(String(DEFAULT_AGE_DAYS));\n const [pattern, setPattern] = useState('feature/*');\n const [inputError, setInputError] = useState<string | null>(null);\n\n // Validate numeric input\n const validateNumber = (value: string): number | null => {\n const num = parseInt(value, 10);\n if (isNaN(num) || num <= 0) {\n return null;\n }\n return num;\n };\n\n const options = [\n {\n label: 'Merged branches (already merged into default branch)',\n value: 'merged' as FilterCriteria,\n },\n {\n label: `Stale branches (no commits in ${staleDays} days)`,\n value: 'stale' as FilterCriteria,\n },\n {\n label: `Branches older than ${ageDays} days`,\n value: 'age' as FilterCriteria,\n },\n {\n label: `Pattern matching: ${pattern}`,\n value: 'pattern' as FilterCriteria,\n },\n ];\n\n useInput((input, key) => {\n if (key.escape) {\n if (inputMode !== 'select') {\n setInputMode('select');\n } else {\n onBack();\n }\n }\n\n // Handle Enter to submit when in select mode\n if (key.return && inputMode === 'select') {\n handleSubmit();\n }\n });\n\n const handleCriteriaChange = (values: string[]) => {\n setSelectedCriteria(values as FilterCriteria[]);\n };\n\n const handleSubmit = () => {\n // Check if we need additional input\n if (selectedCriteria.includes('stale') && inputMode === 'select') {\n setInputMode('staleDays');\n return;\n }\n if (selectedCriteria.includes('age') && inputMode === 'staleDays') {\n setInputMode('ageDays');\n return;\n }\n if (selectedCriteria.includes('pattern') && inputMode === 'ageDays') {\n setInputMode('pattern');\n return;\n }\n if (selectedCriteria.includes('pattern') && inputMode === 'select') {\n setInputMode('pattern');\n return;\n }\n\n // All inputs collected, proceed\n const filters: FilterOptions = {\n merged: selectedCriteria.includes('merged'),\n stale: selectedCriteria.includes('stale'),\n staleDays: parseInt(staleDays, 10) || DEFAULT_STALE_DAYS,\n pattern: selectedCriteria.includes('pattern'),\n patternValue: pattern,\n age: selectedCriteria.includes('age'),\n ageDays: parseInt(ageDays, 10) || DEFAULT_AGE_DAYS,\n };\n\n onSelect(filters);\n };\n\n if (inputMode === 'staleDays') {\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"cyan\">How many days without commits is considered stale?</Text>\n <Box>\n <TextInput\n defaultValue={staleDays}\n onSubmit={(value) => {\n const num = validateNumber(value);\n if (num === null) {\n setInputError('Please enter a valid number greater than 0');\n return;\n }\n setInputError(null);\n setStaleDays(String(num));\n if (selectedCriteria.includes('age')) {\n setInputMode('ageDays');\n } else if (selectedCriteria.includes('pattern')) {\n setInputMode('pattern');\n } else {\n handleSubmit();\n }\n }}\n />\n <Text color=\"gray\"> days</Text>\n </Box>\n {inputError && <Text color=\"red\">{inputError}</Text>}\n </Box>\n );\n }\n\n if (inputMode === 'ageDays') {\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"cyan\">How many days old should a branch be?</Text>\n <Box>\n <TextInput\n defaultValue={ageDays}\n onSubmit={(value) => {\n const num = validateNumber(value);\n if (num === null) {\n setInputError('Please enter a valid number greater than 0');\n return;\n }\n setInputError(null);\n setAgeDays(String(num));\n if (selectedCriteria.includes('pattern')) {\n setInputMode('pattern');\n } else {\n handleSubmit();\n }\n }}\n />\n <Text color=\"gray\"> days</Text>\n </Box>\n {inputError && <Text color=\"red\">{inputError}</Text>}\n </Box>\n );\n }\n\n if (inputMode === 'pattern') {\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"cyan\">Enter branch name pattern (use * as wildcard):</Text>\n <TextInput\n defaultValue={pattern}\n onSubmit={(value) => {\n setPattern(value);\n const filters: FilterOptions = {\n merged: selectedCriteria.includes('merged'),\n stale: selectedCriteria.includes('stale'),\n staleDays: parseInt(staleDays, 10) || DEFAULT_STALE_DAYS,\n pattern: selectedCriteria.includes('pattern'),\n patternValue: value,\n age: selectedCriteria.includes('age'),\n ageDays: parseInt(ageDays, 10) || DEFAULT_AGE_DAYS,\n };\n onSelect(filters);\n }}\n />\n <Text color=\"gray\" dimColor>\n Examples: feature/*, hotfix/*, *-old, test-*\n </Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text color=\"cyan\" bold>\n Step 2:\n </Text>\n <Text> Which branches should be included? (select multiple)</Text>\n </Box>\n\n <Box marginLeft={2}>\n <MultiSelect\n options={options}\n onChange={handleCriteriaChange}\n />\n </Box>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"gray\" dimColor>\n Use ↑↓ to navigate, Space to toggle, Enter to confirm\n </Text>\n <Text color=\"gray\" dimColor>\n Press Esc to go back\n </Text>\n </Box>\n\n {selectedCriteria.length > 0 && (\n <Box marginTop={1}>\n <Text color=\"green\">\n Press Enter to continue with {selectedCriteria.length} filter(s)\n </Text>\n </Box>\n )}\n </Box>\n );\n}\n","// Default configuration values\nexport const DEFAULT_STALE_DAYS = 30;\nexport const DEFAULT_AGE_DAYS = 60;\n\n// Protected branch patterns (in addition to auto-detected default branch)\nexport const PROTECTED_PATTERNS = [\n 'main',\n 'master',\n 'develop',\n 'development',\n 'staging',\n 'production',\n 'release/*',\n];\n\n/**\n * Check if a branch name matches any protected pattern\n */\nexport function matchesProtectedPattern(branchName: string): boolean {\n return PROTECTED_PATTERNS.some((pattern) => {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2);\n return branchName.startsWith(prefix + '/');\n }\n return branchName === pattern;\n });\n}\n","import React, { useState, useMemo } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { MultiSelect } from '@inkjs/ui';\nimport type { Branch } from '../types/index.js';\nimport { formatDaysAgo } from '../utils/date.js';\n\ninterface BranchSelectStepProps {\n branches: Branch[];\n onSelect: (selected: Branch[]) => void;\n onBack: () => void;\n}\n\nexport function BranchSelectStep({\n branches,\n onSelect,\n onBack,\n}: BranchSelectStepProps) {\n const [selectedValues, setSelectedValues] = useState<string[]>([]);\n\n // Create options for MultiSelect\n const options = useMemo(() => {\n return branches.map((branch) => {\n const location = branch.isLocal && branch.isRemote\n ? 'local+remote'\n : branch.isLocal\n ? 'local'\n : 'remote';\n\n const status = branch.isMerged ? 'merged' : 'not merged';\n const age = formatDaysAgo(branch.lastCommitDate);\n\n return {\n label: `${branch.name}`,\n value: branch.name,\n hint: `(${status}, ${age}, ${location})`,\n };\n });\n }, [branches]);\n\n useInput((input, key) => {\n if (key.escape) {\n onBack();\n return;\n }\n\n // Submit on Enter\n if (key.return && selectedValues.length > 0) {\n const selected = branches.filter((b) => selectedValues.includes(b.name));\n onSelect(selected);\n return;\n }\n\n // Select all\n if (input === 'a') {\n setSelectedValues(branches.map((b) => b.name));\n }\n\n // Select none\n if (input === 'n') {\n setSelectedValues([]);\n }\n\n // Invert selection\n if (input === 'i') {\n const inverted = branches\n .filter((b) => !selectedValues.includes(b.name))\n .map((b) => b.name);\n setSelectedValues(inverted);\n }\n });\n\n const handleChange = (values: string[]) => {\n setSelectedValues(values);\n };\n\n const handleSubmit = () => {\n const selected = branches.filter((b) => selectedValues.includes(b.name));\n onSelect(selected);\n };\n\n if (branches.length === 0) {\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text color=\"cyan\" bold>\n Step 3:\n </Text>\n <Text> Select branches to delete</Text>\n </Box>\n <Box marginLeft={2}>\n <Text color=\"yellow\">No branches match your criteria.</Text>\n </Box>\n <Text color=\"gray\" dimColor>\n Press Esc to go back and adjust filters\n </Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text color=\"cyan\" bold>\n Step 3:\n </Text>\n <Text> Select branches to delete ({branches.length} found)</Text>\n </Box>\n\n <Box marginLeft={2} gap={2}>\n <Text color=\"gray\">[a] Select all</Text>\n <Text color=\"gray\">[n] Select none</Text>\n <Text color=\"gray\">[i] Invert</Text>\n </Box>\n\n <Box marginLeft={2} flexDirection=\"column\">\n <MultiSelect\n options={options}\n defaultValue={selectedValues}\n onChange={handleChange}\n />\n </Box>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"gray\" dimColor>\n ↑↓ navigate, Space toggle, Enter confirm, Esc back\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <Text color={selectedValues.length > 0 ? 'green' : 'gray'}>\n {selectedValues.length} branch(es) selected\n </Text>\n {selectedValues.length > 0 && (\n <Text color=\"gray\"> - Press Enter to continue</Text>\n )}\n </Box>\n </Box>\n );\n}\n","/**\n * Calculate the number of days between a date and now\n */\nexport function daysAgo(date: Date): number {\n const now = new Date();\n const diffTime = Math.abs(now.getTime() - date.getTime());\n const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));\n return diffDays;\n}\n\n/**\n * Format a date as a human-readable \"X days ago\" string\n */\nexport function formatDaysAgo(date: Date): string {\n const days = daysAgo(date);\n\n if (days === 0) {\n return 'today';\n } else if (days === 1) {\n return '1 day ago';\n } else if (days < 7) {\n return `${days} days ago`;\n } else if (days < 30) {\n const weeks = Math.floor(days / 7);\n return weeks === 1 ? '1 week ago' : `${weeks} weeks ago`;\n } else if (days < 365) {\n const months = Math.floor(days / 30);\n return months === 1 ? '1 month ago' : `${months} months ago`;\n } else {\n const years = Math.floor(days / 365);\n return years === 1 ? '1 year ago' : `${years} years ago`;\n }\n}\n\n/**\n * Check if a date is older than X days\n */\nexport function isOlderThan(date: Date, days: number): boolean {\n return daysAgo(date) > days;\n}\n","import React from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport type { Branch } from '../types/index.js';\n\ninterface ConfirmStepProps {\n branches: Branch[];\n isDryRun: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n}\n\nexport function ConfirmStep({\n branches,\n isDryRun,\n onConfirm,\n onCancel,\n}: ConfirmStepProps) {\n const localCount = branches.filter((b) => b.isLocal).length;\n const remoteCount = branches.filter((b) => b.isRemote).length;\n\n useInput((input, key) => {\n if (key.return) {\n onConfirm();\n }\n if (key.escape || input === 'n' || input === 'N') {\n onCancel();\n }\n if (input === 'y' || input === 'Y') {\n onConfirm();\n }\n });\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text color=\"cyan\" bold>\n Step 4:\n </Text>\n <Text> Confirm deletion</Text>\n </Box>\n\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor=\"yellow\"\n paddingX={2}\n paddingY={1}\n marginY={1}\n >\n <Text bold>Ready to delete {branches.length} branch(es)</Text>\n\n <Box marginTop={1} gap={2}>\n <Text>\n Local: <Text color=\"cyan\">{localCount}</Text>\n </Text>\n <Text>\n Remote: <Text color=\"magenta\">{remoteCount}</Text>\n </Text>\n </Box>\n\n {isDryRun && (\n <Box marginTop={1}>\n <Text color=\"yellow\" bold>\n DRY RUN MODE - No branches will actually be deleted\n </Text>\n </Box>\n )}\n\n {!isDryRun && (\n <Box marginTop={1}>\n <Text color=\"red\" bold>\n WARNING: This will permanently delete these branches!\n </Text>\n </Box>\n )}\n </Box>\n\n <Box flexDirection=\"column\">\n <Text color=\"gray\">Branches to delete:</Text>\n <Box marginLeft={2} flexDirection=\"column\">\n {branches.slice(0, 10).map((branch) => (\n <Text key={branch.name} color=\"gray\">\n - {branch.name}{' '}\n <Text dimColor>\n ({branch.isLocal && 'local'}\n {branch.isLocal && branch.isRemote && ', '}\n {branch.isRemote && 'remote'})\n </Text>\n </Text>\n ))}\n {branches.length > 10 && (\n <Text color=\"gray\" dimColor>\n ... and {branches.length - 10} more\n </Text>\n )}\n </Box>\n </Box>\n\n <Box marginTop={1} gap={2}>\n <Text color=\"green\">[Enter/Y] Confirm</Text>\n <Text color=\"red\">[Esc/N] Cancel</Text>\n </Box>\n </Box>\n );\n}\n","import React, { useEffect, useState } from 'react';\nimport { Box, Text } from 'ink';\nimport { Spinner } from '@inkjs/ui';\nimport type { Branch, DeletionResult, DeletionSummary } from '../types/index.js';\nimport {\n deleteLocalBranch,\n deleteRemoteBranch as deleteRemoteBranchGit,\n} from '../services/git.js';\n\ninterface ExecutionStepProps {\n branches: Branch[];\n isDryRun: boolean;\n onComplete: (summary: DeletionSummary) => void;\n}\n\nexport function ExecutionStep({\n branches,\n isDryRun,\n onComplete,\n}: ExecutionStepProps) {\n const [currentIndex, setCurrentIndex] = useState(0);\n const [results, setResults] = useState<DeletionResult[]>([]);\n const [isDeleting, setIsDeleting] = useState(true);\n\n useEffect(() => {\n const deleteBranches = async () => {\n const allResults: DeletionResult[] = [];\n\n for (let i = 0; i < branches.length; i++) {\n const branch = branches[i];\n setCurrentIndex(i);\n\n const result: DeletionResult = {\n branch,\n success: true,\n deletedLocal: false,\n deletedRemote: false,\n };\n\n if (isDryRun) {\n // Simulate deletion in dry run mode\n await new Promise((resolve) => setTimeout(resolve, 100));\n result.deletedLocal = branch.isLocal;\n result.deletedRemote = branch.isRemote;\n } else {\n // Actually delete the branch\n try {\n if (branch.isLocal) {\n await deleteLocalBranch(branch.name, true);\n result.deletedLocal = true;\n }\n } catch (error) {\n result.success = false;\n result.error = `Local: ${error instanceof Error ? error.message : 'Unknown error'}`;\n }\n\n try {\n if (branch.isRemote) {\n await deleteRemoteBranchGit(branch.name);\n result.deletedRemote = true;\n }\n } catch (error) {\n if (!result.error) {\n result.success = false;\n result.error = `Remote: ${error instanceof Error ? error.message : 'Unknown error'}`;\n } else {\n result.error += `; Remote: ${error instanceof Error ? error.message : 'Unknown error'}`;\n }\n }\n }\n\n allResults.push(result);\n setResults([...allResults]);\n }\n\n setIsDeleting(false);\n\n // Create summary\n const summary: DeletionSummary = {\n total: branches.length,\n successful: allResults.filter((r) => r.success).length,\n failed: allResults.filter((r) => !r.success).length,\n skipped: 0,\n results: allResults,\n };\n\n // Small delay before completing to show final state\n await new Promise((resolve) => setTimeout(resolve, 500));\n onComplete(summary);\n };\n\n deleteBranches();\n }, [branches, isDryRun, onComplete]);\n\n const currentBranch = branches[currentIndex];\n const completedCount = results.length;\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text color=\"cyan\" bold>\n Step 5:\n </Text>\n <Text> {isDryRun ? 'Simulating deletion...' : 'Deleting branches...'}</Text>\n </Box>\n\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor=\"blue\"\n paddingX={2}\n paddingY={1}\n >\n {isDeleting && currentBranch && (\n <Box gap={1}>\n <Spinner label=\"\" />\n <Text>\n {isDryRun ? 'Processing' : 'Deleting'} {currentBranch.name}\n </Text>\n <Text color=\"gray\">\n ({completedCount + 1}/{branches.length})\n </Text>\n </Box>\n )}\n\n {!isDeleting && (\n <Text color=\"green\">\n {isDryRun ? 'Simulation' : 'Deletion'} complete!\n </Text>\n )}\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"gray\">Results:</Text>\n <Box marginLeft={2} flexDirection=\"column\">\n {results.slice(-8).map((result, index) => (\n <Box key={result.branch.name} gap={1}>\n <Text color={result.success ? 'green' : 'red'}>\n {result.success ? '✓' : '✗'}\n </Text>\n <Text color={result.success ? 'gray' : 'red'}>\n {result.branch.name}\n </Text>\n {result.deletedLocal && <Text color=\"cyan\" dimColor>(local)</Text>}\n {result.deletedRemote && <Text color=\"magenta\" dimColor>(remote)</Text>}\n {result.error && (\n <Text color=\"red\" dimColor>\n - {result.error}\n </Text>\n )}\n </Box>\n ))}\n {results.length > 8 && (\n <Text color=\"gray\" dimColor>\n ... and {results.length - 8} more\n </Text>\n )}\n </Box>\n </Box>\n </Box>\n );\n}\n","import simpleGit, { SimpleGit } from 'simple-git';\nimport type { Branch, RepoInfo } from '../types/index.js';\nimport { matchesProtectedPattern } from '../utils/config.js';\n\nlet git: SimpleGit;\n\n/**\n * Initialize git instance for the current directory\n */\nexport function initGit(cwd?: string): SimpleGit {\n git = simpleGit(cwd);\n return git;\n}\n\n/**\n * Check if current directory is a git repository\n */\nexport async function isGitRepo(): Promise<boolean> {\n try {\n await git.revparse(['--git-dir']);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get current branch name\n */\nexport async function getCurrentBranch(): Promise<string> {\n const result = await git.revparse(['--abbrev-ref', 'HEAD']);\n return result.trim();\n}\n\n/**\n * Get remote URL and extract owner/repo for GitHub\n */\nexport async function getRemoteInfo(): Promise<{ owner: string; repo: string; isGitHub: boolean } | null> {\n try {\n const remotes = await git.getRemotes(true);\n const origin = remotes.find((r) => r.name === 'origin');\n\n if (!origin?.refs?.fetch) {\n return null;\n }\n\n const url = origin.refs.fetch;\n\n // Parse GitHub URL (SSH or HTTPS)\n // SSH: git@github.com:owner/repo.git\n // HTTPS: https://github.com/owner/repo.git\n const sshMatch = url.match(/git@github\\.com:([^/]+)\\/(.+?)(?:\\.git)?$/);\n const httpsMatch = url.match(/https:\\/\\/github\\.com\\/([^/]+)\\/(.+?)(?:\\.git)?$/);\n\n const match = sshMatch || httpsMatch;\n if (match) {\n return {\n owner: match[1],\n repo: match[2],\n isGitHub: true,\n };\n }\n\n return { owner: '', repo: '', isGitHub: false };\n } catch {\n return null;\n }\n}\n\n/**\n * Get all local branches with their last commit dates\n */\nexport async function getLocalBranches(defaultBranch: string, currentBranch: string): Promise<Branch[]> {\n const branches: Branch[] = [];\n\n try {\n // Get all local branches\n const branchSummary = await git.branchLocal();\n\n for (const branchName of branchSummary.all) {\n // Get last commit date for this branch\n const logResult = await git.log({\n [branchName]: null,\n maxCount: 1,\n format: { date: '%aI' },\n });\n\n const lastCommitDate = logResult.latest?.date\n ? new Date(logResult.latest.date)\n : new Date();\n\n // Check if branch is merged into default branch\n const isMerged = await isBranchMerged(branchName, defaultBranch);\n\n // Check if protected\n const isProtected =\n branchName === defaultBranch || matchesProtectedPattern(branchName);\n\n branches.push({\n name: branchName,\n isLocal: true,\n isRemote: false,\n lastCommitDate,\n isMerged,\n isProtected,\n isCurrentBranch: branchName === currentBranch,\n });\n }\n } catch (error) {\n console.error('Error getting local branches:', error);\n }\n\n return branches;\n}\n\n/**\n * Get all remote branches\n */\nexport async function getRemoteBranches(defaultBranch: string): Promise<Branch[]> {\n const branches: Branch[] = [];\n\n try {\n // Fetch to ensure we have latest remote info\n await git.fetch(['--prune']);\n\n // Get all remote branches\n const result = await git.branch(['-r']);\n\n for (const branchName of result.all) {\n // Skip HEAD pointer\n if (branchName.includes('HEAD')) continue;\n\n // Remove 'origin/' prefix for display\n const shortName = branchName.replace(/^origin\\//, '');\n\n // Skip if it's the default branch\n if (shortName === defaultBranch) continue;\n\n // Get last commit date\n const logResult = await git.log({\n [branchName]: null,\n maxCount: 1,\n format: { date: '%aI' },\n });\n\n const lastCommitDate = logResult.latest?.date\n ? new Date(logResult.latest.date)\n : new Date();\n\n // Check if merged into default branch\n const isMerged = await isBranchMerged(branchName, `origin/${defaultBranch}`);\n\n // Check if protected\n const isProtected =\n shortName === defaultBranch || matchesProtectedPattern(shortName);\n\n branches.push({\n name: shortName,\n isLocal: false,\n isRemote: true,\n lastCommitDate,\n isMerged,\n isProtected,\n isCurrentBranch: false,\n });\n }\n } catch (error) {\n console.error('Error getting remote branches:', error);\n }\n\n return branches;\n}\n\n/**\n * Check if a branch is merged into the target branch\n */\nexport async function isBranchMerged(branch: string, target: string): Promise<boolean> {\n try {\n const result = await git.raw(['branch', '--merged', target]);\n const mergedBranches = result\n .split('\\n')\n .map((b) => b.trim().replace(/^\\*\\s*/, ''));\n return mergedBranches.includes(branch) || mergedBranches.includes(branch.replace(/^origin\\//, ''));\n } catch {\n return false;\n }\n}\n\n/**\n * Delete a local branch\n */\nexport async function deleteLocalBranch(branchName: string, force = false): Promise<void> {\n const flag = force ? '-D' : '-d';\n await git.branch([flag, branchName]);\n}\n\n/**\n * Delete a remote branch\n */\nexport async function deleteRemoteBranch(branchName: string, remote = 'origin'): Promise<void> {\n await git.push([remote, '--delete', branchName]);\n}\n\n/**\n * Get full repository info\n */\nexport async function getRepoInfo(defaultBranch?: string): Promise<RepoInfo | null> {\n try {\n const currentBranch = await getCurrentBranch();\n const remoteInfo = await getRemoteInfo();\n\n return {\n owner: remoteInfo?.owner || '',\n repo: remoteInfo?.repo || '',\n defaultBranch: defaultBranch || 'main',\n currentBranch,\n isGitHub: remoteInfo?.isGitHub || false,\n };\n } catch {\n return null;\n }\n}\n","import React from 'react';\nimport { Box, Text, useInput, useApp } from 'ink';\nimport type { DeletionSummary } from '../types/index.js';\n\ninterface SummaryStepProps {\n summary: DeletionSummary;\n isDryRun: boolean;\n onDeleteForReal?: () => void;\n}\n\nexport function SummaryStep({ summary, isDryRun, onDeleteForReal }: SummaryStepProps) {\n const { exit } = useApp();\n\n useInput((input, key) => {\n // Delete for real after dry run\n if (isDryRun && (input === 'd' || input === 'D')) {\n onDeleteForReal?.();\n return;\n }\n\n // Exit on any other key\n if (input === 'q' || input === 'Q' || key.escape) {\n exit();\n return;\n }\n\n // If not dry run, any key exits\n if (!isDryRun) {\n exit();\n }\n });\n\n const successColor = summary.successful > 0 ? 'green' : 'gray';\n const failedColor = summary.failed > 0 ? 'red' : 'gray';\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text color=\"cyan\" bold>\n {isDryRun ? 'Dry Run Complete!' : 'Cleanup Complete!'}\n </Text>\n </Box>\n\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={summary.failed > 0 ? 'yellow' : 'green'}\n paddingX={2}\n paddingY={1}\n >\n <Box flexDirection=\"column\" gap={0}>\n <Box gap={1}>\n <Text color={successColor}>✓</Text>\n <Text>\n {summary.successful} branch(es){' '}\n {isDryRun ? 'would be deleted' : 'deleted successfully'}\n </Text>\n </Box>\n\n {summary.failed > 0 && (\n <Box gap={1}>\n <Text color={failedColor}>✗</Text>\n <Text color={failedColor}>{summary.failed} branch(es) failed</Text>\n </Box>\n )}\n\n {summary.skipped > 0 && (\n <Box gap={1}>\n <Text color=\"gray\">○</Text>\n <Text color=\"gray\">{summary.skipped} branch(es) skipped</Text>\n </Box>\n )}\n </Box>\n </Box>\n\n {isDryRun && summary.successful > 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n <Box gap={2}>\n <Text color=\"red\" bold>[d] Delete for real</Text>\n <Text color=\"gray\">[q] Quit</Text>\n </Box>\n </Box>\n )}\n\n {isDryRun && summary.successful === 0 && (\n <Box marginTop={1}>\n <Text color=\"gray\" dimColor>\n Press any key to exit\n </Text>\n </Box>\n )}\n\n {summary.failed > 0 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"red\">Failed branches:</Text>\n <Box marginLeft={2} flexDirection=\"column\">\n {summary.results\n .filter((r) => !r.success)\n .slice(0, 5)\n .map((result) => (\n <Text key={result.branch.name} color=\"red\">\n - {result.branch.name}: {result.error}\n </Text>\n ))}\n {summary.results.filter((r) => !r.success).length > 5 && (\n <Text color=\"gray\" dimColor>\n ... and {summary.results.filter((r) => !r.success).length - 5} more\n </Text>\n )}\n </Box>\n </Box>\n )}\n\n {!isDryRun && (\n <Box marginTop={1}>\n <Text color=\"gray\" dimColor>\n Press any key to exit\n </Text>\n </Box>\n )}\n </Box>\n );\n}\n","import { useState, useCallback } from 'react';\nimport type { WizardStep } from '../types/index.js';\n\nconst STEP_ORDER: WizardStep[] = [\n 'init',\n 'scope',\n 'criteria',\n 'loading',\n 'select',\n 'confirm',\n 'execute',\n 'summary',\n];\n\nexport function useWizard(initialStep: WizardStep = 'init') {\n const [step, setStep] = useState<WizardStep>(initialStep);\n\n const nextStep = useCallback(() => {\n const currentIndex = STEP_ORDER.indexOf(step);\n if (currentIndex < STEP_ORDER.length - 1) {\n setStep(STEP_ORDER[currentIndex + 1]);\n }\n }, [step]);\n\n const prevStep = useCallback(() => {\n const currentIndex = STEP_ORDER.indexOf(step);\n if (currentIndex > 0) {\n setStep(STEP_ORDER[currentIndex - 1]);\n }\n }, [step]);\n\n const goToStep = useCallback((newStep: WizardStep) => {\n setStep(newStep);\n }, []);\n\n return {\n step,\n nextStep,\n prevStep,\n goToStep,\n };\n}\n","import { Octokit } from '@octokit/rest';\n\nlet octokit: Octokit | null = null;\n\n/**\n * Initialize GitHub API client with token\n */\nexport function initGitHub(token?: string): Octokit {\n const authToken = token || process.env.GITHUB_TOKEN;\n\n octokit = new Octokit({\n auth: authToken,\n });\n\n return octokit;\n}\n\n/**\n * Check if GitHub client is authenticated\n */\nexport function isAuthenticated(): boolean {\n return octokit !== null;\n}\n\n/**\n * Get the default branch for a repository\n */\nexport async function getDefaultBranch(owner: string, repo: string): Promise<string> {\n if (!octokit) {\n return 'main'; // Fallback if not authenticated\n }\n\n try {\n const { data } = await octokit.repos.get({ owner, repo });\n return data.default_branch;\n } catch (error) {\n console.error('Error fetching default branch:', error);\n return 'main';\n }\n}\n\n/**\n * Check if a branch has any open pull requests\n */\nexport async function branchHasOpenPR(\n owner: string,\n repo: string,\n branchName: string\n): Promise<boolean> {\n if (!octokit) {\n return false;\n }\n\n try {\n const { data } = await octokit.pulls.list({\n owner,\n repo,\n state: 'open',\n head: `${owner}:${branchName}`,\n });\n return data.length > 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Delete a branch via GitHub API\n */\nexport async function deleteBranchViaAPI(\n owner: string,\n repo: string,\n branchName: string\n): Promise<void> {\n if (!octokit) {\n throw new Error('GitHub client not initialized');\n }\n\n await octokit.git.deleteRef({\n owner,\n repo,\n ref: `heads/${branchName}`,\n });\n}\n\n/**\n * Get repository information\n */\nexport async function getRepoInfo(owner: string, repo: string): Promise<{\n defaultBranch: string;\n private: boolean;\n description: string | null;\n} | null> {\n if (!octokit) {\n return null;\n }\n\n try {\n const { data } = await octokit.repos.get({ owner, repo });\n return {\n defaultBranch: data.default_branch,\n private: data.private,\n description: data.description,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * List all branches from GitHub API\n */\nexport async function listBranches(\n owner: string,\n repo: string\n): Promise<Array<{ name: string; protected: boolean }>> {\n if (!octokit) {\n return [];\n }\n\n try {\n const branches: Array<{ name: string; protected: boolean }> = [];\n let page = 1;\n\n while (true) {\n const { data } = await octokit.repos.listBranches({\n owner,\n repo,\n per_page: 100,\n page,\n });\n\n if (data.length === 0) break;\n\n for (const branch of data) {\n branches.push({\n name: branch.name,\n protected: branch.protected,\n });\n }\n\n if (data.length < 100) break;\n page++;\n }\n\n return branches;\n } catch {\n return [];\n }\n}\n","import type { Branch, FilterOptions, BranchScope } from '../types/index.js';\nimport { isOlderThan } from '../utils/date.js';\nimport {\n getLocalBranches,\n getRemoteBranches,\n} from './git.js';\n\n/**\n * Fetch branches based on scope\n */\nexport async function fetchBranches(\n scope: BranchScope,\n defaultBranch: string,\n currentBranch: string\n): Promise<Branch[]> {\n let branches: Branch[] = [];\n\n if (scope === 'local' || scope === 'both') {\n const localBranches = await getLocalBranches(defaultBranch, currentBranch);\n branches = [...branches, ...localBranches];\n }\n\n if (scope === 'remote' || scope === 'both') {\n const remoteBranches = await getRemoteBranches(defaultBranch);\n\n // If 'both', merge remote info with local branches\n if (scope === 'both') {\n for (const remoteBranch of remoteBranches) {\n const existingIndex = branches.findIndex(\n (b) => b.name === remoteBranch.name\n );\n if (existingIndex >= 0) {\n // Branch exists locally and remotely\n branches[existingIndex].isRemote = true;\n } else {\n // Remote-only branch\n branches.push(remoteBranch);\n }\n }\n } else {\n branches = remoteBranches;\n }\n }\n\n return branches;\n}\n\n/**\n * Apply all filters to branches\n */\nexport function filterBranches(\n branches: Branch[],\n filters: FilterOptions\n): Branch[] {\n let filtered = [...branches];\n\n // Always exclude protected and current branches\n filtered = filtered.filter((b) => !b.isProtected && !b.isCurrentBranch);\n\n // If no filters selected, return all non-protected branches\n const hasFilters =\n filters.merged || filters.stale || filters.pattern || filters.age;\n\n if (!hasFilters) {\n return filtered;\n }\n\n // Apply filters (OR logic - branch matches if it matches ANY filter)\n filtered = filtered.filter((branch) => {\n const matches: boolean[] = [];\n\n if (filters.merged) {\n matches.push(branch.isMerged);\n }\n\n if (filters.stale) {\n matches.push(isOlderThan(branch.lastCommitDate, filters.staleDays));\n }\n\n if (filters.age) {\n matches.push(isOlderThan(branch.lastCommitDate, filters.ageDays));\n }\n\n if (filters.pattern && filters.patternValue) {\n matches.push(matchesPattern(branch.name, filters.patternValue));\n }\n\n // Return true if branch matches any of the active filters\n return matches.some((m) => m === true);\n });\n\n return filtered;\n}\n\n/**\n * Check if branch name matches a glob-like pattern\n */\nexport function matchesPattern(branchName: string, pattern: string): boolean {\n // Convert glob pattern to regex\n // Supports: * (any characters), ? (single character)\n const regexPattern = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&') // Escape special regex chars\n .replace(/\\*/g, '.*') // * -> .*\n .replace(/\\?/g, '.'); // ? -> .\n\n const regex = new RegExp(`^${regexPattern}$`, 'i');\n return regex.test(branchName);\n}\n\n/**\n * Sort branches by date (oldest first)\n */\nexport function sortByAge(branches: Branch[]): Branch[] {\n return [...branches].sort(\n (a, b) => a.lastCommitDate.getTime() - b.lastCommitDate.getTime()\n );\n}\n\n/**\n * Sort branches by name\n */\nexport function sortByName(branches: Branch[]): Branch[] {\n return [...branches].sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/**\n * Get branch statistics\n */\nexport function getBranchStats(branches: Branch[]): {\n total: number;\n local: number;\n remote: number;\n merged: number;\n protected: number;\n} {\n return {\n total: branches.length,\n local: branches.filter((b) => b.isLocal).length,\n remote: branches.filter((b) => b.isRemote).length,\n merged: branches.filter((b) => b.isMerged).length,\n protected: branches.filter((b) => b.isProtected).length,\n };\n}\n","import { Command } from 'commander';\nimport type { CLIOptions } from './types/index.js';\n\nexport function createCLI(): CLIOptions {\n const program = new Command();\n\n program\n .name('git-tidy')\n .description('Interactive CLI tool for cleaning up unused git branches')\n .version('1.0.0')\n .option('-x, --execute', 'Actually delete branches (default: dry-run mode)', false)\n .option('-y, --yes', 'Skip all confirmations (for scripting)', false)\n .option('-t, --token <token>', 'GitHub personal access token (or use GITHUB_TOKEN env)')\n .parse();\n\n const opts = program.opts();\n\n return {\n execute: opts.execute || false,\n yes: opts.yes || false,\n token: opts.token,\n };\n}\n"],"mappings":";;;AAEA,SAAS,cAAc;;;ACFvB,SAAgB,YAAAA,WAAU,aAAAC,YAAW,eAAAC,oBAAmB;AACxD,SAAS,OAAAC,MAAK,QAAAC,aAAY;AAC1B,SAAS,WAAAC,gBAAe;;;ACDxB,SAAS,KAAK,YAAY;AAiBpB,SACE,KADF;AAVC,SAAS,OAAO,EAAE,SAAS,GAAgB;AAChD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAc;AAAA,MACd,aAAY;AAAA,MACZ,aAAY;AAAA,MACZ,UAAU;AAAA,MACV,UAAU;AAAA,MACV,cAAc;AAAA,MAEd;AAAA,6BAAC,OACC;AAAA,8BAAC,QAAK,OAAM,QAAO,MAAI,MAAC,sBAExB;AAAA,UACA,oBAAC,QAAK,OAAM,QAAO,oCAAsB;AAAA,WAC3C;AAAA,QAEC,YACC,qBAAC,OAAI,KAAK,GACR;AAAA,+BAAC,QAAK,OAAM,QAAO;AAAA;AAAA,YACL;AAAA,YACZ,qBAAC,QAAK,OAAM,SACT;AAAA,uBAAS;AAAA,cAAM;AAAA,cAAE,SAAS;AAAA,eAC7B;AAAA,aACF;AAAA,UACA,qBAAC,QAAK,OAAM,QAAO;AAAA;AAAA,YACT;AAAA,YACR,oBAAC,QAAK,OAAM,SAAS,mBAAS,eAAc;AAAA,aAC9C;AAAA,UACA,qBAAC,QAAK,OAAM,QAAO;AAAA;AAAA,YACR;AAAA,YACT,oBAAC,QAAK,OAAM,UAAU,mBAAS,eAAc;AAAA,aAC/C;AAAA,WACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;;;AC5CA,SAAS,OAAAC,MAAK,QAAAC,aAAY;AAC1B,SAAS,cAAc;AAyBjB,SACE,OAAAC,MADF,QAAAC,aAAA;AAlBC,SAAS,UAAU,EAAE,SAAS,GAAmB;AACtD,QAAMC,WAAU;AAAA,IACd;AAAA,MACE,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF;AAEA,SACE,gBAAAD,MAACH,MAAA,EAAI,eAAc,UAAS,KAAK,GAC/B;AAAA,oBAAAG,MAACH,MAAA,EACC;AAAA,sBAAAE,KAACD,OAAA,EAAK,OAAM,QAAO,MAAI,MAAC,qBAExB;AAAA,MACA,gBAAAC,KAACD,OAAA,EAAK,+CAAiC;AAAA,OACzC;AAAA,IAEA,gBAAAC,KAACF,MAAA,EAAI,YAAY,GACf,0BAAAE;AAAA,MAAC;AAAA;AAAA,QACC,SAASE;AAAA,QACT,UAAU,CAAC,UAAU,SAAS,KAAoB;AAAA;AAAA,IACpD,GACF;AAAA,IAEA,gBAAAF,KAACF,MAAA,EAAI,WAAW,GACd,0BAAAE,KAACD,OAAA,EAAK,OAAM,QAAO,UAAQ,MAAC,2DAE5B,GACF;AAAA,KACF;AAEJ;;;AChDA,SAAgB,gBAAgB;AAChC,SAAS,OAAAI,MAAK,QAAAC,OAAM,gBAAgB;AACpC,SAAS,aAAa,iBAAiB;;;ACDhC,IAAM,qBAAqB;AAC3B,IAAM,mBAAmB;AAGzB,IAAM,qBAAqB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKO,SAAS,wBAAwB,YAA6B;AACnE,SAAO,mBAAmB,KAAK,CAAC,YAAY;AAC1C,QAAI,QAAQ,SAAS,IAAI,GAAG;AAC1B,YAAM,SAAS,QAAQ,MAAM,GAAG,EAAE;AAClC,aAAO,WAAW,WAAW,SAAS,GAAG;AAAA,IAC3C;AACA,WAAO,eAAe;AAAA,EACxB,CAAC;AACH;;;AD8EQ,gBAAAC,MACA,QAAAC,aADA;AA3FD,SAAS,aAAa,EAAE,UAAU,OAAO,GAAsB;AACpE,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAA2B,CAAC,CAAC;AAC7E,QAAM,CAAC,WAAW,YAAY,IAAI,SAAoB,QAAQ;AAC9D,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,OAAO,kBAAkB,CAAC;AACrE,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,OAAO,gBAAgB,CAAC;AAC/D,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,WAAW;AAClD,QAAM,CAAC,YAAY,aAAa,IAAI,SAAwB,IAAI;AAGhE,QAAM,iBAAiB,CAAC,UAAiC;AACvD,UAAM,MAAM,SAAS,OAAO,EAAE;AAC9B,QAAI,MAAM,GAAG,KAAK,OAAO,GAAG;AAC1B,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEA,QAAMC,WAAU;AAAA,IACd;AAAA,MACE,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,OAAO,iCAAiC,SAAS;AAAA,MACjD,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,OAAO,uBAAuB,OAAO;AAAA,MACrC,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,OAAO,qBAAqB,OAAO;AAAA,MACnC,OAAO;AAAA,IACT;AAAA,EACF;AAEA,WAAS,CAAC,OAAO,QAAQ;AACvB,QAAI,IAAI,QAAQ;AACd,UAAI,cAAc,UAAU;AAC1B,qBAAa,QAAQ;AAAA,MACvB,OAAO;AACL,eAAO;AAAA,MACT;AAAA,IACF;AAGA,QAAI,IAAI,UAAU,cAAc,UAAU;AACxC,mBAAa;AAAA,IACf;AAAA,EACF,CAAC;AAED,QAAM,uBAAuB,CAAC,WAAqB;AACjD,wBAAoB,MAA0B;AAAA,EAChD;AAEA,QAAM,eAAe,MAAM;AAEzB,QAAI,iBAAiB,SAAS,OAAO,KAAK,cAAc,UAAU;AAChE,mBAAa,WAAW;AACxB;AAAA,IACF;AACA,QAAI,iBAAiB,SAAS,KAAK,KAAK,cAAc,aAAa;AACjE,mBAAa,SAAS;AACtB;AAAA,IACF;AACA,QAAI,iBAAiB,SAAS,SAAS,KAAK,cAAc,WAAW;AACnE,mBAAa,SAAS;AACtB;AAAA,IACF;AACA,QAAI,iBAAiB,SAAS,SAAS,KAAK,cAAc,UAAU;AAClE,mBAAa,SAAS;AACtB;AAAA,IACF;AAGA,UAAM,UAAyB;AAAA,MAC7B,QAAQ,iBAAiB,SAAS,QAAQ;AAAA,MAC1C,OAAO,iBAAiB,SAAS,OAAO;AAAA,MACxC,WAAW,SAAS,WAAW,EAAE,KAAK;AAAA,MACtC,SAAS,iBAAiB,SAAS,SAAS;AAAA,MAC5C,cAAc;AAAA,MACd,KAAK,iBAAiB,SAAS,KAAK;AAAA,MACpC,SAAS,SAAS,SAAS,EAAE,KAAK;AAAA,IACpC;AAEA,aAAS,OAAO;AAAA,EAClB;AAEA,MAAI,cAAc,aAAa;AAC7B,WACE,gBAAAD,MAACE,MAAA,EAAI,eAAc,UAAS,KAAK,GAC/B;AAAA,sBAAAH,KAACI,OAAA,EAAK,OAAM,QAAO,gEAAkD;AAAA,MACrE,gBAAAH,MAACE,MAAA,EACC;AAAA,wBAAAH;AAAA,UAAC;AAAA;AAAA,YACC,cAAc;AAAA,YACd,UAAU,CAAC,UAAU;AACnB,oBAAM,MAAM,eAAe,KAAK;AAChC,kBAAI,QAAQ,MAAM;AAChB,8BAAc,4CAA4C;AAC1D;AAAA,cACF;AACA,4BAAc,IAAI;AAClB,2BAAa,OAAO,GAAG,CAAC;AACxB,kBAAI,iBAAiB,SAAS,KAAK,GAAG;AACpC,6BAAa,SAAS;AAAA,cACxB,WAAW,iBAAiB,SAAS,SAAS,GAAG;AAC/C,6BAAa,SAAS;AAAA,cACxB,OAAO;AACL,6BAAa;AAAA,cACf;AAAA,YACF;AAAA;AAAA,QACF;AAAA,QACA,gBAAAA,KAACI,OAAA,EAAK,OAAM,QAAO,mBAAK;AAAA,SAC1B;AAAA,MACC,cAAc,gBAAAJ,KAACI,OAAA,EAAK,OAAM,OAAO,sBAAW;AAAA,OAC/C;AAAA,EAEJ;AAEA,MAAI,cAAc,WAAW;AAC3B,WACE,gBAAAH,MAACE,MAAA,EAAI,eAAc,UAAS,KAAK,GAC/B;AAAA,sBAAAH,KAACI,OAAA,EAAK,OAAM,QAAO,mDAAqC;AAAA,MACxD,gBAAAH,MAACE,MAAA,EACC;AAAA,wBAAAH;AAAA,UAAC;AAAA;AAAA,YACC,cAAc;AAAA,YACd,UAAU,CAAC,UAAU;AACnB,oBAAM,MAAM,eAAe,KAAK;AAChC,kBAAI,QAAQ,MAAM;AAChB,8BAAc,4CAA4C;AAC1D;AAAA,cACF;AACA,4BAAc,IAAI;AAClB,yBAAW,OAAO,GAAG,CAAC;AACtB,kBAAI,iBAAiB,SAAS,SAAS,GAAG;AACxC,6BAAa,SAAS;AAAA,cACxB,OAAO;AACL,6BAAa;AAAA,cACf;AAAA,YACF;AAAA;AAAA,QACF;AAAA,QACA,gBAAAA,KAACI,OAAA,EAAK,OAAM,QAAO,mBAAK;AAAA,SAC1B;AAAA,MACC,cAAc,gBAAAJ,KAACI,OAAA,EAAK,OAAM,OAAO,sBAAW;AAAA,OAC/C;AAAA,EAEJ;AAEA,MAAI,cAAc,WAAW;AAC3B,WACE,gBAAAH,MAACE,MAAA,EAAI,eAAc,UAAS,KAAK,GAC/B;AAAA,sBAAAH,KAACI,OAAA,EAAK,OAAM,QAAO,4DAA8C;AAAA,MACjE,gBAAAJ;AAAA,QAAC;AAAA;AAAA,UACC,cAAc;AAAA,UACd,UAAU,CAAC,UAAU;AACnB,uBAAW,KAAK;AAChB,kBAAM,UAAyB;AAAA,cAC7B,QAAQ,iBAAiB,SAAS,QAAQ;AAAA,cAC1C,OAAO,iBAAiB,SAAS,OAAO;AAAA,cACxC,WAAW,SAAS,WAAW,EAAE,KAAK;AAAA,cACtC,SAAS,iBAAiB,SAAS,SAAS;AAAA,cAC5C,cAAc;AAAA,cACd,KAAK,iBAAiB,SAAS,KAAK;AAAA,cACpC,SAAS,SAAS,SAAS,EAAE,KAAK;AAAA,YACpC;AACA,qBAAS,OAAO;AAAA,UAClB;AAAA;AAAA,MACF;AAAA,MACA,gBAAAA,KAACI,OAAA,EAAK,OAAM,QAAO,UAAQ,MAAC,0DAE5B;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,gBAAAH,MAACE,MAAA,EAAI,eAAc,UAAS,KAAK,GAC/B;AAAA,oBAAAF,MAACE,MAAA,EACC;AAAA,sBAAAH,KAACI,OAAA,EAAK,OAAM,QAAO,MAAI,MAAC,qBAExB;AAAA,MACA,gBAAAJ,KAACI,OAAA,EAAK,mEAAqD;AAAA,OAC7D;AAAA,IAEA,gBAAAJ,KAACG,MAAA,EAAI,YAAY,GACf,0BAAAH;AAAA,MAAC;AAAA;AAAA,QACC,SAASE;AAAA,QACT,UAAU;AAAA;AAAA,IACZ,GACF;AAAA,IAEA,gBAAAD,MAACE,MAAA,EAAI,WAAW,GAAG,eAAc,UAC/B;AAAA,sBAAAH,KAACI,OAAA,EAAK,OAAM,QAAO,UAAQ,MAAC,6EAE5B;AAAA,MACA,gBAAAJ,KAACI,OAAA,EAAK,OAAM,QAAO,UAAQ,MAAC,kCAE5B;AAAA,OACF;AAAA,IAEC,iBAAiB,SAAS,KACzB,gBAAAJ,KAACG,MAAA,EAAI,WAAW,GACd,0BAAAF,MAACG,OAAA,EAAK,OAAM,SAAQ;AAAA;AAAA,MACY,iBAAiB;AAAA,MAAO;AAAA,OACxD,GACF;AAAA,KAEJ;AAEJ;;;AE9NA,SAAgB,YAAAC,WAAU,eAAe;AACzC,SAAS,OAAAC,MAAK,QAAAC,OAAM,YAAAC,iBAAgB;AACpC,SAAS,eAAAC,oBAAmB;;;ACCrB,SAAS,QAAQ,MAAoB;AAC1C,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,WAAW,KAAK,IAAI,IAAI,QAAQ,IAAI,KAAK,QAAQ,CAAC;AACxD,QAAM,WAAW,KAAK,MAAM,YAAY,MAAO,KAAK,KAAK,GAAG;AAC5D,SAAO;AACT;AAKO,SAAS,cAAc,MAAoB;AAChD,QAAM,OAAO,QAAQ,IAAI;AAEzB,MAAI,SAAS,GAAG;AACd,WAAO;AAAA,EACT,WAAW,SAAS,GAAG;AACrB,WAAO;AAAA,EACT,WAAW,OAAO,GAAG;AACnB,WAAO,GAAG,IAAI;AAAA,EAChB,WAAW,OAAO,IAAI;AACpB,UAAM,QAAQ,KAAK,MAAM,OAAO,CAAC;AACjC,WAAO,UAAU,IAAI,eAAe,GAAG,KAAK;AAAA,EAC9C,WAAW,OAAO,KAAK;AACrB,UAAM,SAAS,KAAK,MAAM,OAAO,EAAE;AACnC,WAAO,WAAW,IAAI,gBAAgB,GAAG,MAAM;AAAA,EACjD,OAAO;AACL,UAAM,QAAQ,KAAK,MAAM,OAAO,GAAG;AACnC,WAAO,UAAU,IAAI,eAAe,GAAG,KAAK;AAAA,EAC9C;AACF;AAKO,SAAS,YAAY,MAAY,MAAuB;AAC7D,SAAO,QAAQ,IAAI,IAAI;AACzB;;;AD4CQ,SACE,OAAAC,MADF,QAAAC,aAAA;AAvED,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,CAAC,gBAAgB,iBAAiB,IAAIC,UAAmB,CAAC,CAAC;AAGjE,QAAMC,WAAU,QAAQ,MAAM;AAC5B,WAAO,SAAS,IAAI,CAAC,WAAW;AAC9B,YAAM,WAAW,OAAO,WAAW,OAAO,WACtC,iBACA,OAAO,UACL,UACA;AAEN,YAAM,SAAS,OAAO,WAAW,WAAW;AAC5C,YAAM,MAAM,cAAc,OAAO,cAAc;AAE/C,aAAO;AAAA,QACL,OAAO,GAAG,OAAO,IAAI;AAAA,QACrB,OAAO,OAAO;AAAA,QACd,MAAM,IAAI,MAAM,KAAK,GAAG,KAAK,QAAQ;AAAA,MACvC;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,QAAQ,CAAC;AAEb,EAAAC,UAAS,CAAC,OAAO,QAAQ;AACvB,QAAI,IAAI,QAAQ;AACd,aAAO;AACP;AAAA,IACF;AAGA,QAAI,IAAI,UAAU,eAAe,SAAS,GAAG;AAC3C,YAAM,WAAW,SAAS,OAAO,CAAC,MAAM,eAAe,SAAS,EAAE,IAAI,CAAC;AACvE,eAAS,QAAQ;AACjB;AAAA,IACF;AAGA,QAAI,UAAU,KAAK;AACjB,wBAAkB,SAAS,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAAA,IAC/C;AAGA,QAAI,UAAU,KAAK;AACjB,wBAAkB,CAAC,CAAC;AAAA,IACtB;AAGA,QAAI,UAAU,KAAK;AACjB,YAAM,WAAW,SACd,OAAO,CAAC,MAAM,CAAC,eAAe,SAAS,EAAE,IAAI,CAAC,EAC9C,IAAI,CAAC,MAAM,EAAE,IAAI;AACpB,wBAAkB,QAAQ;AAAA,IAC5B;AAAA,EACF,CAAC;AAED,QAAM,eAAe,CAAC,WAAqB;AACzC,sBAAkB,MAAM;AAAA,EAC1B;AAEA,QAAM,eAAe,MAAM;AACzB,UAAM,WAAW,SAAS,OAAO,CAAC,MAAM,eAAe,SAAS,EAAE,IAAI,CAAC;AACvE,aAAS,QAAQ;AAAA,EACnB;AAEA,MAAI,SAAS,WAAW,GAAG;AACzB,WACE,gBAAAH,MAACI,MAAA,EAAI,eAAc,UAAS,KAAK,GAC/B;AAAA,sBAAAJ,MAACI,MAAA,EACC;AAAA,wBAAAL,KAACM,OAAA,EAAK,OAAM,QAAO,MAAI,MAAC,qBAExB;AAAA,QACA,gBAAAN,KAACM,OAAA,EAAK,wCAA0B;AAAA,SAClC;AAAA,MACA,gBAAAN,KAACK,MAAA,EAAI,YAAY,GACf,0BAAAL,KAACM,OAAA,EAAK,OAAM,UAAS,8CAAgC,GACvD;AAAA,MACA,gBAAAN,KAACM,OAAA,EAAK,OAAM,QAAO,UAAQ,MAAC,qDAE5B;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,gBAAAL,MAACI,MAAA,EAAI,eAAc,UAAS,KAAK,GAC/B;AAAA,oBAAAJ,MAACI,MAAA,EACC;AAAA,sBAAAL,KAACM,OAAA,EAAK,OAAM,QAAO,MAAI,MAAC,qBAExB;AAAA,MACA,gBAAAL,MAACK,OAAA,EAAK;AAAA;AAAA,QAA6B,SAAS;AAAA,QAAO;AAAA,SAAO;AAAA,OAC5D;AAAA,IAEA,gBAAAL,MAACI,MAAA,EAAI,YAAY,GAAG,KAAK,GACvB;AAAA,sBAAAL,KAACM,OAAA,EAAK,OAAM,QAAO,4BAAc;AAAA,MACjC,gBAAAN,KAACM,OAAA,EAAK,OAAM,QAAO,6BAAe;AAAA,MAClC,gBAAAN,KAACM,OAAA,EAAK,OAAM,QAAO,wBAAU;AAAA,OAC/B;AAAA,IAEA,gBAAAN,KAACK,MAAA,EAAI,YAAY,GAAG,eAAc,UAChC,0BAAAL;AAAA,MAACO;AAAA,MAAA;AAAA,QACC,SAASJ;AAAA,QACT,cAAc;AAAA,QACd,UAAU;AAAA;AAAA,IACZ,GACF;AAAA,IAEA,gBAAAH,KAACK,MAAA,EAAI,WAAW,GAAG,eAAc,UAC/B,0BAAAL,KAACM,OAAA,EAAK,OAAM,QAAO,UAAQ,MAAC,0EAE5B,GACF;AAAA,IAEA,gBAAAL,MAACI,MAAA,EAAI,WAAW,GACd;AAAA,sBAAAJ,MAACK,OAAA,EAAK,OAAO,eAAe,SAAS,IAAI,UAAU,QAChD;AAAA,uBAAe;AAAA,QAAO;AAAA,SACzB;AAAA,MACC,eAAe,SAAS,KACvB,gBAAAN,KAACM,OAAA,EAAK,OAAM,QAAO,wCAA0B;AAAA,OAEjD;AAAA,KACF;AAEJ;;;AEzIA,SAAS,OAAAE,MAAK,QAAAC,OAAM,YAAAC,iBAAgB;AAiC9B,SACE,OAAAC,MADF,QAAAC,aAAA;AAvBC,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,aAAa,SAAS,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AACrD,QAAM,cAAc,SAAS,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE;AAEvD,EAAAF,UAAS,CAAC,OAAO,QAAQ;AACvB,QAAI,IAAI,QAAQ;AACd,gBAAU;AAAA,IACZ;AACA,QAAI,IAAI,UAAU,UAAU,OAAO,UAAU,KAAK;AAChD,eAAS;AAAA,IACX;AACA,QAAI,UAAU,OAAO,UAAU,KAAK;AAClC,gBAAU;AAAA,IACZ;AAAA,EACF,CAAC;AAED,SACE,gBAAAE,MAACJ,MAAA,EAAI,eAAc,UAAS,KAAK,GAC/B;AAAA,oBAAAI,MAACJ,MAAA,EACC;AAAA,sBAAAG,KAACF,OAAA,EAAK,OAAM,QAAO,MAAI,MAAC,qBAExB;AAAA,MACA,gBAAAE,KAACF,OAAA,EAAK,+BAAiB;AAAA,OACzB;AAAA,IAEA,gBAAAG;AAAA,MAACJ;AAAA,MAAA;AAAA,QACC,eAAc;AAAA,QACd,aAAY;AAAA,QACZ,aAAY;AAAA,QACZ,UAAU;AAAA,QACV,UAAU;AAAA,QACV,SAAS;AAAA,QAET;AAAA,0BAAAI,MAACH,OAAA,EAAK,MAAI,MAAC;AAAA;AAAA,YAAiB,SAAS;AAAA,YAAO;AAAA,aAAW;AAAA,UAEvD,gBAAAG,MAACJ,MAAA,EAAI,WAAW,GAAG,KAAK,GACtB;AAAA,4BAAAI,MAACH,OAAA,EAAK;AAAA;AAAA,cACG,gBAAAE,KAACF,OAAA,EAAK,OAAM,QAAQ,sBAAW;AAAA,eACxC;AAAA,YACA,gBAAAG,MAACH,OAAA,EAAK;AAAA;AAAA,cACI,gBAAAE,KAACF,OAAA,EAAK,OAAM,WAAW,uBAAY;AAAA,eAC7C;AAAA,aACF;AAAA,UAEC,YACC,gBAAAE,KAACH,MAAA,EAAI,WAAW,GACd,0BAAAG,KAACF,OAAA,EAAK,OAAM,UAAS,MAAI,MAAC,iEAE1B,GACF;AAAA,UAGD,CAAC,YACA,gBAAAE,KAACH,MAAA,EAAI,WAAW,GACd,0BAAAG,KAACF,OAAA,EAAK,OAAM,OAAM,MAAI,MAAC,mEAEvB,GACF;AAAA;AAAA;AAAA,IAEJ;AAAA,IAEA,gBAAAG,MAACJ,MAAA,EAAI,eAAc,UACjB;AAAA,sBAAAG,KAACF,OAAA,EAAK,OAAM,QAAO,iCAAmB;AAAA,MACtC,gBAAAG,MAACJ,MAAA,EAAI,YAAY,GAAG,eAAc,UAC/B;AAAA,iBAAS,MAAM,GAAG,EAAE,EAAE,IAAI,CAAC,WAC1B,gBAAAI,MAACH,OAAA,EAAuB,OAAM,QAAO;AAAA;AAAA,UAChC,OAAO;AAAA,UAAM;AAAA,UAChB,gBAAAG,MAACH,OAAA,EAAK,UAAQ,MAAC;AAAA;AAAA,YACX,OAAO,WAAW;AAAA,YACnB,OAAO,WAAW,OAAO,YAAY;AAAA,YACrC,OAAO,YAAY;AAAA,YAAS;AAAA,aAC/B;AAAA,aANS,OAAO,IAOlB,CACD;AAAA,QACA,SAAS,SAAS,MACjB,gBAAAG,MAACH,OAAA,EAAK,OAAM,QAAO,UAAQ,MAAC;AAAA;AAAA,UACjB,SAAS,SAAS;AAAA,UAAG;AAAA,WAChC;AAAA,SAEJ;AAAA,OACF;AAAA,IAEA,gBAAAG,MAACJ,MAAA,EAAI,WAAW,GAAG,KAAK,GACtB;AAAA,sBAAAG,KAACF,OAAA,EAAK,OAAM,SAAQ,+BAAiB;AAAA,MACrC,gBAAAE,KAACF,OAAA,EAAK,OAAM,OAAM,4BAAc;AAAA,OAClC;AAAA,KACF;AAEJ;;;ACxGA,SAAgB,WAAW,YAAAI,iBAAgB;AAC3C,SAAS,OAAAC,MAAK,QAAAC,aAAY;AAC1B,SAAS,eAAe;;;ACFxB,OAAO,eAA8B;AAIrC,IAAI;AAKG,SAAS,QAAQ,KAAyB;AAC/C,QAAM,UAAU,GAAG;AACnB,SAAO;AACT;AAKA,eAAsB,YAA8B;AAClD,MAAI;AACF,UAAM,IAAI,SAAS,CAAC,WAAW,CAAC;AAChC,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,mBAAoC;AACxD,QAAM,SAAS,MAAM,IAAI,SAAS,CAAC,gBAAgB,MAAM,CAAC;AAC1D,SAAO,OAAO,KAAK;AACrB;AAKA,eAAsB,gBAAoF;AACxG,MAAI;AACF,UAAM,UAAU,MAAM,IAAI,WAAW,IAAI;AACzC,UAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ;AAEtD,QAAI,CAAC,QAAQ,MAAM,OAAO;AACxB,aAAO;AAAA,IACT;AAEA,UAAM,MAAM,OAAO,KAAK;AAKxB,UAAM,WAAW,IAAI,MAAM,2CAA2C;AACtE,UAAM,aAAa,IAAI,MAAM,kDAAkD;AAE/E,UAAM,QAAQ,YAAY;AAC1B,QAAI,OAAO;AACT,aAAO;AAAA,QACL,OAAO,MAAM,CAAC;AAAA,QACd,MAAM,MAAM,CAAC;AAAA,QACb,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,WAAO,EAAE,OAAO,IAAI,MAAM,IAAI,UAAU,MAAM;AAAA,EAChD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,iBAAiB,eAAuB,eAA0C;AACtG,QAAM,WAAqB,CAAC;AAE5B,MAAI;AAEF,UAAM,gBAAgB,MAAM,IAAI,YAAY;AAE5C,eAAW,cAAc,cAAc,KAAK;AAE1C,YAAM,YAAY,MAAM,IAAI,IAAI;AAAA,QAC9B,CAAC,UAAU,GAAG;AAAA,QACd,UAAU;AAAA,QACV,QAAQ,EAAE,MAAM,MAAM;AAAA,MACxB,CAAC;AAED,YAAM,iBAAiB,UAAU,QAAQ,OACrC,IAAI,KAAK,UAAU,OAAO,IAAI,IAC9B,oBAAI,KAAK;AAGb,YAAM,WAAW,MAAM,eAAe,YAAY,aAAa;AAG/D,YAAM,cACJ,eAAe,iBAAiB,wBAAwB,UAAU;AAEpE,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,SAAS;AAAA,QACT,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA,iBAAiB,eAAe;AAAA,MAClC,CAAC;AAAA,IACH;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,iCAAiC,KAAK;AAAA,EACtD;AAEA,SAAO;AACT;AAKA,eAAsB,kBAAkB,eAA0C;AAChF,QAAM,WAAqB,CAAC;AAE5B,MAAI;AAEF,UAAM,IAAI,MAAM,CAAC,SAAS,CAAC;AAG3B,UAAM,SAAS,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;AAEtC,eAAW,cAAc,OAAO,KAAK;AAEnC,UAAI,WAAW,SAAS,MAAM,EAAG;AAGjC,YAAM,YAAY,WAAW,QAAQ,aAAa,EAAE;AAGpD,UAAI,cAAc,cAAe;AAGjC,YAAM,YAAY,MAAM,IAAI,IAAI;AAAA,QAC9B,CAAC,UAAU,GAAG;AAAA,QACd,UAAU;AAAA,QACV,QAAQ,EAAE,MAAM,MAAM;AAAA,MACxB,CAAC;AAED,YAAM,iBAAiB,UAAU,QAAQ,OACrC,IAAI,KAAK,UAAU,OAAO,IAAI,IAC9B,oBAAI,KAAK;AAGb,YAAM,WAAW,MAAM,eAAe,YAAY,UAAU,aAAa,EAAE;AAG3E,YAAM,cACJ,cAAc,iBAAiB,wBAAwB,SAAS;AAElE,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,SAAS;AAAA,QACT,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA,iBAAiB;AAAA,MACnB,CAAC;AAAA,IACH;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,kCAAkC,KAAK;AAAA,EACvD;AAEA,SAAO;AACT;AAKA,eAAsB,eAAe,QAAgB,QAAkC;AACrF,MAAI;AACF,UAAM,SAAS,MAAM,IAAI,IAAI,CAAC,UAAU,YAAY,MAAM,CAAC;AAC3D,UAAM,iBAAiB,OACpB,MAAM,IAAI,EACV,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,UAAU,EAAE,CAAC;AAC5C,WAAO,eAAe,SAAS,MAAM,KAAK,eAAe,SAAS,OAAO,QAAQ,aAAa,EAAE,CAAC;AAAA,EACnG,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,kBAAkB,YAAoB,QAAQ,OAAsB;AACxF,QAAM,OAAO,QAAQ,OAAO;AAC5B,QAAM,IAAI,OAAO,CAAC,MAAM,UAAU,CAAC;AACrC;AAKA,eAAsB,mBAAmB,YAAoB,SAAS,UAAyB;AAC7F,QAAM,IAAI,KAAK,CAAC,QAAQ,YAAY,UAAU,CAAC;AACjD;AAKA,eAAsB,YAAY,eAAkD;AAClF,MAAI;AACF,UAAM,gBAAgB,MAAM,iBAAiB;AAC7C,UAAM,aAAa,MAAM,cAAc;AAEvC,WAAO;AAAA,MACL,OAAO,YAAY,SAAS;AAAA,MAC5B,MAAM,YAAY,QAAQ;AAAA,MAC1B,eAAe,iBAAiB;AAAA,MAChC;AAAA,MACA,UAAU,YAAY,YAAY;AAAA,IACpC;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ADzHQ,gBAAAC,MAGA,QAAAC,aAHA;AArFD,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AACF,GAAuB;AACrB,QAAM,CAAC,cAAc,eAAe,IAAIC,UAAS,CAAC;AAClD,QAAM,CAAC,SAAS,UAAU,IAAIA,UAA2B,CAAC,CAAC;AAC3D,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAS,IAAI;AAEjD,YAAU,MAAM;AACd,UAAM,iBAAiB,YAAY;AACjC,YAAM,aAA+B,CAAC;AAEtC,eAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,cAAM,SAAS,SAAS,CAAC;AACzB,wBAAgB,CAAC;AAEjB,cAAM,SAAyB;AAAA,UAC7B;AAAA,UACA,SAAS;AAAA,UACT,cAAc;AAAA,UACd,eAAe;AAAA,QACjB;AAEA,YAAI,UAAU;AAEZ,gBAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAG,CAAC;AACvD,iBAAO,eAAe,OAAO;AAC7B,iBAAO,gBAAgB,OAAO;AAAA,QAChC,OAAO;AAEL,cAAI;AACF,gBAAI,OAAO,SAAS;AAClB,oBAAM,kBAAkB,OAAO,MAAM,IAAI;AACzC,qBAAO,eAAe;AAAA,YACxB;AAAA,UACF,SAAS,OAAO;AACd,mBAAO,UAAU;AACjB,mBAAO,QAAQ,UAAU,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,UACnF;AAEA,cAAI;AACF,gBAAI,OAAO,UAAU;AACnB,oBAAM,mBAAsB,OAAO,IAAI;AACvC,qBAAO,gBAAgB;AAAA,YACzB;AAAA,UACF,SAAS,OAAO;AACd,gBAAI,CAAC,OAAO,OAAO;AACjB,qBAAO,UAAU;AACjB,qBAAO,QAAQ,WAAW,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,YACpF,OAAO;AACL,qBAAO,SAAS,aAAa,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,YACvF;AAAA,UACF;AAAA,QACF;AAEA,mBAAW,KAAK,MAAM;AACtB,mBAAW,CAAC,GAAG,UAAU,CAAC;AAAA,MAC5B;AAEA,oBAAc,KAAK;AAGnB,YAAM,UAA2B;AAAA,QAC/B,OAAO,SAAS;AAAA,QAChB,YAAY,WAAW,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,QAChD,QAAQ,WAAW,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE;AAAA,QAC7C,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAGA,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAG,CAAC;AACvD,iBAAW,OAAO;AAAA,IACpB;AAEA,mBAAe;AAAA,EACjB,GAAG,CAAC,UAAU,UAAU,UAAU,CAAC;AAEnC,QAAM,gBAAgB,SAAS,YAAY;AAC3C,QAAM,iBAAiB,QAAQ;AAE/B,SACE,gBAAAD,MAACE,MAAA,EAAI,eAAc,UAAS,KAAK,GAC/B;AAAA,oBAAAF,MAACE,MAAA,EACC;AAAA,sBAAAH,KAACI,OAAA,EAAK,OAAM,QAAO,MAAI,MAAC,qBAExB;AAAA,MACA,gBAAAH,MAACG,OAAA,EAAK;AAAA;AAAA,QAAE,WAAW,2BAA2B;AAAA,SAAuB;AAAA,OACvE;AAAA,IAEA,gBAAAH;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,eAAc;AAAA,QACd,aAAY;AAAA,QACZ,aAAY;AAAA,QACZ,UAAU;AAAA,QACV,UAAU;AAAA,QAET;AAAA,wBAAc,iBACb,gBAAAF,MAACE,MAAA,EAAI,KAAK,GACR;AAAA,4BAAAH,KAAC,WAAQ,OAAM,IAAG;AAAA,YAClB,gBAAAC,MAACG,OAAA,EACE;AAAA,yBAAW,eAAe;AAAA,cAAW;AAAA,cAAE,cAAc;AAAA,eACxD;AAAA,YACA,gBAAAH,MAACG,OAAA,EAAK,OAAM,QAAO;AAAA;AAAA,cACf,iBAAiB;AAAA,cAAE;AAAA,cAAE,SAAS;AAAA,cAAO;AAAA,eACzC;AAAA,aACF;AAAA,UAGD,CAAC,cACA,gBAAAH,MAACG,OAAA,EAAK,OAAM,SACT;AAAA,uBAAW,eAAe;AAAA,YAAW;AAAA,aACxC;AAAA;AAAA;AAAA,IAEJ;AAAA,IAEA,gBAAAH,MAACE,MAAA,EAAI,eAAc,UAAS,WAAW,GACrC;AAAA,sBAAAH,KAACI,OAAA,EAAK,OAAM,QAAO,sBAAQ;AAAA,MAC3B,gBAAAH,MAACE,MAAA,EAAI,YAAY,GAAG,eAAc,UAC/B;AAAA,gBAAQ,MAAM,EAAE,EAAE,IAAI,CAAC,QAAQ,UAC9B,gBAAAF,MAACE,MAAA,EAA6B,KAAK,GACjC;AAAA,0BAAAH,KAACI,OAAA,EAAK,OAAO,OAAO,UAAU,UAAU,OACrC,iBAAO,UAAU,WAAM,UAC1B;AAAA,UACA,gBAAAJ,KAACI,OAAA,EAAK,OAAO,OAAO,UAAU,SAAS,OACpC,iBAAO,OAAO,MACjB;AAAA,UACC,OAAO,gBAAgB,gBAAAJ,KAACI,OAAA,EAAK,OAAM,QAAO,UAAQ,MAAC,qBAAO;AAAA,UAC1D,OAAO,iBAAiB,gBAAAJ,KAACI,OAAA,EAAK,OAAM,WAAU,UAAQ,MAAC,sBAAQ;AAAA,UAC/D,OAAO,SACN,gBAAAH,MAACG,OAAA,EAAK,OAAM,OAAM,UAAQ,MAAC;AAAA;AAAA,YACtB,OAAO;AAAA,aACZ;AAAA,aAZM,OAAO,OAAO,IAcxB,CACD;AAAA,QACA,QAAQ,SAAS,KAChB,gBAAAH,MAACG,OAAA,EAAK,OAAM,QAAO,UAAQ,MAAC;AAAA;AAAA,UACjB,QAAQ,SAAS;AAAA,UAAE;AAAA,WAC9B;AAAA,SAEJ;AAAA,OACF;AAAA,KACF;AAEJ;;;AEhKA,SAAS,OAAAC,MAAK,QAAAC,OAAM,YAAAC,WAAU,cAAc;AAqCpC,gBAAAC,MAeI,QAAAC,aAfJ;AA5BD,SAAS,YAAY,EAAE,SAAS,UAAU,gBAAgB,GAAqB;AACpF,QAAM,EAAE,KAAK,IAAI,OAAO;AAExB,EAAAF,UAAS,CAAC,OAAO,QAAQ;AAEvB,QAAI,aAAa,UAAU,OAAO,UAAU,MAAM;AAChD,wBAAkB;AAClB;AAAA,IACF;AAGA,QAAI,UAAU,OAAO,UAAU,OAAO,IAAI,QAAQ;AAChD,WAAK;AACL;AAAA,IACF;AAGA,QAAI,CAAC,UAAU;AACb,WAAK;AAAA,IACP;AAAA,EACF,CAAC;AAED,QAAM,eAAe,QAAQ,aAAa,IAAI,UAAU;AACxD,QAAM,cAAc,QAAQ,SAAS,IAAI,QAAQ;AAEjD,SACE,gBAAAE,MAACJ,MAAA,EAAI,eAAc,UAAS,KAAK,GAC/B;AAAA,oBAAAG,KAACH,MAAA,EACC,0BAAAG,KAACF,OAAA,EAAK,OAAM,QAAO,MAAI,MACpB,qBAAW,sBAAsB,qBACpC,GACF;AAAA,IAEA,gBAAAE;AAAA,MAACH;AAAA,MAAA;AAAA,QACC,eAAc;AAAA,QACd,aAAY;AAAA,QACZ,aAAa,QAAQ,SAAS,IAAI,WAAW;AAAA,QAC7C,UAAU;AAAA,QACV,UAAU;AAAA,QAEV,0BAAAI,MAACJ,MAAA,EAAI,eAAc,UAAS,KAAK,GAC/B;AAAA,0BAAAI,MAACJ,MAAA,EAAI,KAAK,GACR;AAAA,4BAAAG,KAACF,OAAA,EAAK,OAAO,cAAc,oBAAC;AAAA,YAC5B,gBAAAG,MAACH,OAAA,EACE;AAAA,sBAAQ;AAAA,cAAW;AAAA,cAAY;AAAA,cAC/B,WAAW,qBAAqB;AAAA,eACnC;AAAA,aACF;AAAA,UAEC,QAAQ,SAAS,KAChB,gBAAAG,MAACJ,MAAA,EAAI,KAAK,GACR;AAAA,4BAAAG,KAACF,OAAA,EAAK,OAAO,aAAa,oBAAC;AAAA,YAC3B,gBAAAG,MAACH,OAAA,EAAK,OAAO,aAAc;AAAA,sBAAQ;AAAA,cAAO;AAAA,eAAkB;AAAA,aAC9D;AAAA,UAGD,QAAQ,UAAU,KACjB,gBAAAG,MAACJ,MAAA,EAAI,KAAK,GACR;AAAA,4BAAAG,KAACF,OAAA,EAAK,OAAM,QAAO,oBAAC;AAAA,YACpB,gBAAAG,MAACH,OAAA,EAAK,OAAM,QAAQ;AAAA,sBAAQ;AAAA,cAAQ;AAAA,eAAmB;AAAA,aACzD;AAAA,WAEJ;AAAA;AAAA,IACF;AAAA,IAEC,YAAY,QAAQ,aAAa,KAChC,gBAAAE,KAACH,MAAA,EAAI,WAAW,GAAG,eAAc,UAC/B,0BAAAI,MAACJ,MAAA,EAAI,KAAK,GACR;AAAA,sBAAAG,KAACF,OAAA,EAAK,OAAM,OAAM,MAAI,MAAC,iCAAmB;AAAA,MAC1C,gBAAAE,KAACF,OAAA,EAAK,OAAM,QAAO,sBAAQ;AAAA,OAC7B,GACF;AAAA,IAGD,YAAY,QAAQ,eAAe,KAClC,gBAAAE,KAACH,MAAA,EAAI,WAAW,GACd,0BAAAG,KAACF,OAAA,EAAK,OAAM,QAAO,UAAQ,MAAC,mCAE5B,GACF;AAAA,IAGD,QAAQ,SAAS,KAChB,gBAAAG,MAACJ,MAAA,EAAI,eAAc,UAAS,WAAW,GACrC;AAAA,sBAAAG,KAACF,OAAA,EAAK,OAAM,OAAM,8BAAgB;AAAA,MAClC,gBAAAG,MAACJ,MAAA,EAAI,YAAY,GAAG,eAAc,UAC/B;AAAA,gBAAQ,QACN,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,EACxB,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,WACJ,gBAAAI,MAACH,OAAA,EAA8B,OAAM,OAAM;AAAA;AAAA,UACtC,OAAO,OAAO;AAAA,UAAK;AAAA,UAAG,OAAO;AAAA,aADvB,OAAO,OAAO,IAEzB,CACD;AAAA,QACF,QAAQ,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,SAAS,KAClD,gBAAAG,MAACH,OAAA,EAAK,OAAM,QAAO,UAAQ,MAAC;AAAA;AAAA,UACjB,QAAQ,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,SAAS;AAAA,UAAE;AAAA,WAChE;AAAA,SAEJ;AAAA,OACF;AAAA,IAGD,CAAC,YACA,gBAAAE,KAACH,MAAA,EAAI,WAAW,GACd,0BAAAG,KAACF,OAAA,EAAK,OAAM,QAAO,UAAQ,MAAC,mCAE5B,GACF;AAAA,KAEJ;AAEJ;;;AC1HA,SAAS,YAAAI,WAAU,mBAAmB;AAGtC,IAAM,aAA2B;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,UAAU,cAA0B,QAAQ;AAC1D,QAAM,CAAC,MAAM,OAAO,IAAIA,UAAqB,WAAW;AAExD,QAAM,WAAW,YAAY,MAAM;AACjC,UAAM,eAAe,WAAW,QAAQ,IAAI;AAC5C,QAAI,eAAe,WAAW,SAAS,GAAG;AACxC,cAAQ,WAAW,eAAe,CAAC,CAAC;AAAA,IACtC;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,QAAM,WAAW,YAAY,MAAM;AACjC,UAAM,eAAe,WAAW,QAAQ,IAAI;AAC5C,QAAI,eAAe,GAAG;AACpB,cAAQ,WAAW,eAAe,CAAC,CAAC;AAAA,IACtC;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,QAAM,WAAW,YAAY,CAAC,YAAwB;AACpD,YAAQ,OAAO;AAAA,EACjB,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACzCA,SAAS,eAAe;AAExB,IAAI,UAA0B;AAKvB,SAAS,WAAW,OAAyB;AAClD,QAAM,YAAY,SAAS,QAAQ,IAAI;AAEvC,YAAU,IAAI,QAAQ;AAAA,IACpB,MAAM;AAAA,EACR,CAAC;AAED,SAAO;AACT;AAYA,eAAsB,iBAAiB,OAAe,MAA+B;AACnF,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,EAAE,KAAK,IAAI,MAAM,QAAQ,MAAM,IAAI,EAAE,OAAO,KAAK,CAAC;AACxD,WAAO,KAAK;AAAA,EACd,SAAS,OAAO;AACd,YAAQ,MAAM,kCAAkC,KAAK;AACrD,WAAO;AAAA,EACT;AACF;;;AC7BA,eAAsB,cACpB,OACA,eACA,eACmB;AACnB,MAAI,WAAqB,CAAC;AAE1B,MAAI,UAAU,WAAW,UAAU,QAAQ;AACzC,UAAM,gBAAgB,MAAM,iBAAiB,eAAe,aAAa;AACzE,eAAW,CAAC,GAAG,UAAU,GAAG,aAAa;AAAA,EAC3C;AAEA,MAAI,UAAU,YAAY,UAAU,QAAQ;AAC1C,UAAM,iBAAiB,MAAM,kBAAkB,aAAa;AAG5D,QAAI,UAAU,QAAQ;AACpB,iBAAW,gBAAgB,gBAAgB;AACzC,cAAM,gBAAgB,SAAS;AAAA,UAC7B,CAAC,MAAM,EAAE,SAAS,aAAa;AAAA,QACjC;AACA,YAAI,iBAAiB,GAAG;AAEtB,mBAAS,aAAa,EAAE,WAAW;AAAA,QACrC,OAAO;AAEL,mBAAS,KAAK,YAAY;AAAA,QAC5B;AAAA,MACF;AAAA,IACF,OAAO;AACL,iBAAW;AAAA,IACb;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,eACd,UACA,SACU;AACV,MAAI,WAAW,CAAC,GAAG,QAAQ;AAG3B,aAAW,SAAS,OAAO,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC,EAAE,eAAe;AAGtE,QAAM,aACJ,QAAQ,UAAU,QAAQ,SAAS,QAAQ,WAAW,QAAQ;AAEhE,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAGA,aAAW,SAAS,OAAO,CAAC,WAAW;AACrC,UAAM,UAAqB,CAAC;AAE5B,QAAI,QAAQ,QAAQ;AAClB,cAAQ,KAAK,OAAO,QAAQ;AAAA,IAC9B;AAEA,QAAI,QAAQ,OAAO;AACjB,cAAQ,KAAK,YAAY,OAAO,gBAAgB,QAAQ,SAAS,CAAC;AAAA,IACpE;AAEA,QAAI,QAAQ,KAAK;AACf,cAAQ,KAAK,YAAY,OAAO,gBAAgB,QAAQ,OAAO,CAAC;AAAA,IAClE;AAEA,QAAI,QAAQ,WAAW,QAAQ,cAAc;AAC3C,cAAQ,KAAK,eAAe,OAAO,MAAM,QAAQ,YAAY,CAAC;AAAA,IAChE;AAGA,WAAO,QAAQ,KAAK,CAAC,MAAM,MAAM,IAAI;AAAA,EACvC,CAAC;AAED,SAAO;AACT;AAKO,SAAS,eAAe,YAAoB,SAA0B;AAG3E,QAAM,eAAe,QAClB,QAAQ,qBAAqB,MAAM,EACnC,QAAQ,OAAO,IAAI,EACnB,QAAQ,OAAO,GAAG;AAErB,QAAM,QAAQ,IAAI,OAAO,IAAI,YAAY,KAAK,GAAG;AACjD,SAAO,MAAM,KAAK,UAAU;AAC9B;;;AbmEM,gBAAAC,MACE,QAAAC,aADF;AA/IC,SAAS,IAAI,EAAE,SAAAC,SAAQ,GAAa;AACzC,QAAM,EAAE,MAAM,SAAS,IAAI,UAAU,MAAM;AAG3C,QAAM,CAAC,UAAU,WAAW,IAAIC,UAA0B,IAAI;AAC9D,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAsB,MAAM;AACtD,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAwB;AAAA,IACpD,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,IACT,cAAc;AAAA,IACd,KAAK;AAAA,IACL,SAAS;AAAA,EACX,CAAC;AACD,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAmB,CAAC,CAAC;AAC3D,QAAM,CAAC,kBAAkB,mBAAmB,IAAIA,UAAmB,CAAC,CAAC;AACrE,QAAM,CAAC,kBAAkB,mBAAmB,IAAIA,UAAmB,CAAC,CAAC;AACrE,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,UAAiC,IAAI;AACnF,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAwB,IAAI;AACtD,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,UAAS,iBAAiB;AACtE,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,UAAS,KAAK;AAG1D,EAAAC,WAAU,MAAM;AACd,UAAM,aAAa,YAAY;AAC7B,UAAI;AAEF,gBAAQ;AAGR,cAAM,SAAS,MAAM,UAAU;AAC/B,YAAI,CAAC,QAAQ;AACX,mBAAS,oEAAoE;AAC7E;AAAA,QACF;AAGA,YAAIF,SAAQ,SAAS,QAAQ,IAAI,cAAc;AAC7C,qBAAWA,SAAQ,KAAK;AAAA,QAC1B;AAGA,0BAAkB,yBAAyB;AAC3C,YAAI,OAAO,MAAM,YAAY;AAE7B,YAAI,MAAM,aAAaA,SAAQ,SAAS,QAAQ,IAAI,eAAe;AAEjE,4BAAkB,yCAAyC;AAC3D,gBAAM,gBAAgB,MAAM,iBAAiB,KAAK,OAAO,KAAK,IAAI;AAClE,iBAAO,EAAE,GAAG,MAAM,cAAc;AAAA,QAClC;AAEA,oBAAY,IAAI;AAChB,iBAAS,OAAO;AAAA,MAClB,SAAS,KAAK;AACZ,iBAAS,eAAe,QAAQ,IAAI,UAAU,wBAAwB;AAAA,MACxE;AAAA,IACF;AAEA,eAAW;AAAA,EACb,GAAG,CAACA,SAAQ,OAAO,QAAQ,CAAC;AAG5B,QAAM,oBAAoBG,aAAY,CAAC,kBAA+B;AACpE,aAAS,aAAa;AACtB,aAAS,UAAU;AAAA,EACrB,GAAG,CAAC,QAAQ,CAAC;AAGb,QAAM,uBAAuBA,aAAY,OAAO,oBAAmC;AACjF,eAAW,eAAe;AAC1B,aAAS,SAAS;AAClB,sBAAkB,sBAAsB;AAExC,QAAI;AACF,UAAI,CAAC,UAAU;AACb,cAAM,IAAI,MAAM,+BAA+B;AAAA,MACjD;AAGA,YAAM,WAAW,MAAM;AAAA,QACrB;AAAA,QACA,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AACA,qBAAe,QAAQ;AAGvB,wBAAkB,uBAAuB;AACzC,YAAM,WAAW,eAAe,UAAU,eAAe;AACzD,0BAAoB,QAAQ;AAE5B,eAAS,QAAQ;AAAA,IACnB,SAAS,KAAK;AACZ,eAAS,eAAe,QAAQ,IAAI,UAAU,0BAA0B;AAAA,IAC1E;AAAA,EACF,GAAG,CAAC,UAAU,OAAO,QAAQ,CAAC;AAG9B,QAAM,qBAAqBA,aAAY,CAAC,aAAuB;AAC7D,wBAAoB,QAAQ;AAC5B,aAAS,SAAS;AAAA,EACpB,GAAG,CAAC,QAAQ,CAAC;AAGb,QAAM,gBAAgBA,aAAY,MAAM;AACtC,aAAS,SAAS;AAAA,EACpB,GAAG,CAAC,QAAQ,CAAC;AAGb,QAAM,yBAAyBA,aAAY,CAAC,YAA6B;AACvE,uBAAmB,OAAO;AAC1B,aAAS,SAAS;AAAA,EACpB,GAAG,CAAC,QAAQ,CAAC;AAGb,QAAM,sBAAsBA,aAAY,MAAM;AAC5C,sBAAkB,IAAI;AACtB,uBAAmB,IAAI;AACvB,aAAS,SAAS;AAAA,EACpB,GAAG,CAAC,QAAQ,CAAC;AAGb,QAAM,aAAaA,aAAY,MAAM;AACnC,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,iBAAS,OAAO;AAChB;AAAA,MACF,KAAK;AACH,iBAAS,UAAU;AACnB;AAAA,MACF,KAAK;AACH,iBAAS,QAAQ;AACjB;AAAA,MACF;AACE;AAAA,IACJ;AAAA,EACF,GAAG,CAAC,MAAM,QAAQ,CAAC;AAGnB,MAAI,OAAO;AACT,WACE,gBAAAL,KAACM,MAAA,EAAI,eAAc,UAAS,SAAS,GACnC,0BAAAL,MAACM,OAAA,EAAK,OAAM,OAAM,MAAI,MAAC;AAAA;AAAA,MACb;AAAA,OACV,GACF;AAAA,EAEJ;AAGA,SACE,gBAAAN,MAACK,MAAA,EAAI,eAAc,UAAS,SAAS,GACnC;AAAA,oBAAAN,KAAC,UAAO,UAAoB;AAAA,IAE3B,SAAS,UACR,gBAAAA,KAACM,MAAA,EAAI,KAAK,GACR,0BAAAN,KAACQ,UAAA,EAAQ,OAAO,gBAAgB,GAClC;AAAA,IAGD,SAAS,aACR,gBAAAR,KAACM,MAAA,EAAI,KAAK,GACR,0BAAAN,KAACQ,UAAA,EAAQ,OAAO,gBAAgB,GAClC;AAAA,IAGD,SAAS,WAAW,gBAAAR,KAAC,aAAU,UAAU,mBAAmB;AAAA,IAE5D,SAAS,cACR,gBAAAA,KAAC,gBAAa,UAAU,sBAAsB,QAAQ,YAAY;AAAA,IAGnE,SAAS,YACR,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,UAAU;AAAA,QACV,UAAU;AAAA,QACV,QAAQ;AAAA;AAAA,IACV;AAAA,IAGD,SAAS,aACR,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,UAAU;AAAA,QACV,UAAU,CAACE,SAAQ;AAAA,QACnB,WAAW;AAAA,QACX,UAAU;AAAA;AAAA,IACZ;AAAA,IAGD,SAAS,aACR,gBAAAF;AAAA,MAAC;AAAA;AAAA,QACC,UAAU;AAAA,QACV,UAAU,CAACE,SAAQ,WAAW,CAAC;AAAA,QAC/B,YAAY;AAAA;AAAA,IACd;AAAA,IAGD,SAAS,aAAa,mBACrB,gBAAAF;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,UAAU,CAACE,SAAQ,WAAW,CAAC;AAAA,QAC/B,iBAAiB;AAAA;AAAA,IACnB;AAAA,KAEJ;AAEJ;;;Ac/OA,SAAS,eAAe;AAGjB,SAAS,YAAwB;AACtC,QAAM,UAAU,IAAI,QAAQ;AAE5B,UACG,KAAK,UAAU,EACf,YAAY,0DAA0D,EACtE,QAAQ,OAAO,EACf,OAAO,iBAAiB,oDAAoD,KAAK,EACjF,OAAO,aAAa,0CAA0C,KAAK,EACnE,OAAO,uBAAuB,wDAAwD,EACtF,MAAM;AAET,QAAM,OAAO,QAAQ,KAAK;AAE1B,SAAO;AAAA,IACL,SAAS,KAAK,WAAW;AAAA,IACzB,KAAK,KAAK,OAAO;AAAA,IACjB,OAAO,KAAK;AAAA,EACd;AACF;;;AfZO,gBAAAO,YAAA;AAHP,IAAM,UAAU,UAAU;AAG1B,OAAO,gBAAAA,KAAC,OAAI,SAAkB,CAAE;","names":["useState","useEffect","useCallback","Box","Text","Spinner","Box","Text","jsx","jsxs","options","Box","Text","jsx","jsxs","options","Box","Text","useState","Box","Text","useInput","MultiSelect","jsx","jsxs","useState","options","useInput","Box","Text","MultiSelect","Box","Text","useInput","jsx","jsxs","useState","Box","Text","jsx","jsxs","useState","Box","Text","Box","Text","useInput","jsx","jsxs","useState","jsx","jsxs","options","useState","useEffect","useCallback","Box","Text","Spinner","jsx"]}
1
+ {"version":3,"sources":["../src/index.tsx","../src/app.tsx","../src/components/Header.tsx","../src/components/ScopeStep.tsx","../src/components/CriteriaStep.tsx","../src/utils/config.ts","../src/components/BranchSelectStep.tsx","../src/utils/date.ts","../src/components/ConfirmStep.tsx","../src/components/ExecutionStep.tsx","../src/services/git.ts","../src/components/SummaryStep.tsx","../src/hooks/useWizard.ts","../src/services/github.ts","../src/services/branch-analyzer.ts","../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport React from 'react';\nimport { render } from 'ink';\nimport { App } from './app.js';\nimport { createCLI } from './cli.js';\n\n// Parse CLI arguments\nconst options = createCLI();\n\n// Render the app\nrender(<App options={options} />);\n","import React, { useState, useEffect, useCallback } from 'react';\nimport { Box, Text } from 'ink';\nimport { Spinner } from '@inkjs/ui';\n\nimport { Header } from './components/Header.js';\nimport { ScopeStep } from './components/ScopeStep.js';\nimport { CriteriaStep } from './components/CriteriaStep.js';\nimport { BranchSelectStep } from './components/BranchSelectStep.js';\nimport { ConfirmStep } from './components/ConfirmStep.js';\nimport { ExecutionStep } from './components/ExecutionStep.js';\nimport { SummaryStep } from './components/SummaryStep.js';\n\nimport { useWizard } from './hooks/useWizard.js';\nimport { initGit, isGitRepo, getRepoInfo } from './services/git.js';\nimport { initGitHub, getDefaultBranch } from './services/github.js';\nimport { fetchBranches, filterBranches } from './services/branch-analyzer.js';\n\nimport type {\n RepoInfo,\n BranchScope,\n FilterOptions,\n Branch,\n DeletionSummary,\n CLIOptions,\n} from './types/index.js';\nimport { DEFAULT_STALE_DAYS, DEFAULT_AGE_DAYS } from './utils/config.js';\n\ninterface AppProps {\n options: CLIOptions;\n}\n\nexport function App({ options }: AppProps) {\n const { step, goToStep } = useWizard('init');\n\n // State\n const [repoInfo, setRepoInfo] = useState<RepoInfo | null>(null);\n const [scope, setScope] = useState<BranchScope>('both');\n const [filters, setFilters] = useState<FilterOptions>({\n merged: false,\n stale: false,\n staleDays: DEFAULT_STALE_DAYS,\n pattern: false,\n patternValue: '',\n age: false,\n ageDays: DEFAULT_AGE_DAYS,\n });\n const [allBranches, setAllBranches] = useState<Branch[]>([]);\n const [filteredBranches, setFilteredBranches] = useState<Branch[]>([]);\n const [selectedBranches, setSelectedBranches] = useState<Branch[]>([]);\n const [deletionSummary, setDeletionSummary] = useState<DeletionSummary | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [loadingMessage, setLoadingMessage] = useState('Initializing...');\n const [executeForReal, setExecuteForReal] = useState(false);\n\n // Initialize on mount\n useEffect(() => {\n const initialize = async () => {\n try {\n // Initialize git\n initGit();\n\n // Check if we're in a git repo\n const isRepo = await isGitRepo();\n if (!isRepo) {\n setError('Not a git repository. Please run this command in a git repository.');\n return;\n }\n\n // Initialize GitHub if token is provided\n if (options.token || process.env.GITHUB_TOKEN) {\n initGitHub(options.token);\n }\n\n // Get repo info\n setLoadingMessage('Detecting repository...');\n let info = await getRepoInfo();\n\n if (info?.isGitHub && (options.token || process.env.GITHUB_TOKEN)) {\n // Get default branch from GitHub API\n setLoadingMessage('Fetching repository info from GitHub...');\n const defaultBranch = await getDefaultBranch(info.owner, info.repo);\n info = { ...info, defaultBranch };\n }\n\n setRepoInfo(info);\n goToStep('scope');\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Unknown error occurred');\n }\n };\n\n initialize();\n }, [options.token, goToStep]);\n\n // Handle scope selection\n const handleScopeSelect = useCallback((selectedScope: BranchScope) => {\n setScope(selectedScope);\n goToStep('criteria');\n }, [goToStep]);\n\n // Handle criteria selection\n const handleCriteriaSelect = useCallback(async (selectedFilters: FilterOptions) => {\n setFilters(selectedFilters);\n goToStep('loading');\n setLoadingMessage('Fetching branches...');\n\n try {\n if (!repoInfo) {\n throw new Error('Repository info not available');\n }\n\n // Fetch branches\n const branches = await fetchBranches(\n scope,\n repoInfo.defaultBranch,\n repoInfo.currentBranch\n );\n setAllBranches(branches);\n\n // Apply filters\n setLoadingMessage('Analyzing branches...');\n const filtered = filterBranches(branches, selectedFilters);\n setFilteredBranches(filtered);\n\n goToStep('select');\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to fetch branches');\n }\n }, [repoInfo, scope, goToStep]);\n\n // Handle branch selection\n const handleBranchSelect = useCallback((selected: Branch[]) => {\n setSelectedBranches(selected);\n goToStep('confirm');\n }, [goToStep]);\n\n // Handle confirmation\n const handleConfirm = useCallback(() => {\n goToStep('execute');\n }, [goToStep]);\n\n // Handle deletion complete\n const handleDeletionComplete = useCallback((summary: DeletionSummary) => {\n setDeletionSummary(summary);\n goToStep('summary');\n }, [goToStep]);\n\n // Handle delete for real after dry run\n const handleDeleteForReal = useCallback(() => {\n setExecuteForReal(true);\n setDeletionSummary(null);\n goToStep('execute');\n }, [goToStep]);\n\n // Handle cancel/back\n const handleBack = useCallback(() => {\n switch (step) {\n case 'criteria':\n goToStep('scope');\n break;\n case 'select':\n goToStep('criteria');\n break;\n case 'confirm':\n goToStep('select');\n break;\n default:\n break;\n }\n }, [step, goToStep]);\n\n // Render error state\n if (error) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Text color=\"red\" bold>\n Error: {error}\n </Text>\n </Box>\n );\n }\n\n // Render based on current step\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Header repoInfo={repoInfo} />\n\n {step === 'init' && (\n <Box gap={1}>\n <Spinner label={loadingMessage} />\n </Box>\n )}\n\n {step === 'loading' && (\n <Box gap={1}>\n <Spinner label={loadingMessage} />\n </Box>\n )}\n\n {step === 'scope' && <ScopeStep onSelect={handleScopeSelect} />}\n\n {step === 'criteria' && (\n <CriteriaStep onSelect={handleCriteriaSelect} onBack={handleBack} />\n )}\n\n {step === 'select' && (\n <BranchSelectStep\n branches={filteredBranches}\n onSelect={handleBranchSelect}\n onBack={handleBack}\n />\n )}\n\n {step === 'confirm' && (\n <ConfirmStep\n branches={selectedBranches}\n isDryRun={!options.execute}\n onConfirm={handleConfirm}\n onCancel={handleBack}\n />\n )}\n\n {step === 'execute' && (\n <ExecutionStep\n branches={selectedBranches}\n isDryRun={!options.execute && !executeForReal}\n onComplete={handleDeletionComplete}\n />\n )}\n\n {step === 'summary' && deletionSummary && (\n <SummaryStep\n summary={deletionSummary}\n isDryRun={!options.execute && !executeForReal}\n onDeleteForReal={handleDeleteForReal}\n />\n )}\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport type { RepoInfo } from '../types/index.js';\n\ninterface HeaderProps {\n repoInfo: RepoInfo | null;\n}\n\nexport function Header({ repoInfo }: HeaderProps) {\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor=\"cyan\"\n paddingX={2}\n paddingY={0}\n marginBottom={1}\n >\n <Box>\n <Text color=\"cyan\" bold>\n git-tidy\n </Text>\n <Text color=\"gray\"> - Branch Cleanup Tool</Text>\n </Box>\n\n {repoInfo && (\n <Box gap={2}>\n <Text color=\"gray\">\n Repository:{' '}\n <Text color=\"white\">\n {repoInfo.owner}/{repoInfo.repo}\n </Text>\n </Text>\n <Text color=\"gray\">\n Branch:{' '}\n <Text color=\"green\">{repoInfo.currentBranch}</Text>\n </Text>\n <Text color=\"gray\">\n Default:{' '}\n <Text color=\"yellow\">{repoInfo.defaultBranch}</Text>\n </Text>\n </Box>\n )}\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport { Select } from '@inkjs/ui';\nimport type { BranchScope } from '../types/index.js';\n\ninterface ScopeStepProps {\n onSelect: (scope: BranchScope) => void;\n}\n\nexport function ScopeStep({ onSelect }: ScopeStepProps) {\n const options = [\n {\n label: 'Both local and remote branches',\n value: 'both' as BranchScope,\n },\n {\n label: 'Local branches only',\n value: 'local' as BranchScope,\n },\n {\n label: 'Remote branches only',\n value: 'remote' as BranchScope,\n },\n ];\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text color=\"cyan\" bold>\n Step 1:\n </Text>\n <Text> What would you like to clean up?</Text>\n </Box>\n\n <Box marginLeft={2}>\n <Select\n options={options}\n onChange={(value) => onSelect(value as BranchScope)}\n />\n </Box>\n\n <Box marginTop={1}>\n <Text color=\"gray\" dimColor>\n Use ↑↓ to navigate, Enter to select\n </Text>\n </Box>\n </Box>\n );\n}\n","import React, { useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { MultiSelect, TextInput } from '@inkjs/ui';\nimport type { FilterOptions, FilterCriteria } from '../types/index.js';\nimport { DEFAULT_STALE_DAYS, DEFAULT_AGE_DAYS } from '../utils/config.js';\n\ninterface CriteriaStepProps {\n onSelect: (filters: FilterOptions) => void;\n onBack: () => void;\n}\n\ntype InputMode = 'select' | 'staleDays' | 'ageDays' | 'pattern';\n\nexport function CriteriaStep({ onSelect, onBack }: CriteriaStepProps) {\n const [selectedCriteria, setSelectedCriteria] = useState<FilterCriteria[]>([]);\n const [inputMode, setInputMode] = useState<InputMode>('select');\n const [staleDays, setStaleDays] = useState(String(DEFAULT_STALE_DAYS));\n const [ageDays, setAgeDays] = useState(String(DEFAULT_AGE_DAYS));\n const [pattern, setPattern] = useState('feature/*');\n const [inputError, setInputError] = useState<string | null>(null);\n\n // Validate numeric input\n const validateNumber = (value: string): number | null => {\n const num = parseInt(value, 10);\n if (isNaN(num) || num <= 0) {\n return null;\n }\n return num;\n };\n\n const options = [\n {\n label: 'Merged branches (already merged into default branch)',\n value: 'merged' as FilterCriteria,\n },\n {\n label: `Stale branches (no commits in ${staleDays} days)`,\n value: 'stale' as FilterCriteria,\n },\n {\n label: `Branches older than ${ageDays} days`,\n value: 'age' as FilterCriteria,\n },\n {\n label: `Pattern matching: ${pattern}`,\n value: 'pattern' as FilterCriteria,\n },\n ];\n\n useInput((input, key) => {\n if (key.escape) {\n if (inputMode !== 'select') {\n setInputMode('select');\n } else {\n onBack();\n }\n }\n\n // Handle Enter to submit when in select mode\n if (key.return && inputMode === 'select') {\n handleSubmit();\n }\n });\n\n const handleCriteriaChange = (values: string[]) => {\n setSelectedCriteria(values as FilterCriteria[]);\n };\n\n const handleSubmit = () => {\n // Check if we need additional input\n if (selectedCriteria.includes('stale') && inputMode === 'select') {\n setInputMode('staleDays');\n return;\n }\n if (selectedCriteria.includes('age') && inputMode === 'staleDays') {\n setInputMode('ageDays');\n return;\n }\n if (selectedCriteria.includes('pattern') && inputMode === 'ageDays') {\n setInputMode('pattern');\n return;\n }\n if (selectedCriteria.includes('pattern') && inputMode === 'select') {\n setInputMode('pattern');\n return;\n }\n\n // All inputs collected, proceed\n const filters: FilterOptions = {\n merged: selectedCriteria.includes('merged'),\n stale: selectedCriteria.includes('stale'),\n staleDays: parseInt(staleDays, 10) || DEFAULT_STALE_DAYS,\n pattern: selectedCriteria.includes('pattern'),\n patternValue: pattern,\n age: selectedCriteria.includes('age'),\n ageDays: parseInt(ageDays, 10) || DEFAULT_AGE_DAYS,\n };\n\n onSelect(filters);\n };\n\n if (inputMode === 'staleDays') {\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"cyan\">How many days without commits is considered stale?</Text>\n <Box>\n <TextInput\n defaultValue={staleDays}\n onSubmit={(value) => {\n const num = validateNumber(value);\n if (num === null) {\n setInputError('Please enter a valid number greater than 0');\n return;\n }\n setInputError(null);\n setStaleDays(String(num));\n if (selectedCriteria.includes('age')) {\n setInputMode('ageDays');\n } else if (selectedCriteria.includes('pattern')) {\n setInputMode('pattern');\n } else {\n handleSubmit();\n }\n }}\n />\n <Text color=\"gray\"> days</Text>\n </Box>\n {inputError && <Text color=\"red\">{inputError}</Text>}\n </Box>\n );\n }\n\n if (inputMode === 'ageDays') {\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"cyan\">How many days old should a branch be?</Text>\n <Box>\n <TextInput\n defaultValue={ageDays}\n onSubmit={(value) => {\n const num = validateNumber(value);\n if (num === null) {\n setInputError('Please enter a valid number greater than 0');\n return;\n }\n setInputError(null);\n setAgeDays(String(num));\n if (selectedCriteria.includes('pattern')) {\n setInputMode('pattern');\n } else {\n handleSubmit();\n }\n }}\n />\n <Text color=\"gray\"> days</Text>\n </Box>\n {inputError && <Text color=\"red\">{inputError}</Text>}\n </Box>\n );\n }\n\n if (inputMode === 'pattern') {\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Text color=\"cyan\">Enter branch name pattern (use * as wildcard):</Text>\n <TextInput\n defaultValue={pattern}\n onSubmit={(value) => {\n setPattern(value);\n const filters: FilterOptions = {\n merged: selectedCriteria.includes('merged'),\n stale: selectedCriteria.includes('stale'),\n staleDays: parseInt(staleDays, 10) || DEFAULT_STALE_DAYS,\n pattern: selectedCriteria.includes('pattern'),\n patternValue: value,\n age: selectedCriteria.includes('age'),\n ageDays: parseInt(ageDays, 10) || DEFAULT_AGE_DAYS,\n };\n onSelect(filters);\n }}\n />\n <Text color=\"gray\" dimColor>\n Examples: feature/*, hotfix/*, *-old, test-*\n </Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text color=\"cyan\" bold>\n Step 2:\n </Text>\n <Text> Which branches should be included? (select multiple)</Text>\n </Box>\n\n <Box marginLeft={2}>\n <MultiSelect\n options={options}\n onChange={handleCriteriaChange}\n />\n </Box>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"gray\" dimColor>\n Use ↑↓ to navigate, Space to toggle, Enter to confirm\n </Text>\n <Text color=\"gray\" dimColor>\n Press Esc to go back\n </Text>\n </Box>\n\n {selectedCriteria.length > 0 && (\n <Box marginTop={1}>\n <Text color=\"green\">\n Press Enter to continue with {selectedCriteria.length} filter(s)\n </Text>\n </Box>\n )}\n </Box>\n );\n}\n","// Default configuration values\nexport const DEFAULT_STALE_DAYS = 30;\nexport const DEFAULT_AGE_DAYS = 60;\n\n// Protected branch patterns (in addition to auto-detected default branch)\nexport const PROTECTED_PATTERNS = [\n 'main',\n 'master',\n 'develop',\n 'development',\n 'staging',\n 'production',\n 'release/*',\n];\n\n/**\n * Check if a branch name matches any protected pattern\n */\nexport function matchesProtectedPattern(branchName: string): boolean {\n return PROTECTED_PATTERNS.some((pattern) => {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2);\n return branchName.startsWith(prefix + '/');\n }\n return branchName === pattern;\n });\n}\n","import React, { useState, useMemo } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { MultiSelect } from '@inkjs/ui';\nimport type { Branch } from '../types/index.js';\nimport { formatDaysAgo } from '../utils/date.js';\n\ninterface BranchSelectStepProps {\n branches: Branch[];\n onSelect: (selected: Branch[]) => void;\n onBack: () => void;\n}\n\nexport function BranchSelectStep({\n branches,\n onSelect,\n onBack,\n}: BranchSelectStepProps) {\n const [selectedValues, setSelectedValues] = useState<string[]>([]);\n const [selectKey, setSelectKey] = useState(0);\n\n // Create options for MultiSelect\n const options = useMemo(() => {\n return branches.map((branch) => {\n const location = branch.isLocal && branch.isRemote\n ? 'local+remote'\n : branch.isLocal\n ? 'local'\n : 'remote';\n\n const status = branch.isMerged ? 'merged' : 'not merged';\n const age = formatDaysAgo(branch.lastCommitDate);\n\n return {\n label: `${branch.name}`,\n value: branch.name,\n hint: `(${status}, ${age}, ${location})`,\n };\n });\n }, [branches]);\n\n useInput((input, key) => {\n if (key.escape) {\n onBack();\n return;\n }\n\n // Submit on Enter\n if (key.return && selectedValues.length > 0) {\n const selected = branches.filter((b) => selectedValues.includes(b.name));\n onSelect(selected);\n return;\n }\n\n // Select all\n if (input === 'a') {\n setSelectedValues(branches.map((b) => b.name));\n setSelectKey(k => k + 1);\n }\n\n // Select none\n if (input === 'n') {\n setSelectedValues([]);\n setSelectKey(k => k + 1);\n }\n\n // Invert selection\n if (input === 'i') {\n const inverted = branches\n .filter((b) => !selectedValues.includes(b.name))\n .map((b) => b.name);\n setSelectedValues(inverted);\n setSelectKey(k => k + 1);\n }\n });\n\n const handleChange = (values: string[]) => {\n setSelectedValues(values);\n };\n\n const handleSubmit = () => {\n const selected = branches.filter((b) => selectedValues.includes(b.name));\n onSelect(selected);\n };\n\n if (branches.length === 0) {\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text color=\"cyan\" bold>\n Step 3:\n </Text>\n <Text> Select branches to delete</Text>\n </Box>\n <Box marginLeft={2}>\n <Text color=\"yellow\">No branches match your criteria.</Text>\n </Box>\n <Text color=\"gray\" dimColor>\n Press Esc to go back and adjust filters\n </Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text color=\"cyan\" bold>\n Step 3:\n </Text>\n <Text> Select branches to delete ({branches.length} found)</Text>\n </Box>\n\n <Box marginLeft={2} gap={2}>\n <Text color=\"gray\">[a] Select all</Text>\n <Text color=\"gray\">[n] Select none</Text>\n <Text color=\"gray\">[i] Invert</Text>\n </Box>\n\n <Box marginLeft={2} flexDirection=\"column\">\n <MultiSelect\n key={selectKey}\n options={options}\n defaultValue={selectedValues}\n onChange={handleChange}\n />\n </Box>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text color=\"gray\" dimColor>\n ↑↓ navigate, Space toggle, Enter confirm, Esc back\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <Text color={selectedValues.length > 0 ? 'green' : 'gray'}>\n {selectedValues.length} branch(es) selected\n </Text>\n {selectedValues.length > 0 && (\n <Text color=\"gray\"> - Press Enter to continue</Text>\n )}\n </Box>\n </Box>\n );\n}\n","/**\n * Calculate the number of days between a date and now\n */\nexport function daysAgo(date: Date): number {\n const now = new Date();\n const diffTime = Math.abs(now.getTime() - date.getTime());\n const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));\n return diffDays;\n}\n\n/**\n * Format a date as a human-readable \"X days ago\" string\n */\nexport function formatDaysAgo(date: Date): string {\n const days = daysAgo(date);\n\n if (days === 0) {\n return 'today';\n } else if (days === 1) {\n return '1 day ago';\n } else if (days < 7) {\n return `${days} days ago`;\n } else if (days < 30) {\n const weeks = Math.floor(days / 7);\n return weeks === 1 ? '1 week ago' : `${weeks} weeks ago`;\n } else if (days < 365) {\n const months = Math.floor(days / 30);\n return months === 1 ? '1 month ago' : `${months} months ago`;\n } else {\n const years = Math.floor(days / 365);\n return years === 1 ? '1 year ago' : `${years} years ago`;\n }\n}\n\n/**\n * Check if a date is older than X days\n */\nexport function isOlderThan(date: Date, days: number): boolean {\n return daysAgo(date) > days;\n}\n","import React from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport type { Branch } from '../types/index.js';\n\ninterface ConfirmStepProps {\n branches: Branch[];\n isDryRun: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n}\n\nexport function ConfirmStep({\n branches,\n isDryRun,\n onConfirm,\n onCancel,\n}: ConfirmStepProps) {\n const localCount = branches.filter((b) => b.isLocal).length;\n const remoteCount = branches.filter((b) => b.isRemote).length;\n\n useInput((input, key) => {\n if (key.return) {\n onConfirm();\n }\n if (key.escape || input === 'n' || input === 'N') {\n onCancel();\n }\n if (input === 'y' || input === 'Y') {\n onConfirm();\n }\n });\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text color=\"cyan\" bold>\n Step 4:\n </Text>\n <Text> Confirm deletion</Text>\n </Box>\n\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor=\"yellow\"\n paddingX={2}\n paddingY={1}\n marginY={1}\n >\n <Text bold>Ready to delete {branches.length} branch(es)</Text>\n\n <Box marginTop={1} gap={2}>\n <Text>\n Local: <Text color=\"cyan\">{localCount}</Text>\n </Text>\n <Text>\n Remote: <Text color=\"magenta\">{remoteCount}</Text>\n </Text>\n </Box>\n\n {isDryRun && (\n <Box marginTop={1}>\n <Text color=\"yellow\" bold>\n DRY RUN MODE - No branches will actually be deleted\n </Text>\n </Box>\n )}\n\n {!isDryRun && (\n <Box marginTop={1}>\n <Text color=\"red\" bold>\n WARNING: This will permanently delete these branches!\n </Text>\n </Box>\n )}\n </Box>\n\n <Box flexDirection=\"column\">\n <Text color=\"gray\">Branches to delete:</Text>\n <Box marginLeft={2} flexDirection=\"column\">\n {branches.slice(0, 10).map((branch) => (\n <Text key={branch.name} color=\"gray\">\n - {branch.name}{' '}\n <Text dimColor>\n ({branch.isLocal && 'local'}\n {branch.isLocal && branch.isRemote && ', '}\n {branch.isRemote && 'remote'})\n </Text>\n </Text>\n ))}\n {branches.length > 10 && (\n <Text color=\"gray\" dimColor>\n ... and {branches.length - 10} more\n </Text>\n )}\n </Box>\n </Box>\n\n <Box marginTop={1} gap={2}>\n <Text color=\"green\">[Enter/Y] Confirm</Text>\n <Text color=\"red\">[Esc/N] Cancel</Text>\n </Box>\n </Box>\n );\n}\n","import React, { useEffect, useState } from 'react';\nimport { Box, Text } from 'ink';\nimport { Spinner } from '@inkjs/ui';\nimport type { Branch, DeletionResult, DeletionSummary } from '../types/index.js';\nimport {\n deleteLocalBranch,\n deleteRemoteBranch as deleteRemoteBranchGit,\n} from '../services/git.js';\n\ninterface ExecutionStepProps {\n branches: Branch[];\n isDryRun: boolean;\n onComplete: (summary: DeletionSummary) => void;\n}\n\nexport function ExecutionStep({\n branches,\n isDryRun,\n onComplete,\n}: ExecutionStepProps) {\n const [currentIndex, setCurrentIndex] = useState(0);\n const [results, setResults] = useState<DeletionResult[]>([]);\n const [isDeleting, setIsDeleting] = useState(true);\n\n useEffect(() => {\n const deleteBranches = async () => {\n const allResults: DeletionResult[] = [];\n\n for (let i = 0; i < branches.length; i++) {\n const branch = branches[i];\n setCurrentIndex(i);\n\n const result: DeletionResult = {\n branch,\n success: true,\n deletedLocal: false,\n deletedRemote: false,\n };\n\n if (isDryRun) {\n // Simulate deletion in dry run mode\n await new Promise((resolve) => setTimeout(resolve, 100));\n result.deletedLocal = branch.isLocal;\n result.deletedRemote = branch.isRemote;\n } else {\n // Actually delete the branch\n try {\n if (branch.isLocal) {\n await deleteLocalBranch(branch.name, true);\n result.deletedLocal = true;\n }\n } catch (error) {\n result.success = false;\n result.error = `Local: ${error instanceof Error ? error.message : 'Unknown error'}`;\n }\n\n try {\n if (branch.isRemote) {\n await deleteRemoteBranchGit(branch.name);\n result.deletedRemote = true;\n }\n } catch (error) {\n if (!result.error) {\n result.success = false;\n result.error = `Remote: ${error instanceof Error ? error.message : 'Unknown error'}`;\n } else {\n result.error += `; Remote: ${error instanceof Error ? error.message : 'Unknown error'}`;\n }\n }\n }\n\n allResults.push(result);\n setResults([...allResults]);\n }\n\n setIsDeleting(false);\n\n // Create summary\n const summary: DeletionSummary = {\n total: branches.length,\n successful: allResults.filter((r) => r.success).length,\n failed: allResults.filter((r) => !r.success).length,\n skipped: 0,\n results: allResults,\n };\n\n // Small delay before completing to show final state\n await new Promise((resolve) => setTimeout(resolve, 500));\n onComplete(summary);\n };\n\n deleteBranches();\n }, [branches, isDryRun, onComplete]);\n\n const currentBranch = branches[currentIndex];\n const completedCount = results.length;\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text color=\"cyan\" bold>\n Step 5:\n </Text>\n <Text> {isDryRun ? 'Simulating deletion...' : 'Deleting branches...'}</Text>\n </Box>\n\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor=\"blue\"\n paddingX={2}\n paddingY={1}\n >\n {isDeleting && currentBranch && (\n <Box gap={1}>\n <Spinner label=\"\" />\n <Text>\n {isDryRun ? 'Processing' : 'Deleting'} {currentBranch.name}\n </Text>\n <Text color=\"gray\">\n ({completedCount + 1}/{branches.length})\n </Text>\n </Box>\n )}\n\n {!isDeleting && (\n <Text color=\"green\">\n {isDryRun ? 'Simulation' : 'Deletion'} complete!\n </Text>\n )}\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"gray\">Results:</Text>\n <Box marginLeft={2} flexDirection=\"column\">\n {results.slice(-8).map((result, index) => (\n <Box key={result.branch.name} gap={1}>\n <Text color={result.success ? 'green' : 'red'}>\n {result.success ? '✓' : '✗'}\n </Text>\n <Text color={result.success ? 'gray' : 'red'}>\n {result.branch.name}\n </Text>\n {result.deletedLocal && <Text color=\"cyan\" dimColor>(local)</Text>}\n {result.deletedRemote && <Text color=\"magenta\" dimColor>(remote)</Text>}\n {result.error && (\n <Text color=\"red\" dimColor>\n - {result.error}\n </Text>\n )}\n </Box>\n ))}\n {results.length > 8 && (\n <Text color=\"gray\" dimColor>\n ... and {results.length - 8} more\n </Text>\n )}\n </Box>\n </Box>\n </Box>\n );\n}\n","import simpleGit, { SimpleGit } from 'simple-git';\nimport type { Branch, RepoInfo } from '../types/index.js';\nimport { matchesProtectedPattern } from '../utils/config.js';\n\nlet git: SimpleGit;\n\n/**\n * Initialize git instance for the current directory\n */\nexport function initGit(cwd?: string): SimpleGit {\n git = simpleGit(cwd);\n return git;\n}\n\n/**\n * Check if current directory is a git repository\n */\nexport async function isGitRepo(): Promise<boolean> {\n try {\n await git.revparse(['--git-dir']);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get current branch name\n */\nexport async function getCurrentBranch(): Promise<string> {\n const result = await git.revparse(['--abbrev-ref', 'HEAD']);\n return result.trim();\n}\n\n/**\n * Get remote URL and extract owner/repo for GitHub\n */\nexport async function getRemoteInfo(): Promise<{ owner: string; repo: string; isGitHub: boolean } | null> {\n try {\n const remotes = await git.getRemotes(true);\n const origin = remotes.find((r) => r.name === 'origin');\n\n if (!origin?.refs?.fetch) {\n return null;\n }\n\n const url = origin.refs.fetch;\n\n // Parse GitHub URL (SSH or HTTPS)\n // SSH: git@github.com:owner/repo.git\n // HTTPS: https://github.com/owner/repo.git\n const sshMatch = url.match(/git@github\\.com:([^/]+)\\/(.+?)(?:\\.git)?$/);\n const httpsMatch = url.match(/https:\\/\\/github\\.com\\/([^/]+)\\/(.+?)(?:\\.git)?$/);\n\n const match = sshMatch || httpsMatch;\n if (match) {\n return {\n owner: match[1],\n repo: match[2],\n isGitHub: true,\n };\n }\n\n return { owner: '', repo: '', isGitHub: false };\n } catch {\n return null;\n }\n}\n\n/**\n * Get all local branches with their last commit dates\n */\nexport async function getLocalBranches(defaultBranch: string, currentBranch: string): Promise<Branch[]> {\n const branches: Branch[] = [];\n\n try {\n // Get all local branches\n const branchSummary = await git.branchLocal();\n\n for (const branchName of branchSummary.all) {\n // Get last commit date for this branch\n const logResult = await git.log({\n [branchName]: null,\n maxCount: 1,\n format: { date: '%aI' },\n });\n\n const lastCommitDate = logResult.latest?.date\n ? new Date(logResult.latest.date)\n : new Date();\n\n // Check if branch is merged into default branch\n const isMerged = await isBranchMerged(branchName, defaultBranch);\n\n // Check if protected\n const isProtected =\n branchName === defaultBranch || matchesProtectedPattern(branchName);\n\n branches.push({\n name: branchName,\n isLocal: true,\n isRemote: false,\n lastCommitDate,\n isMerged,\n isProtected,\n isCurrentBranch: branchName === currentBranch,\n });\n }\n } catch (error) {\n console.error('Error getting local branches:', error);\n }\n\n return branches;\n}\n\n/**\n * Get all remote branches\n */\nexport async function getRemoteBranches(defaultBranch: string): Promise<Branch[]> {\n const branches: Branch[] = [];\n\n try {\n // Fetch to ensure we have latest remote info\n await git.fetch(['--prune']);\n\n // Get all remote branches\n const result = await git.branch(['-r']);\n\n for (const branchName of result.all) {\n // Skip HEAD pointer\n if (branchName.includes('HEAD')) continue;\n\n // Remove 'origin/' prefix for display\n const shortName = branchName.replace(/^origin\\//, '');\n\n // Skip if it's the default branch\n if (shortName === defaultBranch) continue;\n\n // Get last commit date\n const logResult = await git.log({\n [branchName]: null,\n maxCount: 1,\n format: { date: '%aI' },\n });\n\n const lastCommitDate = logResult.latest?.date\n ? new Date(logResult.latest.date)\n : new Date();\n\n // Check if merged into default branch\n const isMerged = await isBranchMerged(branchName, `origin/${defaultBranch}`);\n\n // Check if protected\n const isProtected =\n shortName === defaultBranch || matchesProtectedPattern(shortName);\n\n branches.push({\n name: shortName,\n isLocal: false,\n isRemote: true,\n lastCommitDate,\n isMerged,\n isProtected,\n isCurrentBranch: false,\n });\n }\n } catch (error) {\n console.error('Error getting remote branches:', error);\n }\n\n return branches;\n}\n\n/**\n * Check if a branch is merged into the target branch\n */\nexport async function isBranchMerged(branch: string, target: string): Promise<boolean> {\n try {\n const result = await git.raw(['branch', '--merged', target]);\n const mergedBranches = result\n .split('\\n')\n .map((b) => b.trim().replace(/^\\*\\s*/, ''));\n return mergedBranches.includes(branch) || mergedBranches.includes(branch.replace(/^origin\\//, ''));\n } catch {\n return false;\n }\n}\n\n/**\n * Delete a local branch\n */\nexport async function deleteLocalBranch(branchName: string, force = false): Promise<void> {\n const flag = force ? '-D' : '-d';\n await git.branch([flag, branchName]);\n}\n\n/**\n * Delete a remote branch\n */\nexport async function deleteRemoteBranch(branchName: string, remote = 'origin'): Promise<void> {\n await git.push([remote, '--delete', branchName]);\n}\n\n/**\n * Get full repository info\n */\nexport async function getRepoInfo(defaultBranch?: string): Promise<RepoInfo | null> {\n try {\n const currentBranch = await getCurrentBranch();\n const remoteInfo = await getRemoteInfo();\n\n return {\n owner: remoteInfo?.owner || '',\n repo: remoteInfo?.repo || '',\n defaultBranch: defaultBranch || 'main',\n currentBranch,\n isGitHub: remoteInfo?.isGitHub || false,\n };\n } catch {\n return null;\n }\n}\n","import React from 'react';\nimport { Box, Text, useInput, useApp } from 'ink';\nimport type { DeletionSummary } from '../types/index.js';\n\ninterface SummaryStepProps {\n summary: DeletionSummary;\n isDryRun: boolean;\n onDeleteForReal?: () => void;\n}\n\nexport function SummaryStep({ summary, isDryRun, onDeleteForReal }: SummaryStepProps) {\n const { exit } = useApp();\n\n useInput((input, key) => {\n // Delete for real after dry run\n if (isDryRun && (input === 'd' || input === 'D')) {\n onDeleteForReal?.();\n return;\n }\n\n // Exit on any other key\n if (input === 'q' || input === 'Q' || key.escape) {\n exit();\n return;\n }\n\n // If not dry run, any key exits\n if (!isDryRun) {\n exit();\n }\n });\n\n const successColor = summary.successful > 0 ? 'green' : 'gray';\n const failedColor = summary.failed > 0 ? 'red' : 'gray';\n\n return (\n <Box flexDirection=\"column\" gap={1}>\n <Box>\n <Text color=\"cyan\" bold>\n {isDryRun ? 'Dry Run Complete!' : 'Cleanup Complete!'}\n </Text>\n </Box>\n\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={summary.failed > 0 ? 'yellow' : 'green'}\n paddingX={2}\n paddingY={1}\n >\n <Box flexDirection=\"column\" gap={0}>\n <Box gap={1}>\n <Text color={successColor}>✓</Text>\n <Text>\n {summary.successful} branch(es){' '}\n {isDryRun ? 'would be deleted' : 'deleted successfully'}\n </Text>\n </Box>\n\n {summary.failed > 0 && (\n <Box gap={1}>\n <Text color={failedColor}>✗</Text>\n <Text color={failedColor}>{summary.failed} branch(es) failed</Text>\n </Box>\n )}\n\n {summary.skipped > 0 && (\n <Box gap={1}>\n <Text color=\"gray\">○</Text>\n <Text color=\"gray\">{summary.skipped} branch(es) skipped</Text>\n </Box>\n )}\n </Box>\n </Box>\n\n {isDryRun && summary.successful > 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n <Box gap={2}>\n <Text color=\"red\" bold>[d] Delete for real</Text>\n <Text color=\"gray\">[q] Quit</Text>\n </Box>\n </Box>\n )}\n\n {isDryRun && summary.successful === 0 && (\n <Box marginTop={1}>\n <Text color=\"gray\" dimColor>\n Press any key to exit\n </Text>\n </Box>\n )}\n\n {summary.failed > 0 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"red\">Failed branches:</Text>\n <Box marginLeft={2} flexDirection=\"column\">\n {summary.results\n .filter((r) => !r.success)\n .slice(0, 5)\n .map((result) => (\n <Text key={result.branch.name} color=\"red\">\n - {result.branch.name}: {result.error}\n </Text>\n ))}\n {summary.results.filter((r) => !r.success).length > 5 && (\n <Text color=\"gray\" dimColor>\n ... and {summary.results.filter((r) => !r.success).length - 5} more\n </Text>\n )}\n </Box>\n </Box>\n )}\n\n {!isDryRun && (\n <Box marginTop={1}>\n <Text color=\"gray\" dimColor>\n Press any key to exit\n </Text>\n </Box>\n )}\n </Box>\n );\n}\n","import { useState, useCallback } from 'react';\nimport type { WizardStep } from '../types/index.js';\n\nconst STEP_ORDER: WizardStep[] = [\n 'init',\n 'scope',\n 'criteria',\n 'loading',\n 'select',\n 'confirm',\n 'execute',\n 'summary',\n];\n\nexport function useWizard(initialStep: WizardStep = 'init') {\n const [step, setStep] = useState<WizardStep>(initialStep);\n\n const nextStep = useCallback(() => {\n const currentIndex = STEP_ORDER.indexOf(step);\n if (currentIndex < STEP_ORDER.length - 1) {\n setStep(STEP_ORDER[currentIndex + 1]);\n }\n }, [step]);\n\n const prevStep = useCallback(() => {\n const currentIndex = STEP_ORDER.indexOf(step);\n if (currentIndex > 0) {\n setStep(STEP_ORDER[currentIndex - 1]);\n }\n }, [step]);\n\n const goToStep = useCallback((newStep: WizardStep) => {\n setStep(newStep);\n }, []);\n\n return {\n step,\n nextStep,\n prevStep,\n goToStep,\n };\n}\n","import { Octokit } from '@octokit/rest';\n\nlet octokit: Octokit | null = null;\n\n/**\n * Initialize GitHub API client with token\n */\nexport function initGitHub(token?: string): Octokit {\n const authToken = token || process.env.GITHUB_TOKEN;\n\n octokit = new Octokit({\n auth: authToken,\n });\n\n return octokit;\n}\n\n/**\n * Check if GitHub client is authenticated\n */\nexport function isAuthenticated(): boolean {\n return octokit !== null;\n}\n\n/**\n * Get the default branch for a repository\n */\nexport async function getDefaultBranch(owner: string, repo: string): Promise<string> {\n if (!octokit) {\n return 'main'; // Fallback if not authenticated\n }\n\n try {\n const { data } = await octokit.repos.get({ owner, repo });\n return data.default_branch;\n } catch (error) {\n console.error('Error fetching default branch:', error);\n return 'main';\n }\n}\n\n/**\n * Check if a branch has any open pull requests\n */\nexport async function branchHasOpenPR(\n owner: string,\n repo: string,\n branchName: string\n): Promise<boolean> {\n if (!octokit) {\n return false;\n }\n\n try {\n const { data } = await octokit.pulls.list({\n owner,\n repo,\n state: 'open',\n head: `${owner}:${branchName}`,\n });\n return data.length > 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Delete a branch via GitHub API\n */\nexport async function deleteBranchViaAPI(\n owner: string,\n repo: string,\n branchName: string\n): Promise<void> {\n if (!octokit) {\n throw new Error('GitHub client not initialized');\n }\n\n await octokit.git.deleteRef({\n owner,\n repo,\n ref: `heads/${branchName}`,\n });\n}\n\n/**\n * Get repository information\n */\nexport async function getRepoInfo(owner: string, repo: string): Promise<{\n defaultBranch: string;\n private: boolean;\n description: string | null;\n} | null> {\n if (!octokit) {\n return null;\n }\n\n try {\n const { data } = await octokit.repos.get({ owner, repo });\n return {\n defaultBranch: data.default_branch,\n private: data.private,\n description: data.description,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * List all branches from GitHub API\n */\nexport async function listBranches(\n owner: string,\n repo: string\n): Promise<Array<{ name: string; protected: boolean }>> {\n if (!octokit) {\n return [];\n }\n\n try {\n const branches: Array<{ name: string; protected: boolean }> = [];\n let page = 1;\n\n while (true) {\n const { data } = await octokit.repos.listBranches({\n owner,\n repo,\n per_page: 100,\n page,\n });\n\n if (data.length === 0) break;\n\n for (const branch of data) {\n branches.push({\n name: branch.name,\n protected: branch.protected,\n });\n }\n\n if (data.length < 100) break;\n page++;\n }\n\n return branches;\n } catch {\n return [];\n }\n}\n","import type { Branch, FilterOptions, BranchScope } from '../types/index.js';\nimport { isOlderThan } from '../utils/date.js';\nimport {\n getLocalBranches,\n getRemoteBranches,\n} from './git.js';\n\n/**\n * Fetch branches based on scope\n */\nexport async function fetchBranches(\n scope: BranchScope,\n defaultBranch: string,\n currentBranch: string\n): Promise<Branch[]> {\n let branches: Branch[] = [];\n\n if (scope === 'local' || scope === 'both') {\n const localBranches = await getLocalBranches(defaultBranch, currentBranch);\n branches = [...branches, ...localBranches];\n }\n\n if (scope === 'remote' || scope === 'both') {\n const remoteBranches = await getRemoteBranches(defaultBranch);\n\n // If 'both', merge remote info with local branches\n if (scope === 'both') {\n for (const remoteBranch of remoteBranches) {\n const existingIndex = branches.findIndex(\n (b) => b.name === remoteBranch.name\n );\n if (existingIndex >= 0) {\n // Branch exists locally and remotely\n branches[existingIndex].isRemote = true;\n } else {\n // Remote-only branch\n branches.push(remoteBranch);\n }\n }\n } else {\n branches = remoteBranches;\n }\n }\n\n return branches;\n}\n\n/**\n * Apply all filters to branches\n */\nexport function filterBranches(\n branches: Branch[],\n filters: FilterOptions\n): Branch[] {\n let filtered = [...branches];\n\n // Always exclude protected and current branches\n filtered = filtered.filter((b) => !b.isProtected && !b.isCurrentBranch);\n\n // If no filters selected, return all non-protected branches\n const hasFilters =\n filters.merged || filters.stale || filters.pattern || filters.age;\n\n if (!hasFilters) {\n return filtered;\n }\n\n // Apply filters (OR logic - branch matches if it matches ANY filter)\n filtered = filtered.filter((branch) => {\n const matches: boolean[] = [];\n\n if (filters.merged) {\n matches.push(branch.isMerged);\n }\n\n if (filters.stale) {\n matches.push(isOlderThan(branch.lastCommitDate, filters.staleDays));\n }\n\n if (filters.age) {\n matches.push(isOlderThan(branch.lastCommitDate, filters.ageDays));\n }\n\n if (filters.pattern && filters.patternValue) {\n matches.push(matchesPattern(branch.name, filters.patternValue));\n }\n\n // Return true if branch matches any of the active filters\n return matches.some((m) => m === true);\n });\n\n return filtered;\n}\n\n/**\n * Check if branch name matches a glob-like pattern\n */\nexport function matchesPattern(branchName: string, pattern: string): boolean {\n // Convert glob pattern to regex\n // Supports: * (any characters), ? (single character)\n const regexPattern = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&') // Escape special regex chars\n .replace(/\\*/g, '.*') // * -> .*\n .replace(/\\?/g, '.'); // ? -> .\n\n const regex = new RegExp(`^${regexPattern}$`, 'i');\n return regex.test(branchName);\n}\n\n/**\n * Sort branches by date (oldest first)\n */\nexport function sortByAge(branches: Branch[]): Branch[] {\n return [...branches].sort(\n (a, b) => a.lastCommitDate.getTime() - b.lastCommitDate.getTime()\n );\n}\n\n/**\n * Sort branches by name\n */\nexport function sortByName(branches: Branch[]): Branch[] {\n return [...branches].sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/**\n * Get branch statistics\n */\nexport function getBranchStats(branches: Branch[]): {\n total: number;\n local: number;\n remote: number;\n merged: number;\n protected: number;\n} {\n return {\n total: branches.length,\n local: branches.filter((b) => b.isLocal).length,\n remote: branches.filter((b) => b.isRemote).length,\n merged: branches.filter((b) => b.isMerged).length,\n protected: branches.filter((b) => b.isProtected).length,\n };\n}\n","import { Command } from 'commander';\nimport type { CLIOptions } from './types/index.js';\n\nexport function createCLI(): CLIOptions {\n const program = new Command();\n\n program\n .name('git-tidy')\n .description('Interactive CLI tool for cleaning up unused git branches')\n .version('1.0.0')\n .option('-x, --execute', 'Actually delete branches (default: dry-run mode)', false)\n .option('-y, --yes', 'Skip all confirmations (for scripting)', false)\n .option('-t, --token <token>', 'GitHub personal access token (or use GITHUB_TOKEN env)')\n .parse();\n\n const opts = program.opts();\n\n return {\n execute: opts.execute || false,\n yes: opts.yes || false,\n token: opts.token,\n };\n}\n"],"mappings":"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","names":["useState","useEffect","useCallback","Box","Text","Spinner","Box","Text","jsx","jsxs","options","Box","Text","jsx","jsxs","options","Box","Text","useState","Box","Text","useInput","MultiSelect","jsx","jsxs","useState","options","useInput","Box","Text","MultiSelect","Box","Text","useInput","jsx","jsxs","useState","Box","Text","jsx","jsxs","useState","Box","Text","Box","Text","useInput","jsx","jsxs","useState","jsx","jsxs","options","useState","useEffect","useCallback","Box","Text","Spinner","jsx"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-tidy-cli",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Interactive CLI tool for cleaning up unused git branches with a beautiful TUI",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",