@rotorsoft/gent 1.20.1 → 1.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-O6JNGCPQ.js → chunk-75KVN7ZC.js} +36 -8
- package/dist/chunk-75KVN7ZC.js.map +1 -0
- package/dist/index.js +82 -13
- package/dist/index.js.map +1 -1
- package/dist/{setup-labels-MIGOHCYM.js → setup-labels-STWAFV2E.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-O6JNGCPQ.js.map +0 -1
- /package/dist/{setup-labels-MIGOHCYM.js.map → setup-labels-STWAFV2E.js.map} +0 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/lib/progress.ts","../src/commands/create.ts","../src/lib/ai-provider.ts","../src/lib/prompts.ts","../src/commands/list.ts","../src/lib/git.ts","../src/lib/branch.ts","../src/commands/run.ts","../src/lib/playwright.ts","../src/commands/pr.ts","../src/commands/fix.ts","../src/lib/review-feedback.ts","../src/lib/version.ts","../package.json","../src/commands/status.ts","../src/commands/tui.ts","../src/tui/state.ts","../src/tui/actions.ts","../src/tui/display.ts","../src/tui/modal.ts","../src/tui/key-reader.ts","../src/tui/select-dialog.ts","../src/tui/confirm-dialog.ts","../src/tui/input-dialog.ts","../src/tui/multiline-input.ts","../src/commands/github-remote.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { setupLabelsCommand } from \"./commands/setup-labels.js\";\nimport { createCommand } from \"./commands/create.js\";\nimport { listCommand } from \"./commands/list.js\";\nimport { runCommand } from \"./commands/run.js\";\nimport { prCommand } from \"./commands/pr.js\";\nimport { fixCommand } from \"./commands/fix.js\";\nimport { statusCommand } from \"./commands/status.js\";\nimport { tuiCommand } from \"./commands/tui.js\";\nimport { githubRemoteCommand } from \"./commands/github-remote.js\";\nimport {\n getVersion,\n checkForUpdates,\n formatUpgradeNotification,\n} from \"./lib/version.js\";\nimport { logger } from \"./utils/logger.js\";\n\nconst version = getVersion();\n\nfunction startVersionCheck(): void {\n // Skip if disabled via environment variable\n if (process.env.GENT_SKIP_UPDATE_CHECK === \"1\") return;\n\n checkForUpdates()\n .then((result) => {\n if (result.updateAvailable && result.latestVersion) {\n logger.newline();\n logger.warning(\n formatUpgradeNotification(result.currentVersion, result.latestVersion)\n );\n }\n })\n .catch(() => {\n // Silently ignore errors\n });\n}\n\nconst program = new Command();\n\nprogram\n .name(\"gent\")\n .description(\n \"AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs\"\n )\n .version(version)\n .option(\"--skip-update-check\", \"Skip checking for CLI updates\")\n .hook(\"preAction\", (thisCommand) => {\n // Start version check before any command runs (unless skipped)\n if (!thisCommand.opts().skipUpdateCheck) {\n startVersionCheck();\n }\n });\n\nprogram\n .command(\"init\")\n .description(\"Initialize gent workflow in current repository\")\n .option(\"-f, --force\", \"Overwrite existing configuration\")\n .action(async (options) => {\n await initCommand(options);\n });\n\nprogram\n .command(\"setup-labels\")\n .description(\"Setup GitHub labels for AI workflow\")\n .action(async () => {\n await setupLabelsCommand();\n });\n\nprogram\n .command(\"create <description>\")\n .description(\"Create an AI-enhanced GitHub issue\")\n .option(\"-y, --yes\", \"Skip confirmation and create issue immediately\")\n .option(\n \"-p, --provider <provider>\",\n \"AI provider to use (claude, gemini, or codex)\"\n )\n .option(\"-t, --title <title>\", \"Override the generated issue title\")\n .action(async (description, options) => {\n await createCommand(description, {\n yes: options.yes,\n provider: options.provider,\n title: options.title,\n });\n });\n\nprogram\n .command(\"list\")\n .description(\"List and switch to GitHub issues\")\n .option(\"-l, --label <label>\", \"Filter by label\")\n .option(\n \"-s, --status <status>\",\n \"Filter by workflow status (ready, in-progress, completed, blocked, all)\"\n )\n .option(\"-n, --limit <number>\", \"Maximum number of issues to show\", \"20\")\n .action(async (options) => {\n await listCommand({\n label: options.label,\n status: options.status,\n limit: parseInt(options.limit, 10),\n });\n });\n\nprogram\n .command(\"run [issue-number]\")\n .description(\"Run AI to implement a GitHub issue\")\n .option(\n \"-p, --provider <provider>\",\n \"AI provider to use (claude, gemini, or codex)\"\n )\n .action(async (issueNumber, options) => {\n await runCommand(issueNumber, { provider: options.provider });\n });\n\nprogram\n .command(\"pr\")\n .description(\"Create an AI-enhanced pull request\")\n .option(\"-d, --draft\", \"Create as draft PR\")\n .option(\n \"-p, --provider <provider>\",\n \"AI provider to use (claude, gemini, or codex)\"\n )\n .option(\"--no-video\", \"Disable video capture for UI changes\")\n .action(async (options) => {\n await prCommand({\n draft: options.draft,\n provider: options.provider,\n video: options.video,\n });\n });\n\nprogram\n .command(\"fix\")\n .description(\"Apply PR review feedback using AI\")\n .option(\n \"-p, --provider <provider>\",\n \"AI provider to use (claude, gemini, or codex)\"\n )\n .action(async (options) => {\n await fixCommand({ provider: options.provider });\n });\n\nprogram\n .command(\"status\")\n .description(\"Show current workflow status\")\n .action(async () => {\n await statusCommand();\n });\n\nprogram\n .command(\"github-remote\")\n .description(\"Create a GitHub repository and push local repo\")\n .action(async () => {\n await githubRemoteCommand();\n });\n\nprogram\n .command(\"ui\")\n .description(\"Launch interactive dashboard\")\n .action(async () => {\n await tuiCommand();\n });\n\n// Launch dashboard when `gent` is run with no subcommand\nprogram.action(async () => {\n await tuiCommand();\n});\n\nprogram.parse();\n","import { writeFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport inquirer from \"inquirer\";\nimport { logger, colors } from \"../utils/logger.js\";\nimport { checkGitRepo } from \"../utils/validators.js\";\nimport {\n configExists,\n generateDefaultConfig,\n getConfigPath,\n} from \"../lib/config.js\";\nimport { initializeProgress } from \"../lib/progress.js\";\nimport { loadConfig } from \"../lib/config.js\";\n\nconst DEFAULT_AGENT_MD = `# AI Agent Instructions\n\nThis file contains instructions for the AI when working on this repository.\n\n## Project Overview\n\n[Describe your project, its purpose, and key technologies used]\n\n## Code Patterns\n\n### Architecture\n[Document your architecture - e.g., MVC, Clean Architecture, etc.]\n\n### Naming Conventions\n[Document naming conventions for files, functions, variables, etc.]\n\n### Component Structure\n[If applicable, describe component/module structure]\n\n## Testing Requirements\n\n### Unit Tests\n- All new functions should have corresponding unit tests\n- Use [your testing framework] for unit tests\n- Aim for [X]% coverage on new code\n\n### Integration Tests\n[Document when and how to write integration tests]\n\n## Commit Conventions\n\nFollow conventional commits format:\n- \\`feat:\\` New feature\n- \\`fix:\\` Bug fix\n- \\`refactor:\\` Code improvement without behavior change\n- \\`test:\\` Testing additions\n- \\`chore:\\` Maintenance/dependencies\n- \\`docs:\\` Documentation\n\nAll AI commits should include the Co-Authored-By trailer as specified in the task prompt.\n\n## Important Files\n\n[List key files the AI should understand before making changes]\n\n- \\`src/index.ts\\` - Main entry point\n- \\`src/config/\\` - Configuration files\n- [Add more key files]\n\n## Constraints\n\n- [List any constraints or limitations]\n- [E.g., \"Do not modify files in /vendor\"]\n- [E.g., \"Always use async/await over callbacks\"]\n`;\n\nexport async function initCommand(options: { force?: boolean }): Promise<void> {\n logger.bold(\"Initializing gent workflow...\");\n logger.newline();\n\n // Check if we're in a git repo\n const isGitRepo = await checkGitRepo();\n if (!isGitRepo) {\n logger.error(\"Not a git repository. Please run 'git init' first.\");\n process.exit(1);\n }\n\n const cwd = process.cwd();\n\n // Check if already initialized\n if (configExists(cwd) && !options.force) {\n const { overwrite } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"overwrite\",\n message: \"gent is already initialized. Overwrite existing config?\",\n default: false,\n },\n ]);\n\n if (!overwrite) {\n logger.info(\"Initialization cancelled.\");\n return;\n }\n }\n\n const { provider } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"provider\",\n message: \"Which AI provider would you like to use by default?\",\n choices: [\"claude\", \"gemini\", \"codex\"],\n default: \"claude\",\n },\n ]);\n\n // Create .gent.yml\n const configPath = getConfigPath(cwd);\n writeFileSync(configPath, generateDefaultConfig(provider), \"utf-8\");\n logger.success(`Created ${colors.file(\".gent.yml\")}`);\n\n // Create AGENT.md\n const agentPath = join(cwd, \"AGENT.md\");\n if (!existsSync(agentPath) || options.force) {\n writeFileSync(agentPath, DEFAULT_AGENT_MD, \"utf-8\");\n logger.success(`Created ${colors.file(\"AGENT.md\")}`);\n } else {\n logger.info(`${colors.file(\"AGENT.md\")} already exists, skipping`);\n }\n\n // Create progress.txt\n const config = loadConfig(cwd);\n initializeProgress(config, cwd);\n logger.success(`Created ${colors.file(config.progress.file)}`);\n\n logger.newline();\n logger.box(\n \"Setup Complete\",\n `Next steps:\n1. Edit ${colors.file(\"AGENT.md\")} with your project-specific instructions\n2. Edit ${colors.file(\".gent.yml\")} to customize settings\n3. Run ${colors.command(\"gent setup-labels\")} to create GitHub labels\n4. Run ${colors.command(\"gent create <description>\")} to create your first ticket`\n );\n\n // Ask about setting up labels\n const { setupLabels } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"setupLabels\",\n message: \"Would you like to setup GitHub labels now?\",\n default: true,\n },\n ]);\n\n if (setupLabels) {\n const { setupLabelsCommand } = await import(\"./setup-labels.js\");\n await setupLabelsCommand();\n }\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport type { GentConfig, ProgressEntry } from \"../types/index.js\";\n\nexport function getProgressPath(\n config: GentConfig,\n cwd: string = process.cwd()\n): string {\n return join(cwd, config.progress.file);\n}\n\nexport function progressExists(\n config: GentConfig,\n cwd: string = process.cwd()\n): boolean {\n return existsSync(getProgressPath(config, cwd));\n}\n\nexport function readProgress(\n config: GentConfig,\n cwd: string = process.cwd()\n): string {\n const path = getProgressPath(config, cwd);\n if (!existsSync(path)) {\n return \"\";\n }\n return readFileSync(path, \"utf-8\");\n}\n\nexport function appendProgress(\n config: GentConfig,\n entry: ProgressEntry,\n cwd: string = process.cwd()\n): void {\n const path = getProgressPath(config, cwd);\n const content = formatProgressEntry(entry);\n\n // Ensure directory exists\n const dir = dirname(path);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Read existing content\n let existing = \"\";\n if (existsSync(path)) {\n existing = readFileSync(path, \"utf-8\");\n }\n\n // Check if we need to archive\n const lines = existing.split(\"\\n\").length;\n if (lines > config.progress.archive_threshold) {\n archiveProgress(config, existing, cwd);\n existing = `# Progress Log (archived previous entries)\\n\\n`;\n }\n\n // Append new entry\n writeFileSync(path, existing + content, \"utf-8\");\n}\n\nexport function formatProgressEntry(entry: ProgressEntry): string {\n let content = `\\n[${entry.date}] ${entry.type}: ${entry.description}\\n`;\n\n if (entry.issue) {\n content += `- Completed GitHub issue #${entry.issue}\\n`;\n }\n\n if (entry.decisions.length > 0) {\n content += `- Key implementation decisions:\\n`;\n for (const decision of entry.decisions) {\n content += ` * ${decision}\\n`;\n }\n }\n\n if (entry.files.length > 0) {\n content += `- Files changed:\\n`;\n for (const file of entry.files) {\n content += ` * ${file}\\n`;\n }\n }\n\n if (entry.tests.length > 0) {\n content += `- Tests: ${entry.tests.join(\", \")}\\n`;\n }\n\n if (entry.concerns.length > 0) {\n content += `- Concerns for reviewers:\\n`;\n for (const concern of entry.concerns) {\n content += ` * ${concern}\\n`;\n }\n }\n\n if (entry.followUp.length > 0) {\n content += `- Follow-up tasks:\\n`;\n for (const task of entry.followUp) {\n content += ` * ${task}\\n`;\n }\n }\n\n if (entry.commit) {\n content += `- Commit: ${entry.commit}\\n`;\n }\n\n return content;\n}\n\nfunction archiveProgress(\n config: GentConfig,\n content: string,\n cwd: string\n): void {\n const archiveDir = join(cwd, config.progress.archive_dir);\n\n if (!existsSync(archiveDir)) {\n mkdirSync(archiveDir, { recursive: true });\n }\n\n const date = new Date().toISOString().split(\"T\")[0];\n const archivePath = join(archiveDir, `progress-${date}.txt`);\n\n writeFileSync(archivePath, content, \"utf-8\");\n}\n\nexport function initializeProgress(\n config: GentConfig,\n cwd: string = process.cwd()\n): void {\n const path = getProgressPath(config, cwd);\n\n if (existsSync(path)) {\n return;\n }\n\n const initialContent = `# Progress Log\n\nThis file tracks AI-assisted development progress.\nEach entry documents: date, feature, decisions, files changed, tests, and concerns.\n\n---\n`;\n\n const dir = dirname(path);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n writeFileSync(path, initialContent, \"utf-8\");\n}\n\nexport function getRecentProgress(\n config: GentConfig,\n cwd: string = process.cwd(),\n maxLines: number = 100\n): string {\n const content = readProgress(config, cwd);\n const lines = content.split(\"\\n\");\n\n if (lines.length <= maxLines) {\n return content;\n }\n\n return lines.slice(-maxLines).join(\"\\n\");\n}\n","import inquirer from \"inquirer\";\nimport chalk from \"chalk\";\nimport { logger, colors } from \"../utils/logger.js\";\nimport { withSpinner, createSpinner, aiSpinnerText } from \"../utils/spinner.js\";\nimport {\n loadConfig,\n loadAgentInstructions,\n resolveProvider,\n} from \"../lib/config.js\";\nimport {\n buildTicketPrompt,\n parseTicketMeta,\n extractIssueBody,\n extractTitle,\n generateFallbackTitle,\n} from \"../lib/prompts.js\";\nimport {\n invokeAI,\n getProviderDisplayName,\n getOtherAvailableProviders,\n} from \"../lib/ai-provider.js\";\nimport { createIssue } from \"../lib/github.js\";\nimport { buildIssueLabels } from \"../lib/labels.js\";\nimport { checkGhAuth, checkAIProvider } from \"../utils/validators.js\";\nimport type { AIProvider } from \"../types/index.js\";\n\nexport interface CreateOptions {\n yes?: boolean;\n provider?: AIProvider;\n title?: string;\n}\n\ninterface TicketMeta {\n type: string;\n priority: string;\n risk: string;\n area: string;\n}\n\nexport async function createCommand(\n description: string,\n options: CreateOptions\n): Promise<void> {\n const config = loadConfig();\n\n // Determine which provider to use\n let currentProvider = resolveProvider(options, config);\n\n // Validate prerequisites\n const [ghAuth, aiOk] = await Promise.all([\n checkGhAuth(),\n checkAIProvider(currentProvider),\n ]);\n\n if (!ghAuth) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n return;\n }\n\n if (!aiOk) {\n logger.error(\n `${getProviderDisplayName(currentProvider)} CLI not found. Please install ${currentProvider} CLI first.`\n );\n return;\n }\n\n const agentInstructions = loadAgentInstructions();\n\n // Generate ticket with AI (may loop if user wants to regenerate)\n let aiOutput: string;\n let additionalHints: string | null = null;\n\n while (true) {\n // Build prompt and invoke AI\n const prompt = buildTicketPrompt(\n description,\n agentInstructions,\n additionalHints\n );\n\n try {\n const spinner = createSpinner(aiSpinnerText(getProviderDisplayName(currentProvider), \"generate ticket\"));\n spinner.start();\n const result = await invokeAI(\n { prompt, streamOutput: true, onFirstData: () => spinner.stop() },\n config,\n currentProvider\n );\n spinner.stop();\n aiOutput = result.output;\n logger.newline();\n } catch (error) {\n const providerName = getProviderDisplayName(currentProvider);\n if (error && typeof error === \"object\" && \"rateLimited\" in error) {\n logger.warning(`${providerName} is rate limited.`);\n\n const others = await getOtherAvailableProviders(currentProvider);\n if (others.length > 0) {\n const { nextProvider } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"nextProvider\",\n message: \"Would you like to try another provider?\",\n choices: [\n ...others.map((p) => ({\n name: `Switch to ${getProviderDisplayName(p)}`,\n value: p,\n })),\n { name: \"Cancel\", value: \"cancel\" },\n ],\n },\n ]);\n\n if (nextProvider !== \"cancel\") {\n currentProvider = nextProvider as AIProvider;\n logger.info(\n `Switching to ${getProviderDisplayName(currentProvider)}...`\n );\n continue;\n }\n }\n }\n\n logger.error(`${providerName} invocation failed: ${error}`);\n return;\n }\n\n // Parse metadata\n const meta = parseTicketMeta(aiOutput);\n if (!meta) {\n logger.warning(\n \"Could not parse metadata from AI output. Using defaults.\"\n );\n }\n\n const finalMeta: TicketMeta = meta || {\n type: \"feature\",\n priority: \"medium\",\n risk: \"low\",\n area: \"shared\",\n };\n\n // Extract issue body (without META line) and append signature\n const issueBody =\n extractIssueBody(aiOutput) +\n `\\n\\n---\\n*Created with ${getProviderDisplayName(currentProvider)} by [gent](https://github.com/Rotorsoft/gent)*`;\n\n // Determine title: user override > AI-generated > fallback\n let title: string;\n if (options.title) {\n title = options.title;\n } else {\n const aiTitle = extractTitle(aiOutput);\n if (aiTitle) {\n title = aiTitle;\n } else {\n title = generateFallbackTitle(description);\n logger.warning(\"Could not extract AI-generated title. Using fallback.\");\n }\n }\n\n // Build labels\n const labels = buildIssueLabels(finalMeta);\n\n // Show ticket preview\n displayTicketPreview(title, finalMeta, issueBody);\n\n // Skip confirmation if --yes flag is passed\n if (options.yes) {\n await createAndDisplayIssue(title, issueBody, labels, finalMeta);\n return;\n }\n\n // Ask for confirmation\n const { action } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"action\",\n message: \"What would you like to do?\",\n choices: [\n { name: \"Create issue\", value: \"create\" },\n { name: \"Edit description and regenerate\", value: \"edit\" },\n { name: \"Cancel\", value: \"cancel\" },\n ],\n },\n ]);\n\n if (action === \"cancel\") {\n logger.info(\"Issue creation cancelled.\");\n return;\n }\n\n if (action === \"create\") {\n await createAndDisplayIssue(title, issueBody, labels, finalMeta);\n return;\n }\n\n // action === \"edit\" - prompt for additional hints\n const { hints } = await inquirer.prompt([\n {\n type: \"input\",\n name: \"hints\",\n message: \"Enter additional hints or context for the AI:\",\n },\n ]);\n\n if (hints.trim()) {\n additionalHints = additionalHints\n ? `${additionalHints}\\n${hints.trim()}`\n : hints.trim();\n }\n\n logger.newline();\n logger.info(\"Regenerating ticket with additional context...\");\n logger.newline();\n }\n}\n\nfunction displayTicketPreview(\n title: string,\n meta: TicketMeta,\n body: string\n): void {\n // Count lines for summary\n const lineCount = body.split(\"\\n\").length;\n\n // Section header helper\n const sectionHeader = (label: string) =>\n console.log(chalk.bold.cyan(`${label}`));\n\n // Display preview with clean sections\n console.log(chalk.bold.white(\"━━━ Ticket Preview ━━━\"));\n logger.newline();\n\n sectionHeader(\"Title\");\n console.log(` ${title}`);\n logger.newline();\n\n sectionHeader(\"Labels\");\n console.log(\n ` ${colors.label(`type:${meta.type}`)} ${colors.label(`priority:${meta.priority}`)} ${colors.label(`risk:${meta.risk}`)} ${colors.label(`area:${meta.area}`)}`\n );\n logger.newline();\n\n sectionHeader(`Body (${lineCount} lines)`);\n // Indent each line of the body for visual hierarchy\n const bodyLines = body.split(\"\\n\");\n for (const line of bodyLines) {\n console.log(` ${line}`);\n }\n\n logger.newline();\n console.log(chalk.bold.white(\"━━━━━━━━━━━━━━━━━━━━━━\"));\n logger.newline();\n}\n\nasync function createAndDisplayIssue(\n title: string,\n body: string,\n labels: string[],\n meta: TicketMeta\n): Promise<void> {\n let issueNumber: number;\n try {\n issueNumber = await withSpinner(\"Creating GitHub issue...\", async () => {\n return createIssue({\n title,\n body,\n labels,\n });\n });\n } catch (error) {\n logger.error(`Failed to create issue: ${error}`);\n return;\n }\n\n logger.newline();\n logger.success(`Created issue ${colors.issue(`#${issueNumber}`)}`);\n logger.newline();\n\n logger.box(\n \"Issue Created\",\n `Issue: ${colors.issue(`#${issueNumber}`)}\nType: ${colors.label(`type:${meta.type}`)}\nPriority: ${colors.label(`priority:${meta.priority}`)}\nRisk: ${colors.label(`risk:${meta.risk}`)}\nArea: ${colors.label(`area:${meta.area}`)}\n\nNext steps:\n1. Review the issue on GitHub\n2. Run ${colors.command(`gent run ${issueNumber}`)} to implement`\n );\n}\n","import { spawn } from \"child_process\";\nimport { execa, type ResultPromise } from \"execa\";\nimport type { GentConfig, AIProvider } from \"../types/index.js\";\nimport { logger, colors } from \"../utils/logger.js\";\n\nimport { checkAIProvider } from \"../utils/validators.js\";\n\nexport interface AIProviderOptions {\n prompt: string;\n permissionMode?: string;\n printOutput?: boolean;\n streamOutput?: boolean;\n onFirstData?: () => void;\n}\n\nexport interface AIProviderResult {\n output: string;\n provider: AIProvider;\n rateLimited?: boolean;\n}\n\n/**\n * Get list of available AI providers except the current one\n */\nexport async function getOtherAvailableProviders(\n currentProvider: AIProvider\n): Promise<AIProvider[]> {\n const allProviders: AIProvider[] = [\"claude\", \"gemini\", \"codex\"];\n const others = allProviders.filter((p) => p !== currentProvider);\n const available: AIProvider[] = [];\n\n for (const p of others) {\n if (await checkAIProvider(p)) {\n available.push(p);\n }\n }\n\n return available;\n}\n\nasync function invokeInternal(\n provider: AIProvider,\n options: AIProviderOptions\n): Promise<string> {\n switch (provider) {\n case \"claude\":\n return invokeClaudeInternal(options);\n case \"gemini\":\n return invokeGeminiInternal(options);\n case \"codex\":\n return invokeCodexInternal(options);\n }\n}\n\n/**\n * Invoke AI provider (non-interactive mode)\n * Returns output from the provider\n */\nexport async function invokeAI(\n options: AIProviderOptions,\n config: GentConfig,\n providerOverride?: AIProvider\n): Promise<AIProviderResult> {\n const provider = providerOverride ?? config.ai.provider;\n\n try {\n const output = await invokeInternal(provider, options);\n\n return { output, provider };\n } catch (error) {\n // Check for rate limiting\n if (isRateLimitError(error, provider)) {\n // Try fallback if configured\n if (\n config.ai.auto_fallback &&\n config.ai.fallback_provider &&\n !providerOverride\n ) {\n const fallback = config.ai.fallback_provider;\n logger.warning(\n `Rate limit reached on ${getProviderDisplayName(provider)}, switching to ${getProviderDisplayName(fallback)}...`\n );\n\n const output = await invokeInternal(fallback, options);\n\n return { output, provider: fallback };\n }\n\n // Return rate limited error\n const err = error as Error;\n err.message = `Rate limited on ${getProviderDisplayName(provider)}`;\n (err as Error & { rateLimited: boolean }).rateLimited = true;\n throw err;\n }\n\n throw error;\n }\n}\n\n/**\n * Invoke AI provider in interactive mode (stdio inherited)\n * Used for implementation sessions\n */\nexport async function invokeAIInteractive(\n prompt: string,\n config: GentConfig,\n providerOverride?: AIProvider\n): Promise<{ result: ResultPromise; provider: AIProvider }> {\n const provider = providerOverride ?? config.ai.provider;\n\n switch (provider) {\n case \"claude\": {\n const args = [\"--permission-mode\", config.claude.permission_mode, prompt];\n return {\n result: execa(\"claude\", args, { stdio: \"inherit\" }),\n provider,\n };\n }\n case \"gemini\": {\n // Gemini CLI uses -i/--prompt-interactive for interactive mode with initial prompt\n // Without -i, the positional prompt runs in one-shot mode and exits\n return {\n result: execa(\"gemini\", [\"-i\", prompt], { stdio: \"inherit\" }),\n provider,\n };\n }\n case \"codex\": {\n // Codex CLI uses the TUI for interactive sessions; prompt is optional\n const args = prompt ? [prompt] : [];\n return {\n result: execa(\"codex\", args, { stdio: \"inherit\" }),\n provider,\n };\n }\n }\n}\n\n/**\n * Get display name for provider\n */\nexport function getProviderDisplayName(provider: AIProvider): string {\n switch (provider) {\n case \"claude\":\n return \"Claude\";\n case \"gemini\":\n return \"Gemini\";\n case \"codex\":\n return \"Codex\";\n }\n}\n\n/**\n * Get email for provider co-author credit\n */\nexport function getProviderEmail(provider: AIProvider): string {\n switch (provider) {\n case \"claude\":\n return \"noreply@anthropic.com\";\n case \"gemini\":\n return \"noreply@google.com\";\n case \"codex\":\n return \"noreply@openai.com\";\n }\n}\n\n/**\n * Get colored provider name for display\n */\nexport function getProviderDisplay(provider: AIProvider): string {\n const name = getProviderDisplayName(provider);\n switch (provider) {\n case \"claude\":\n return colors.command(name);\n case \"gemini\":\n return colors.label(name);\n case \"codex\":\n return colors.file(name);\n }\n}\n\n/**\n * Check if error is a rate limit error\n */\nfunction isRateLimitError(error: unknown, provider: AIProvider): boolean {\n if (!error || typeof error !== \"object\") return false;\n\n // Claude and Codex CLIs may use exit code 2 for rate limiting\n if (\n (provider === \"claude\" || provider === \"codex\") &&\n \"exitCode\" in error &&\n error.exitCode === 2\n ) {\n return true;\n }\n\n // Gemini CLI may use different exit codes or error messages\n // Check for common rate limit patterns in error messages\n if (\"message\" in error && typeof error.message === \"string\") {\n const msg = error.message.toLowerCase();\n if (\n msg.includes(\"rate limit\") ||\n msg.includes(\"quota exceeded\") ||\n msg.includes(\"too many requests\")\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Internal Claude invocation\n */\nasync function invokeClaudeInternal(\n options: AIProviderOptions\n): Promise<string> {\n const args = [\"--print\"];\n\n if (options.permissionMode) {\n args.push(\"--permission-mode\", options.permissionMode);\n }\n\n args.push(options.prompt);\n\n if (options.printOutput) {\n // Stream output to console without capturing\n const subprocess = execa(\"claude\", args, {\n stdio: \"inherit\",\n });\n await subprocess;\n return \"\";\n } else if (options.streamOutput) {\n // Use native spawn for better streaming control\n return new Promise((resolve, reject) => {\n const child = spawn(\"claude\", args, {\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n });\n\n let output = \"\";\n let firstData = true;\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n if (firstData) {\n firstData = false;\n options.onFirstData?.();\n }\n const text = chunk.toString();\n output += text;\n process.stdout.write(text);\n });\n\n child.stderr.on(\"data\", (chunk: Buffer) => {\n process.stderr.write(chunk);\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve(output);\n } else {\n const error = new Error(`Claude exited with code ${code}`);\n (error as Error & { exitCode: number }).exitCode = code ?? 1;\n reject(error);\n }\n });\n\n child.on(\"error\", reject);\n });\n } else {\n const { stdout } = await execa(\"claude\", args);\n return stdout;\n }\n}\n\n/**\n * Internal Gemini invocation\n */\nasync function invokeGeminiInternal(\n options: AIProviderOptions\n): Promise<string> {\n // Gemini CLI uses different argument structure\n const args: string[] = [];\n\n // Add prompt\n args.push(options.prompt);\n\n if (options.printOutput) {\n const subprocess = execa(\"gemini\", args, {\n stdio: \"inherit\",\n });\n await subprocess;\n return \"\";\n } else if (options.streamOutput) {\n return new Promise((resolve, reject) => {\n const child = spawn(\"gemini\", args, {\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n });\n\n let output = \"\";\n let firstData = true;\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n if (firstData) {\n firstData = false;\n options.onFirstData?.();\n }\n const text = chunk.toString();\n output += text;\n process.stdout.write(text);\n });\n\n child.stderr.on(\"data\", (chunk: Buffer) => {\n process.stderr.write(chunk);\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve(output);\n } else {\n const error = new Error(`Gemini exited with code ${code}`);\n (error as Error & { exitCode: number }).exitCode = code ?? 1;\n reject(error);\n }\n });\n\n child.on(\"error\", reject);\n });\n } else {\n const { stdout } = await execa(\"gemini\", args);\n return stdout;\n }\n}\n\n/**\n * Internal Codex invocation\n */\nasync function invokeCodexInternal(\n options: AIProviderOptions\n): Promise<string> {\n // Use non-interactive mode to avoid TTY requirements\n const args = [\"exec\", options.prompt];\n\n if (options.printOutput) {\n const subprocess = execa(\"codex\", args, {\n stdio: \"inherit\",\n });\n await subprocess;\n return \"\";\n } else if (options.streamOutput) {\n return new Promise((resolve, reject) => {\n const child = spawn(\"codex\", args, {\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n });\n\n let output = \"\";\n let firstData = true;\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n if (firstData) {\n firstData = false;\n options.onFirstData?.();\n }\n const text = chunk.toString();\n output += text;\n process.stdout.write(text);\n });\n\n child.stderr.on(\"data\", (chunk: Buffer) => {\n process.stderr.write(chunk);\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve(output);\n } else {\n const error = new Error(`Codex exited with code ${code}`);\n (error as Error & { exitCode: number }).exitCode = code ?? 1;\n reject(error);\n }\n });\n\n child.on(\"error\", reject);\n });\n } else {\n const { stdout } = await execa(\"codex\", args);\n return stdout;\n }\n}\n","import type { GentConfig } from \"../types/index.js\";\nimport { getProviderDisplayName, getProviderEmail } from \"./ai-provider.js\";\n\nexport function buildTicketPrompt(\n description: string,\n agentInstructions: string | null,\n additionalHints: string | null = null\n): string {\n const basePrompt = `You are creating a GitHub issue for a software project following an AI-assisted development workflow.\n\nUser Request: ${description}\n\n${agentInstructions ? `Project-Specific Instructions:\\n${agentInstructions}\\n\\n` : \"\"}${additionalHints ? `Additional Context/Hints:\\n${additionalHints}\\n\\n` : \"\"}\n\nCreate a detailed GitHub issue following this exact template.\n\nIMPORTANT: Start your output IMMEDIATELY with \"TITLE:\" followed by a clear, concise issue title in imperative mood (e.g., \"Add OAuth2 authentication for Google and GitHub\"). Keep titles under 100 characters when possible. Then on the next line, start with \"## Description\". Do not include any preamble, commentary, or introduction.\n\nTITLE: [Clear, concise issue title in imperative mood]\n\n## Description\n[Clear user-facing description of what needs to be done]\n\n## Technical Context\n**Type:** feature | fix | refactor | chore | docs | test\n**Category:** ui | api | database | workers | shared | testing | infra\n**Priority:** critical | high | medium | low\n**Risk:** low | medium | high\n\n### Architecture Notes\n- [Relevant patterns to follow]\n- [Related systems affected]\n- [Constraints or invariants]\n\n## Implementation Steps\n- [ ] Step 1: Specific technical task\n- [ ] Step 2: Specific technical task\n- [ ] Step 3: Specific technical task\n\n## Testing Requirements\n- **Unit tests:** [What to test]\n- **Integration tests:** [What to test if applicable]\n- **Manual verification:** [What to check]\n\n## Acceptance Criteria\n- [ ] Criterion 1\n- [ ] Criterion 2\n\n---\nIMPORTANT: After the issue content, on a new line, output ONLY the following metadata in this exact format:\nMETA:type=<type>,priority=<priority>,risk=<risk>,area=<area>\n\nExample: META:type=feature,priority=high,risk=low,area=ui`;\n\n return basePrompt;\n}\n\nexport function buildImplementationPrompt(\n issue: { number: number; title: string; body: string },\n agentInstructions: string | null,\n progressContent: string | null,\n config: GentConfig,\n extraContext: string | null = null\n): string {\n const providerName = getProviderDisplayName(config.ai.provider);\n const providerEmail = getProviderEmail(config.ai.provider);\n\n return `GitHub Issue #${issue.number}: ${issue.title}\n\n${issue.body}\n\n${agentInstructions ? `## Project-Specific Instructions\\n${agentInstructions}\\n\\n` : \"\"}\n${progressContent ? `## Previous Progress\\n${progressContent}\\n\\n` : \"\"}\n${extraContext ? `${extraContext}\\n\\n` : \"\"}\n\n## Your Task\n\n1. **Implement the feature/fix** following patterns from the project's AGENT.md or codebase conventions\n2. **Add unit tests** for any new functionality\n3. **Run validation** before committing:\n${config.validation.map((cmd) => ` - ${cmd}`).join(\"\\n\")}\n4. **Make an atomic commit** with a clear message following conventional commits format:\n - Use format: <type>: <description>\n - Include \"Completed GitHub issue #${issue.number}\" in body\n - End with: Co-Authored-By: ${providerName} <${providerEmail}>\n5. **Update ${config.progress.file}** - append a compact entry documenting your work:\n \\\n [YYYY-MM-DD] #${issue.number} <type>: <brief description>\n - Files: <comma-separated list of changed files>\n - Changes: <1-2 sentence summary of what was implemented>\n - Decisions: <key technical decisions made, if any>\n - Issues: <concerns or follow-ups for reviewers, if any>\n \\\n Keep entries minimal (4-6 lines max). Skip sections if not applicable.\n6. **Do NOT push** - the user will review and push manually\n\nFocus on clean, minimal implementation. Don't over-engineer.`;\n}\n\nexport function buildPrPrompt(\n issue: { number: number; title: string; body: string } | null,\n commits: string[],\n diffSummary: string\n): string {\n return `Generate a pull request description for the following changes.\n\n${issue ? `## Related Issue\\n#${issue.number}: ${issue.title}\\n\\n${issue.body}\\n\\n` : \"\"}\n\n## Commits\n${commits.map((c) => `- ${c}`).join(\"\\n\")}\n\n## Changed Files\n${diffSummary}\n\nGenerate a PR description in this format:\n\n## Summary\n- [1-3 bullet points summarizing the changes]\n\n## Test Plan\n- [ ] [Testing steps]\n\n${issue ? `Closes #${issue.number}` : \"\"}\n\nOnly output the PR description, nothing else.`;\n}\n\nexport function buildCommitMessagePrompt(\n diff: string,\n issueNumber: number | null,\n issueTitle: string | null\n): string {\n const issueContext = issueNumber\n ? `\\nRelated Issue: #${issueNumber}${issueTitle ? ` - ${issueTitle}` : \"\"}\\n`\n : \"\";\n\n return `Generate a concise git commit message for the following changes.\n${issueContext}\n## Diff\n${diff}\n\nRules:\n- Use conventional commit format: <type>: <short description>\n- Types: feat, fix, refactor, chore, docs, test, style, perf\n- Keep the first line under 72 characters\n- Do NOT include a body or footer\n- Output ONLY the commit message, nothing else`;\n}\n\nexport function parseTicketMeta(\n output: string\n): { type: string; priority: string; risk: string; area: string } | null {\n const metaMatch = output.match(\n /META:type=(\\w+),priority=(\\w+),risk=(\\w+),area=(\\w+)/\n );\n\n if (!metaMatch) {\n return null;\n }\n\n return {\n type: metaMatch[1],\n priority: metaMatch[2],\n risk: metaMatch[3],\n area: metaMatch[4],\n };\n}\n\nexport function extractIssueBody(output: string): string {\n // Remove the META line from the output\n let body = output\n .replace(/\\n?META:type=\\w+,priority=\\w+,risk=\\w+,area=\\w+\\s*$/, \"\")\n .trim();\n\n // Strip the TITLE line if present\n body = body.replace(/^TITLE:\\s*.+\\n+/, \"\");\n\n // Strip any preamble text before \"## Description\"\n const descriptionIndex = body.indexOf(\"## Description\");\n if (descriptionIndex > 0) {\n body = body.substring(descriptionIndex);\n }\n\n return body;\n}\n\n/**\n * Extract the generated title from AI output\n * Returns null if no valid title is found\n */\nexport function extractTitle(output: string): string | null {\n const match = output.match(/^TITLE:\\s*(.+)$/m);\n if (!match) {\n return null;\n }\n\n let title = match[1].trim();\n\n // Remove surrounding quotes if present\n if (\n (title.startsWith('\"') && title.endsWith('\"')) ||\n (title.startsWith(\"'\") && title.endsWith(\"'\"))\n ) {\n title = title.slice(1, -1);\n }\n\n // Remove template placeholder if AI didn't replace it\n if (title.includes(\"[\") && title.includes(\"]\")) {\n return null;\n }\n\n // Ensure reasonable length (not empty, not too long)\n if (title.length < 5 || title.length > 200) {\n return null;\n }\n\n return title;\n}\n\n/**\n * Generate a fallback title from the user's description\n * Truncates long descriptions at word boundary without ellipsis\n */\nexport function generateFallbackTitle(description: string): string {\n const maxLength = 200;\n if (description.length <= maxLength) {\n return description;\n }\n // Truncate at last word boundary before maxLength\n const truncated = description.slice(0, maxLength);\n const lastSpace = truncated.lastIndexOf(\" \");\n if (lastSpace > maxLength * 0.5) {\n return truncated.slice(0, lastSpace);\n }\n return truncated;\n}\n\n/**\n * Build prompt for Playwright video capture of UI changes.\n * Instructs AI to upload video to GitHub assets rather than committing to repo.\n */\nexport function buildVideoPrompt(\n issueNumber: number,\n issueTitle: string,\n videoConfig: { max_duration: number; width: number; height: number },\n agentInstructions: string | null\n): string {\n return `You are helping capture a Playwright video demonstration of UI changes for GitHub Issue #${issueNumber}: ${issueTitle}\n\n${agentInstructions ? `## Project-Specific Instructions\\n${agentInstructions}\\n\\n` : \"\"}\n\n## Task: Record UI Demo Video\n\nCreate a short video (max ${videoConfig.max_duration}s) demonstrating the UI changes made for this issue.\n\n### Video Requirements\n- Resolution: ${videoConfig.width}x${videoConfig.height}\n- Format: WebM or MP4\n- Duration: Under ${videoConfig.max_duration} seconds\n- Show the key UI interactions and visual changes\n\n### Steps\n\n1. **Start the development server** if not already running\n2. **Use Playwright to record video** of the relevant UI interactions:\n - Navigate to the affected pages/components\n - Demonstrate the new or changed functionality\n - Show before/after if applicable\n\n3. **Upload video to GitHub** as a release asset or use GitHub's drag-drop upload:\n - Create a GitHub release or upload to issue comments\n - Get the permanent URL for the video\n - Do NOT commit video files to the repository\n\n4. **Add video to PR** by commenting with the video URL or embedding it\n\n### Important\n- Upload video to GitHub assets, NOT to the repository\n- Keep the video concise - focus on demonstrating the changes\n- Ensure the video clearly shows the UI improvements\n\nOutput the GitHub URL where the video was uploaded when complete.`;\n}\n","import chalk from \"chalk\";\nimport inquirer from \"inquirer\";\nimport { logger, colors } from \"../utils/logger.js\";\nimport { withSpinner } from \"../utils/spinner.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { listIssues, listOpenPrs, type OpenPr } from \"../lib/github.js\";\nimport {\n getCurrentBranch,\n getDefaultBranch,\n hasUncommittedChanges,\n branchExists,\n checkoutBranch,\n createBranch,\n listLocalBranches,\n remoteBranchExists,\n fetchAndCheckout,\n} from \"../lib/git.js\";\nimport { parseBranchName, generateBranchName } from \"../lib/branch.js\";\nimport { getWorkflowLabels, sortByPriority } from \"../lib/labels.js\";\nimport { checkGhAuth } from \"../utils/validators.js\";\nimport type { GitHubIssue } from \"../types/index.js\";\n\nexport interface ListOptions {\n label?: string;\n status?: \"ready\" | \"in-progress\" | \"completed\" | \"blocked\" | \"all\";\n limit?: number;\n}\n\nexport interface TicketChoice {\n issueNumber: number;\n title: string;\n branch: string | null;\n category: \"in-progress\" | \"open-pr\" | \"ready\";\n}\n\n/**\n * Find the local branch associated with an issue number by scanning all local branches.\n */\nexport function findBranchForIssue(\n issueNumber: number,\n branches: string[]\n): string | null {\n for (const branch of branches) {\n const info = parseBranchName(branch);\n if (info && info.issueNumber === issueNumber) {\n return branch;\n }\n }\n return null;\n}\n\n/**\n * Build categorized ticket choices from GitHub data and local branches.\n */\nexport function buildTicketChoices(\n inProgressIssues: GitHubIssue[],\n readyIssues: GitHubIssue[],\n openPrs: OpenPr[],\n localBranches: string[]\n): TicketChoice[] {\n const choices: TicketChoice[] = [];\n const seen = new Set<number>();\n\n // Map PR branches to issue numbers\n const prByIssue = new Map<number, OpenPr>();\n for (const pr of openPrs) {\n const info = parseBranchName(pr.headRefName);\n if (info) {\n prByIssue.set(info.issueNumber, pr);\n }\n }\n\n // In-progress issues first\n for (const issue of inProgressIssues) {\n if (seen.has(issue.number)) continue;\n seen.add(issue.number);\n const branch = findBranchForIssue(issue.number, localBranches);\n const pr = prByIssue.get(issue.number);\n choices.push({\n issueNumber: issue.number,\n title: issue.title,\n branch: branch || pr?.headRefName || null,\n category: pr ? \"open-pr\" : \"in-progress\",\n });\n }\n\n // Issues with open PRs (not already added)\n for (const [issueNumber, pr] of prByIssue) {\n if (seen.has(issueNumber)) continue;\n seen.add(issueNumber);\n const issue = [...inProgressIssues, ...readyIssues].find(\n (i) => i.number === issueNumber\n );\n choices.push({\n issueNumber,\n title: issue?.title || pr.title,\n branch: pr.headRefName,\n category: \"open-pr\",\n });\n }\n\n // Ready issues\n for (const issue of readyIssues) {\n if (seen.has(issue.number)) continue;\n seen.add(issue.number);\n const branch = findBranchForIssue(issue.number, localBranches);\n choices.push({\n issueNumber: issue.number,\n title: issue.title,\n branch,\n category: \"ready\",\n });\n }\n\n return choices;\n}\n\nfunction categoryLabel(category: TicketChoice[\"category\"]): string {\n switch (category) {\n case \"in-progress\":\n return chalk.yellow(\"[in progress]\");\n case \"open-pr\":\n return chalk.blue(\"[open PR]\");\n case \"ready\":\n return chalk.green(\"[ready]\");\n }\n}\n\nfunction formatChoice(choice: TicketChoice): string {\n const num = colors.issue(`#${choice.issueNumber}`);\n const cat = categoryLabel(choice.category);\n const title =\n choice.title.length > 50 ? choice.title.slice(0, 50) + \"...\" : choice.title;\n return `${num} ${cat} ${title}`;\n}\n\nexport async function listCommand(options: ListOptions): Promise<void> {\n const isAuthed = await checkGhAuth();\n if (!isAuthed) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n return;\n }\n\n const config = loadConfig();\n const workflowLabels = getWorkflowLabels(config);\n const currentBranch = await getCurrentBranch();\n const defaultBranch = await getDefaultBranch();\n\n // Determine which categories to fetch based on status filter\n const statusFilter = options.status;\n const limit = options.limit || 20;\n\n let inProgressIssues: GitHubIssue[] = [];\n let readyIssues: GitHubIssue[] = [];\n\n if (statusFilter && statusFilter !== \"all\") {\n // Filtered mode: fetch only the requested status\n const labels: string[] = [];\n if (options.label) labels.push(options.label);\n\n switch (statusFilter) {\n case \"ready\":\n labels.push(workflowLabels.ready);\n break;\n case \"in-progress\":\n labels.push(workflowLabels.inProgress);\n break;\n case \"completed\":\n labels.push(workflowLabels.completed);\n break;\n case \"blocked\":\n labels.push(workflowLabels.blocked);\n break;\n }\n\n const [issues, localBranches] = await withSpinner(\n \"Fetching tickets...\",\n () =>\n Promise.all([\n listIssues({ labels, state: \"open\", limit }),\n listLocalBranches(),\n ])\n );\n\n sortByPriority(issues);\n\n // Map filtered issues into the right category\n if (statusFilter === \"in-progress\") {\n inProgressIssues = issues;\n } else {\n readyIssues = issues;\n }\n\n const choices = buildTicketChoices(\n inProgressIssues,\n readyIssues,\n [],\n localBranches\n );\n\n if (choices.length === 0) {\n logger.info(\"No issues found matching the criteria.\");\n return;\n }\n\n await presentSelector(choices, currentBranch, defaultBranch, config);\n return;\n }\n\n // Default: fetch all active categories in parallel\n const labelFilter = options.label ? [options.label] : [];\n const [inProgress, ready, prs, localBranches] = await withSpinner(\n \"Fetching tickets...\",\n () =>\n Promise.all([\n listIssues({\n labels: [workflowLabels.inProgress, ...labelFilter],\n state: \"open\",\n limit,\n }),\n listIssues({\n labels: [workflowLabels.ready, ...labelFilter],\n state: \"open\",\n limit,\n }),\n listOpenPrs(30),\n listLocalBranches(),\n ])\n );\n\n sortByPriority(inProgress);\n sortByPriority(ready);\n\n const choices = buildTicketChoices(inProgress, ready, prs, localBranches);\n\n if (choices.length === 0) {\n logger.info(\"No tickets found.\");\n logger.dim(\n `Create a ticket with ${colors.command(\"gent create\")} or add the '${workflowLabels.ready}' label to an issue.`\n );\n return;\n }\n\n await presentSelector(choices, currentBranch, defaultBranch, config);\n}\n\nasync function presentSelector(\n choices: TicketChoice[],\n currentBranch: string,\n defaultBranch: string,\n config: ReturnType<typeof loadConfig>\n): Promise<void> {\n // Check for uncommitted changes before allowing switch\n const dirty = await hasUncommittedChanges();\n\n // Build inquirer choices with separator groups\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const inquirerChoices: any[] = [];\n\n // Main/master option always first\n inquirerChoices.push({\n name: `${chalk.magenta(defaultBranch)}${currentBranch === defaultBranch ? chalk.dim(\" (current)\") : \"\"}`,\n value: \"__main__\",\n });\n inquirerChoices.push(new inquirer.Separator(\"─\"));\n\n // Group by category\n const inProgress = choices.filter((c) => c.category === \"in-progress\");\n const openPrChoices = choices.filter((c) => c.category === \"open-pr\");\n const ready = choices.filter((c) => c.category === \"ready\");\n\n if (inProgress.length > 0) {\n inquirerChoices.push(new inquirer.Separator(chalk.yellow(\" In Progress\")));\n for (const c of inProgress) {\n inquirerChoices.push({\n name: formatChoice(c),\n value: String(c.issueNumber),\n });\n }\n }\n\n if (openPrChoices.length > 0) {\n inquirerChoices.push(new inquirer.Separator(chalk.blue(\" Open PRs\")));\n for (const c of openPrChoices) {\n inquirerChoices.push({\n name: formatChoice(c),\n value: String(c.issueNumber),\n });\n }\n }\n\n if (ready.length > 0) {\n inquirerChoices.push(new inquirer.Separator(chalk.green(\" Ready\")));\n for (const c of ready) {\n inquirerChoices.push({\n name: formatChoice(c),\n value: String(c.issueNumber),\n });\n }\n }\n\n const { selected } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"selected\",\n message: \"Select a ticket to switch to:\",\n choices: inquirerChoices,\n pageSize: 20,\n },\n ]);\n\n // Handle main branch selection\n if (selected === \"__main__\") {\n if (currentBranch === defaultBranch) {\n logger.info(`Already on ${colors.branch(defaultBranch)}`);\n return;\n }\n if (dirty) {\n const ok = await confirmDirty();\n if (!ok) return;\n }\n await withSpinner(`Switching to ${defaultBranch}...`, async () => {\n await checkoutBranch(defaultBranch);\n });\n logger.success(`Switched to ${colors.branch(defaultBranch)}`);\n return;\n }\n\n // Find the selected ticket\n const issueNumber = parseInt(selected, 10);\n const ticket = choices.find((c) => c.issueNumber === issueNumber);\n if (!ticket) return;\n\n if (dirty) {\n const ok = await confirmDirty();\n if (!ok) return;\n }\n\n // Resolve branch\n const targetBranch = ticket.branch;\n\n if (targetBranch) {\n if (await branchExists(targetBranch)) {\n await withSpinner(`Switching to ${targetBranch}...`, async () => {\n await checkoutBranch(targetBranch);\n });\n logger.success(`Switched to ${colors.branch(targetBranch)}`);\n } else if (await remoteBranchExists(targetBranch)) {\n await withSpinner(`Fetching ${targetBranch} from remote...`, async () => {\n await fetchAndCheckout(targetBranch);\n });\n logger.success(`Fetched and switched to ${colors.branch(targetBranch)}`);\n } else {\n logger.warning(\n `Branch ${colors.branch(targetBranch)} not found locally or on remote.`\n );\n await offerCreateBranch(config, issueNumber, ticket.title);\n }\n } else {\n await offerCreateBranch(config, issueNumber, ticket.title);\n }\n}\n\nasync function confirmDirty(): Promise<boolean> {\n logger.warning(\"You have uncommitted changes.\");\n const { proceed } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"proceed\",\n message: \"Continue anyway? (changes will carry over to the new branch)\",\n default: false,\n },\n ]);\n if (!proceed) {\n logger.info(\"Aborting. Please commit or stash your changes first.\");\n }\n return proceed;\n}\n\nasync function offerCreateBranch(\n config: Parameters<typeof generateBranchName>[0],\n issueNumber: number,\n title: string\n): Promise<void> {\n const branchName = await generateBranchName(\n config,\n issueNumber,\n title,\n \"feature\"\n );\n\n const { create } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"create\",\n message: `No branch exists. Create ${colors.branch(branchName)}?`,\n default: true,\n },\n ]);\n\n if (!create) return;\n\n const defaultBranch = await getDefaultBranch();\n await withSpinner(`Creating branch ${branchName}...`, async () => {\n await createBranch(branchName, defaultBranch);\n });\n logger.success(`Created and switched to ${colors.branch(branchName)}`);\n}\n","import { execa } from \"execa\";\n\nexport async function getCurrentBranch(): Promise<string> {\n const { stdout } = await execa(\"git\", [\"branch\", \"--show-current\"]);\n return stdout.trim();\n}\n\nexport async function isOnMainBranch(): Promise<boolean> {\n const branch = await getCurrentBranch();\n return branch === \"main\" || branch === \"master\";\n}\n\nexport async function getDefaultBranch(): Promise<string> {\n try {\n const { stdout } = await execa(\"git\", [\n \"symbolic-ref\",\n \"refs/remotes/origin/HEAD\",\n ]);\n return stdout.trim().replace(\"refs/remotes/origin/\", \"\");\n } catch {\n // Fallback to checking if main or master exists\n try {\n await execa(\"git\", [\"rev-parse\", \"--verify\", \"main\"]);\n return \"main\";\n } catch {\n return \"master\";\n }\n }\n}\n\nexport async function branchExists(name: string): Promise<boolean> {\n try {\n await execa(\"git\", [\"rev-parse\", \"--verify\", name]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function createBranch(name: string, from?: string): Promise<void> {\n if (from) {\n await execa(\"git\", [\"checkout\", \"-b\", name, from]);\n } else {\n await execa(\"git\", [\"checkout\", \"-b\", name]);\n }\n}\n\nexport async function checkoutBranch(name: string): Promise<void> {\n await execa(\"git\", [\"checkout\", name]);\n}\n\nexport async function hasUncommittedChanges(): Promise<boolean> {\n const { stdout } = await execa(\"git\", [\"status\", \"--porcelain\"]);\n return stdout.trim().length > 0;\n}\n\nexport async function getUnpushedCommits(): Promise<boolean> {\n try {\n const { stdout } = await execa(\"git\", [\"log\", \"@{u}..HEAD\", \"--oneline\"]);\n return stdout.trim().length > 0;\n } catch {\n // No upstream set\n return true;\n }\n}\n\nexport async function pushBranch(branch?: string): Promise<void> {\n const branchName = branch || (await getCurrentBranch());\n await execa(\"git\", [\"push\", \"-u\", \"origin\", branchName]);\n}\n\nexport async function getAuthorInitials(): Promise<string> {\n // Try git config user.initials first\n try {\n const { stdout } = await execa(\"git\", [\"config\", \"user.initials\"]);\n if (stdout.trim()) {\n return stdout.trim();\n }\n } catch {\n // Not set, continue\n }\n\n // Fall back to deriving from user.name\n try {\n const { stdout } = await execa(\"git\", [\"config\", \"user.name\"]);\n const name = stdout.trim();\n if (name) {\n // Extract initials from name (e.g., \"John Doe\" -> \"jd\")\n const parts = name.split(/\\s+/);\n return parts.map((p) => p[0]?.toLowerCase() || \"\").join(\"\");\n }\n } catch {\n // Not set\n }\n\n return \"dev\";\n}\n\nexport async function getRepoInfo(): Promise<{\n owner: string;\n repo: string;\n} | null> {\n try {\n const { stdout } = await execa(\"git\", [\n \"config\",\n \"--get\",\n \"remote.origin.url\",\n ]);\n const url = stdout.trim();\n\n // Handle SSH format: git@github.com:owner/repo.git\n const sshMatch = url.match(/git@github\\.com:([^/]+)\\/([^.]+)/);\n if (sshMatch) {\n return { owner: sshMatch[1], repo: sshMatch[2] };\n }\n\n // Handle HTTPS format: https://github.com/owner/repo.git\n const httpsMatch = url.match(/github\\.com\\/([^/]+)\\/([^.]+)/);\n if (httpsMatch) {\n return { owner: httpsMatch[1], repo: httpsMatch[2] };\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\nexport async function getCommitsSinceBase(\n base: string = \"main\"\n): Promise<string[]> {\n try {\n const { stdout } = await execa(\"git\", [\n \"log\",\n `${base}..HEAD`,\n \"--pretty=format:%s\",\n ]);\n return stdout.trim().split(\"\\n\").filter(Boolean);\n } catch {\n return [];\n }\n}\n\nexport async function getDiffSummary(base: string = \"main\"): Promise<string> {\n try {\n const { stdout } = await execa(\"git\", [\"diff\", `${base}...HEAD`, \"--stat\"]);\n return stdout.trim();\n } catch {\n return \"\";\n }\n}\n\nexport async function getCurrentCommitSha(): Promise<string> {\n const { stdout } = await execa(\"git\", [\"rev-parse\", \"HEAD\"]);\n return stdout.trim();\n}\n\nexport async function hasNewCommits(beforeSha: string): Promise<boolean> {\n const currentSha = await getCurrentCommitSha();\n return currentSha !== beforeSha;\n}\n\nexport async function getLastCommitTimestamp(): Promise<string> {\n const { stdout } = await execa(\"git\", [\"log\", \"-1\", \"--format=%cI\"]);\n return stdout.trim();\n}\n\nexport async function listLocalBranches(): Promise<string[]> {\n const { stdout } = await execa(\"git\", [\n \"branch\",\n \"--format=%(refname:short)\",\n ]);\n return stdout.trim().split(\"\\n\").filter(Boolean);\n}\n\nexport async function remoteBranchExists(name: string): Promise<boolean> {\n try {\n await execa(\"git\", [\"ls-remote\", \"--exit-code\", \"--heads\", \"origin\", name]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function fetchAndCheckout(name: string): Promise<void> {\n await execa(\"git\", [\"fetch\", \"origin\", `${name}:${name}`]);\n await execa(\"git\", [\"checkout\", name]);\n}\n","import type { GentConfig, BranchInfo } from \"../types/index.js\";\nimport { getAuthorInitials } from \"./git.js\";\nimport { sanitizeSlug } from \"../utils/validators.js\";\n\nexport async function generateBranchName(\n config: GentConfig,\n issueNumber: number,\n issueTitle: string,\n type: string\n): Promise<string> {\n const author = await resolveAuthor(config);\n const slug = sanitizeSlug(issueTitle);\n\n return config.branch.pattern\n .replace(\"{author}\", author)\n .replace(\"{type}\", type)\n .replace(\"{issue}\", String(issueNumber))\n .replace(\"{slug}\", slug);\n}\n\nasync function resolveAuthor(config: GentConfig): Promise<string> {\n switch (config.branch.author_source) {\n case \"env\": {\n const envValue = process.env[config.branch.author_env_var];\n if (envValue) {\n return envValue;\n }\n // Fall through to git\n return getAuthorInitials();\n }\n case \"git\":\n default:\n return getAuthorInitials();\n }\n}\n\nexport function parseBranchName(branchName: string): BranchInfo | null {\n // Pattern 1: author/type-issue-slug (e.g., ro/feature-123-add-login)\n const pattern1 =\n /^([^/]+)\\/(feature|fix|refactor|chore|docs|test)-(\\d+)-(.+)$/;\n const match1 = branchName.match(pattern1);\n if (match1) {\n return {\n name: branchName,\n author: match1[1],\n type: match1[2],\n issueNumber: parseInt(match1[3], 10),\n slug: match1[4],\n };\n }\n\n // Pattern 2: type/issue-slug (e.g., feature/123-add-login)\n const pattern2 = /^(feature|fix|refactor|chore|docs|test)\\/(\\d+)-(.+)$/;\n const match2 = branchName.match(pattern2);\n if (match2) {\n return {\n name: branchName,\n author: \"\",\n type: match2[1],\n issueNumber: parseInt(match2[2], 10),\n slug: match2[3],\n };\n }\n\n // Pattern 3: issue-slug (e.g., 123-add-login)\n const pattern3 = /^(\\d+)-(.+)$/;\n const match3 = branchName.match(pattern3);\n if (match3) {\n return {\n name: branchName,\n author: \"\",\n type: \"feature\",\n issueNumber: parseInt(match3[1], 10),\n slug: match3[2],\n };\n }\n\n // Pattern 4: Just look for issue number anywhere\n const issueMatch = branchName.match(/(\\d+)/);\n if (issueMatch) {\n return {\n name: branchName,\n author: \"\",\n type: \"feature\",\n issueNumber: parseInt(issueMatch[1], 10),\n slug: branchName,\n };\n }\n\n return null;\n}\n\nexport function extractIssueNumber(branchName: string): number | null {\n const info = parseBranchName(branchName);\n return info?.issueNumber ?? null;\n}\n","import inquirer from \"inquirer\";\nimport { logger, colors } from \"../utils/logger.js\";\nimport { withSpinner, createSpinner, aiSpinnerText } from \"../utils/spinner.js\";\nimport { loadConfig, loadAgentInstructions } from \"../lib/config.js\";\nimport { getIssue, updateIssueLabels, addIssueComment } from \"../lib/github.js\";\nimport { buildImplementationPrompt } from \"../lib/prompts.js\";\nimport {\n invokeAIInteractive,\n getProviderDisplayName,\n} from \"../lib/ai-provider.js\";\nimport {\n getCurrentBranch,\n isOnMainBranch,\n createBranch,\n branchExists,\n checkoutBranch,\n hasUncommittedChanges,\n getCurrentCommitSha,\n hasNewCommits,\n} from \"../lib/git.js\";\nimport { generateBranchName } from \"../lib/branch.js\";\nimport { getWorkflowLabels, extractTypeFromLabels } from \"../lib/labels.js\";\nimport { readProgress } from \"../lib/progress.js\";\nimport {\n checkGhAuth,\n checkAIProvider,\n isValidIssueNumber,\n} from \"../utils/validators.js\";\nimport type { GitHubIssue, AIProvider } from \"../types/index.js\";\n\nexport interface RunOptions {\n provider?: AIProvider;\n}\n\nexport async function runCommand(\n issueNumberArg: string | undefined,\n options: RunOptions\n): Promise<void> {\n const config = loadConfig();\n\n // Determine which provider to use\n const provider = options.provider ?? config.ai.provider;\n const providerName = getProviderDisplayName(provider);\n\n // Validate prerequisites\n const [ghAuth, aiOk] = await Promise.all([\n checkGhAuth(),\n checkAIProvider(provider),\n ]);\n\n if (!ghAuth) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n return;\n }\n\n if (!aiOk) {\n logger.error(\n `${providerName} CLI not found. Please install ${provider} CLI first.`\n );\n return;\n }\n\n // Check for uncommitted changes\n const hasChanges = await hasUncommittedChanges();\n if (hasChanges) {\n logger.warning(\"You have uncommitted changes.\");\n const { proceed } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"proceed\",\n message: \"Continue anyway?\",\n default: false,\n },\n ]);\n if (!proceed) {\n logger.info(\"Aborting. Please commit or stash your changes first.\");\n return;\n }\n }\n\n const workflowLabels = getWorkflowLabels(config);\n\n // Get issue number\n let issueNumber: number;\n\n if (issueNumberArg) {\n if (!isValidIssueNumber(issueNumberArg)) {\n logger.error(\"Invalid issue number.\");\n return;\n }\n issueNumber = parseInt(issueNumberArg, 10);\n } else {\n logger.error(\n \"Please provide an issue number. Use 'gent switch' to browse tickets.\"\n );\n return;\n }\n\n // Fetch issue details\n let issue: GitHubIssue;\n try {\n issue = await withSpinner(\"Fetching issue...\", async () => {\n return getIssue(issueNumber);\n });\n } catch (error) {\n logger.error(`Failed to fetch issue #${issueNumber}: ${error}`);\n return;\n }\n\n // Verify issue has ai-ready label\n if (!issue.labels.includes(workflowLabels.ready)) {\n logger.warning(\n `Issue #${issueNumber} does not have the '${workflowLabels.ready}' label.`\n );\n const { proceed } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"proceed\",\n message: \"Continue anyway?\",\n default: false,\n },\n ]);\n if (!proceed) {\n return;\n }\n }\n\n logger.newline();\n logger.box(\n \"Issue Details\",\n `#${issue.number}: ${issue.title}\nLabels: ${issue.labels.join(\", \")}`\n );\n logger.newline();\n\n // Generate branch name\n const type = extractTypeFromLabels(issue.labels);\n const branchName = await generateBranchName(\n config,\n issueNumber,\n issue.title,\n type\n );\n\n // Handle branch\n const currentBranch = await getCurrentBranch();\n const onMain = await isOnMainBranch();\n\n if (await branchExists(branchName)) {\n logger.info(`Branch ${colors.branch(branchName)} already exists.`);\n const { action } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"action\",\n message: \"What would you like to do?\",\n choices: [\n { name: \"Continue on existing branch\", value: \"continue\" },\n { name: \"Delete and recreate branch\", value: \"recreate\" },\n { name: \"Cancel\", value: \"cancel\" },\n ],\n },\n ]);\n\n if (action === \"cancel\") {\n return;\n } else if (action === \"continue\") {\n await checkoutBranch(branchName);\n } else {\n // Recreate would require deleting first - for safety, just checkout\n await checkoutBranch(branchName);\n }\n } else {\n if (!onMain) {\n logger.warning(\n `Not on main branch (currently on ${colors.branch(currentBranch)}).`\n );\n const { fromMain } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"fromMain\",\n message: \"Create branch from main instead?\",\n default: true,\n },\n ]);\n\n if (fromMain) {\n await createBranch(branchName, \"main\");\n } else {\n await createBranch(branchName);\n }\n } else {\n await createBranch(branchName);\n }\n logger.success(`Created branch ${colors.branch(branchName)}`);\n }\n\n // Update issue labels\n try {\n await updateIssueLabels(issueNumber, {\n add: [workflowLabels.inProgress],\n remove: [workflowLabels.ready],\n });\n logger.success(\n `Updated issue labels: ${colors.label(workflowLabels.ready)} → ${colors.label(workflowLabels.inProgress)}`\n );\n } catch (error) {\n logger.warning(`Failed to update labels: ${error}`);\n }\n\n // Build implementation prompt\n const agentInstructions = loadAgentInstructions();\n const progressContent = readProgress(config);\n const prompt = buildImplementationPrompt(\n issue,\n agentInstructions,\n progressContent,\n config\n );\n\n logger.newline();\n const spinner = createSpinner(aiSpinnerText(providerName, \"implement ticket\"));\n spinner.start();\n\n // Capture commit SHA before AI runs\n const beforeSha = await getCurrentCommitSha();\n\n // Track if operation was cancelled\n let wasCancelled = false;\n const handleSignal = () => {\n wasCancelled = true;\n };\n process.on(\"SIGINT\", handleSignal);\n process.on(\"SIGTERM\", handleSignal);\n\n // Invoke AI interactively\n spinner.stop();\n let aiExitCode: number | undefined;\n let usedProvider = provider;\n try {\n const { result, provider: actualProvider } = await invokeAIInteractive(\n prompt,\n config,\n options.provider\n );\n usedProvider = actualProvider;\n aiExitCode = result.exitCode ?? undefined;\n } catch (error) {\n if (error && typeof error === \"object\" && \"exitCode\" in error) {\n aiExitCode = error.exitCode as number;\n }\n logger.error(\n `${getProviderDisplayName(usedProvider)} session failed: ${error}`\n );\n // Don't exit - allow user to see what happened\n } finally {\n // Clean up signal handlers\n process.off(\"SIGINT\", handleSignal);\n process.off(\"SIGTERM\", handleSignal);\n }\n\n // Post-completion\n logger.newline();\n\n // Check if any new commits were created\n const commitsCreated = await hasNewCommits(beforeSha);\n\n // Handle cancellation - don't change labels\n if (wasCancelled) {\n logger.warning(\"Operation was cancelled. Labels unchanged.\");\n return;\n }\n\n // Determine appropriate label based on whether work was done\n const usedProviderName = getProviderDisplayName(usedProvider);\n if (commitsCreated) {\n logger.success(`${usedProviderName} session completed with new commits.`);\n\n // Update labels to completed\n try {\n await updateIssueLabels(issueNumber, {\n add: [workflowLabels.completed],\n remove: [workflowLabels.inProgress],\n });\n logger.success(\n `Updated labels: ${colors.label(workflowLabels.inProgress)} → ${colors.label(workflowLabels.completed)}`\n );\n } catch (error) {\n logger.warning(`Failed to update labels: ${error}`);\n }\n\n // Post comment to issue\n try {\n await addIssueComment(\n issueNumber,\n `AI implementation completed on branch \\`${branchName}\\` using ${usedProviderName}.\\n\\nPlease review the changes and create a PR when ready.`\n );\n logger.success(\"Posted completion comment to issue\");\n } catch (error) {\n logger.warning(`Failed to post comment: ${error}`);\n }\n } else {\n // No commits created - check if it was a rate limit or other issue\n // Exit code 2 typically indicates rate limiting for the AI provider CLI\n // Gemini may use different patterns\n const isRateLimited = aiExitCode === 2;\n\n if (isRateLimited) {\n logger.warning(\n `${usedProviderName} session ended due to rate limits. No commits were created.`\n );\n\n // Set ai-blocked label\n try {\n await updateIssueLabels(issueNumber, {\n add: [workflowLabels.blocked],\n remove: [workflowLabels.inProgress],\n });\n logger.info(\n `Updated labels: ${colors.label(workflowLabels.inProgress)} → ${colors.label(workflowLabels.blocked)}`\n );\n } catch (error) {\n logger.warning(`Failed to update labels: ${error}`);\n }\n\n // Post comment about rate limiting\n try {\n await addIssueComment(\n issueNumber,\n `AI implementation was blocked due to API rate limits on branch \\`${branchName}\\` (${usedProviderName}).\\n\\nNo commits were created. Please retry later.`\n );\n logger.info(\"Posted rate-limit comment to issue\");\n } catch (error) {\n logger.warning(`Failed to post comment: ${error}`);\n }\n } else {\n logger.warning(\n `${usedProviderName} session completed but no commits were created. Labels unchanged.`\n );\n // Leave as ai-in-progress so it can be retried\n }\n\n return;\n }\n\n logger.newline();\n logger.box(\n \"Next Steps\",\n `1. Review changes: ${colors.command(\"git diff HEAD~1\")}\n2. Run tests: ${colors.command(\"npm test\")}\n3. Push branch: ${colors.command(\"git push -u origin \" + branchName)}\n4. Create PR: ${colors.command(\"gent pr\")}`\n );\n}\n","import { execa } from \"execa\";\n\n// UI file patterns that indicate UI changes\nconst UI_FILE_PATTERNS = [\n /\\.(tsx|jsx)$/,\n /\\.(vue|svelte)$/,\n /\\.css$/,\n /\\.scss$/,\n /\\.less$/,\n /\\.styled\\.(ts|js)$/,\n /components?\\//i,\n /pages?\\//i,\n /views?\\//i,\n /layouts?\\//i,\n /ui\\//i,\n /styles?\\//i,\n];\n\n/**\n * Check if Playwright is available (installed locally or globally).\n */\nexport async function isPlaywrightAvailable(): Promise<boolean> {\n try {\n const { exitCode } = await execa(\"npx\", [\"playwright\", \"--version\"], {\n reject: false,\n });\n return exitCode === 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Detect if the changed files indicate UI changes\n */\nexport function hasUIChanges(changedFiles: string[]): boolean {\n return changedFiles.some((file) =>\n UI_FILE_PATTERNS.some((pattern) => pattern.test(file))\n );\n}\n\n/**\n * Get list of changed files from git diff\n */\nexport async function getChangedFiles(\n baseBranch: string = \"main\"\n): Promise<string[]> {\n try {\n const { stdout } = await execa(\"git\", [\n \"diff\",\n `${baseBranch}...HEAD`,\n \"--name-only\",\n ]);\n return stdout.trim().split(\"\\n\").filter(Boolean);\n } catch {\n return [];\n }\n}\n","import { logger, colors } from \"../utils/logger.js\";\nimport { withSpinner, createSpinner, aiSpinnerText } from \"../utils/spinner.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport {\n getIssue,\n createPullRequest,\n getPrForBranch,\n assignIssue,\n getCurrentUser,\n updateIssueLabels,\n} from \"../lib/github.js\";\nimport { buildPrPrompt } from \"../lib/prompts.js\";\nimport {\n invokeAI,\n getProviderDisplayName,\n getOtherAvailableProviders,\n} from \"../lib/ai-provider.js\";\nimport {\n getCurrentBranch,\n isOnMainBranch,\n getDefaultBranch,\n getCommitsSinceBase,\n getDiffSummary,\n getUnpushedCommits,\n pushBranch,\n} from \"../lib/git.js\";\nimport { extractIssueNumber } from \"../lib/branch.js\";\nimport { getWorkflowLabels } from \"../lib/labels.js\";\nimport { checkGhAuth, checkAIProvider } from \"../utils/validators.js\";\nimport {\n isPlaywrightAvailable,\n hasUIChanges,\n getChangedFiles,\n} from \"../lib/playwright.js\";\nimport type { GitHubIssue, AIProvider } from \"../types/index.js\";\nimport inquirer from \"inquirer\";\n\nexport interface PrOptions {\n draft?: boolean;\n provider?: AIProvider;\n video?: boolean;\n}\n\nexport async function prCommand(options: PrOptions): Promise<void> {\n const config = loadConfig();\n\n // Determine which provider to use\n let currentProvider = options.provider ?? config.ai.provider;\n\n // Validate prerequisites\n const [ghAuth, aiOk] = await Promise.all([\n checkGhAuth(),\n checkAIProvider(currentProvider),\n ]);\n\n if (!ghAuth) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n return;\n }\n\n if (!aiOk) {\n logger.error(\n `${getProviderDisplayName(currentProvider)} CLI not found. Please install ${currentProvider} CLI first.`\n );\n return;\n }\n\n // Check we're not on main\n if (await isOnMainBranch()) {\n logger.error(\"Cannot create PR from main/master branch.\");\n return;\n }\n\n // Check for existing PR\n const existingPr = await getPrForBranch();\n if (existingPr) {\n logger.warning(\n `A PR already exists for this branch: ${colors.url(existingPr.url)}`\n );\n return;\n }\n\n const currentBranch = await getCurrentBranch();\n const baseBranch = await getDefaultBranch();\n\n logger.info(`Branch: ${colors.branch(currentBranch)}`);\n logger.info(`Base: ${colors.branch(baseBranch)}`);\n\n // Auto-push if needed\n const hasUnpushed = await getUnpushedCommits();\n if (hasUnpushed) {\n await withSpinner(\"Pushing branch...\", async () => {\n await pushBranch();\n });\n logger.success(\"Branch pushed\");\n }\n\n // Extract issue number from branch\n const issueNumber = extractIssueNumber(currentBranch);\n let issue: GitHubIssue | null = null;\n\n if (issueNumber) {\n try {\n issue = await getIssue(issueNumber);\n logger.info(\n `Linked issue: ${colors.issue(`#${issueNumber}`)} - ${issue.title}`\n );\n } catch {\n logger.warning(`Could not fetch issue #${issueNumber}`);\n }\n } else {\n logger.warning(\"Could not extract issue number from branch name.\");\n }\n\n // Get commits and diff\n const commits = await getCommitsSinceBase(baseBranch);\n const diffSummary = await getDiffSummary(baseBranch);\n\n if (commits.length === 0) {\n logger.error(\"No commits found since base branch.\");\n return;\n }\n\n logger.info(`Commits: ${commits.length}`);\n logger.newline();\n\n // Check for UI changes and video capture capability\n // Video is enabled by default (config.video.enabled), but can be disabled with --no-video\n const shouldCaptureVideo = options.video !== false && config.video.enabled;\n let captureVideoInstructions = \"\";\n\n if (shouldCaptureVideo) {\n const changedFiles = await getChangedFiles(baseBranch);\n const uiChangesDetected = hasUIChanges(changedFiles);\n\n if (uiChangesDetected) {\n logger.info(\"UI changes detected in this branch\");\n\n const playwrightAvailable = await isPlaywrightAvailable();\n if (!playwrightAvailable) {\n logger.warning(\"Playwright not available. Skipping video capture.\");\n logger.dim(\"Install Playwright with: npm install -D playwright\");\n } else {\n logger.info(\n \"Playwright available - AI will capture demo video via MCP\"\n );\n captureVideoInstructions = `\n\nIMPORTANT: This PR contains UI changes. Use the Playwright MCP plugin to:\n1. Start the dev server if needed\n2. Navigate to the relevant pages showing the UI changes\n3. Capture a short demo video (max ${config.video.max_duration}s) showcasing the changes\n4. Upload the video to GitHub and include it in the PR description under a \"## Demo Video\" section\n`;\n }\n }\n }\n\n // Generate PR description with AI\n const prompt =\n buildPrPrompt(issue, commits, diffSummary) + captureVideoInstructions;\n\n let prBody: string;\n let usedProvider = currentProvider;\n\n while (true) {\n const providerName = getProviderDisplayName(usedProvider);\n try {\n const spinner = createSpinner(aiSpinnerText(providerName, \"generate PR\"));\n spinner.start();\n const result = await invokeAI(\n { prompt, streamOutput: true, onFirstData: () => spinner.stop() },\n config,\n usedProvider\n );\n spinner.stop();\n prBody = result.output;\n logger.newline();\n break;\n } catch (error) {\n if (error && typeof error === \"object\" && \"rateLimited\" in error) {\n logger.warning(`${providerName} is rate limited.`);\n\n const others = await getOtherAvailableProviders(usedProvider);\n if (others.length > 0) {\n const { nextProvider } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"nextProvider\",\n message: \"Would you like to try another provider?\",\n choices: [\n ...others.map((p) => ({\n name: `Switch to ${getProviderDisplayName(p)}`,\n value: p,\n })),\n { name: \"Fall back to basic description\", value: \"fallback\" },\n ],\n },\n ]);\n\n if (nextProvider !== \"fallback\") {\n usedProvider = nextProvider as AIProvider;\n logger.info(\n `Switching to ${getProviderDisplayName(usedProvider)}...`\n );\n continue;\n }\n }\n }\n\n logger.warning(`${providerName} invocation failed: ${error}`);\n // Fall back to basic description\n prBody = generateFallbackBody(issue, commits);\n break;\n }\n }\n\n // Append signature footer\n prBody += `\\n\\n---\\n*Created with ${getProviderDisplayName(usedProvider)} by [gent](https://github.com/Rotorsoft/gent)*`;\n\n // Generate title\n const prTitle = issue?.title || commits[0] || currentBranch;\n\n // Create PR\n let prUrl: string;\n try {\n prUrl = await withSpinner(\"Creating pull request...\", async () => {\n return createPullRequest({\n title: prTitle,\n body: prBody,\n base: baseBranch,\n draft: options.draft,\n });\n });\n } catch (error) {\n logger.error(`Failed to create PR: ${error}`);\n return;\n }\n\n // Assign issue to current user if linked\n if (issueNumber) {\n try {\n const user = await getCurrentUser();\n await assignIssue(issueNumber, user);\n logger.success(`Assigned issue #${issueNumber} to ${user}`);\n } catch {\n // Non-critical, ignore\n }\n\n // Update issue labels to ai-completed\n const workflowLabels = getWorkflowLabels(config);\n try {\n await updateIssueLabels(issueNumber, {\n add: [workflowLabels.completed],\n remove: [workflowLabels.inProgress],\n });\n logger.success(\n `Updated labels: ${colors.label(workflowLabels.inProgress)} → ${colors.label(workflowLabels.completed)}`\n );\n } catch {\n // Non-critical, ignore\n }\n }\n\n logger.newline();\n logger.success(`Pull request created!`);\n logger.newline();\n logger.highlight(prUrl);\n logger.newline();\n\n if (options.draft) {\n logger.dim(\"Created as draft. Mark as ready for review when done.\");\n }\n\n // Suggest video creation if UI changes detected and Playwright available\n if (shouldCaptureVideo) {\n const changedFilesForHint =\n captureVideoInstructions !== \"\"\n ? [] // already checked above\n : await getChangedFiles(baseBranch);\n const uiChangesForHint =\n captureVideoInstructions !== \"\"\n ? true\n : hasUIChanges(changedFilesForHint);\n\n if (uiChangesForHint) {\n const playwrightOk = await isPlaywrightAvailable();\n if (playwrightOk) {\n logger.bold(\"Next Steps\");\n logger.info(\n \"Run `claude` with Playwright MCP to record a demo video of the changes.\"\n );\n logger.info(\n \"Upload the result to GitHub Assets to keep the repo light.\"\n );\n logger.newline();\n }\n }\n }\n}\n\nfunction generateFallbackBody(\n issue: GitHubIssue | null,\n commits: string[]\n): string {\n let body = \"## Summary\\n\\n\";\n\n if (issue) {\n body += `Implements #${issue.number}: ${issue.title}\\n\\n`;\n }\n\n body += \"## Changes\\n\\n\";\n for (const commit of commits.slice(0, 10)) {\n body += `- ${commit}\\n`;\n }\n\n body += \"\\n## Test Plan\\n\\n- [ ] Tests pass\\n- [ ] Manual verification\\n\\n\";\n\n if (issue) {\n body += `Closes #${issue.number}\\n`;\n }\n\n return body;\n}\n","import inquirer from \"inquirer\";\nimport { logger } from \"../utils/logger.js\";\nimport { withSpinner, createSpinner, aiSpinnerText } from \"../utils/spinner.js\";\nimport { loadConfig, loadAgentInstructions } from \"../lib/config.js\";\nimport {\n getIssue,\n getPrForBranch,\n getPrReviewData,\n replyToReviewComment,\n addPrComment,\n} from \"../lib/github.js\";\nimport { buildImplementationPrompt } from \"../lib/prompts.js\";\nimport {\n invokeAIInteractive,\n getProviderDisplayName,\n} from \"../lib/ai-provider.js\";\nimport {\n getCurrentBranch,\n isOnMainBranch,\n hasUncommittedChanges,\n getCurrentCommitSha,\n hasNewCommits,\n getLastCommitTimestamp,\n} from \"../lib/git.js\";\nimport { extractIssueNumber } from \"../lib/branch.js\";\nimport { readProgress } from \"../lib/progress.js\";\nimport {\n summarizeReviewFeedback,\n type ReviewFeedbackItem,\n} from \"../lib/review-feedback.js\";\nimport { checkGhAuth, checkAIProvider } from \"../utils/validators.js\";\nimport type { AIProvider, GitHubReviewData } from \"../types/index.js\";\n\nexport interface FixOptions {\n provider?: AIProvider;\n}\n\nexport async function fixCommand(options: FixOptions): Promise<void> {\n const config = loadConfig();\n const provider = options.provider ?? config.ai.provider;\n const providerName = getProviderDisplayName(provider);\n\n const [ghAuth, aiOk] = await Promise.all([\n checkGhAuth(),\n checkAIProvider(provider),\n ]);\n\n if (!ghAuth) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n process.exit(1);\n }\n\n if (!aiOk) {\n logger.error(\n `${providerName} CLI not found. Please install ${provider} CLI first.`\n );\n process.exit(1);\n }\n\n if (await isOnMainBranch()) {\n logger.error(\n \"Cannot apply fixes from main/master branch. Switch to the PR branch first.\"\n );\n process.exit(1);\n }\n\n const hasChanges = await hasUncommittedChanges();\n if (hasChanges) {\n logger.warning(\"You have uncommitted changes.\");\n const { proceed } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"proceed\",\n message: \"Continue anyway?\",\n default: false,\n },\n ]);\n if (!proceed) {\n logger.info(\"Aborting. Please commit or stash your changes first.\");\n process.exit(0);\n }\n }\n\n const pr = await withSpinner(\"Resolving pull request...\", async () => {\n return getPrForBranch();\n });\n\n if (!pr) {\n logger.error(\n \"No pull request found for the current branch. Create one with 'gent pr' first.\"\n );\n process.exit(1);\n }\n\n const lastCommitTimestamp = await getLastCommitTimestamp();\n\n const reviewData = await withSpinner(\n \"Fetching review feedback...\",\n async () => {\n return getPrReviewData(pr.number);\n }\n );\n\n const totalComments = countReviewComments(reviewData);\n if (totalComments === 0) {\n logger.error(`No review comments found for PR #${pr.number}.`);\n process.exit(1);\n }\n\n // Filter feedback to only show comments after the last commit (plus unresolved threads)\n const { items, summary } = summarizeReviewFeedback(reviewData, {\n afterTimestamp: lastCommitTimestamp,\n });\n if (items.length === 0 || !summary) {\n logger.error(\n \"No new actionable review feedback found since your last commit.\"\n );\n process.exit(1);\n }\n\n logger.newline();\n logger.box(\"Review Feedback Summary\", summary);\n logger.newline();\n\n const currentBranch = await getCurrentBranch();\n const issueNumber = extractIssueNumber(currentBranch);\n if (!issueNumber) {\n logger.error(\"Could not determine issue number from branch name.\");\n process.exit(1);\n }\n\n const issue = await withSpinner(\"Fetching linked issue...\", async () => {\n return getIssue(issueNumber);\n });\n\n const agentInstructions = loadAgentInstructions();\n const progressContent = readProgress(config);\n const prompt = buildImplementationPrompt(\n issue,\n agentInstructions,\n progressContent,\n config,\n `## Review Feedback\\n${summary}`\n );\n\n logger.newline();\n const spinner = createSpinner(aiSpinnerText(providerName, \"apply fixes\"));\n spinner.start();\n\n const beforeSha = await getCurrentCommitSha();\n\n let wasCancelled = false;\n const handleSignal = () => {\n wasCancelled = true;\n };\n process.on(\"SIGINT\", handleSignal);\n process.on(\"SIGTERM\", handleSignal);\n\n spinner.stop();\n let aiExitCode: number | undefined;\n try {\n const { result } = await invokeAIInteractive(\n prompt,\n config,\n options.provider\n );\n aiExitCode = result.exitCode ?? undefined;\n } catch (error) {\n if (error && typeof error === \"object\" && \"exitCode\" in error) {\n aiExitCode = error.exitCode as number;\n }\n logger.error(`${providerName} session failed: ${error}`);\n } finally {\n process.off(\"SIGINT\", handleSignal);\n process.off(\"SIGTERM\", handleSignal);\n }\n\n logger.newline();\n\n if (wasCancelled) {\n logger.warning(\"Operation was cancelled. No changes were recorded.\");\n return;\n }\n\n const commitsCreated = await hasNewCommits(beforeSha);\n if (commitsCreated) {\n logger.success(`${providerName} session completed with new commits.`);\n\n // Reply to feedback items to indicate they were addressed\n await replyToFeedbackItems(pr.number, items);\n\n return;\n }\n\n const isRateLimited = aiExitCode === 2;\n if (isRateLimited) {\n logger.warning(\n `${providerName} session ended due to rate limits. No commits were created.`\n );\n return;\n }\n\n logger.warning(\n `${providerName} session completed but no commits were created.`\n );\n}\n\nfunction countReviewComments(data: GitHubReviewData): number {\n const reviewBodies = data.reviews.filter((review) =>\n review.body?.trim()\n ).length;\n const threadBodies = data.reviewThreads.reduce((count, thread) => {\n const threadCount = (thread.comments ?? []).filter((comment) =>\n comment.body?.trim()\n ).length;\n return count + threadCount;\n }, 0);\n const prComments = (data.comments ?? []).filter((comment) =>\n comment.body?.trim()\n ).length;\n return reviewBodies + threadBodies + prComments;\n}\n\nasync function replyToFeedbackItems(\n prNumber: number,\n items: ReviewFeedbackItem[]\n): Promise<void> {\n const replyBody = \"Addressed in latest commit.\";\n let repliedCount = 0;\n\n for (const item of items) {\n try {\n if (item.source === \"thread\" && typeof item.commentId === \"number\") {\n await replyToReviewComment(prNumber, item.commentId, replyBody);\n repliedCount++;\n } else if (item.source === \"comment\" && item.commentId) {\n // PR comments don't support threading, so we add a general comment\n await addPrComment(prNumber, `@${item.author} ${replyBody}`);\n repliedCount++;\n }\n // Skip reviews - they don't have a direct reply mechanism\n } catch {\n // Silently ignore reply failures - non-critical\n }\n }\n\n if (repliedCount > 0) {\n logger.dim(\n `Replied to ${repliedCount} feedback item${repliedCount > 1 ? \"s\" : \"\"}.`\n );\n }\n}\n","import type { GitHubReviewData } from \"../types/index.js\";\n\nexport interface ReviewFeedbackItem {\n source: \"review\" | \"thread\" | \"comment\";\n author: string;\n body: string;\n state?: string;\n path?: string;\n line?: number | null;\n commentId?: number | string;\n}\n\nexport interface ReviewFeedbackOptions {\n afterTimestamp?: string;\n}\n\nconst ACTIONABLE_KEYWORDS = [\n \"todo\",\n \"fix\",\n \"should\",\n \"must\",\n \"needs\",\n \"please\",\n \"consider\",\n \"can you\",\n \"change\",\n \"update\",\n \"remove\",\n \"add\",\n];\n\nconst TRIVIAL_COMMENTS = [\"lgtm\", \"looks good\", \"approved\"];\n\nexport function summarizeReviewFeedback(\n data: GitHubReviewData,\n options?: ReviewFeedbackOptions\n): {\n items: ReviewFeedbackItem[];\n summary: string;\n} {\n const items = extractReviewFeedbackItems(data, options);\n return {\n items,\n summary: items.length > 0 ? formatReviewFeedbackSummary(items) : \"\",\n };\n}\n\nfunction isAfterTimestamp(\n itemTimestamp: string | undefined,\n afterTimestamp: string | undefined\n): boolean {\n if (!afterTimestamp || !itemTimestamp) {\n return true;\n }\n return new Date(itemTimestamp) > new Date(afterTimestamp);\n}\n\nexport function extractReviewFeedbackItems(\n data: GitHubReviewData,\n options?: ReviewFeedbackOptions\n): ReviewFeedbackItem[] {\n const items: ReviewFeedbackItem[] = [];\n const afterTimestamp = options?.afterTimestamp;\n\n for (const review of data.reviews) {\n const body = review.body?.trim() ?? \"\";\n if (!body || isTrivialComment(body)) {\n continue;\n }\n\n // Filter by timestamp if provided\n if (!isAfterTimestamp(review.submittedAt, afterTimestamp)) {\n continue;\n }\n\n const isChangesRequested = review.state === \"CHANGES_REQUESTED\";\n const actionable = isChangesRequested || isActionableText(body);\n if (!actionable) {\n continue;\n }\n\n items.push({\n source: \"review\",\n author: review.author,\n body,\n state: review.state,\n });\n }\n\n for (const thread of data.reviewThreads) {\n // Skip outdated threads (code has changed)\n if (thread.isOutdated) {\n continue;\n }\n\n const isUnresolved =\n thread.isResolved === false ||\n thread.isResolved === undefined ||\n thread.isResolved === null;\n\n const hasRecentComments = (thread.comments ?? []).some((c) =>\n isAfterTimestamp(c.createdAt, afterTimestamp)\n );\n\n // If resolved, must have recent comments\n if (!isUnresolved && !hasRecentComments) {\n continue;\n }\n\n // If unresolved AND we have a timestamp constraint, must have recent comments.\n // This allows skipping unresolved threads that were addressed in a recent commit (implied by timestamp).\n if (isUnresolved && afterTimestamp && !hasRecentComments) {\n continue;\n }\n\n if (!isActionableThread(thread)) {\n continue;\n }\n\n const comments = thread.comments ?? [];\n const latestComment = findLatestMeaningfulComment(comments);\n if (!latestComment) {\n continue;\n }\n\n items.push({\n source: \"thread\",\n author: latestComment.author,\n body: latestComment.body,\n path: thread.path ?? latestComment.path,\n line: thread.line ?? latestComment.line ?? null,\n commentId: latestComment.id,\n });\n }\n\n // Process PR comments\n for (const comment of data.comments ?? []) {\n const body = comment.body?.trim() ?? \"\";\n if (!body || isTrivialComment(body)) {\n continue;\n }\n\n // Filter by timestamp if provided\n if (!isAfterTimestamp(comment.createdAt, afterTimestamp)) {\n continue;\n }\n\n // Only include actionable comments\n if (!isActionableText(body)) {\n continue;\n }\n\n items.push({\n source: \"comment\",\n author: comment.author,\n body,\n commentId: comment.id,\n });\n }\n\n return items;\n}\n\nexport function formatReviewFeedbackSummary(\n items: ReviewFeedbackItem[]\n): string {\n return items\n .map((item) => {\n const location = formatLocation(item);\n const stateLabel = item.state ? formatState(item.state) : null;\n const author = item.author ? `@${item.author}` : \"Reviewer\";\n const body = truncateComment(item.body);\n let header: string;\n if (item.source === \"review\") {\n header = stateLabel ? `Review (${stateLabel})` : \"Review\";\n } else if (item.source === \"comment\") {\n header = \"Comment\";\n } else {\n header = location;\n }\n return `- [${header}] ${author}: ${body}`;\n })\n .join(\"\\n\");\n}\n\nfunction isActionableThread(thread: {\n isResolved?: boolean | null;\n comments?: { body: string }[];\n}): boolean {\n if (\n thread.isResolved === false ||\n thread.isResolved === undefined ||\n thread.isResolved === null\n ) {\n return true;\n }\n return (thread.comments ?? []).some((comment) =>\n isActionableText(comment.body)\n );\n}\n\nfunction isActionableText(text: string): boolean {\n const normalized = text.toLowerCase();\n return ACTIONABLE_KEYWORDS.some((keyword) => normalized.includes(keyword));\n}\n\nfunction isTrivialComment(text: string): boolean {\n const normalized = text.trim().toLowerCase();\n return TRIVIAL_COMMENTS.some((entry) => normalized === entry);\n}\n\nfunction findLatestMeaningfulComment<\n T extends { body: string; id?: number | string },\n>(comments: T[]): T | null {\n for (let i = comments.length - 1; i >= 0; i -= 1) {\n const body = comments[i].body?.trim() ?? \"\";\n if (body && !isTrivialComment(body)) {\n return comments[i];\n }\n }\n return null;\n}\n\nfunction formatLocation(item: { path?: string; line?: number | null }): string {\n if (item.path && item.line) {\n return `${item.path}:${item.line}`;\n }\n if (item.path) {\n return item.path;\n }\n return \"Thread\";\n}\n\nfunction formatState(state: string): string {\n return state.replace(/_/g, \" \").toLowerCase();\n}\n\nfunction truncateComment(body: string, maxLength = 200): string {\n const normalized = body.replace(/\\s+/g, \" \").trim();\n if (normalized.length <= maxLength) {\n return normalized;\n }\n return `${normalized.slice(0, maxLength - 3)}...`;\n}\n\nexport interface ReviewFeedbackCounts {\n total: number;\n unresolvedThreads: number;\n changesRequested: number;\n}\n\nexport function countActionableFeedback(\n data: GitHubReviewData,\n options?: ReviewFeedbackOptions\n): ReviewFeedbackCounts {\n const items = extractReviewFeedbackItems(data, options);\n\n let unresolvedThreads = 0;\n let changesRequested = 0;\n\n for (const item of items) {\n if (item.source === \"thread\") {\n unresolvedThreads++;\n } else if (item.source === \"review\" && item.state === \"CHANGES_REQUESTED\") {\n changesRequested++;\n }\n }\n\n return {\n total: items.length,\n unresolvedThreads,\n changesRequested,\n };\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport packageJson from \"../../package.json\" with { type: \"json\" };\n\nconst NPM_REGISTRY_URL = \"https://registry.npmjs.org/@rotorsoft/gent/latest\";\nconst CACHE_DIR = join(homedir(), \".gent\");\nconst CACHE_FILE = join(CACHE_DIR, \"version-check.json\");\nconst DEFAULT_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours\nconst FETCH_TIMEOUT_MS = 3000; // 3 seconds\n\nexport interface VersionCheckResult {\n currentVersion: string;\n latestVersion: string | null;\n updateAvailable: boolean;\n lastChecked: number | null;\n}\n\ninterface VersionCache {\n latestVersion: string;\n checkedAt: number;\n}\n\n/**\n * Reads the version from package.json\n */\nexport function getVersion(): string {\n return packageJson.version;\n}\n\n/**\n * Compares two semver versions\n * Returns: 1 if a > b, -1 if a < b, 0 if equal\n */\nexport function compareVersions(a: string, b: string): number {\n const parseVersion = (v: string) => {\n const [main] = v.split(\"-\"); // Ignore pre-release suffix\n return main.split(\".\").map((n) => parseInt(n, 10));\n };\n\n const aParts = parseVersion(a);\n const bParts = parseVersion(b);\n\n for (let i = 0; i < 3; i++) {\n const aVal = aParts[i] || 0;\n const bVal = bParts[i] || 0;\n if (aVal > bVal) return 1;\n if (aVal < bVal) return -1;\n }\n return 0;\n}\n\n/**\n * Reads cached version check result\n */\nfunction readCache(): VersionCache | null {\n try {\n if (!existsSync(CACHE_FILE)) return null;\n const content = readFileSync(CACHE_FILE, \"utf8\");\n return JSON.parse(content) as VersionCache;\n } catch {\n return null;\n }\n}\n\n/**\n * Writes version check result to cache\n */\nfunction writeCache(cache: VersionCache): void {\n try {\n if (!existsSync(CACHE_DIR)) {\n mkdirSync(CACHE_DIR, { recursive: true });\n }\n writeFileSync(CACHE_FILE, JSON.stringify(cache), \"utf8\");\n } catch {\n // Silently ignore cache write errors\n }\n}\n\n/**\n * Fetches the latest version from npm registry\n */\nasync function fetchLatestVersion(): Promise<string | null> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n\n const response = await fetch(NPM_REGISTRY_URL, {\n signal: controller.signal,\n headers: { Accept: \"application/json\" },\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) return null;\n\n const data = (await response.json()) as { version?: string };\n return data.version || null;\n } catch {\n // Network error, timeout, or parse error - fail silently\n return null;\n }\n}\n\n/**\n * Checks if a newer version is available\n * Uses caching to avoid excessive API calls\n */\nexport async function checkForUpdates(\n checkIntervalMs: number = DEFAULT_CHECK_INTERVAL_MS\n): Promise<VersionCheckResult> {\n const currentVersion = getVersion();\n const cache = readCache();\n const now = Date.now();\n\n // Use cached result if still valid\n if (cache && now - cache.checkedAt < checkIntervalMs) {\n const updateAvailable =\n compareVersions(cache.latestVersion, currentVersion) > 0;\n return {\n currentVersion,\n latestVersion: cache.latestVersion,\n updateAvailable,\n lastChecked: cache.checkedAt,\n };\n }\n\n // Fetch fresh version from npm\n const latestVersion = await fetchLatestVersion();\n\n if (latestVersion) {\n writeCache({ latestVersion, checkedAt: now });\n const updateAvailable = compareVersions(latestVersion, currentVersion) > 0;\n return {\n currentVersion,\n latestVersion,\n updateAvailable,\n lastChecked: now,\n };\n }\n\n // Fetch failed, return cached or unknown state\n return {\n currentVersion,\n latestVersion: cache?.latestVersion || null,\n updateAvailable: cache\n ? compareVersions(cache.latestVersion, currentVersion) > 0\n : false,\n lastChecked: cache?.checkedAt || null,\n };\n}\n\n/**\n * Formats the upgrade notification message\n */\nexport function formatUpgradeNotification(\n currentVersion: string,\n latestVersion: string\n): string {\n return `Update available: ${currentVersion} → ${latestVersion}\\nRun: npm install -g @rotorsoft/gent`;\n}\n","{\n \"name\": \"@rotorsoft/gent\",\n \"version\": \"1.20.1\",\n \"description\": \"AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs\",\n \"keywords\": [\n \"cli\",\n \"ai\",\n \"claude\",\n \"github\",\n \"workflow\",\n \"automation\",\n \"developer-tools\"\n ],\n \"homepage\": \"https://github.com/rotorsoft/gent#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/rotorsoft/gent/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/rotorsoft/gent.git\"\n },\n \"license\": \"MIT\",\n \"author\": \"Rotorsoft\",\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\"\n }\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"bin\": {\n \"gent\": \"./dist/index.js\"\n },\n \"files\": [\n \"dist\",\n \"templates\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsx src/index.ts\",\n \"watch\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"lint\": \"eslint src/\",\n \"lint:fix\": \"eslint src/ --fix\",\n \"format\": \"prettier --write \\\"src/**/*.ts\\\"\",\n \"format:check\": \"prettier --check \\\"src/**/*.ts\\\"\",\n \"typecheck\": \"tsc --noEmit\",\n \"prepublishOnly\": \"npm run build\",\n \"prepare\": \"npm run build\"\n },\n \"dependencies\": {\n \"chalk\": \"^5.3.0\",\n \"commander\": \"^12.1.0\",\n \"execa\": \"^9.5.2\",\n \"inquirer\": \"^12.2.0\",\n \"ora\": \"^8.1.1\",\n \"yaml\": \"^2.6.1\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.17.0\",\n \"@semantic-release/changelog\": \"^6.0.3\",\n \"@semantic-release/git\": \"^10.0.1\",\n \"@types/inquirer\": \"^9.0.7\",\n \"@types/node\": \"^22.10.5\",\n \"@typescript-eslint/eslint-plugin\": \"^8.19.1\",\n \"@typescript-eslint/parser\": \"^8.19.1\",\n \"@vitest/coverage-v8\": \"^2.1.8\",\n \"eslint\": \"^9.17.0\",\n \"eslint-config-prettier\": \"^9.1.0\",\n \"prettier\": \"^3.4.2\",\n \"semantic-release\": \"^24.2.1\",\n \"tsup\": \"^8.3.5\",\n \"tsx\": \"^4.21.0\",\n \"typescript\": \"^5.7.3\",\n \"vitest\": \"^2.1.8\"\n },\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}\n","import { logger, colors } from \"../utils/logger.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { getIssue, getPrStatus, getPrReviewData } from \"../lib/github.js\";\nimport {\n getCurrentBranch,\n isOnMainBranch,\n hasUncommittedChanges,\n getUnpushedCommits,\n getCommitsSinceBase,\n getDefaultBranch,\n getLastCommitTimestamp,\n} from \"../lib/git.js\";\nimport { extractIssueNumber, parseBranchName } from \"../lib/branch.js\";\nimport { getWorkflowLabels } from \"../lib/labels.js\";\nimport { progressExists, readProgress } from \"../lib/progress.js\";\nimport { configExists } from \"../lib/config.js\";\nimport {\n checkGhAuth,\n checkClaudeCli,\n checkGeminiCli,\n checkGitRepo,\n} from \"../utils/validators.js\";\nimport { getProviderDisplayName } from \"../lib/ai-provider.js\";\nimport { getVersion } from \"../lib/version.js\";\nimport {\n summarizeReviewFeedback,\n type ReviewFeedbackItem,\n} from \"../lib/review-feedback.js\";\n\nfunction formatPrState(\n state: \"open\" | \"closed\" | \"merged\",\n isDraft: boolean\n): string {\n if (state === \"merged\") {\n return \"Merged\";\n }\n if (state === \"closed\") {\n return \"Closed\";\n }\n return isDraft ? \"Open (Draft)\" : \"Open\";\n}\n\nfunction formatReviewDecision(decision: string): string {\n switch (decision) {\n case \"APPROVED\":\n return \"Approved\";\n case \"CHANGES_REQUESTED\":\n return \"Changes Requested\";\n case \"REVIEW_REQUIRED\":\n return \"Review Required\";\n default:\n return decision.replace(/_/g, \" \").toLowerCase();\n }\n}\n\nfunction formatFeedbackLocation(item: ReviewFeedbackItem): string {\n if (item.path && item.line) {\n return `${item.path}:${item.line}`;\n }\n if (item.path) {\n return item.path;\n }\n if (item.source === \"review\") {\n const stateLabel = item.state\n ? item.state.replace(/_/g, \" \").toLowerCase()\n : \"review\";\n return `[${stateLabel}]`;\n }\n return \"[comment]\";\n}\n\nfunction truncateFeedbackBody(body: string, maxLength: number): string {\n const normalized = body.replace(/\\s+/g, \" \").trim();\n if (normalized.length <= maxLength) {\n return normalized;\n }\n return `${normalized.slice(0, maxLength - 3)}...`;\n}\n\nexport async function statusCommand(): Promise<void> {\n const version = getVersion();\n logger.bold(`Gent Workflow Status ${colors.label(`v${version}`)}`);\n logger.newline();\n\n // Check prerequisites\n const gitRepo = await checkGitRepo();\n if (!gitRepo) {\n logger.error(\"Not a git repository.\");\n process.exit(1);\n }\n\n const config = loadConfig();\n const workflowLabels = getWorkflowLabels(config);\n\n // Configuration status\n logger.bold(\"Configuration:\");\n if (configExists()) {\n logger.success(\" .gent.yml found\");\n } else {\n logger.warning(\" .gent.yml not found - using defaults\");\n }\n\n if (progressExists(config)) {\n const progress = readProgress(config);\n const lines = progress.split(\"\\n\").length;\n logger.success(` ${config.progress.file} found (${lines} lines)`);\n } else {\n logger.warning(` ${config.progress.file} not found`);\n }\n\n logger.newline();\n\n // AI Provider status\n logger.bold(\"AI Provider:\");\n const providerName = getProviderDisplayName(config.ai.provider);\n logger.info(` Active: ${colors.provider(providerName)}`);\n if (config.ai.fallback_provider) {\n const fallbackName = getProviderDisplayName(config.ai.fallback_provider);\n logger.info(\n ` Fallback: ${fallbackName} (auto: ${config.ai.auto_fallback ? \"enabled\" : \"disabled\"})`\n );\n }\n logger.newline();\n\n // Prerequisites\n logger.bold(\"Prerequisites:\");\n const ghAuth = await checkGhAuth();\n if (ghAuth) {\n logger.success(\" GitHub CLI authenticated\");\n } else {\n logger.error(\" GitHub CLI not authenticated\");\n }\n\n // Check all AI providers\n const claudeOk = await checkClaudeCli();\n const geminiOk = await checkGeminiCli();\n\n const getProviderStatus = (provider: \"claude\" | \"gemini\"): string => {\n const isActive = config.ai.provider === provider;\n const isFallback = config.ai.fallback_provider === provider;\n const suffix = isActive ? \" (active)\" : isFallback ? \" (fallback)\" : \"\";\n return suffix;\n };\n\n if (claudeOk) {\n logger.success(` Claude CLI available${getProviderStatus(\"claude\")}`);\n } else {\n logger.error(` Claude CLI not found${getProviderStatus(\"claude\")}`);\n }\n\n if (geminiOk) {\n logger.success(` Gemini CLI available${getProviderStatus(\"gemini\")}`);\n } else {\n logger.error(` Gemini CLI not found${getProviderStatus(\"gemini\")}`);\n }\n\n logger.newline();\n\n // Git status\n logger.bold(\"Git Status:\");\n const currentBranch = await getCurrentBranch();\n const onMain = await isOnMainBranch();\n const uncommitted = await hasUncommittedChanges();\n const baseBranch = await getDefaultBranch();\n\n logger.info(` Branch: ${colors.branch(currentBranch)}`);\n\n if (onMain) {\n logger.info(\" On main branch - ready to start new work\");\n } else {\n const branchInfo = parseBranchName(currentBranch);\n if (branchInfo) {\n logger.info(` Issue: ${colors.issue(`#${branchInfo.issueNumber}`)}`);\n logger.info(` Type: ${branchInfo.type}`);\n }\n\n const commits = await getCommitsSinceBase(baseBranch);\n logger.info(` Commits ahead of ${baseBranch}: ${commits.length}`);\n\n const unpushed = await getUnpushedCommits();\n if (unpushed) {\n logger.warning(\" Has unpushed commits\");\n } else {\n logger.success(\" Up to date with remote\");\n }\n }\n\n if (uncommitted) {\n logger.warning(\" Has uncommitted changes\");\n }\n\n logger.newline();\n\n // Linked issue status and PR status (only when not on main)\n let prStatus: Awaited<ReturnType<typeof getPrStatus>> = null;\n let hasActionableFeedback = false;\n\n if (!onMain) {\n const issueNumber = extractIssueNumber(currentBranch);\n if (issueNumber) {\n logger.bold(\"Linked Issue:\");\n try {\n const issue = await getIssue(issueNumber);\n logger.info(` #${issue.number}: ${issue.title}`);\n logger.info(` State: ${issue.state}`);\n logger.info(` Labels: ${issue.labels.join(\", \")}`);\n\n // Check workflow status\n if (issue.labels.includes(workflowLabels.ready)) {\n logger.info(` Workflow: ${colors.label(\"ai-ready\")}`);\n } else if (issue.labels.includes(workflowLabels.inProgress)) {\n logger.info(` Workflow: ${colors.label(\"ai-in-progress\")}`);\n } else if (issue.labels.includes(workflowLabels.completed)) {\n logger.info(` Workflow: ${colors.label(\"ai-completed\")}`);\n } else if (issue.labels.includes(workflowLabels.blocked)) {\n logger.info(` Workflow: ${colors.label(\"ai-blocked\")}`);\n }\n } catch {\n logger.warning(` Could not fetch issue #${issueNumber}`);\n }\n logger.newline();\n }\n\n // PR status\n logger.bold(\"Pull Request:\");\n prStatus = await getPrStatus();\n if (prStatus) {\n const stateDisplay = formatPrState(prStatus.state, prStatus.isDraft);\n logger.info(` PR #${prStatus.number}: ${stateDisplay}`);\n logger.info(` ${colors.url(prStatus.url)}`);\n\n if (prStatus.state === \"open\") {\n // Fetch review data to show actionable feedback\n try {\n const lastCommitTimestamp = await getLastCommitTimestamp();\n const reviewData = await getPrReviewData(prStatus.number);\n const { items } = summarizeReviewFeedback(reviewData, {\n afterTimestamp: lastCommitTimestamp,\n });\n hasActionableFeedback = items.length > 0;\n\n if (prStatus.reviewDecision) {\n logger.info(\n ` Review: ${formatReviewDecision(prStatus.reviewDecision)}`\n );\n }\n\n if (items.length > 0) {\n logger.warning(\n ` ${items.length} actionable comment${items.length > 1 ? \"s\" : \"\"} to fix with ${colors.command(\"gent fix\")}:`\n );\n for (const item of items) {\n const location = formatFeedbackLocation(item);\n const body = truncateFeedbackBody(item.body, 60);\n logger.dim(` ${location}: ${body}`);\n }\n } else if (prStatus.reviewDecision === \"APPROVED\") {\n logger.success(\" Ready to merge!\");\n } else {\n logger.info(\" No actionable review comments\");\n }\n } catch {\n // Silently ignore review data fetch errors\n }\n } else if (prStatus.state === \"merged\") {\n logger.success(\" This PR has been merged!\");\n logger.dim(\n ` Run ${colors.command(\"git checkout main && git pull\")} to sync`\n );\n } else if (prStatus.state === \"closed\") {\n logger.warning(\" This PR was closed without merging\");\n logger.dim(\n ` Consider reopening or creating a new PR if changes are still needed`\n );\n }\n } else {\n logger.info(\" No PR created yet\");\n logger.dim(` Run ${colors.command(\"gent pr\")} to create one`);\n }\n logger.newline();\n }\n\n // Suggestions\n logger.bold(\"Suggested Actions:\");\n if (onMain) {\n logger.list([\n `${colors.command(\"gent list\")} - View ai-ready issues`,\n `${colors.command(\"gent run --auto\")} - Start working on highest priority issue`,\n `${colors.command(\"gent create <description>\")} - Create a new ticket`,\n ]);\n } else if (!prStatus) {\n logger.list([\n `${colors.command(\"gent pr\")} - Create a pull request`,\n `${colors.command(\"git push\")} - Push your changes`,\n ]);\n } else if (prStatus.state === \"merged\") {\n logger.list([\n `${colors.command(\"git checkout main && git pull\")} - Sync with merged changes`,\n ]);\n } else if (prStatus.state === \"closed\") {\n logger.list([\n `Reopen the PR if changes are still needed`,\n `${colors.command(\"git checkout main\")} - Return to main branch`,\n ]);\n } else if (hasActionableFeedback) {\n logger.list([\n `${colors.command(\"gent fix\")} - Address review comments with AI`,\n `${colors.command(\"git push\")} - Push any local changes`,\n ]);\n } else {\n logger.list([\n `Review and merge your PR`,\n `${colors.command(\"git checkout main\")} - Return to main branch`,\n ]);\n }\n}\n","import { execa } from \"execa\";\nimport { aggregateState, type TuiState } from \"../tui/state.js\";\nimport { getAvailableActions, type TuiAction } from \"../tui/actions.js\";\nimport {\n renderDashboard,\n buildDashboardLines,\n renderActionPanel,\n clearScreen,\n} from \"../tui/display.js\";\nimport {\n showConfirm,\n showSelect,\n showInput,\n showMultilineInput,\n showStatus,\n type SelectEntry,\n} from \"../tui/modal.js\";\nimport { checkForUpdates, type VersionCheckResult } from \"../lib/version.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { aiSpinnerText } from \"../utils/spinner.js\";\nimport { createCommand } from \"./create.js\";\nimport { prCommand } from \"./pr.js\";\nimport { buildTicketChoices } from \"./list.js\";\nimport { githubRemoteCommand } from \"./github-remote.js\";\nimport {\n buildCommitMessagePrompt,\n buildImplementationPrompt,\n} from \"../lib/prompts.js\";\nimport {\n invokeAI,\n invokeAIInteractive,\n getProviderDisplayName,\n getProviderEmail,\n} from \"../lib/ai-provider.js\";\nimport {\n loadAgentInstructions,\n loadConfig,\n setRuntimeProvider,\n} from \"../lib/config.js\";\nimport { readProgress } from \"../lib/progress.js\";\nimport { listIssues, listOpenPrs } from \"../lib/github.js\";\nimport {\n getCurrentBranch,\n getDefaultBranch,\n hasUncommittedChanges,\n branchExists,\n checkoutBranch,\n createBranch,\n listLocalBranches,\n remoteBranchExists,\n fetchAndCheckout,\n} from \"../lib/git.js\";\nimport { getWorkflowLabels, sortByPriority } from \"../lib/labels.js\";\nimport { generateBranchName } from \"../lib/branch.js\";\nimport type { AIProvider } from \"../types/index.js\";\n\nconst CANCEL = Symbol(\"cancel\");\n\nasync function waitForKey(validKeys: string[]): Promise<string> {\n return new Promise((resolve) => {\n const { stdin } = process;\n const wasRaw = stdin.isRaw;\n stdin.setRawMode(true);\n stdin.resume();\n stdin.setEncoding(\"utf8\");\n\n const onData = (key: string) => {\n // Handle Ctrl+C\n if (key === \"\\x03\") {\n stdin.setRawMode(wasRaw ?? false);\n stdin.pause();\n stdin.removeListener(\"data\", onData);\n resolve(\"q\");\n return;\n }\n\n if (validKeys.includes(key)) {\n stdin.setRawMode(wasRaw ?? false);\n stdin.pause();\n stdin.removeListener(\"data\", onData);\n resolve(key);\n }\n };\n\n stdin.on(\"data\", onData);\n });\n}\n\nexport interface ActionResult {\n running: boolean;\n refresh: boolean;\n}\n\nconst CONTINUE: ActionResult = { running: true, refresh: true };\nconst SKIP_REFRESH: ActionResult = { running: true, refresh: false };\nconst QUIT: ActionResult = { running: false, refresh: false };\n\nexport async function executeAction(\n actionId: string,\n state: TuiState,\n dashboardLines: string[]\n): Promise<ActionResult> {\n switch (actionId) {\n case \"quit\":\n return QUIT;\n\n case \"list\": {\n const switched = await handleList(dashboardLines);\n return switched ? CONTINUE : SKIP_REFRESH;\n }\n\n case \"create\": {\n const description = await showMultilineInput({\n title: \"New Ticket\",\n label: \"Describe the ticket:\",\n dashboardLines,\n });\n if (!description) return SKIP_REFRESH;\n\n clearScreen();\n try {\n await createCommand(description, {});\n } catch (error) {\n logger.error(`Create failed: ${error}`);\n }\n return CONTINUE;\n }\n\n case \"commit\": {\n const committed = await handleCommit(state, dashboardLines);\n return committed ? CONTINUE : SKIP_REFRESH;\n }\n\n case \"push\":\n await handlePush(dashboardLines);\n return CONTINUE;\n\n case \"pr\": {\n clearScreen();\n await prCommand({});\n return CONTINUE;\n }\n\n case \"run\": {\n await handleRun(state);\n return CONTINUE;\n }\n\n case \"github-remote\": {\n const confirmed = await showConfirm({\n title: \"Push to GitHub\",\n message: \"Create a private GitHub repo and push?\",\n dashboardLines,\n });\n if (!confirmed) return SKIP_REFRESH;\n showStatus(\"Pushing\", \"Creating GitHub repo and pushing...\", dashboardLines);\n await githubRemoteCommand();\n return CONTINUE;\n }\n\n case \"switch-provider\":\n await handleSwitchProvider(state, dashboardLines);\n return SKIP_REFRESH;\n\n case \"refresh\":\n return CONTINUE;\n\n default:\n return SKIP_REFRESH;\n }\n}\n\n/** Returns true if a commit was made. */\nasync function handleCommit(\n state: TuiState,\n dashboardLines: string[]\n): Promise<boolean> {\n try {\n const { stdout: status } = await execa(\"git\", [\"status\", \"--short\"]);\n if (!status.trim()) {\n showStatus(\"Commit\", \"No changes to commit\", dashboardLines);\n await new Promise((r) => setTimeout(r, 1500));\n return false;\n }\n\n // Stage all changes\n await execa(\"git\", [\"add\", \"-A\"]);\n\n // Get staged diff for AI commit message generation\n const { stdout: diffStat } = await execa(\"git\", [\n \"diff\",\n \"--cached\",\n \"--stat\",\n ]);\n const { stdout: diffPatch } = await execa(\"git\", [\"diff\", \"--cached\"]);\n const diffContent = (diffStat + \"\\n\\n\" + diffPatch).slice(0, 4000);\n\n const issueNumber = state.issue?.number ?? null;\n const issueTitle = state.issue?.title ?? null;\n const provider = state.config.ai.provider;\n const providerName = getProviderDisplayName(provider);\n\n // Modal select: AI or Manual\n const mode = await showSelect({\n title: \"Commit\",\n items: [\n { name: `Generate with ${providerName}`, value: \"ai\" },\n { name: \"Enter manually\", value: \"manual\" },\n ],\n dashboardLines,\n });\n\n if (!mode) {\n await execa(\"git\", [\"reset\", \"HEAD\"]);\n return false;\n }\n\n let message: string | typeof CANCEL;\n\n if (mode === \"manual\") {\n const input = await showInput({\n title: \"Commit Message\",\n label: \"Enter commit message:\",\n dashboardLines,\n });\n message = input || CANCEL;\n } else {\n showStatus(\"Generating\", aiSpinnerText(providerName, \"generate commit message\"), dashboardLines);\n message = await generateCommitMessage(\n diffContent,\n issueNumber,\n issueTitle,\n state,\n dashboardLines\n );\n }\n\n if (message === CANCEL) {\n await execa(\"git\", [\"reset\", \"HEAD\"]);\n return false;\n }\n\n // Confirm commit with generated message\n const confirmed = await showConfirm({\n title: \"Commit\",\n message: `Message: ${message.length > 50 ? message.slice(0, 50) + \"…\" : message}`,\n dashboardLines,\n });\n\n if (!confirmed) {\n await execa(\"git\", [\"reset\", \"HEAD\"]);\n return false;\n }\n\n const providerEmail = getProviderEmail(provider);\n const fullMessage = `${message}\\n\\nCo-Authored-By: ${providerName} <${providerEmail}>`;\n\n showStatus(\"Committing\", \"Committing changes...\", dashboardLines);\n await execa(\"git\", [\"commit\", \"-m\", fullMessage]);\n return true;\n } catch (error) {\n logger.error(`Commit failed: ${error}`);\n return false;\n }\n}\n\nasync function generateCommitMessage(\n diffContent: string,\n issueNumber: number | null,\n issueTitle: string | null,\n state: TuiState,\n dashboardLines: string[]\n): Promise<string | typeof CANCEL> {\n try {\n const prompt = buildCommitMessagePrompt(\n diffContent,\n issueNumber,\n issueTitle\n );\n const result = await invokeAI({ prompt, streamOutput: false }, state.config);\n let message = result.output.trim().split(\"\\n\")[0].trim();\n // Strip wrapping quotes, backticks, or code fences\n for (const q of ['\"', \"'\", \"`\"]) {\n if (message.startsWith(q) && message.endsWith(q)) {\n message = message.slice(1, -1);\n break;\n }\n }\n message = message.replace(/^```\\w*\\s*/, \"\").replace(/\\s*```$/, \"\");\n return message;\n } catch {\n // AI failed — fall back to manual input\n const input = await showInput({\n title: \"Commit Message\",\n label: \"AI generation failed. Enter commit message:\",\n dashboardLines,\n });\n return input || CANCEL;\n }\n}\n\nasync function handleRun(state: TuiState): Promise<void> {\n if (!state.issue) {\n logger.error(\"No linked issue found\");\n return;\n }\n\n const agentInstructions = loadAgentInstructions();\n const progressContent = readProgress(state.config);\n\n // Build context based on current state\n const contextParts: string[] = [];\n\n if (state.commits.length > 0) {\n contextParts.push(\n `## Current Progress\\nThere are ${state.commits.length} existing commit(s) on this branch:\\n${state.commits.map((c) => `- ${c}`).join(\"\\n\")}\\n\\nContinue the implementation from where it left off. Review the existing work and complete any remaining tasks.`\n );\n }\n\n if (state.hasActionableFeedback && state.reviewFeedback.length > 0) {\n const feedbackLines = state.reviewFeedback\n .map((f) => `- [${f.source}] ${f.body.slice(0, 200)}`)\n .join(\"\\n\");\n contextParts.push(`## Review Feedback\\n${feedbackLines}`);\n }\n\n const extraContext =\n contextParts.length > 0 ? contextParts.join(\"\\n\\n\") : null;\n\n const prompt = buildImplementationPrompt(\n state.issue,\n agentInstructions,\n progressContent,\n state.config,\n extraContext\n );\n\n const providerName = getProviderDisplayName(state.config.ai.provider);\n\n clearScreen();\n renderActionPanel(`${providerName} Session`, [\n `Implementing: #${state.issue.number} ${state.issue.title}`,\n state.commits.length > 0\n ? `Continuing from ${state.commits.length} existing commit(s)`\n : \"Starting fresh implementation\",\n ...(state.hasActionableFeedback\n ? [`Includes ${state.reviewFeedback.length} review feedback item(s)`]\n : []),\n ]);\n console.log();\n\n try {\n const { result } = await invokeAIInteractive(prompt, state.config);\n await result;\n } catch (error) {\n logger.error(`${providerName} session failed: ${error}`);\n }\n}\n\nasync function handlePush(dashboardLines: string[]): Promise<void> {\n try {\n const { stdout: branch } = await execa(\"git\", [\"branch\", \"--show-current\"]);\n const branchName = branch.trim();\n\n showStatus(\"Pushing\", `Pushing ${branchName} to remote...`, dashboardLines);\n await execa(\"git\", [\"push\", \"-u\", \"origin\", branchName]);\n } catch (error) {\n logger.error(`Push failed: ${error}`);\n }\n}\n\nconst PROVIDERS: AIProvider[] = [\"claude\", \"gemini\", \"codex\"];\n\nasync function handleSwitchProvider(\n state: TuiState,\n dashboardLines: string[]\n): Promise<void> {\n const current = state.config.ai.provider;\n const items = PROVIDERS.map((p) => ({\n name:\n p.charAt(0).toUpperCase() +\n p.slice(1) +\n (p === current ? \" (current)\" : \"\"),\n value: p,\n }));\n\n const provider = await showSelect({\n title: \"AI Provider\",\n items,\n dashboardLines,\n });\n\n if (!provider || provider === current) return;\n\n setRuntimeProvider(provider as AIProvider);\n // Update in-memory state so dashboard re-renders with new provider\n state.config.ai.provider = provider as AIProvider;\n}\n\n/** Returns true if a branch switch occurred. */\nasync function handleList(\n dashboardLines: string[]\n): Promise<boolean> {\n try {\n showStatus(\"Loading\", \"Fetching tickets...\", dashboardLines);\n\n const config = loadConfig();\n const workflowLabels = getWorkflowLabels(config);\n\n const [inProgress, ready, prs, localBranches, dirty] = await Promise.all([\n listIssues({\n labels: [workflowLabels.inProgress],\n state: \"open\",\n limit: 20,\n }),\n listIssues({\n labels: [workflowLabels.ready],\n state: \"open\",\n limit: 20,\n }),\n listOpenPrs(30),\n listLocalBranches(),\n hasUncommittedChanges(),\n ]);\n\n sortByPriority(inProgress);\n sortByPriority(ready);\n\n const choices = buildTicketChoices(inProgress, ready, prs, localBranches);\n const currentBranch = await getCurrentBranch();\n const defaultBranch = await getDefaultBranch();\n\n // Build modal select entries with category separators\n const items: SelectEntry[] = [];\n let initialIndex = 0;\n let selectableIdx = 0;\n\n // Main branch option\n const isMain = currentBranch === defaultBranch;\n const mainLabel = defaultBranch + (isMain ? \" (current)\" : \"\");\n\n if (dirty && !isMain) {\n items.push({\n name: `${mainLabel} (disabled - uncommitted changes)`,\n value: \"__main_disabled__\",\n });\n } else {\n items.push({ name: mainLabel, value: \"__main__\" });\n }\n if (isMain) initialIndex = selectableIdx;\n selectableIdx++;\n\n const inProgressChoices = choices.filter(\n (c) => c.category === \"in-progress\"\n );\n const openPrChoices = choices.filter((c) => c.category === \"open-pr\");\n const readyChoices = choices.filter((c) => c.category === \"ready\");\n\n const addChoices = (list: typeof choices) => {\n for (const c of list) {\n const isCurrent = c.branch === currentBranch;\n items.push({\n name: `#${c.issueNumber} ${c.title}`,\n value: String(c.issueNumber),\n });\n if (isCurrent) initialIndex = selectableIdx;\n selectableIdx++;\n }\n };\n\n if (inProgressChoices.length > 0) {\n items.push({ separator: \"── In Progress ──\" });\n addChoices(inProgressChoices);\n }\n if (openPrChoices.length > 0) {\n items.push({ separator: \"── Open PRs ──\" });\n addChoices(openPrChoices);\n }\n if (readyChoices.length > 0) {\n items.push({ separator: \"── Ready ──\" });\n addChoices(readyChoices);\n }\n\n const selected = await showSelect({\n title: \"Switch Ticket\",\n items,\n dashboardLines,\n initialIndex,\n currentIndex: initialIndex,\n });\n\n if (!selected) return false;\n\n // Handle disabled main\n if (selected === \"__main_disabled__\") {\n showStatus(\n \"Uncommitted Changes\",\n \"Commit or stash changes before switching to main\",\n dashboardLines\n );\n await new Promise((r) => setTimeout(r, 2000));\n return false;\n }\n\n // Handle main branch selection\n if (selected === \"__main__\") {\n if (currentBranch === defaultBranch) return false;\n showStatus(\"Switching\", `Switching to ${defaultBranch}...`, dashboardLines);\n await checkoutBranch(defaultBranch);\n return true;\n }\n\n // Find selected ticket\n const issueNumber = parseInt(selected, 10);\n const ticket = choices.find((c) => c.issueNumber === issueNumber);\n if (!ticket) return false;\n\n if (dirty) {\n const ok = await showConfirm({\n title: \"Uncommitted Changes\",\n message: \"You have uncommitted changes. Continue?\",\n dashboardLines,\n });\n if (!ok) return false;\n }\n\n const targetBranch = ticket.branch;\n\n if (targetBranch) {\n if (await branchExists(targetBranch)) {\n showStatus(\"Switching\", `Switching to ${targetBranch}...`, dashboardLines);\n await checkoutBranch(targetBranch);\n return true;\n } else if (await remoteBranchExists(targetBranch)) {\n showStatus(\"Fetching\", `Fetching ${targetBranch}...`, dashboardLines);\n await fetchAndCheckout(targetBranch);\n return true;\n } else {\n return await offerCreateBranch(\n issueNumber,\n ticket.title,\n dashboardLines\n );\n }\n } else {\n return await offerCreateBranch(\n issueNumber,\n ticket.title,\n dashboardLines\n );\n }\n } catch (error) {\n logger.error(`List failed: ${error}`);\n return false;\n }\n}\n\n/** Returns true if a branch was created. */\nasync function offerCreateBranch(\n issueNumber: number,\n title: string,\n dashboardLines: string[]\n): Promise<boolean> {\n const config = loadConfig();\n const branchName = await generateBranchName(\n config,\n issueNumber,\n title,\n \"feature\"\n );\n\n const create = await showConfirm({\n title: \"Create Branch\",\n message: `No branch found. Create ${branchName}?`,\n dashboardLines,\n });\n\n if (!create) return false;\n\n const defaultBranch = await getDefaultBranch();\n showStatus(\"Creating\", `Creating ${branchName}...`, dashboardLines);\n await createBranch(branchName, defaultBranch);\n return true;\n}\n\nconst VERSION_CHECK_INTERVAL_MS = 30 * 60 * 1000; // 30 minutes\n\nexport async function tuiCommand(): Promise<void> {\n let running = true;\n let lastActions: TuiAction[] = [];\n let lastDashboardLines: string[] = [];\n let versionCheck: VersionCheckResult | null = null;\n\n // Initial placeholder state for the first \"Loading...\" render\n const config = loadConfig();\n let lastState: TuiState = {\n isGitRepo: true,\n isGhAuthenticated: true,\n isAIProviderAvailable: true,\n config,\n hasConfig: true,\n hasProgress: false,\n branch: \"\",\n branchInfo: null,\n isOnMain: true,\n hasUncommittedChanges: false,\n hasUnpushedCommits: false,\n commits: [],\n baseBranch: \"main\",\n issue: null,\n workflowStatus: \"none\",\n pr: null,\n reviewFeedback: [],\n hasActionableFeedback: false,\n hasUIChanges: false,\n isPlaywrightAvailable: false,\n hasValidRemote: true,\n };\n\n let needsRefresh = true;\n let isFirstLoad = true;\n\n while (running) {\n if (needsRefresh) {\n // Show dashboard with refreshing indicator while loading new state\n clearScreen();\n renderDashboard(lastState, lastActions, undefined, true, versionCheck);\n\n // Fire version check in parallel with state aggregation (non-blocking)\n // Force a fresh check on first load (interval=0), then throttle subsequent checks\n const checkInterval = isFirstLoad ? 0 : VERSION_CHECK_INTERVAL_MS;\n isFirstLoad = false;\n const [state, versionResult] = await Promise.all([\n aggregateState(),\n checkForUpdates(checkInterval).catch(() => null),\n ]);\n const actions = getAvailableActions(state);\n\n // Save for next refresh cycle\n lastState = state;\n lastActions = actions;\n if (versionResult) versionCheck = versionResult;\n }\n\n // Contextual hint\n let hint: string | undefined;\n if (lastState.isOnMain) {\n hint = \"Select an action to get started\";\n } else if (lastState.hasUncommittedChanges && !lastState.pr) {\n hint = \"Commit your changes before creating a PR\";\n } else if (lastState.hasActionableFeedback) {\n hint = \"Review feedback needs attention\";\n }\n\n // Build and render dashboard, capturing lines for modal overlays\n lastDashboardLines = buildDashboardLines(lastState, lastActions, hint, false, versionCheck);\n clearScreen();\n for (const line of lastDashboardLines) {\n console.log(line);\n }\n\n // Wait for a valid keypress\n const validKeys = lastActions.map((a) => a.shortcut);\n const key = await waitForKey(validKeys);\n\n // Find the matching action\n const action = lastActions.find((a) => a.shortcut === key);\n if (action) {\n const result = await executeAction(action.id, lastState, lastDashboardLines);\n running = result.running;\n needsRefresh = result.refresh;\n }\n }\n}\n","import { loadConfig, configExists } from \"../lib/config.js\";\nimport {\n getIssue,\n getPrStatus,\n getPrReviewData,\n type PrStatusInfo,\n} from \"../lib/github.js\";\nimport {\n getCurrentBranch,\n isOnMainBranch,\n hasUncommittedChanges,\n getUnpushedCommits,\n getCommitsSinceBase,\n getDefaultBranch,\n getLastCommitTimestamp,\n getRepoInfo,\n} from \"../lib/git.js\";\nimport { extractIssueNumber, parseBranchName } from \"../lib/branch.js\";\nimport { getWorkflowLabels } from \"../lib/labels.js\";\nimport { progressExists } from \"../lib/progress.js\";\nimport {\n checkGhAuth,\n checkAIProvider,\n checkGitRepo,\n} from \"../utils/validators.js\";\nimport {\n summarizeReviewFeedback,\n type ReviewFeedbackItem,\n} from \"../lib/review-feedback.js\";\nimport {\n hasUIChanges,\n getChangedFiles,\n isPlaywrightAvailable,\n} from \"../lib/playwright.js\";\nimport type { GentConfig, GitHubIssue, BranchInfo } from \"../types/index.js\";\n\nexport type WorkflowStatus =\n | \"ready\"\n | \"in-progress\"\n | \"completed\"\n | \"blocked\"\n | \"none\";\n\nexport interface TuiState {\n // Prerequisites\n isGitRepo: boolean;\n isGhAuthenticated: boolean;\n isAIProviderAvailable: boolean;\n\n // Configuration\n config: GentConfig;\n hasConfig: boolean;\n hasProgress: boolean;\n\n // Git state\n branch: string;\n branchInfo: BranchInfo | null;\n isOnMain: boolean;\n hasUncommittedChanges: boolean;\n hasUnpushedCommits: boolean;\n commits: string[];\n baseBranch: string;\n\n // Issue state\n issue: GitHubIssue | null;\n workflowStatus: WorkflowStatus;\n\n // PR state\n pr: PrStatusInfo | null;\n reviewFeedback: ReviewFeedbackItem[];\n hasActionableFeedback: boolean;\n\n // UI changes detection\n hasUIChanges: boolean;\n isPlaywrightAvailable: boolean;\n\n // Remote detection\n hasValidRemote: boolean;\n}\n\n// Session-level cache for environment checks that don't change mid-session\nlet envCache: {\n isGhAuthenticated: boolean;\n isAIProviderAvailable: boolean;\n isPlaywrightAvailable: boolean;\n} | null = null;\n\n/** Reset the environment cache (for testing). */\nexport function resetEnvCache(): void {\n envCache = null;\n}\n\nexport async function aggregateState(): Promise<TuiState> {\n // Check prerequisites first\n const isGitRepo = await checkGitRepo();\n if (!isGitRepo) {\n // Return minimal state for non-git directories\n const config = loadConfig();\n return {\n isGitRepo: false,\n isGhAuthenticated: false,\n isAIProviderAvailable: false,\n config,\n hasConfig: false,\n hasProgress: false,\n branch: \"\",\n branchInfo: null,\n isOnMain: false,\n hasUncommittedChanges: false,\n hasUnpushedCommits: false,\n commits: [],\n baseBranch: \"main\",\n issue: null,\n workflowStatus: \"none\",\n pr: null,\n reviewFeedback: [],\n hasActionableFeedback: false,\n hasUIChanges: false,\n isPlaywrightAvailable: false,\n hasValidRemote: false,\n };\n }\n\n const config = loadConfig();\n const workflowLabels = getWorkflowLabels(config);\n\n // Check environment once per session (these don't change mid-session)\n if (!envCache) {\n const [ghAuth, aiAvail] = await Promise.all([\n checkGhAuth(),\n checkAIProvider(config.ai.provider),\n ]);\n envCache = {\n isGhAuthenticated: ghAuth,\n isAIProviderAvailable: aiAvail,\n isPlaywrightAvailable: false, // resolved below on first feature branch visit\n };\n }\n const { isGhAuthenticated, isAIProviderAvailable } = envCache;\n\n // Gather git state in parallel\n const [branch, isOnMain, uncommitted, baseBranch, repoInfo] =\n await Promise.all([\n getCurrentBranch(),\n isOnMainBranch(),\n hasUncommittedChanges(),\n getDefaultBranch(),\n getRepoInfo(),\n ]);\n\n const hasConfig = configExists();\n const hasProgress = progressExists(config);\n const branchInfo = parseBranchName(branch);\n\n // Get commits and unpushed status\n const [commits, unpushed] = await Promise.all([\n getCommitsSinceBase(baseBranch),\n getUnpushedCommits(),\n ]);\n\n // Initialize state\n let issue: GitHubIssue | null = null;\n let workflowStatus: WorkflowStatus = \"none\";\n let pr: PrStatusInfo | null = null;\n let reviewFeedback: ReviewFeedbackItem[] = [];\n let hasActionableFeedback = false;\n let uiChanges = false;\n let playwrightAvailable = false;\n\n // If not on main, fetch issue and PR data\n if (!isOnMain) {\n const issueNumber = extractIssueNumber(branch);\n\n // Fetch issue, PR status, and UI change detection in parallel\n // Playwright availability is cached per session\n const needsPlaywrightCheck = !envCache!.isPlaywrightAvailable;\n const [issueResult, prResult, changedFiles, playwrightResult] =\n await Promise.all([\n issueNumber\n ? getIssue(issueNumber).catch(() => null)\n : Promise.resolve(null),\n getPrStatus().catch(() => null),\n getChangedFiles(baseBranch),\n needsPlaywrightCheck\n ? isPlaywrightAvailable()\n : Promise.resolve(envCache!.isPlaywrightAvailable),\n ]);\n\n issue = issueResult;\n pr = prResult;\n uiChanges = hasUIChanges(changedFiles);\n playwrightAvailable = playwrightResult;\n if (needsPlaywrightCheck) {\n envCache!.isPlaywrightAvailable = playwrightResult;\n }\n\n // Determine workflow status from labels\n if (issue) {\n if (issue.labels.includes(workflowLabels.ready)) {\n workflowStatus = \"ready\";\n } else if (issue.labels.includes(workflowLabels.inProgress)) {\n workflowStatus = \"in-progress\";\n } else if (issue.labels.includes(workflowLabels.completed)) {\n workflowStatus = \"completed\";\n } else if (issue.labels.includes(workflowLabels.blocked)) {\n workflowStatus = \"blocked\";\n }\n }\n\n // Fetch review feedback if PR exists and is open\n if (pr && pr.state === \"open\") {\n try {\n const lastCommitTimestamp = await getLastCommitTimestamp();\n const reviewData = await getPrReviewData(pr.number);\n const { items } = summarizeReviewFeedback(reviewData, {\n afterTimestamp: lastCommitTimestamp,\n });\n reviewFeedback = items;\n hasActionableFeedback = items.length > 0;\n } catch {\n // Ignore review data fetch errors\n }\n }\n }\n\n return {\n isGitRepo,\n isGhAuthenticated,\n isAIProviderAvailable,\n config,\n hasConfig,\n hasProgress,\n branch,\n branchInfo,\n isOnMain,\n hasUncommittedChanges: uncommitted,\n hasUnpushedCommits: unpushed,\n commits,\n baseBranch,\n issue,\n workflowStatus,\n pr,\n reviewFeedback,\n hasActionableFeedback,\n hasUIChanges: uiChanges,\n isPlaywrightAvailable: playwrightAvailable,\n hasValidRemote: repoInfo !== null,\n };\n}\n","import type { TuiState } from \"./state.js\";\n\nexport interface TuiAction {\n id: string;\n label: string;\n shortcut: string;\n}\n\nexport function getAvailableActions(state: TuiState): TuiAction[] {\n const actions: TuiAction[] = [];\n\n if (!state.isGitRepo || !state.isGhAuthenticated) {\n actions.push({ id: \"quit\", label: \"quit\", shortcut: \"q\" });\n return actions;\n }\n\n // Common actions available everywhere (gated on valid remote for GitHub-dependent actions)\n if (state.hasValidRemote) {\n actions.push({ id: \"create\", label: \"new\", shortcut: \"n\" });\n }\n\n // On feature branch - add context-aware actions BEFORE other common actions\n if (!state.isOnMain) {\n if (state.hasUncommittedChanges) {\n actions.push({ id: \"commit\", label: \"commit\", shortcut: \"c\" });\n }\n\n if (state.hasUnpushedCommits && state.commits.length > 0) {\n actions.push({ id: \"push\", label: \"push\", shortcut: \"s\" });\n }\n\n if (state.hasValidRemote && !state.pr && state.commits.length > 0) {\n actions.push({ id: \"pr\", label: \"pr\", shortcut: \"p\" });\n }\n\n if (state.issue && state.pr?.state !== \"merged\") {\n actions.push({ id: \"run\", label: \"run\", shortcut: \"r\" });\n }\n }\n\n // Common navigation/config actions\n if (state.hasValidRemote) {\n actions.push({ id: \"list\", label: \"list\", shortcut: \"l\" });\n } else {\n actions.push({ id: \"github-remote\", label: \"github\", shortcut: \"g\" });\n }\n actions.push({ id: \"refresh\", label: \"refresh\", shortcut: \"f\" });\n actions.push({ id: \"switch-provider\", label: \"ai\", shortcut: \"a\" });\n actions.push({ id: \"quit\", label: \"quit\", shortcut: \"q\" });\n\n return actions;\n}\n","import chalk from \"chalk\";\nimport { getProviderDisplayName } from \"../lib/ai-provider.js\";\nimport { getVersion, type VersionCheckResult } from \"../lib/version.js\";\nimport type { TuiAction } from \"./actions.js\";\nimport type { TuiState } from \"./state.js\";\n\n// eslint-disable-next-line no-control-regex\nexport const stripAnsi = (str: string) => str.replace(/\\x1b\\[[0-9;]*m/g, \"\");\nexport const visibleLen = (str: string) => stripAnsi(str).length;\n\nexport function truncateAnsi(text: string, max: number): string {\n if (visibleLen(text) <= max) return text;\n // Walk through the string, tracking visible characters\n let visible = 0;\n let i = 0;\n while (i < text.length && visible < max - 1) {\n if (text[i] === \"\\x1b\") {\n // Skip ANSI escape sequence\n const end = text.indexOf(\"m\", i);\n if (end !== -1) {\n i = end + 1;\n continue;\n }\n }\n visible++;\n i++;\n }\n // Include any trailing ANSI reset sequences\n return text.slice(0, i) + \"\\x1b[0m…\";\n}\n\nexport function termWidth(): number {\n return Math.min(process.stdout.columns || 80, 90);\n}\n\nfunction truncate(text: string, max: number): string {\n if (text.length <= max) return text;\n return text.slice(0, max - 1) + \"…\";\n}\n\nfunction extractDescription(body: string, maxLen: number): string {\n const lines = body.split(\"\\n\");\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n if (trimmed.startsWith(\"#\")) continue;\n if (trimmed.startsWith(\"---\")) continue;\n if (trimmed.startsWith(\"META:\")) continue;\n if (trimmed.startsWith(\"**Type:**\")) continue;\n const clean = trimmed\n .replace(/\\*\\*/g, \"\")\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\");\n return truncate(clean, maxLen);\n }\n return \"\";\n}\n\n// ── Box drawing ─────────────────────────────────────────────────\n\nfunction topRow(title: string, w: number): string {\n const label = ` ${title} `;\n const fill = w - 2 - label.length;\n return (\n chalk.dim(\"┌\") +\n chalk.bold.cyan(label) +\n chalk.dim(\"─\".repeat(Math.max(0, fill)) + \"┐\")\n );\n}\n\nfunction midRow(title: string, w: number): string {\n const label = ` ${title} `;\n const fill = w - 2 - label.length;\n return (\n chalk.dim(\"├\") +\n chalk.bold.cyan(label) +\n chalk.dim(\"─\".repeat(Math.max(0, fill)) + \"┤\")\n );\n}\n\nfunction divRow(w: number): string {\n return chalk.dim(\"├\" + \"─\".repeat(w - 2) + \"┤\");\n}\n\nfunction botRow(w: number): string {\n return chalk.dim(\"└\" + \"─\".repeat(w - 2) + \"┘\");\n}\n\nfunction row(text: string, w: number): string {\n const inner = w - 4;\n const fitted = truncateAnsi(text, inner);\n const pad = Math.max(0, inner - visibleLen(fitted));\n return chalk.dim(\"│\") + \" \" + fitted + \" \".repeat(pad) + \" \" + chalk.dim(\"│\");\n}\n\n// ── Formatters ──────────────────────────────────────────────────\n\nfunction workflowBadge(status: string): string {\n switch (status) {\n case \"ready\":\n return chalk.bgGreen.black(\" READY \");\n case \"in-progress\":\n return chalk.bgYellow.black(\" IN PROGRESS \");\n case \"completed\":\n return chalk.bgBlue.white(\" COMPLETED \");\n case \"blocked\":\n return chalk.bgRed.white(\" BLOCKED \");\n default:\n return \"\";\n }\n}\n\nfunction prBadge(state: \"open\" | \"closed\" | \"merged\", draft: boolean): string {\n if (state === \"merged\") return chalk.bgMagenta.white(\" MERGED \");\n if (state === \"closed\") return chalk.bgRed.white(\" CLOSED \");\n return draft\n ? chalk.bgYellow.black(\" DRAFT \")\n : chalk.bgGreen.black(\" OPEN \");\n}\n\nfunction reviewBadge(decision: string | null): string {\n if (!decision) return \"\";\n switch (decision) {\n case \"APPROVED\":\n return \" \" + chalk.green(\"Approved\");\n case \"CHANGES_REQUESTED\":\n return \" \" + chalk.red(\"Changes requested\");\n case \"REVIEW_REQUIRED\":\n return \" \" + chalk.yellow(\"Review pending\");\n default:\n return \"\";\n }\n}\n\n// Rotating color palette for shortcut keys\nconst shortcutColors = [\n chalk.cyan.bold,\n chalk.green.bold,\n chalk.yellow.bold,\n chalk.magenta.bold,\n chalk.blue.bold,\n chalk.red.bold,\n];\n\nfunction formatAction(a: TuiAction, color: (s: string) => string): string {\n const idx = a.label.indexOf(a.shortcut);\n const styledKey = color(chalk.underline(a.shortcut));\n if (idx >= 0) {\n const before = a.label.slice(0, idx);\n const after = a.label.slice(idx + a.shortcut.length);\n return chalk.dim(before) + styledKey + chalk.dim(after);\n }\n return styledKey + \" \" + chalk.dim(a.label);\n}\n\nfunction formatCommandBar(actions: TuiAction[], w: number): string[] {\n const parts = actions.map((a, i) => {\n const color = shortcutColors[i % shortcutColors.length];\n return formatAction(a, color);\n });\n const inner = w - 4;\n const lines: string[] = [];\n let cur = \"\";\n for (const part of parts) {\n const next = cur + (cur.length > 0 ? \" \" : \"\") + part;\n if (visibleLen(next) > inner) {\n lines.push(cur);\n cur = part;\n } else {\n cur = next;\n }\n }\n if (cur.length > 0) lines.push(cur);\n return lines;\n}\n\n/**\n * Render a framed panel for action output.\n * Shows a titled box with multiline content, used for command results\n * and AI interaction status within the TUI.\n */\nexport function renderActionPanel(title: string, content: string[]): void {\n const w = termWidth();\n console.log(topRow(title, w));\n for (const line of content) {\n console.log(row(line, w));\n }\n console.log(botRow(w));\n}\n\n// ── Dashboard line builder ──────────────────────────────────────\n\ntype Out = (line: string) => void;\n\nfunction renderSettingsTo(\n state: TuiState,\n w: number,\n out: Out,\n versionCheck?: VersionCheckResult | null\n): void {\n const provider = getProviderDisplayName(state.config.ai.provider);\n const provTag = state.isAIProviderAvailable\n ? chalk.green(provider)\n : chalk.red(provider);\n const ghTag = state.isGhAuthenticated\n ? chalk.green(\"authenticated\")\n : chalk.red(\"not authenticated\");\n\n out(row(chalk.dim(\"Provider: \") + provTag, w));\n out(row(chalk.dim(\"GitHub: \") + ghTag, w));\n\n if (versionCheck?.updateAvailable && versionCheck.latestVersion) {\n out(\n row(\n chalk.yellow(\n `Update available: ${versionCheck.currentVersion} → ${versionCheck.latestVersion}`\n ) +\n chalk.dim(' — run \"npm install -g @rotorsoft/gent\" to upgrade'),\n w\n )\n );\n }\n}\n\n/**\n * Build dashboard output as an array of strings.\n * Used by modals to capture dashboard state for overlay rendering.\n */\nexport function buildDashboardLines(\n state: TuiState,\n actions: TuiAction[],\n hint?: string,\n refreshing?: boolean,\n versionCheck?: VersionCheckResult | null\n): string[] {\n const lines: string[] = [];\n const out: Out = (line: string) => lines.push(line);\n const w = termWidth();\n const descMax = w - 8;\n const version = getVersion();\n\n const titleLabel = `gent v${version}`;\n out(topRow(titleLabel, w));\n renderSettingsTo(state, w, out, versionCheck);\n\n // ── Error states ──────────────────────────────────────────────\n if (!state.isGitRepo) {\n out(row(chalk.yellow(\"Not a git repository\"), w));\n out(row(chalk.dim(\"Navigate to a git repository to get started\"), w));\n out(divRow(w));\n for (const line of formatCommandBar(actions, w)) {\n out(row(line, w));\n }\n out(botRow(w));\n return lines;\n }\n if (!state.isGhAuthenticated) {\n out(row(chalk.red(\"GitHub CLI not authenticated\"), w));\n out(row(chalk.dim(\"Run: gh auth login\"), w));\n out(divRow(w));\n for (const line of formatCommandBar(actions, w)) {\n out(row(line, w));\n }\n out(botRow(w));\n return lines;\n }\n\n const section = (title: string) => {\n out(midRow(title, w));\n };\n\n // Ticket\n if (state.issue || !state.isOnMain) {\n section(\"Ticket\");\n if (state.issue) {\n out(\n row(\n chalk.dim(\"· \") +\n chalk.cyan(`#${state.issue.number}`) +\n \" \" +\n chalk.bold(state.issue.title),\n w\n )\n );\n const desc = extractDescription(state.issue.body, descMax);\n if (desc) out(row(\" \" + chalk.dim(desc), w));\n const tags: string[] = [];\n if (state.workflowStatus !== \"none\")\n tags.push(workflowBadge(state.workflowStatus));\n for (const prefix of [\"type:\", \"priority:\", \"risk:\", \"area:\"]) {\n const l = state.issue.labels.find((x) => x.startsWith(prefix));\n if (l) tags.push(chalk.dim(l));\n }\n if (tags.length) out(row(\" \" + tags.join(\" \"), w));\n } else {\n out(row(chalk.dim(\" No linked issue\"), w));\n }\n }\n\n // Branch\n section(\"Branch\");\n let branchLine = chalk.dim(\"· \") + chalk.magenta(state.branch);\n if (state.isOnMain && !state.hasUncommittedChanges) {\n branchLine += chalk.dim(\" · ready to start new work\");\n }\n out(row(branchLine, w));\n\n const bits: string[] = [];\n if (state.commits.length > 0)\n bits.push(chalk.dim(`${state.commits.length} ahead`));\n if (state.hasUncommittedChanges) bits.push(chalk.yellow(\"● uncommitted\"));\n if (state.hasUnpushedCommits) bits.push(chalk.yellow(\"● unpushed\"));\n if (\n !state.hasUncommittedChanges &&\n !state.hasUnpushedCommits &&\n state.commits.length > 0\n ) {\n bits.push(chalk.green(\"● synced\"));\n }\n if (bits.length) out(row(\" \" + bits.join(chalk.dim(\" · \")), w));\n\n // Pull Request\n if (state.pr || !state.isOnMain) {\n section(\"Pull Request\");\n if (state.pr) {\n const titleText = state.pr.title ? \" \" + state.pr.title : \"\";\n out(\n row(\n chalk.dim(\"· \") + chalk.cyan(`#${state.pr.number}`) + titleText,\n w\n )\n );\n out(\n row(\n \" \" +\n prBadge(state.pr.state, state.pr.isDraft) +\n reviewBadge(state.pr.reviewDecision),\n w\n )\n );\n if (state.hasActionableFeedback) {\n const n = state.reviewFeedback.length;\n out(\n row(\n \" \" +\n chalk.yellow(`${n} actionable comment${n !== 1 ? \"s\" : \"\"} pending`),\n w\n )\n );\n }\n if (\n state.hasUIChanges &&\n state.isPlaywrightAvailable &&\n state.config.video.enabled &&\n state.pr.state === \"open\"\n ) {\n out(\n row(\n \" \" +\n chalk.cyan(\"UI changes detected\") +\n chalk.dim(\" · video capture available\"),\n w\n )\n );\n }\n out(row(\" \" + chalk.dim(state.pr.url), w));\n } else {\n out(row(chalk.dim(\" No PR created\"), w));\n }\n }\n\n // Commits\n if (state.commits.length > 0 || !state.isOnMain) {\n section(\"Commits\");\n if (state.commits.length > 0) {\n const max = 6;\n for (const c of state.commits.slice(0, max)) {\n out(row(chalk.dim(\"· \") + c, w));\n }\n if (state.commits.length > max) {\n out(row(chalk.dim(` … and ${state.commits.length - max} more`), w));\n }\n } else {\n out(row(chalk.dim(\" No commits\"), w));\n }\n }\n\n // Hint\n if (!state.hasValidRemote) {\n section(\"Hint\");\n out(\n row(\n chalk.yellow(\n \"Press [g] to create a GitHub repo and push\"\n ),\n w\n )\n );\n } else if (hint) {\n section(\"Hint\");\n out(row(chalk.yellow(hint), w));\n }\n\n // Command bar (inside the frame)\n out(divRow(w));\n if (refreshing) {\n out(row(chalk.yellow(\"Refreshing…\"), w));\n } else {\n for (const line of formatCommandBar(actions, w)) {\n out(row(line, w));\n }\n }\n out(botRow(w));\n\n return lines;\n}\n\n// ── Main render ─────────────────────────────────────────────────\n\nexport function renderDashboard(\n state: TuiState,\n actions: TuiAction[],\n hint?: string,\n refreshing?: boolean,\n versionCheck?: VersionCheckResult | null\n): void {\n const lines = buildDashboardLines(state, actions, hint, refreshing, versionCheck);\n for (const line of lines) {\n console.log(line);\n }\n}\n\nexport function clearScreen(): void {\n process.stdout.write(\"\\x1B[2J\\x1B[0f\");\n}\n","import chalk from \"chalk\";\nimport { stripAnsi, visibleLen, truncateAnsi } from \"./display.js\";\n\n// ── Re-exports ──────────────────────────────────────────────────\n// Keep all dialog types accessible via modal.ts so existing\n// consumers (tui.ts, tui.test.ts) don't need import changes.\n\nexport { readKey, type KeyPress } from \"./key-reader.js\";\nexport { showSelect, buildSelectContent, type SelectItem, type SelectSeparator, type SelectEntry, type SelectOptions } from \"./select-dialog.js\";\nexport { showConfirm, buildConfirmContent, type ConfirmOptions } from \"./confirm-dialog.js\";\nexport { showInput, buildInputContent, type InputOptions } from \"./input-dialog.js\";\nexport { showMultilineInput, buildMultilineInputContent } from \"./multiline-input.js\";\n\n// ── Modal frame builders (pure, testable) ────────────────────────\n\nfunction modalTopRow(title: string, w: number): string {\n const label = ` ${title} `;\n const fill = w - 2 - label.length;\n return (\n chalk.bold(\"┌\") +\n chalk.bold.cyan(label) +\n chalk.bold(\"─\".repeat(Math.max(0, fill)) + \"┐\")\n );\n}\n\nfunction modalDivRow(w: number): string {\n return chalk.bold(\"├\" + \"─\".repeat(w - 2) + \"┤\");\n}\n\nfunction modalBotRow(w: number): string {\n return chalk.bold(\"└\" + \"─\".repeat(w - 2) + \"┘\");\n}\n\nfunction modalRow(text: string, w: number): string {\n const inner = w - 4;\n const fitted = truncateAnsi(text, inner);\n const pad = Math.max(0, inner - visibleLen(fitted));\n return chalk.bold(\"│\") + \" \" + fitted + \" \".repeat(pad) + \" \" + chalk.bold(\"│\");\n}\n\nfunction modalEmptyRow(w: number): string {\n return modalRow(\"\", w);\n}\n\n/**\n * Build modal frame lines (pure function for testing).\n */\nexport function buildModalFrame(\n title: string,\n contentLines: string[],\n footerText: string,\n width: number\n): string[] {\n const lines: string[] = [];\n lines.push(modalTopRow(title, width));\n lines.push(modalEmptyRow(width));\n for (const line of contentLines) {\n lines.push(modalRow(line, width));\n }\n lines.push(modalEmptyRow(width));\n lines.push(modalDivRow(width));\n lines.push(modalRow(chalk.dim(footerText), width));\n lines.push(modalBotRow(width));\n return lines;\n}\n\n// ── Terminal helpers ──────────────────────────────────────────────\n\nfunction termSize(): { cols: number; rows: number } {\n return {\n cols: process.stdout.columns || 80,\n rows: process.stdout.rows || 24,\n };\n}\n\nfunction moveTo(row: number, col: number): string {\n return `\\x1B[${row};${col}H`;\n}\n\nfunction hideCursor(): string {\n return \"\\x1B[?25l\";\n}\n\nexport function showCursor(): string {\n return \"\\x1B[?25h\";\n}\n\nexport function modalWidth(): number {\n const cols = process.stdout.columns || 80;\n return Math.min(60, cols - 4);\n}\n\n// ── Overlay rendering ────────────────────────────────────────────\n\n/**\n * Render dashboard lines dimmed with modal lines overlaid in center.\n */\nexport function renderOverlay(\n dashboardLines: string[],\n modalLines: string[],\n mWidth: number\n): void {\n const { cols, rows } = termSize();\n\n // Clear screen\n process.stdout.write(\"\\x1B[2J\\x1B[0f\");\n process.stdout.write(hideCursor());\n\n // Render dimmed dashboard\n for (let i = 0; i < dashboardLines.length && i < rows; i++) {\n process.stdout.write(\n moveTo(i + 1, 1) + chalk.dim(stripAnsi(dashboardLines[i]))\n );\n }\n\n // Calculate modal position (centered)\n const startRow = Math.max(1, Math.floor((rows - modalLines.length) / 2));\n const startCol = Math.max(1, Math.floor((cols - mWidth) / 2));\n\n // Render modal lines at position\n for (let i = 0; i < modalLines.length; i++) {\n process.stdout.write(moveTo(startRow + i, startCol) + modalLines[i]);\n }\n\n // Move cursor below modal\n process.stdout.write(moveTo(startRow + modalLines.length + 1, 1));\n}\n\n// ── Status dialog ────────────────────────────────────────────────\n\n/**\n * Show a brief status message in a modal overlay.\n * Auto-dismisses — caller controls when to re-render dashboard.\n */\nexport function showStatus(\n title: string,\n message: string,\n dashboardLines: string[]\n): void {\n const w = modalWidth();\n const content = [message];\n const footer = \"\";\n const lines = buildModalFrame(title, content, footer, w);\n renderOverlay(dashboardLines, lines, w);\n}\n","export interface KeyPress {\n name: string;\n raw: string;\n}\n\nexport function readKey(): Promise<KeyPress> {\n return new Promise((resolve) => {\n const { stdin } = process;\n const wasRaw = stdin.isRaw;\n stdin.setRawMode(true);\n stdin.resume();\n stdin.setEncoding(\"utf8\");\n\n const onData = (data: string) => {\n stdin.setRawMode(wasRaw ?? false);\n stdin.pause();\n stdin.removeListener(\"data\", onData);\n\n if (data === \"\\x03\") {\n resolve({ name: \"escape\", raw: data }); // Ctrl+C → escape\n } else if (data === \"\\x1b\" || data === \"\\x1b\\x1b\") {\n resolve({ name: \"escape\", raw: data });\n } else if (data === \"\\x1b[A\") {\n resolve({ name: \"up\", raw: data });\n } else if (data === \"\\x1b[B\") {\n resolve({ name: \"down\", raw: data });\n } else if (data === \"\\x1b[C\") {\n resolve({ name: \"right\", raw: data });\n } else if (data === \"\\x1b[D\") {\n resolve({ name: \"left\", raw: data });\n } else if (data === \"\\x1b[1;5C\" || data === \"\\x1b[5C\") {\n resolve({ name: \"ctrl-right\", raw: data });\n } else if (data === \"\\x1b[1;5D\" || data === \"\\x1b[5D\") {\n resolve({ name: \"ctrl-left\", raw: data });\n } else if (data === \"\\x1b[3~\") {\n resolve({ name: \"delete\", raw: data });\n } else if (data === \"\\x1b[H\" || data === \"\\x1b[1~\") {\n resolve({ name: \"home\", raw: data });\n } else if (data === \"\\x1b[F\" || data === \"\\x1b[4~\") {\n resolve({ name: \"end\", raw: data });\n } else if (data === \"\\x01\") {\n resolve({ name: \"home\", raw: data }); // Ctrl+A\n } else if (data === \"\\x05\") {\n resolve({ name: \"end\", raw: data }); // Ctrl+E\n } else if (data === \"\\r\" || data === \"\\n\") {\n resolve({ name: \"enter\", raw: data });\n } else if (data === \"\\x7f\" || data === \"\\x08\") {\n resolve({ name: \"backspace\", raw: data });\n } else if (data === \"\\t\") {\n resolve({ name: \"tab\", raw: data });\n } else if (data === \"\\x13\") {\n resolve({ name: \"ctrl-s\", raw: data }); // Ctrl+S\n } else if (data.length === 1 && data.charCodeAt(0) >= 32) {\n resolve({ name: data, raw: data });\n } else {\n // Unknown sequence — treat as no-op, read again\n stdin.setRawMode(true);\n stdin.resume();\n stdin.on(\"data\", onData);\n }\n };\n\n stdin.on(\"data\", onData);\n });\n}\n","import chalk from \"chalk\";\nimport { truncateAnsi } from \"./display.js\";\nimport { readKey } from \"./key-reader.js\";\nimport { buildModalFrame, renderOverlay, modalWidth, showCursor } from \"./modal.js\";\n\n// ── Types ────────────────────────────────────────────────────────\n\nexport interface SelectItem {\n name: string;\n value: string;\n}\n\nexport interface SelectSeparator {\n separator: string;\n}\n\nexport type SelectEntry = SelectItem | SelectSeparator;\n\nfunction isSeparator(entry: SelectEntry): entry is SelectSeparator {\n return \"separator\" in entry;\n}\n\n// ── Content builder (pure, testable) ─────────────────────────────\n\nexport function buildSelectContent(\n items: SelectEntry[],\n selectedIndex: number,\n maxWidth: number,\n currentIndex?: number\n): string[] {\n const lines: string[] = [];\n let selectableIdx = 0;\n\n for (const item of items) {\n if (isSeparator(item)) {\n lines.push(chalk.dim(item.separator));\n } else {\n const isSelected = selectableIdx === selectedIndex;\n const isCurrent = currentIndex != null && selectableIdx === currentIndex;\n const prefix = isSelected ? chalk.cyan.bold(\"> \") : \" \";\n const bullet = chalk.dim(\"· \");\n const label = truncateAnsi(item.name, maxWidth - 4);\n const styledLabel = isSelected\n ? chalk.bold(label)\n : isCurrent\n ? chalk.cyan(label)\n : label;\n lines.push(prefix + bullet + styledLabel);\n selectableIdx++;\n }\n }\n\n return lines;\n}\n\n// ── Dialog ───────────────────────────────────────────────────────\n\nexport interface SelectOptions {\n title: string;\n items: SelectEntry[];\n dashboardLines: string[];\n initialIndex?: number;\n currentIndex?: number;\n}\n\n/**\n * Get the selectable items count (excluding separators).\n */\nfunction selectableCount(items: SelectEntry[]): number {\n return items.filter((i) => !isSeparator(i)).length;\n}\n\n/**\n * Show a select dialog overlaying the dashboard.\n * Returns the selected value or null if cancelled.\n */\nexport async function showSelect(opts: SelectOptions): Promise<string | null> {\n const w = modalWidth();\n const maxItems = selectableCount(opts.items);\n if (maxItems === 0) return null;\n\n let selectedIndex = opts.initialIndex ?? 0;\n\n const render = () => {\n const content = buildSelectContent(opts.items, selectedIndex, w - 6, opts.currentIndex);\n const footer = \"↑↓ Navigate Enter Select Esc Cancel\";\n const lines = buildModalFrame(opts.title, content, footer, w);\n renderOverlay(opts.dashboardLines, lines, w);\n };\n\n render();\n\n while (true) {\n const key = await readKey();\n\n switch (key.name) {\n case \"up\":\n selectedIndex = (selectedIndex - 1 + maxItems) % maxItems;\n render();\n break;\n\n case \"down\":\n selectedIndex = (selectedIndex + 1) % maxItems;\n render();\n break;\n\n case \"enter\": {\n process.stdout.write(showCursor());\n // Find the nth selectable item\n let idx = 0;\n for (const item of opts.items) {\n if (!isSeparator(item)) {\n if (idx === selectedIndex) return item.value;\n idx++;\n }\n }\n return null;\n }\n\n case \"escape\":\n process.stdout.write(showCursor());\n return null;\n }\n }\n}\n","import chalk from \"chalk\";\nimport { readKey } from \"./key-reader.js\";\nimport { buildModalFrame, renderOverlay, modalWidth, showCursor } from \"./modal.js\";\n\n// ── Content builder (pure, testable) ─────────────────────────────\n\nexport function buildConfirmContent(\n message: string,\n selectedYes: boolean\n): string[] {\n const yes = selectedYes\n ? chalk.cyan.bold(\"> Yes\")\n : chalk.dim(\" Yes\");\n const no = !selectedYes\n ? chalk.cyan.bold(\"> No\")\n : chalk.dim(\" No\");\n return [message, \"\", yes, no];\n}\n\n// ── Dialog ───────────────────────────────────────────────────────\n\nexport interface ConfirmOptions {\n title: string;\n message: string;\n dashboardLines: string[];\n}\n\n/**\n * Show a confirm dialog overlaying the dashboard.\n * Returns true for yes, false for no/cancel.\n */\nexport async function showConfirm(opts: ConfirmOptions): Promise<boolean> {\n const w = modalWidth();\n let selectedYes = true;\n\n const render = () => {\n const content = buildConfirmContent(opts.message, selectedYes);\n const footer = \"↑↓ Select Enter Confirm Esc Cancel\";\n const lines = buildModalFrame(opts.title, content, footer, w);\n renderOverlay(opts.dashboardLines, lines, w);\n };\n\n render();\n\n while (true) {\n const key = await readKey();\n\n switch (key.name) {\n case \"up\":\n case \"down\":\n case \"tab\":\n selectedYes = !selectedYes;\n render();\n break;\n\n case \"enter\":\n process.stdout.write(showCursor());\n return selectedYes;\n\n case \"escape\":\n process.stdout.write(showCursor());\n return false;\n\n case \"y\":\n process.stdout.write(showCursor());\n return true;\n\n case \"n\":\n process.stdout.write(showCursor());\n return false;\n }\n }\n}\n","import chalk from \"chalk\";\nimport { readKey } from \"./key-reader.js\";\nimport { buildModalFrame, renderOverlay, modalWidth, showCursor } from \"./modal.js\";\n\n// ── Content builder (pure, testable) ─────────────────────────────\n\nexport function buildInputContent(\n label: string,\n value: string,\n cursorVisible: boolean\n): string[] {\n const cursorChar = cursorVisible ? chalk.inverse(\" \") : \"\";\n return [label, \"\", chalk.cyan(\"> \") + value + cursorChar];\n}\n\n// ── Dialog ───────────────────────────────────────────────────────\n\nexport interface InputOptions {\n title: string;\n label: string;\n dashboardLines: string[];\n}\n\n/**\n * Show a text input dialog overlaying the dashboard.\n * Returns the entered text or null if cancelled.\n */\nexport async function showInput(opts: InputOptions): Promise<string | null> {\n const w = modalWidth();\n let value = \"\";\n let cursorBlink = true;\n\n const render = () => {\n const maxLen = w - 10;\n const displayValue = value.length > maxLen\n ? value.slice(value.length - maxLen)\n : value;\n const content = buildInputContent(opts.label, displayValue, cursorBlink);\n const footer = \"Enter Submit Esc Cancel\";\n const lines = buildModalFrame(opts.title, content, footer, w);\n renderOverlay(opts.dashboardLines, lines, w);\n };\n\n render();\n\n while (true) {\n const key = await readKey();\n\n switch (key.name) {\n case \"enter\":\n process.stdout.write(showCursor());\n return value.trim() || null;\n\n case \"escape\":\n process.stdout.write(showCursor());\n return null;\n\n case \"backspace\":\n if (value.length > 0) {\n value = value.slice(0, -1);\n }\n render();\n break;\n\n default:\n // Single printable character\n if (key.raw.length === 1 && key.raw.charCodeAt(0) >= 32) {\n value += key.raw;\n cursorBlink = true;\n render();\n }\n break;\n }\n }\n}\n","import chalk from \"chalk\";\nimport { readKey } from \"./key-reader.js\";\nimport { type InputOptions } from \"./input-dialog.js\";\nimport { buildModalFrame, renderOverlay, modalWidth, showCursor } from \"./modal.js\";\n\n// ── Visual line mapping for cursor positioning ──────────────────\n\ninterface WrapSegment {\n text: string;\n offset: number; // start offset within the logical line\n}\n\nfunction wrapLineWithMap(text: string, width: number): WrapSegment[] {\n if (width <= 0) return [{ text, offset: 0 }];\n if (text.length <= width) return [{ text, offset: 0 }];\n\n const result: WrapSegment[] = [];\n let pos = 0;\n let remaining = text;\n while (remaining.length > width) {\n let breakAt = remaining.lastIndexOf(\" \", width);\n if (breakAt <= 0) breakAt = width;\n result.push({ text: remaining.slice(0, breakAt), offset: pos });\n pos += breakAt;\n remaining = remaining.slice(breakAt);\n if (remaining.startsWith(\" \")) {\n remaining = remaining.slice(1);\n pos += 1;\n }\n }\n if (remaining.length > 0 || result.length === 0) {\n result.push({ text: remaining, offset: pos });\n }\n return result;\n}\n\nexport interface VisualLine {\n text: string;\n globalOffset: number; // offset in the full value string\n length: number;\n}\n\nexport function getVisualLines(value: string, contentWidth: number): VisualLine[] {\n const inputLines = value.split(\"\\n\");\n const result: VisualLine[] = [];\n let globalPos = 0;\n\n for (let i = 0; i < inputLines.length; i++) {\n const raw = inputLines[i];\n const wrapped = wrapLineWithMap(raw, contentWidth);\n for (const seg of wrapped) {\n result.push({\n text: seg.text,\n globalOffset: globalPos + seg.offset,\n length: seg.text.length,\n });\n }\n globalPos += raw.length + 1; // +1 for the newline\n }\n\n return result;\n}\n\nexport function findCursorVisualPos(\n visualLines: VisualLine[],\n cursorPos: number\n): { row: number; col: number } {\n for (let i = 0; i < visualLines.length; i++) {\n const vl = visualLines[i];\n if (cursorPos >= vl.globalOffset && cursorPos <= vl.globalOffset + vl.length) {\n return { row: i, col: cursorPos - vl.globalOffset };\n }\n }\n const last = visualLines[visualLines.length - 1];\n return { row: visualLines.length - 1, col: last.length };\n}\n\n// ── Cursor movement helpers (pure, testable) ────────────────────\n\nexport function moveCursorVertical(\n value: string,\n cursorPos: number,\n contentWidth: number,\n direction: -1 | 1\n): number {\n const visualLines = getVisualLines(value, contentWidth);\n const { row, col } = findCursorVisualPos(visualLines, cursorPos);\n const newRow = row + direction;\n if (newRow < 0 || newRow >= visualLines.length) return cursorPos;\n const targetLine = visualLines[newRow];\n const newCol = Math.min(col, targetLine.length);\n return targetLine.globalOffset + newCol;\n}\n\nexport function moveCursorHome(\n value: string,\n cursorPos: number,\n contentWidth: number\n): number {\n const visualLines = getVisualLines(value, contentWidth);\n const { row } = findCursorVisualPos(visualLines, cursorPos);\n return visualLines[row].globalOffset;\n}\n\nexport function moveCursorEnd(\n value: string,\n cursorPos: number,\n contentWidth: number\n): number {\n const visualLines = getVisualLines(value, contentWidth);\n const { row } = findCursorVisualPos(visualLines, cursorPos);\n return visualLines[row].globalOffset + visualLines[row].length;\n}\n\nexport function moveCursorWordLeft(value: string, cursorPos: number): number {\n if (cursorPos <= 0) return 0;\n let pos = cursorPos - 1;\n // Skip non-word chars\n while (pos > 0 && !/\\w/.test(value[pos])) pos--;\n // Skip word chars\n while (pos > 0 && /\\w/.test(value[pos - 1])) pos--;\n return pos;\n}\n\nexport function moveCursorWordRight(value: string, cursorPos: number): number {\n if (cursorPos >= value.length) return value.length;\n let pos = cursorPos;\n // Skip word chars\n while (pos < value.length && /\\w/.test(value[pos])) pos++;\n // Skip non-word chars\n while (pos < value.length && !/\\w/.test(value[pos])) pos++;\n return pos;\n}\n\n// ── Content builder (pure, testable) ─────────────────────────────\n\n/**\n * Build multiline input content with word wrapping.\n * Cursor is rendered at cursorPos (defaults to end of text).\n */\nexport function buildMultilineInputContent(\n label: string,\n value: string,\n cursorVisible: boolean,\n maxWidth: number,\n cursorPos?: number\n): string[] {\n const cp = cursorPos ?? value.length;\n const lines: string[] = [label, \"\"];\n const contentWidth = maxWidth - 2;\n\n const visualLines = getVisualLines(value, contentWidth);\n const { row: cursorRow, col: cursorCol } = findCursorVisualPos(visualLines, cp);\n\n for (let i = 0; i < visualLines.length; i++) {\n const text = visualLines[i].text;\n if (i === cursorRow && cursorVisible) {\n const charUnderCursor = cursorCol < text.length ? text[cursorCol] : \" \";\n lines.push(\n chalk.cyan(\" \") +\n text.slice(0, cursorCol) +\n chalk.inverse(charUnderCursor) +\n text.slice(cursorCol + 1)\n );\n } else {\n lines.push(chalk.cyan(\" \") + text);\n }\n }\n\n return lines;\n}\n\n// ── Multiline input dialog ───────────────────────────────────────\n\n/**\n * Show a multiline text input dialog overlaying the dashboard.\n * Enter inserts a newline; Ctrl+S submits.\n * Returns the entered text or null if cancelled.\n */\nexport async function showMultilineInput(\n opts: InputOptions\n): Promise<string | null> {\n const w = modalWidth();\n let value = \"\";\n let cursorPos = 0;\n let cursorBlink = true;\n const contentWidth = w - 6; // inner width minus borders and padding\n\n const render = () => {\n const content = buildMultilineInputContent(\n opts.label,\n value,\n cursorBlink,\n contentWidth,\n cursorPos\n );\n const footer = \"Enter Newline Ctrl+S Submit Esc Cancel\";\n const lines = buildModalFrame(opts.title, content, footer, w);\n renderOverlay(opts.dashboardLines, lines, w);\n };\n\n render();\n\n while (true) {\n const key = await readKey();\n\n switch (key.name) {\n case \"ctrl-s\":\n process.stdout.write(showCursor());\n return value.trim() || null;\n\n case \"enter\":\n value = value.slice(0, cursorPos) + \"\\n\" + value.slice(cursorPos);\n cursorPos++;\n cursorBlink = true;\n render();\n break;\n\n case \"escape\":\n process.stdout.write(showCursor());\n return null;\n\n case \"backspace\":\n if (cursorPos > 0) {\n value = value.slice(0, cursorPos - 1) + value.slice(cursorPos);\n cursorPos--;\n }\n render();\n break;\n\n case \"delete\":\n if (cursorPos < value.length) {\n value = value.slice(0, cursorPos) + value.slice(cursorPos + 1);\n }\n render();\n break;\n\n case \"left\":\n if (cursorPos > 0) cursorPos--;\n render();\n break;\n\n case \"right\":\n if (cursorPos < value.length) cursorPos++;\n render();\n break;\n\n case \"up\":\n cursorPos = moveCursorVertical(value, cursorPos, contentWidth - 2, -1);\n render();\n break;\n\n case \"down\":\n cursorPos = moveCursorVertical(value, cursorPos, contentWidth - 2, 1);\n render();\n break;\n\n case \"home\":\n cursorPos = moveCursorHome(value, cursorPos, contentWidth - 2);\n render();\n break;\n\n case \"end\":\n cursorPos = moveCursorEnd(value, cursorPos, contentWidth - 2);\n render();\n break;\n\n case \"ctrl-left\":\n cursorPos = moveCursorWordLeft(value, cursorPos);\n render();\n break;\n\n case \"ctrl-right\":\n cursorPos = moveCursorWordRight(value, cursorPos);\n render();\n break;\n\n default:\n if (key.raw.length === 1 && key.raw.charCodeAt(0) >= 32) {\n value = value.slice(0, cursorPos) + key.raw + value.slice(cursorPos);\n cursorPos++;\n cursorBlink = true;\n render();\n }\n break;\n }\n }\n}\n","import { execa } from \"execa\";\nimport { logger } from \"../utils/logger.js\";\nimport { getCurrentBranch } from \"../lib/git.js\";\nimport { checkGhAuth } from \"../utils/validators.js\";\n\nexport async function githubRemoteCommand(): Promise<boolean> {\n const isAuthenticated = await checkGhAuth();\n if (!isAuthenticated) {\n logger.error(\"GitHub CLI is not authenticated. Run: gh auth login\");\n return false;\n }\n\n try {\n // Check if remote origin already exists\n try {\n const { stdout } = await execa(\"git\", [\n \"config\",\n \"--get\",\n \"remote.origin.url\",\n ]);\n if (stdout.trim()) {\n logger.error(\"Remote origin already exists: \" + stdout.trim());\n return false;\n }\n } catch {\n // No remote origin — expected\n }\n\n // Create a GitHub repo using gh CLI (uses current directory name)\n logger.info(\"Creating GitHub repository...\");\n await execa(\"gh\", [\"repo\", \"create\", \"--source=.\", \"--push\", \"--private\"]);\n\n const branch = await getCurrentBranch();\n logger.success(`Repository created and ${branch} pushed to GitHub`);\n return true;\n } catch (error) {\n logger.error(`Failed to create remote: ${error}`);\n return false;\n }\n}\n"],"mappings":"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","names":["writeFileSync","existsSync","join","writeFileSync","join","existsSync","setupLabelsCommand","inquirer","inquirer","chalk","inquirer","execa","chalk","localBranches","choices","inquirer","inquirer","inquirer","execa","inquirer","inquirer","inquirer","readFileSync","writeFileSync","existsSync","mkdirSync","join","join","existsSync","readFileSync","mkdirSync","writeFileSync","version","execa","config","chalk","chalk","version","chalk","chalk","chalk","chalk","chalk","chalk","chalk","chalk","row","chalk","chalk","row","execa","execa","execa","offerCreateBranch"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/lib/progress.ts","../src/commands/create.ts","../src/lib/ai-provider.ts","../src/lib/prompts.ts","../src/commands/list.ts","../src/lib/git.ts","../src/lib/branch.ts","../src/commands/run.ts","../src/lib/playwright.ts","../src/commands/pr.ts","../src/commands/fix.ts","../src/lib/review-feedback.ts","../src/lib/version.ts","../package.json","../src/commands/status.ts","../src/commands/tui.ts","../src/tui/state.ts","../src/tui/actions.ts","../src/tui/display.ts","../src/tui/modal.ts","../src/tui/key-reader.ts","../src/tui/select-dialog.ts","../src/tui/confirm-dialog.ts","../src/tui/input-dialog.ts","../src/tui/multiline-input.ts","../src/commands/github-remote.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { setupLabelsCommand } from \"./commands/setup-labels.js\";\nimport { createCommand } from \"./commands/create.js\";\nimport { listCommand } from \"./commands/list.js\";\nimport { runCommand } from \"./commands/run.js\";\nimport { prCommand } from \"./commands/pr.js\";\nimport { fixCommand } from \"./commands/fix.js\";\nimport { statusCommand } from \"./commands/status.js\";\nimport { tuiCommand } from \"./commands/tui.js\";\nimport { githubRemoteCommand } from \"./commands/github-remote.js\";\nimport {\n getVersion,\n checkForUpdates,\n formatUpgradeNotification,\n} from \"./lib/version.js\";\nimport { logger } from \"./utils/logger.js\";\nimport { checkInitialized } from \"./utils/validators.js\";\nimport { checkLabelsExist } from \"./lib/github.js\";\n\nconst version = getVersion();\n\nfunction startVersionCheck(): void {\n // Skip if disabled via environment variable\n if (process.env.GENT_SKIP_UPDATE_CHECK === \"1\") return;\n\n checkForUpdates()\n .then((result) => {\n if (result.updateAvailable && result.latestVersion) {\n logger.newline();\n logger.warning(\n formatUpgradeNotification(result.currentVersion, result.latestVersion)\n );\n }\n })\n .catch(() => {\n // Silently ignore errors\n });\n}\n\n/** Returns true if prerequisites are met, false if command should abort. */\nasync function checkPrerequisites(): Promise<boolean> {\n if (!checkInitialized()) {\n logger.warning('Repository not initialized. Run \"gent init\" to set up this repository.');\n return false;\n }\n const labelsOk = await checkLabelsExist();\n if (!labelsOk) {\n logger.warning('GitHub labels not found. Run \"gent setup-labels\" to create required labels.');\n return false;\n }\n return true;\n}\n\nconst program = new Command();\n\nprogram\n .name(\"gent\")\n .description(\n \"AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs\"\n )\n .version(version)\n .option(\"--skip-update-check\", \"Skip checking for CLI updates\")\n .hook(\"preAction\", (thisCommand) => {\n // Start version check before any command runs (unless skipped)\n if (!thisCommand.opts().skipUpdateCheck) {\n startVersionCheck();\n }\n });\n\nprogram\n .command(\"init\")\n .description(\"Initialize gent workflow in current repository\")\n .option(\"-f, --force\", \"Overwrite existing configuration\")\n .action(async (options) => {\n await initCommand(options);\n });\n\nprogram\n .command(\"setup-labels\")\n .description(\"Setup GitHub labels for AI workflow\")\n .action(async () => {\n await setupLabelsCommand();\n });\n\nprogram\n .command(\"create <description>\")\n .description(\"Create an AI-enhanced GitHub issue\")\n .option(\"-y, --yes\", \"Skip confirmation and create issue immediately\")\n .option(\n \"-p, --provider <provider>\",\n \"AI provider to use (claude, gemini, or codex)\"\n )\n .option(\"-t, --title <title>\", \"Override the generated issue title\")\n .action(async (description, options) => {\n if (!(await checkPrerequisites())) return;\n await createCommand(description, {\n yes: options.yes,\n provider: options.provider,\n title: options.title,\n });\n });\n\nprogram\n .command(\"list\")\n .description(\"List and switch to GitHub issues\")\n .option(\"-l, --label <label>\", \"Filter by label\")\n .option(\n \"-s, --status <status>\",\n \"Filter by workflow status (ready, in-progress, completed, blocked, all)\"\n )\n .option(\"-n, --limit <number>\", \"Maximum number of issues to show\", \"20\")\n .action(async (options) => {\n if (!(await checkPrerequisites())) return;\n await listCommand({\n label: options.label,\n status: options.status,\n limit: parseInt(options.limit, 10),\n });\n });\n\nprogram\n .command(\"run [issue-number]\")\n .description(\"Run AI to implement a GitHub issue\")\n .option(\n \"-p, --provider <provider>\",\n \"AI provider to use (claude, gemini, or codex)\"\n )\n .action(async (issueNumber, options) => {\n if (!(await checkPrerequisites())) return;\n await runCommand(issueNumber, { provider: options.provider });\n });\n\nprogram\n .command(\"pr\")\n .description(\"Create an AI-enhanced pull request\")\n .option(\"-d, --draft\", \"Create as draft PR\")\n .option(\n \"-p, --provider <provider>\",\n \"AI provider to use (claude, gemini, or codex)\"\n )\n .option(\"--no-video\", \"Disable video capture for UI changes\")\n .action(async (options) => {\n if (!(await checkPrerequisites())) return;\n await prCommand({\n draft: options.draft,\n provider: options.provider,\n video: options.video,\n });\n });\n\nprogram\n .command(\"fix\")\n .description(\"Apply PR review feedback using AI\")\n .option(\n \"-p, --provider <provider>\",\n \"AI provider to use (claude, gemini, or codex)\"\n )\n .action(async (options) => {\n if (!(await checkPrerequisites())) return;\n await fixCommand({ provider: options.provider });\n });\n\nprogram\n .command(\"status\")\n .description(\"Show current workflow status\")\n .action(async () => {\n if (!(await checkPrerequisites())) return;\n await statusCommand();\n });\n\nprogram\n .command(\"github-remote\")\n .description(\"Create a GitHub repository and push local repo\")\n .action(async () => {\n await githubRemoteCommand();\n });\n\nprogram\n .command(\"ui\")\n .description(\"Launch interactive dashboard\")\n .action(async () => {\n await tuiCommand();\n });\n\n// Launch dashboard when `gent` is run with no subcommand\nprogram.action(async () => {\n await tuiCommand();\n});\n\nprogram.parse();\n","import { writeFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport inquirer from \"inquirer\";\nimport { logger, colors } from \"../utils/logger.js\";\nimport { checkGitRepo } from \"../utils/validators.js\";\nimport {\n configExists,\n generateDefaultConfig,\n getConfigPath,\n} from \"../lib/config.js\";\nimport { initializeProgress } from \"../lib/progress.js\";\nimport { loadConfig } from \"../lib/config.js\";\n\nconst DEFAULT_AGENT_MD = `# AI Agent Instructions\n\nThis file contains instructions for the AI when working on this repository.\n\n## Project Overview\n\n[Describe your project, its purpose, and key technologies used]\n\n## Code Patterns\n\n### Architecture\n[Document your architecture - e.g., MVC, Clean Architecture, etc.]\n\n### Naming Conventions\n[Document naming conventions for files, functions, variables, etc.]\n\n### Component Structure\n[If applicable, describe component/module structure]\n\n## Testing Requirements\n\n### Unit Tests\n- All new functions should have corresponding unit tests\n- Use [your testing framework] for unit tests\n- Aim for [X]% coverage on new code\n\n### Integration Tests\n[Document when and how to write integration tests]\n\n## Commit Conventions\n\nFollow conventional commits format:\n- \\`feat:\\` New feature\n- \\`fix:\\` Bug fix\n- \\`refactor:\\` Code improvement without behavior change\n- \\`test:\\` Testing additions\n- \\`chore:\\` Maintenance/dependencies\n- \\`docs:\\` Documentation\n\nAll AI commits should include the Co-Authored-By trailer as specified in the task prompt.\n\n## Important Files\n\n[List key files the AI should understand before making changes]\n\n- \\`src/index.ts\\` - Main entry point\n- \\`src/config/\\` - Configuration files\n- [Add more key files]\n\n## Constraints\n\n- [List any constraints or limitations]\n- [E.g., \"Do not modify files in /vendor\"]\n- [E.g., \"Always use async/await over callbacks\"]\n`;\n\nexport async function initCommand(options: { force?: boolean }): Promise<void> {\n logger.bold(\"Initializing gent workflow...\");\n logger.newline();\n\n // Check if we're in a git repo\n const isGitRepo = await checkGitRepo();\n if (!isGitRepo) {\n logger.error(\"Not a git repository. Please run 'git init' first.\");\n process.exit(1);\n }\n\n const cwd = process.cwd();\n\n // Check if already initialized\n if (configExists(cwd) && !options.force) {\n const { overwrite } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"overwrite\",\n message: \"gent is already initialized. Overwrite existing config?\",\n default: false,\n },\n ]);\n\n if (!overwrite) {\n logger.info(\"Initialization cancelled.\");\n return;\n }\n }\n\n const { provider } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"provider\",\n message: \"Which AI provider would you like to use by default?\",\n choices: [\"claude\", \"gemini\", \"codex\"],\n default: \"claude\",\n },\n ]);\n\n // Create .gent.yml\n const configPath = getConfigPath(cwd);\n writeFileSync(configPath, generateDefaultConfig(provider), \"utf-8\");\n logger.success(`Created ${colors.file(\".gent.yml\")}`);\n\n // Create AGENT.md\n const agentPath = join(cwd, \"AGENT.md\");\n if (!existsSync(agentPath) || options.force) {\n writeFileSync(agentPath, DEFAULT_AGENT_MD, \"utf-8\");\n logger.success(`Created ${colors.file(\"AGENT.md\")}`);\n } else {\n logger.info(`${colors.file(\"AGENT.md\")} already exists, skipping`);\n }\n\n // Create progress.txt\n const config = loadConfig(cwd);\n initializeProgress(config, cwd);\n logger.success(`Created ${colors.file(config.progress.file)}`);\n\n logger.newline();\n logger.box(\n \"Setup Complete\",\n `Next steps:\n1. Edit ${colors.file(\"AGENT.md\")} with your project-specific instructions\n2. Edit ${colors.file(\".gent.yml\")} to customize settings\n3. Run ${colors.command(\"gent setup-labels\")} to create GitHub labels\n4. Run ${colors.command(\"gent create <description>\")} to create your first ticket`\n );\n\n // Ask about setting up labels\n const { setupLabels } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"setupLabels\",\n message: \"Would you like to setup GitHub labels now?\",\n default: true,\n },\n ]);\n\n if (setupLabels) {\n const { setupLabelsCommand } = await import(\"./setup-labels.js\");\n await setupLabelsCommand();\n }\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport type { GentConfig, ProgressEntry } from \"../types/index.js\";\n\nexport function getProgressPath(\n config: GentConfig,\n cwd: string = process.cwd()\n): string {\n return join(cwd, config.progress.file);\n}\n\nexport function progressExists(\n config: GentConfig,\n cwd: string = process.cwd()\n): boolean {\n return existsSync(getProgressPath(config, cwd));\n}\n\nexport function readProgress(\n config: GentConfig,\n cwd: string = process.cwd()\n): string {\n const path = getProgressPath(config, cwd);\n if (!existsSync(path)) {\n return \"\";\n }\n return readFileSync(path, \"utf-8\");\n}\n\nexport function appendProgress(\n config: GentConfig,\n entry: ProgressEntry,\n cwd: string = process.cwd()\n): void {\n const path = getProgressPath(config, cwd);\n const content = formatProgressEntry(entry);\n\n // Ensure directory exists\n const dir = dirname(path);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Read existing content\n let existing = \"\";\n if (existsSync(path)) {\n existing = readFileSync(path, \"utf-8\");\n }\n\n // Check if we need to archive\n const lines = existing.split(\"\\n\").length;\n if (lines > config.progress.archive_threshold) {\n archiveProgress(config, existing, cwd);\n existing = `# Progress Log (archived previous entries)\\n\\n`;\n }\n\n // Append new entry\n writeFileSync(path, existing + content, \"utf-8\");\n}\n\nexport function formatProgressEntry(entry: ProgressEntry): string {\n let content = `\\n[${entry.date}] ${entry.type}: ${entry.description}\\n`;\n\n if (entry.issue) {\n content += `- Completed GitHub issue #${entry.issue}\\n`;\n }\n\n if (entry.decisions.length > 0) {\n content += `- Key implementation decisions:\\n`;\n for (const decision of entry.decisions) {\n content += ` * ${decision}\\n`;\n }\n }\n\n if (entry.files.length > 0) {\n content += `- Files changed:\\n`;\n for (const file of entry.files) {\n content += ` * ${file}\\n`;\n }\n }\n\n if (entry.tests.length > 0) {\n content += `- Tests: ${entry.tests.join(\", \")}\\n`;\n }\n\n if (entry.concerns.length > 0) {\n content += `- Concerns for reviewers:\\n`;\n for (const concern of entry.concerns) {\n content += ` * ${concern}\\n`;\n }\n }\n\n if (entry.followUp.length > 0) {\n content += `- Follow-up tasks:\\n`;\n for (const task of entry.followUp) {\n content += ` * ${task}\\n`;\n }\n }\n\n if (entry.commit) {\n content += `- Commit: ${entry.commit}\\n`;\n }\n\n return content;\n}\n\nfunction archiveProgress(\n config: GentConfig,\n content: string,\n cwd: string\n): void {\n const archiveDir = join(cwd, config.progress.archive_dir);\n\n if (!existsSync(archiveDir)) {\n mkdirSync(archiveDir, { recursive: true });\n }\n\n const date = new Date().toISOString().split(\"T\")[0];\n const archivePath = join(archiveDir, `progress-${date}.txt`);\n\n writeFileSync(archivePath, content, \"utf-8\");\n}\n\nexport function initializeProgress(\n config: GentConfig,\n cwd: string = process.cwd()\n): void {\n const path = getProgressPath(config, cwd);\n\n if (existsSync(path)) {\n return;\n }\n\n const initialContent = `# Progress Log\n\nThis file tracks AI-assisted development progress.\nEach entry documents: date, feature, decisions, files changed, tests, and concerns.\n\n---\n`;\n\n const dir = dirname(path);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n writeFileSync(path, initialContent, \"utf-8\");\n}\n\nexport function getRecentProgress(\n config: GentConfig,\n cwd: string = process.cwd(),\n maxLines: number = 100\n): string {\n const content = readProgress(config, cwd);\n const lines = content.split(\"\\n\");\n\n if (lines.length <= maxLines) {\n return content;\n }\n\n return lines.slice(-maxLines).join(\"\\n\");\n}\n","import inquirer from \"inquirer\";\nimport chalk from \"chalk\";\nimport { logger, colors } from \"../utils/logger.js\";\nimport { withSpinner, createSpinner, aiSpinnerText } from \"../utils/spinner.js\";\nimport {\n loadConfig,\n loadAgentInstructions,\n resolveProvider,\n} from \"../lib/config.js\";\nimport {\n buildTicketPrompt,\n parseTicketMeta,\n extractIssueBody,\n extractTitle,\n generateFallbackTitle,\n} from \"../lib/prompts.js\";\nimport {\n invokeAI,\n getProviderDisplayName,\n getOtherAvailableProviders,\n} from \"../lib/ai-provider.js\";\nimport { createIssue } from \"../lib/github.js\";\nimport { buildIssueLabels } from \"../lib/labels.js\";\nimport { checkGhAuth, checkAIProvider } from \"../utils/validators.js\";\nimport type { AIProvider } from \"../types/index.js\";\n\nexport interface CreateOptions {\n yes?: boolean;\n provider?: AIProvider;\n title?: string;\n}\n\ninterface TicketMeta {\n type: string;\n priority: string;\n risk: string;\n area: string;\n}\n\nexport async function createCommand(\n description: string,\n options: CreateOptions\n): Promise<void> {\n const config = loadConfig();\n\n // Determine which provider to use\n let currentProvider = resolveProvider(options, config);\n\n // Validate prerequisites\n const [ghAuth, aiOk] = await Promise.all([\n checkGhAuth(),\n checkAIProvider(currentProvider),\n ]);\n\n if (!ghAuth) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n return;\n }\n\n if (!aiOk) {\n logger.error(\n `${getProviderDisplayName(currentProvider)} CLI not found. Please install ${currentProvider} CLI first.`\n );\n return;\n }\n\n const agentInstructions = loadAgentInstructions();\n\n // Generate ticket with AI (may loop if user wants to regenerate)\n let aiOutput: string;\n let additionalHints: string | null = null;\n\n while (true) {\n // Build prompt and invoke AI\n const prompt = buildTicketPrompt(\n description,\n agentInstructions,\n additionalHints\n );\n\n try {\n const spinner = createSpinner(aiSpinnerText(getProviderDisplayName(currentProvider), \"generate ticket\"));\n spinner.start();\n const result = await invokeAI(\n { prompt, streamOutput: true, onFirstData: () => spinner.stop() },\n config,\n currentProvider\n );\n spinner.stop();\n aiOutput = result.output;\n logger.newline();\n } catch (error) {\n const providerName = getProviderDisplayName(currentProvider);\n if (error && typeof error === \"object\" && \"rateLimited\" in error) {\n logger.warning(`${providerName} is rate limited.`);\n\n const others = await getOtherAvailableProviders(currentProvider);\n if (others.length > 0) {\n const { nextProvider } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"nextProvider\",\n message: \"Would you like to try another provider?\",\n choices: [\n ...others.map((p) => ({\n name: `Switch to ${getProviderDisplayName(p)}`,\n value: p,\n })),\n { name: \"Cancel\", value: \"cancel\" },\n ],\n },\n ]);\n\n if (nextProvider !== \"cancel\") {\n currentProvider = nextProvider as AIProvider;\n logger.info(\n `Switching to ${getProviderDisplayName(currentProvider)}...`\n );\n continue;\n }\n }\n }\n\n logger.error(`${providerName} invocation failed: ${error}`);\n return;\n }\n\n // Parse metadata\n const meta = parseTicketMeta(aiOutput);\n if (!meta) {\n logger.warning(\n \"Could not parse metadata from AI output. Using defaults.\"\n );\n }\n\n const finalMeta: TicketMeta = meta || {\n type: \"feature\",\n priority: \"medium\",\n risk: \"low\",\n area: \"shared\",\n };\n\n // Extract issue body (without META line) and append signature\n const issueBody =\n extractIssueBody(aiOutput) +\n `\\n\\n---\\n*Created with ${getProviderDisplayName(currentProvider)} by [gent](https://github.com/Rotorsoft/gent)*`;\n\n // Determine title: user override > AI-generated > fallback\n let title: string;\n if (options.title) {\n title = options.title;\n } else {\n const aiTitle = extractTitle(aiOutput);\n if (aiTitle) {\n title = aiTitle;\n } else {\n title = generateFallbackTitle(description);\n logger.warning(\"Could not extract AI-generated title. Using fallback.\");\n }\n }\n\n // Build labels\n const labels = buildIssueLabels(finalMeta);\n\n // Show ticket preview\n displayTicketPreview(title, finalMeta, issueBody);\n\n // Skip confirmation if --yes flag is passed\n if (options.yes) {\n await createAndDisplayIssue(title, issueBody, labels, finalMeta);\n return;\n }\n\n // Ask for confirmation\n const { action } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"action\",\n message: \"What would you like to do?\",\n choices: [\n { name: \"Create issue\", value: \"create\" },\n { name: \"Edit description and regenerate\", value: \"edit\" },\n { name: \"Cancel\", value: \"cancel\" },\n ],\n },\n ]);\n\n if (action === \"cancel\") {\n logger.info(\"Issue creation cancelled.\");\n return;\n }\n\n if (action === \"create\") {\n await createAndDisplayIssue(title, issueBody, labels, finalMeta);\n return;\n }\n\n // action === \"edit\" - prompt for additional hints\n const { hints } = await inquirer.prompt([\n {\n type: \"input\",\n name: \"hints\",\n message: \"Enter additional hints or context for the AI:\",\n },\n ]);\n\n if (hints.trim()) {\n additionalHints = additionalHints\n ? `${additionalHints}\\n${hints.trim()}`\n : hints.trim();\n }\n\n logger.newline();\n logger.info(\"Regenerating ticket with additional context...\");\n logger.newline();\n }\n}\n\nfunction displayTicketPreview(\n title: string,\n meta: TicketMeta,\n body: string\n): void {\n // Count lines for summary\n const lineCount = body.split(\"\\n\").length;\n\n // Section header helper\n const sectionHeader = (label: string) =>\n console.log(chalk.bold.cyan(`${label}`));\n\n // Display preview with clean sections\n console.log(chalk.bold.white(\"━━━ Ticket Preview ━━━\"));\n logger.newline();\n\n sectionHeader(\"Title\");\n console.log(` ${title}`);\n logger.newline();\n\n sectionHeader(\"Labels\");\n console.log(\n ` ${colors.label(`type:${meta.type}`)} ${colors.label(`priority:${meta.priority}`)} ${colors.label(`risk:${meta.risk}`)} ${colors.label(`area:${meta.area}`)}`\n );\n logger.newline();\n\n sectionHeader(`Body (${lineCount} lines)`);\n // Indent each line of the body for visual hierarchy\n const bodyLines = body.split(\"\\n\");\n for (const line of bodyLines) {\n console.log(` ${line}`);\n }\n\n logger.newline();\n console.log(chalk.bold.white(\"━━━━━━━━━━━━━━━━━━━━━━\"));\n logger.newline();\n}\n\nasync function createAndDisplayIssue(\n title: string,\n body: string,\n labels: string[],\n meta: TicketMeta\n): Promise<void> {\n let issueNumber: number;\n try {\n issueNumber = await withSpinner(\"Creating GitHub issue...\", async () => {\n return createIssue({\n title,\n body,\n labels,\n });\n });\n } catch (error) {\n logger.error(`Failed to create issue: ${error}`);\n return;\n }\n\n logger.newline();\n logger.success(`Created issue ${colors.issue(`#${issueNumber}`)}`);\n logger.newline();\n\n logger.box(\n \"Issue Created\",\n `Issue: ${colors.issue(`#${issueNumber}`)}\nType: ${colors.label(`type:${meta.type}`)}\nPriority: ${colors.label(`priority:${meta.priority}`)}\nRisk: ${colors.label(`risk:${meta.risk}`)}\nArea: ${colors.label(`area:${meta.area}`)}\n\nNext steps:\n1. Review the issue on GitHub\n2. Run ${colors.command(`gent run ${issueNumber}`)} to implement`\n );\n}\n","import { spawn } from \"child_process\";\nimport { execa, type ResultPromise } from \"execa\";\nimport type { GentConfig, AIProvider } from \"../types/index.js\";\nimport { logger, colors } from \"../utils/logger.js\";\n\nimport { checkAIProvider } from \"../utils/validators.js\";\n\nexport interface AIProviderOptions {\n prompt: string;\n permissionMode?: string;\n printOutput?: boolean;\n streamOutput?: boolean;\n onFirstData?: () => void;\n}\n\nexport interface AIProviderResult {\n output: string;\n provider: AIProvider;\n rateLimited?: boolean;\n}\n\n/**\n * Get list of available AI providers except the current one\n */\nexport async function getOtherAvailableProviders(\n currentProvider: AIProvider\n): Promise<AIProvider[]> {\n const allProviders: AIProvider[] = [\"claude\", \"gemini\", \"codex\"];\n const others = allProviders.filter((p) => p !== currentProvider);\n const available: AIProvider[] = [];\n\n for (const p of others) {\n if (await checkAIProvider(p)) {\n available.push(p);\n }\n }\n\n return available;\n}\n\nasync function invokeInternal(\n provider: AIProvider,\n options: AIProviderOptions\n): Promise<string> {\n switch (provider) {\n case \"claude\":\n return invokeClaudeInternal(options);\n case \"gemini\":\n return invokeGeminiInternal(options);\n case \"codex\":\n return invokeCodexInternal(options);\n }\n}\n\n/**\n * Invoke AI provider (non-interactive mode)\n * Returns output from the provider\n */\nexport async function invokeAI(\n options: AIProviderOptions,\n config: GentConfig,\n providerOverride?: AIProvider\n): Promise<AIProviderResult> {\n const provider = providerOverride ?? config.ai.provider;\n\n try {\n const output = await invokeInternal(provider, options);\n\n return { output, provider };\n } catch (error) {\n // Check for rate limiting\n if (isRateLimitError(error, provider)) {\n // Try fallback if configured\n if (\n config.ai.auto_fallback &&\n config.ai.fallback_provider &&\n !providerOverride\n ) {\n const fallback = config.ai.fallback_provider;\n logger.warning(\n `Rate limit reached on ${getProviderDisplayName(provider)}, switching to ${getProviderDisplayName(fallback)}...`\n );\n\n const output = await invokeInternal(fallback, options);\n\n return { output, provider: fallback };\n }\n\n // Return rate limited error\n const err = error as Error;\n err.message = `Rate limited on ${getProviderDisplayName(provider)}`;\n (err as Error & { rateLimited: boolean }).rateLimited = true;\n throw err;\n }\n\n throw error;\n }\n}\n\n/**\n * Invoke AI provider in interactive mode (stdio inherited)\n * Used for implementation sessions\n */\nexport async function invokeAIInteractive(\n prompt: string,\n config: GentConfig,\n providerOverride?: AIProvider\n): Promise<{ result: ResultPromise; provider: AIProvider }> {\n const provider = providerOverride ?? config.ai.provider;\n\n switch (provider) {\n case \"claude\": {\n const args = [\"--permission-mode\", config.claude.permission_mode, prompt];\n return {\n result: execa(\"claude\", args, { stdio: \"inherit\" }),\n provider,\n };\n }\n case \"gemini\": {\n // Gemini CLI uses -i/--prompt-interactive for interactive mode with initial prompt\n // Without -i, the positional prompt runs in one-shot mode and exits\n return {\n result: execa(\"gemini\", [\"-i\", prompt], { stdio: \"inherit\" }),\n provider,\n };\n }\n case \"codex\": {\n // Codex CLI uses the TUI for interactive sessions; prompt is optional\n const args = prompt ? [prompt] : [];\n return {\n result: execa(\"codex\", args, { stdio: \"inherit\" }),\n provider,\n };\n }\n }\n}\n\n/**\n * Get display name for provider\n */\nexport function getProviderDisplayName(provider: AIProvider): string {\n switch (provider) {\n case \"claude\":\n return \"Claude\";\n case \"gemini\":\n return \"Gemini\";\n case \"codex\":\n return \"Codex\";\n }\n}\n\n/**\n * Get email for provider co-author credit\n */\nexport function getProviderEmail(provider: AIProvider): string {\n switch (provider) {\n case \"claude\":\n return \"noreply@anthropic.com\";\n case \"gemini\":\n return \"noreply@google.com\";\n case \"codex\":\n return \"noreply@openai.com\";\n }\n}\n\n/**\n * Get colored provider name for display\n */\nexport function getProviderDisplay(provider: AIProvider): string {\n const name = getProviderDisplayName(provider);\n switch (provider) {\n case \"claude\":\n return colors.command(name);\n case \"gemini\":\n return colors.label(name);\n case \"codex\":\n return colors.file(name);\n }\n}\n\n/**\n * Check if error is a rate limit error\n */\nfunction isRateLimitError(error: unknown, provider: AIProvider): boolean {\n if (!error || typeof error !== \"object\") return false;\n\n // Claude and Codex CLIs may use exit code 2 for rate limiting\n if (\n (provider === \"claude\" || provider === \"codex\") &&\n \"exitCode\" in error &&\n error.exitCode === 2\n ) {\n return true;\n }\n\n // Gemini CLI may use different exit codes or error messages\n // Check for common rate limit patterns in error messages\n if (\"message\" in error && typeof error.message === \"string\") {\n const msg = error.message.toLowerCase();\n if (\n msg.includes(\"rate limit\") ||\n msg.includes(\"quota exceeded\") ||\n msg.includes(\"too many requests\")\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Internal Claude invocation\n */\nasync function invokeClaudeInternal(\n options: AIProviderOptions\n): Promise<string> {\n const args = [\"--print\"];\n\n if (options.permissionMode) {\n args.push(\"--permission-mode\", options.permissionMode);\n }\n\n args.push(options.prompt);\n\n if (options.printOutput) {\n // Stream output to console without capturing\n const subprocess = execa(\"claude\", args, {\n stdio: \"inherit\",\n });\n await subprocess;\n return \"\";\n } else if (options.streamOutput) {\n // Use native spawn for better streaming control\n return new Promise((resolve, reject) => {\n const child = spawn(\"claude\", args, {\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n });\n\n let output = \"\";\n let firstData = true;\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n if (firstData) {\n firstData = false;\n options.onFirstData?.();\n }\n const text = chunk.toString();\n output += text;\n process.stdout.write(text);\n });\n\n child.stderr.on(\"data\", (chunk: Buffer) => {\n process.stderr.write(chunk);\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve(output);\n } else {\n const error = new Error(`Claude exited with code ${code}`);\n (error as Error & { exitCode: number }).exitCode = code ?? 1;\n reject(error);\n }\n });\n\n child.on(\"error\", reject);\n });\n } else {\n const { stdout } = await execa(\"claude\", args);\n return stdout;\n }\n}\n\n/**\n * Internal Gemini invocation\n */\nasync function invokeGeminiInternal(\n options: AIProviderOptions\n): Promise<string> {\n // Gemini CLI uses different argument structure\n const args: string[] = [];\n\n // Add prompt\n args.push(options.prompt);\n\n if (options.printOutput) {\n const subprocess = execa(\"gemini\", args, {\n stdio: \"inherit\",\n });\n await subprocess;\n return \"\";\n } else if (options.streamOutput) {\n return new Promise((resolve, reject) => {\n const child = spawn(\"gemini\", args, {\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n });\n\n let output = \"\";\n let firstData = true;\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n if (firstData) {\n firstData = false;\n options.onFirstData?.();\n }\n const text = chunk.toString();\n output += text;\n process.stdout.write(text);\n });\n\n child.stderr.on(\"data\", (chunk: Buffer) => {\n process.stderr.write(chunk);\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve(output);\n } else {\n const error = new Error(`Gemini exited with code ${code}`);\n (error as Error & { exitCode: number }).exitCode = code ?? 1;\n reject(error);\n }\n });\n\n child.on(\"error\", reject);\n });\n } else {\n const { stdout } = await execa(\"gemini\", args);\n return stdout;\n }\n}\n\n/**\n * Internal Codex invocation\n */\nasync function invokeCodexInternal(\n options: AIProviderOptions\n): Promise<string> {\n // Use non-interactive mode to avoid TTY requirements\n const args = [\"exec\", options.prompt];\n\n if (options.printOutput) {\n const subprocess = execa(\"codex\", args, {\n stdio: \"inherit\",\n });\n await subprocess;\n return \"\";\n } else if (options.streamOutput) {\n return new Promise((resolve, reject) => {\n const child = spawn(\"codex\", args, {\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n });\n\n let output = \"\";\n let firstData = true;\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n if (firstData) {\n firstData = false;\n options.onFirstData?.();\n }\n const text = chunk.toString();\n output += text;\n process.stdout.write(text);\n });\n\n child.stderr.on(\"data\", (chunk: Buffer) => {\n process.stderr.write(chunk);\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve(output);\n } else {\n const error = new Error(`Codex exited with code ${code}`);\n (error as Error & { exitCode: number }).exitCode = code ?? 1;\n reject(error);\n }\n });\n\n child.on(\"error\", reject);\n });\n } else {\n const { stdout } = await execa(\"codex\", args);\n return stdout;\n }\n}\n","import type { GentConfig } from \"../types/index.js\";\nimport { getProviderDisplayName, getProviderEmail } from \"./ai-provider.js\";\n\nexport function buildTicketPrompt(\n description: string,\n agentInstructions: string | null,\n additionalHints: string | null = null\n): string {\n const basePrompt = `You are creating a GitHub issue for a software project following an AI-assisted development workflow.\n\nUser Request: ${description}\n\n${agentInstructions ? `Project-Specific Instructions:\\n${agentInstructions}\\n\\n` : \"\"}${additionalHints ? `Additional Context/Hints:\\n${additionalHints}\\n\\n` : \"\"}\n\nCreate a detailed GitHub issue following this exact template.\n\nIMPORTANT: Start your output IMMEDIATELY with \"TITLE:\" followed by a clear, concise issue title in imperative mood (e.g., \"Add OAuth2 authentication for Google and GitHub\"). Keep titles under 100 characters when possible. Then on the next line, start with \"## Description\". Do not include any preamble, commentary, or introduction.\n\nTITLE: [Clear, concise issue title in imperative mood]\n\n## Description\n[Clear user-facing description of what needs to be done]\n\n## Technical Context\n**Type:** feature | fix | refactor | chore | docs | test\n**Category:** ui | api | database | workers | shared | testing | infra\n**Priority:** critical | high | medium | low\n**Risk:** low | medium | high\n\n### Architecture Notes\n- [Relevant patterns to follow]\n- [Related systems affected]\n- [Constraints or invariants]\n\n## Implementation Steps\n- [ ] Step 1: Specific technical task\n- [ ] Step 2: Specific technical task\n- [ ] Step 3: Specific technical task\n\n## Testing Requirements\n- **Unit tests:** [What to test]\n- **Integration tests:** [What to test if applicable]\n- **Manual verification:** [What to check]\n\n## Acceptance Criteria\n- [ ] Criterion 1\n- [ ] Criterion 2\n\n---\nIMPORTANT: After the issue content, on a new line, output ONLY the following metadata in this exact format:\nMETA:type=<type>,priority=<priority>,risk=<risk>,area=<area>\n\nExample: META:type=feature,priority=high,risk=low,area=ui`;\n\n return basePrompt;\n}\n\nexport function buildImplementationPrompt(\n issue: { number: number; title: string; body: string },\n agentInstructions: string | null,\n progressContent: string | null,\n config: GentConfig,\n extraContext: string | null = null\n): string {\n const providerName = getProviderDisplayName(config.ai.provider);\n const providerEmail = getProviderEmail(config.ai.provider);\n\n return `GitHub Issue #${issue.number}: ${issue.title}\n\n${issue.body}\n\n${agentInstructions ? `## Project-Specific Instructions\\n${agentInstructions}\\n\\n` : \"\"}\n${progressContent ? `## Previous Progress\\n${progressContent}\\n\\n` : \"\"}\n${extraContext ? `${extraContext}\\n\\n` : \"\"}\n\n## Your Task\n\n1. **Implement the feature/fix** following patterns from the project's AGENT.md or codebase conventions\n2. **Add unit tests** for any new functionality\n3. **Run validation** before committing:\n${config.validation.map((cmd) => ` - ${cmd}`).join(\"\\n\")}\n4. **Make an atomic commit** with a clear message following conventional commits format:\n - Use format: <type>: <description>\n - Include \"Completed GitHub issue #${issue.number}\" in body\n - End with: Co-Authored-By: ${providerName} <${providerEmail}>\n5. **Update ${config.progress.file}** - append a compact entry documenting your work:\n \\\n [YYYY-MM-DD] #${issue.number} <type>: <brief description>\n - Files: <comma-separated list of changed files>\n - Changes: <1-2 sentence summary of what was implemented>\n - Decisions: <key technical decisions made, if any>\n - Issues: <concerns or follow-ups for reviewers, if any>\n \\\n Keep entries minimal (4-6 lines max). Skip sections if not applicable.\n6. **Do NOT push** - the user will review and push manually\n\nFocus on clean, minimal implementation. Don't over-engineer.`;\n}\n\nexport function buildPrPrompt(\n issue: { number: number; title: string; body: string } | null,\n commits: string[],\n diffSummary: string\n): string {\n return `Generate a pull request description for the following changes.\n\n${issue ? `## Related Issue\\n#${issue.number}: ${issue.title}\\n\\n${issue.body}\\n\\n` : \"\"}\n\n## Commits\n${commits.map((c) => `- ${c}`).join(\"\\n\")}\n\n## Changed Files\n${diffSummary}\n\nGenerate a PR description in this format:\n\n## Summary\n- [1-3 bullet points summarizing the changes]\n\n## Test Plan\n- [ ] [Testing steps]\n\n${issue ? `Closes #${issue.number}` : \"\"}\n\nOnly output the PR description, nothing else.`;\n}\n\nexport function buildCommitMessagePrompt(\n diff: string,\n issueNumber: number | null,\n issueTitle: string | null\n): string {\n const issueContext = issueNumber\n ? `\\nRelated Issue: #${issueNumber}${issueTitle ? ` - ${issueTitle}` : \"\"}\\n`\n : \"\";\n\n return `Generate a concise git commit message for the following changes.\n${issueContext}\n## Diff\n${diff}\n\nRules:\n- Use conventional commit format: <type>: <short description>\n- Types: feat, fix, refactor, chore, docs, test, style, perf\n- Keep the first line under 72 characters\n- Do NOT include a body or footer\n- Output ONLY the commit message, nothing else`;\n}\n\nexport function parseTicketMeta(\n output: string\n): { type: string; priority: string; risk: string; area: string } | null {\n const metaMatch = output.match(\n /META:type=(\\w+),priority=(\\w+),risk=(\\w+),area=(\\w+)/\n );\n\n if (!metaMatch) {\n return null;\n }\n\n return {\n type: metaMatch[1],\n priority: metaMatch[2],\n risk: metaMatch[3],\n area: metaMatch[4],\n };\n}\n\nexport function extractIssueBody(output: string): string {\n // Remove the META line from the output\n let body = output\n .replace(/\\n?META:type=\\w+,priority=\\w+,risk=\\w+,area=\\w+\\s*$/, \"\")\n .trim();\n\n // Strip the TITLE line if present\n body = body.replace(/^TITLE:\\s*.+\\n+/, \"\");\n\n // Strip any preamble text before \"## Description\"\n const descriptionIndex = body.indexOf(\"## Description\");\n if (descriptionIndex > 0) {\n body = body.substring(descriptionIndex);\n }\n\n return body;\n}\n\n/**\n * Extract the generated title from AI output\n * Returns null if no valid title is found\n */\nexport function extractTitle(output: string): string | null {\n const match = output.match(/^TITLE:\\s*(.+)$/m);\n if (!match) {\n return null;\n }\n\n let title = match[1].trim();\n\n // Remove surrounding quotes if present\n if (\n (title.startsWith('\"') && title.endsWith('\"')) ||\n (title.startsWith(\"'\") && title.endsWith(\"'\"))\n ) {\n title = title.slice(1, -1);\n }\n\n // Remove template placeholder if AI didn't replace it\n if (title.includes(\"[\") && title.includes(\"]\")) {\n return null;\n }\n\n // Ensure reasonable length (not empty, not too long)\n if (title.length < 5 || title.length > 200) {\n return null;\n }\n\n return title;\n}\n\n/**\n * Generate a fallback title from the user's description\n * Truncates long descriptions at word boundary without ellipsis\n */\nexport function generateFallbackTitle(description: string): string {\n const maxLength = 200;\n if (description.length <= maxLength) {\n return description;\n }\n // Truncate at last word boundary before maxLength\n const truncated = description.slice(0, maxLength);\n const lastSpace = truncated.lastIndexOf(\" \");\n if (lastSpace > maxLength * 0.5) {\n return truncated.slice(0, lastSpace);\n }\n return truncated;\n}\n\n/**\n * Build prompt for Playwright video capture of UI changes.\n * Instructs AI to upload video to GitHub assets rather than committing to repo.\n */\nexport function buildVideoPrompt(\n issueNumber: number,\n issueTitle: string,\n videoConfig: { max_duration: number; width: number; height: number },\n agentInstructions: string | null\n): string {\n return `You are helping capture a Playwright video demonstration of UI changes for GitHub Issue #${issueNumber}: ${issueTitle}\n\n${agentInstructions ? `## Project-Specific Instructions\\n${agentInstructions}\\n\\n` : \"\"}\n\n## Task: Record UI Demo Video\n\nCreate a short video (max ${videoConfig.max_duration}s) demonstrating the UI changes made for this issue.\n\n### Video Requirements\n- Resolution: ${videoConfig.width}x${videoConfig.height}\n- Format: WebM or MP4\n- Duration: Under ${videoConfig.max_duration} seconds\n- Show the key UI interactions and visual changes\n\n### Steps\n\n1. **Start the development server** if not already running\n2. **Use Playwright to record video** of the relevant UI interactions:\n - Navigate to the affected pages/components\n - Demonstrate the new or changed functionality\n - Show before/after if applicable\n\n3. **Upload video to GitHub** as a release asset or use GitHub's drag-drop upload:\n - Create a GitHub release or upload to issue comments\n - Get the permanent URL for the video\n - Do NOT commit video files to the repository\n\n4. **Add video to PR** by commenting with the video URL or embedding it\n\n### Important\n- Upload video to GitHub assets, NOT to the repository\n- Keep the video concise - focus on demonstrating the changes\n- Ensure the video clearly shows the UI improvements\n\nOutput the GitHub URL where the video was uploaded when complete.`;\n}\n","import chalk from \"chalk\";\nimport inquirer from \"inquirer\";\nimport { logger, colors } from \"../utils/logger.js\";\nimport { withSpinner } from \"../utils/spinner.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { listIssues, listOpenPrs, type OpenPr } from \"../lib/github.js\";\nimport {\n getCurrentBranch,\n getDefaultBranch,\n hasUncommittedChanges,\n branchExists,\n checkoutBranch,\n createBranch,\n listLocalBranches,\n remoteBranchExists,\n fetchAndCheckout,\n} from \"../lib/git.js\";\nimport { parseBranchName, generateBranchName } from \"../lib/branch.js\";\nimport { getWorkflowLabels, sortByPriority } from \"../lib/labels.js\";\nimport { checkGhAuth } from \"../utils/validators.js\";\nimport type { GitHubIssue } from \"../types/index.js\";\n\nexport interface ListOptions {\n label?: string;\n status?: \"ready\" | \"in-progress\" | \"completed\" | \"blocked\" | \"all\";\n limit?: number;\n}\n\nexport interface TicketChoice {\n issueNumber: number;\n title: string;\n branch: string | null;\n category: \"in-progress\" | \"open-pr\" | \"ready\";\n}\n\n/**\n * Find the local branch associated with an issue number by scanning all local branches.\n */\nexport function findBranchForIssue(\n issueNumber: number,\n branches: string[]\n): string | null {\n for (const branch of branches) {\n const info = parseBranchName(branch);\n if (info && info.issueNumber === issueNumber) {\n return branch;\n }\n }\n return null;\n}\n\n/**\n * Build categorized ticket choices from GitHub data and local branches.\n */\nexport function buildTicketChoices(\n inProgressIssues: GitHubIssue[],\n readyIssues: GitHubIssue[],\n openPrs: OpenPr[],\n localBranches: string[]\n): TicketChoice[] {\n const choices: TicketChoice[] = [];\n const seen = new Set<number>();\n\n // Map PR branches to issue numbers\n const prByIssue = new Map<number, OpenPr>();\n for (const pr of openPrs) {\n const info = parseBranchName(pr.headRefName);\n if (info) {\n prByIssue.set(info.issueNumber, pr);\n }\n }\n\n // In-progress issues first\n for (const issue of inProgressIssues) {\n if (seen.has(issue.number)) continue;\n seen.add(issue.number);\n const branch = findBranchForIssue(issue.number, localBranches);\n const pr = prByIssue.get(issue.number);\n choices.push({\n issueNumber: issue.number,\n title: issue.title,\n branch: branch || pr?.headRefName || null,\n category: pr ? \"open-pr\" : \"in-progress\",\n });\n }\n\n // Issues with open PRs (not already added)\n for (const [issueNumber, pr] of prByIssue) {\n if (seen.has(issueNumber)) continue;\n seen.add(issueNumber);\n const issue = [...inProgressIssues, ...readyIssues].find(\n (i) => i.number === issueNumber\n );\n choices.push({\n issueNumber,\n title: issue?.title || pr.title,\n branch: pr.headRefName,\n category: \"open-pr\",\n });\n }\n\n // Ready issues\n for (const issue of readyIssues) {\n if (seen.has(issue.number)) continue;\n seen.add(issue.number);\n const branch = findBranchForIssue(issue.number, localBranches);\n choices.push({\n issueNumber: issue.number,\n title: issue.title,\n branch,\n category: \"ready\",\n });\n }\n\n return choices;\n}\n\nfunction categoryLabel(category: TicketChoice[\"category\"]): string {\n switch (category) {\n case \"in-progress\":\n return chalk.yellow(\"[in progress]\");\n case \"open-pr\":\n return chalk.blue(\"[open PR]\");\n case \"ready\":\n return chalk.green(\"[ready]\");\n }\n}\n\nfunction formatChoice(choice: TicketChoice): string {\n const num = colors.issue(`#${choice.issueNumber}`);\n const cat = categoryLabel(choice.category);\n const title =\n choice.title.length > 50 ? choice.title.slice(0, 50) + \"...\" : choice.title;\n return `${num} ${cat} ${title}`;\n}\n\nexport async function listCommand(options: ListOptions): Promise<void> {\n const isAuthed = await checkGhAuth();\n if (!isAuthed) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n return;\n }\n\n const config = loadConfig();\n const workflowLabels = getWorkflowLabels(config);\n const currentBranch = await getCurrentBranch();\n const defaultBranch = await getDefaultBranch();\n\n // Determine which categories to fetch based on status filter\n const statusFilter = options.status;\n const limit = options.limit || 20;\n\n let inProgressIssues: GitHubIssue[] = [];\n let readyIssues: GitHubIssue[] = [];\n\n if (statusFilter && statusFilter !== \"all\") {\n // Filtered mode: fetch only the requested status\n const labels: string[] = [];\n if (options.label) labels.push(options.label);\n\n switch (statusFilter) {\n case \"ready\":\n labels.push(workflowLabels.ready);\n break;\n case \"in-progress\":\n labels.push(workflowLabels.inProgress);\n break;\n case \"completed\":\n labels.push(workflowLabels.completed);\n break;\n case \"blocked\":\n labels.push(workflowLabels.blocked);\n break;\n }\n\n const [issues, localBranches] = await withSpinner(\n \"Fetching tickets...\",\n () =>\n Promise.all([\n listIssues({ labels, state: \"open\", limit }),\n listLocalBranches(),\n ])\n );\n\n sortByPriority(issues);\n\n // Map filtered issues into the right category\n if (statusFilter === \"in-progress\") {\n inProgressIssues = issues;\n } else {\n readyIssues = issues;\n }\n\n const choices = buildTicketChoices(\n inProgressIssues,\n readyIssues,\n [],\n localBranches\n );\n\n if (choices.length === 0) {\n logger.info(\"No issues found matching the criteria.\");\n return;\n }\n\n await presentSelector(choices, currentBranch, defaultBranch, config);\n return;\n }\n\n // Default: fetch all active categories in parallel\n const labelFilter = options.label ? [options.label] : [];\n const [inProgress, ready, prs, localBranches] = await withSpinner(\n \"Fetching tickets...\",\n () =>\n Promise.all([\n listIssues({\n labels: [workflowLabels.inProgress, ...labelFilter],\n state: \"open\",\n limit,\n }),\n listIssues({\n labels: [workflowLabels.ready, ...labelFilter],\n state: \"open\",\n limit,\n }),\n listOpenPrs(30),\n listLocalBranches(),\n ])\n );\n\n sortByPriority(inProgress);\n sortByPriority(ready);\n\n const choices = buildTicketChoices(inProgress, ready, prs, localBranches);\n\n if (choices.length === 0) {\n logger.info(\"No tickets found.\");\n logger.dim(\n `Create a ticket with ${colors.command(\"gent create\")} or add the '${workflowLabels.ready}' label to an issue.`\n );\n return;\n }\n\n await presentSelector(choices, currentBranch, defaultBranch, config);\n}\n\nasync function presentSelector(\n choices: TicketChoice[],\n currentBranch: string,\n defaultBranch: string,\n config: ReturnType<typeof loadConfig>\n): Promise<void> {\n // Check for uncommitted changes before allowing switch\n const dirty = await hasUncommittedChanges();\n\n // Build inquirer choices with separator groups\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const inquirerChoices: any[] = [];\n\n // Main/master option always first\n inquirerChoices.push({\n name: `${chalk.magenta(defaultBranch)}${currentBranch === defaultBranch ? chalk.dim(\" (current)\") : \"\"}`,\n value: \"__main__\",\n });\n inquirerChoices.push(new inquirer.Separator(\"─\"));\n\n // Group by category\n const inProgress = choices.filter((c) => c.category === \"in-progress\");\n const openPrChoices = choices.filter((c) => c.category === \"open-pr\");\n const ready = choices.filter((c) => c.category === \"ready\");\n\n if (inProgress.length > 0) {\n inquirerChoices.push(new inquirer.Separator(chalk.yellow(\" In Progress\")));\n for (const c of inProgress) {\n inquirerChoices.push({\n name: formatChoice(c),\n value: String(c.issueNumber),\n });\n }\n }\n\n if (openPrChoices.length > 0) {\n inquirerChoices.push(new inquirer.Separator(chalk.blue(\" Open PRs\")));\n for (const c of openPrChoices) {\n inquirerChoices.push({\n name: formatChoice(c),\n value: String(c.issueNumber),\n });\n }\n }\n\n if (ready.length > 0) {\n inquirerChoices.push(new inquirer.Separator(chalk.green(\" Ready\")));\n for (const c of ready) {\n inquirerChoices.push({\n name: formatChoice(c),\n value: String(c.issueNumber),\n });\n }\n }\n\n const { selected } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"selected\",\n message: \"Select a ticket to switch to:\",\n choices: inquirerChoices,\n pageSize: 20,\n },\n ]);\n\n // Handle main branch selection\n if (selected === \"__main__\") {\n if (currentBranch === defaultBranch) {\n logger.info(`Already on ${colors.branch(defaultBranch)}`);\n return;\n }\n if (dirty) {\n const ok = await confirmDirty();\n if (!ok) return;\n }\n await withSpinner(`Switching to ${defaultBranch}...`, async () => {\n await checkoutBranch(defaultBranch);\n });\n logger.success(`Switched to ${colors.branch(defaultBranch)}`);\n return;\n }\n\n // Find the selected ticket\n const issueNumber = parseInt(selected, 10);\n const ticket = choices.find((c) => c.issueNumber === issueNumber);\n if (!ticket) return;\n\n if (dirty) {\n const ok = await confirmDirty();\n if (!ok) return;\n }\n\n // Resolve branch\n const targetBranch = ticket.branch;\n\n if (targetBranch) {\n if (await branchExists(targetBranch)) {\n await withSpinner(`Switching to ${targetBranch}...`, async () => {\n await checkoutBranch(targetBranch);\n });\n logger.success(`Switched to ${colors.branch(targetBranch)}`);\n } else if (await remoteBranchExists(targetBranch)) {\n await withSpinner(`Fetching ${targetBranch} from remote...`, async () => {\n await fetchAndCheckout(targetBranch);\n });\n logger.success(`Fetched and switched to ${colors.branch(targetBranch)}`);\n } else {\n logger.warning(\n `Branch ${colors.branch(targetBranch)} not found locally or on remote.`\n );\n await offerCreateBranch(config, issueNumber, ticket.title);\n }\n } else {\n await offerCreateBranch(config, issueNumber, ticket.title);\n }\n}\n\nasync function confirmDirty(): Promise<boolean> {\n logger.warning(\"You have uncommitted changes.\");\n const { proceed } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"proceed\",\n message: \"Continue anyway? (changes will carry over to the new branch)\",\n default: false,\n },\n ]);\n if (!proceed) {\n logger.info(\"Aborting. Please commit or stash your changes first.\");\n }\n return proceed;\n}\n\nasync function offerCreateBranch(\n config: Parameters<typeof generateBranchName>[0],\n issueNumber: number,\n title: string\n): Promise<void> {\n const branchName = await generateBranchName(\n config,\n issueNumber,\n title,\n \"feature\"\n );\n\n const { create } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"create\",\n message: `No branch exists. Create ${colors.branch(branchName)}?`,\n default: true,\n },\n ]);\n\n if (!create) return;\n\n const defaultBranch = await getDefaultBranch();\n await withSpinner(`Creating branch ${branchName}...`, async () => {\n await createBranch(branchName, defaultBranch);\n });\n logger.success(`Created and switched to ${colors.branch(branchName)}`);\n}\n","import { execa } from \"execa\";\n\nexport async function getCurrentBranch(): Promise<string> {\n const { stdout } = await execa(\"git\", [\"branch\", \"--show-current\"]);\n return stdout.trim();\n}\n\nexport async function isOnMainBranch(): Promise<boolean> {\n const branch = await getCurrentBranch();\n return branch === \"main\" || branch === \"master\";\n}\n\nexport async function getDefaultBranch(): Promise<string> {\n try {\n const { stdout } = await execa(\"git\", [\n \"symbolic-ref\",\n \"refs/remotes/origin/HEAD\",\n ]);\n return stdout.trim().replace(\"refs/remotes/origin/\", \"\");\n } catch {\n // Fallback to checking if main or master exists\n try {\n await execa(\"git\", [\"rev-parse\", \"--verify\", \"main\"]);\n return \"main\";\n } catch {\n return \"master\";\n }\n }\n}\n\nexport async function branchExists(name: string): Promise<boolean> {\n try {\n await execa(\"git\", [\"rev-parse\", \"--verify\", name]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function createBranch(name: string, from?: string): Promise<void> {\n if (from) {\n await execa(\"git\", [\"checkout\", \"-b\", name, from]);\n } else {\n await execa(\"git\", [\"checkout\", \"-b\", name]);\n }\n}\n\nexport async function checkoutBranch(name: string): Promise<void> {\n await execa(\"git\", [\"checkout\", name]);\n}\n\nexport async function hasUncommittedChanges(): Promise<boolean> {\n const { stdout } = await execa(\"git\", [\"status\", \"--porcelain\"]);\n return stdout.trim().length > 0;\n}\n\nexport async function getUnpushedCommits(): Promise<boolean> {\n try {\n const { stdout } = await execa(\"git\", [\"log\", \"@{u}..HEAD\", \"--oneline\"]);\n return stdout.trim().length > 0;\n } catch {\n // No upstream set\n return true;\n }\n}\n\nexport async function pushBranch(branch?: string): Promise<void> {\n const branchName = branch || (await getCurrentBranch());\n await execa(\"git\", [\"push\", \"-u\", \"origin\", branchName]);\n}\n\nexport async function getAuthorInitials(): Promise<string> {\n // Try git config user.initials first\n try {\n const { stdout } = await execa(\"git\", [\"config\", \"user.initials\"]);\n if (stdout.trim()) {\n return stdout.trim();\n }\n } catch {\n // Not set, continue\n }\n\n // Fall back to deriving from user.name\n try {\n const { stdout } = await execa(\"git\", [\"config\", \"user.name\"]);\n const name = stdout.trim();\n if (name) {\n // Extract initials from name (e.g., \"John Doe\" -> \"jd\")\n const parts = name.split(/\\s+/);\n return parts.map((p) => p[0]?.toLowerCase() || \"\").join(\"\");\n }\n } catch {\n // Not set\n }\n\n return \"dev\";\n}\n\nexport async function getRepoInfo(): Promise<{\n owner: string;\n repo: string;\n} | null> {\n try {\n const { stdout } = await execa(\"git\", [\n \"config\",\n \"--get\",\n \"remote.origin.url\",\n ]);\n const url = stdout.trim();\n\n // Handle SSH format: git@github.com:owner/repo.git\n const sshMatch = url.match(/git@github\\.com:([^/]+)\\/([^.]+)/);\n if (sshMatch) {\n return { owner: sshMatch[1], repo: sshMatch[2] };\n }\n\n // Handle HTTPS format: https://github.com/owner/repo.git\n const httpsMatch = url.match(/github\\.com\\/([^/]+)\\/([^.]+)/);\n if (httpsMatch) {\n return { owner: httpsMatch[1], repo: httpsMatch[2] };\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\nexport async function getCommitsSinceBase(\n base: string = \"main\"\n): Promise<string[]> {\n try {\n const { stdout } = await execa(\"git\", [\n \"log\",\n `${base}..HEAD`,\n \"--pretty=format:%s\",\n ]);\n return stdout.trim().split(\"\\n\").filter(Boolean);\n } catch {\n return [];\n }\n}\n\nexport async function getDiffSummary(base: string = \"main\"): Promise<string> {\n try {\n const { stdout } = await execa(\"git\", [\"diff\", `${base}...HEAD`, \"--stat\"]);\n return stdout.trim();\n } catch {\n return \"\";\n }\n}\n\nexport async function getCurrentCommitSha(): Promise<string> {\n const { stdout } = await execa(\"git\", [\"rev-parse\", \"HEAD\"]);\n return stdout.trim();\n}\n\nexport async function hasNewCommits(beforeSha: string): Promise<boolean> {\n const currentSha = await getCurrentCommitSha();\n return currentSha !== beforeSha;\n}\n\nexport async function getLastCommitTimestamp(): Promise<string> {\n const { stdout } = await execa(\"git\", [\"log\", \"-1\", \"--format=%cI\"]);\n return stdout.trim();\n}\n\nexport async function listLocalBranches(): Promise<string[]> {\n const { stdout } = await execa(\"git\", [\n \"branch\",\n \"--format=%(refname:short)\",\n ]);\n return stdout.trim().split(\"\\n\").filter(Boolean);\n}\n\nexport async function remoteBranchExists(name: string): Promise<boolean> {\n try {\n await execa(\"git\", [\"ls-remote\", \"--exit-code\", \"--heads\", \"origin\", name]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function fetchAndCheckout(name: string): Promise<void> {\n await execa(\"git\", [\"fetch\", \"origin\", `${name}:${name}`]);\n await execa(\"git\", [\"checkout\", name]);\n}\n","import type { GentConfig, BranchInfo } from \"../types/index.js\";\nimport { getAuthorInitials } from \"./git.js\";\nimport { sanitizeSlug } from \"../utils/validators.js\";\n\nexport async function generateBranchName(\n config: GentConfig,\n issueNumber: number,\n issueTitle: string,\n type: string\n): Promise<string> {\n const author = await resolveAuthor(config);\n const slug = sanitizeSlug(issueTitle);\n\n return config.branch.pattern\n .replace(\"{author}\", author)\n .replace(\"{type}\", type)\n .replace(\"{issue}\", String(issueNumber))\n .replace(\"{slug}\", slug);\n}\n\nasync function resolveAuthor(config: GentConfig): Promise<string> {\n switch (config.branch.author_source) {\n case \"env\": {\n const envValue = process.env[config.branch.author_env_var];\n if (envValue) {\n return envValue;\n }\n // Fall through to git\n return getAuthorInitials();\n }\n case \"git\":\n default:\n return getAuthorInitials();\n }\n}\n\nexport function parseBranchName(branchName: string): BranchInfo | null {\n // Pattern 1: author/type-issue-slug (e.g., ro/feature-123-add-login)\n const pattern1 =\n /^([^/]+)\\/(feature|fix|refactor|chore|docs|test)-(\\d+)-(.+)$/;\n const match1 = branchName.match(pattern1);\n if (match1) {\n return {\n name: branchName,\n author: match1[1],\n type: match1[2],\n issueNumber: parseInt(match1[3], 10),\n slug: match1[4],\n };\n }\n\n // Pattern 2: type/issue-slug (e.g., feature/123-add-login)\n const pattern2 = /^(feature|fix|refactor|chore|docs|test)\\/(\\d+)-(.+)$/;\n const match2 = branchName.match(pattern2);\n if (match2) {\n return {\n name: branchName,\n author: \"\",\n type: match2[1],\n issueNumber: parseInt(match2[2], 10),\n slug: match2[3],\n };\n }\n\n // Pattern 3: issue-slug (e.g., 123-add-login)\n const pattern3 = /^(\\d+)-(.+)$/;\n const match3 = branchName.match(pattern3);\n if (match3) {\n return {\n name: branchName,\n author: \"\",\n type: \"feature\",\n issueNumber: parseInt(match3[1], 10),\n slug: match3[2],\n };\n }\n\n // Pattern 4: Just look for issue number anywhere\n const issueMatch = branchName.match(/(\\d+)/);\n if (issueMatch) {\n return {\n name: branchName,\n author: \"\",\n type: \"feature\",\n issueNumber: parseInt(issueMatch[1], 10),\n slug: branchName,\n };\n }\n\n return null;\n}\n\nexport function extractIssueNumber(branchName: string): number | null {\n const info = parseBranchName(branchName);\n return info?.issueNumber ?? null;\n}\n","import inquirer from \"inquirer\";\nimport { logger, colors } from \"../utils/logger.js\";\nimport { withSpinner, createSpinner, aiSpinnerText } from \"../utils/spinner.js\";\nimport { loadConfig, loadAgentInstructions } from \"../lib/config.js\";\nimport { getIssue, updateIssueLabels, addIssueComment } from \"../lib/github.js\";\nimport { buildImplementationPrompt } from \"../lib/prompts.js\";\nimport {\n invokeAIInteractive,\n getProviderDisplayName,\n} from \"../lib/ai-provider.js\";\nimport {\n getCurrentBranch,\n isOnMainBranch,\n createBranch,\n branchExists,\n checkoutBranch,\n hasUncommittedChanges,\n getCurrentCommitSha,\n hasNewCommits,\n} from \"../lib/git.js\";\nimport { generateBranchName } from \"../lib/branch.js\";\nimport { getWorkflowLabels, extractTypeFromLabels } from \"../lib/labels.js\";\nimport { readProgress } from \"../lib/progress.js\";\nimport {\n checkGhAuth,\n checkAIProvider,\n isValidIssueNumber,\n} from \"../utils/validators.js\";\nimport type { GitHubIssue, AIProvider } from \"../types/index.js\";\n\nexport interface RunOptions {\n provider?: AIProvider;\n}\n\nexport async function runCommand(\n issueNumberArg: string | undefined,\n options: RunOptions\n): Promise<void> {\n const config = loadConfig();\n\n // Determine which provider to use\n const provider = options.provider ?? config.ai.provider;\n const providerName = getProviderDisplayName(provider);\n\n // Validate prerequisites\n const [ghAuth, aiOk] = await Promise.all([\n checkGhAuth(),\n checkAIProvider(provider),\n ]);\n\n if (!ghAuth) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n return;\n }\n\n if (!aiOk) {\n logger.error(\n `${providerName} CLI not found. Please install ${provider} CLI first.`\n );\n return;\n }\n\n // Check for uncommitted changes\n const hasChanges = await hasUncommittedChanges();\n if (hasChanges) {\n logger.warning(\"You have uncommitted changes.\");\n const { proceed } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"proceed\",\n message: \"Continue anyway?\",\n default: false,\n },\n ]);\n if (!proceed) {\n logger.info(\"Aborting. Please commit or stash your changes first.\");\n return;\n }\n }\n\n const workflowLabels = getWorkflowLabels(config);\n\n // Get issue number\n let issueNumber: number;\n\n if (issueNumberArg) {\n if (!isValidIssueNumber(issueNumberArg)) {\n logger.error(\"Invalid issue number.\");\n return;\n }\n issueNumber = parseInt(issueNumberArg, 10);\n } else {\n logger.error(\n \"Please provide an issue number. Use 'gent switch' to browse tickets.\"\n );\n return;\n }\n\n // Fetch issue details\n let issue: GitHubIssue;\n try {\n issue = await withSpinner(\"Fetching issue...\", async () => {\n return getIssue(issueNumber);\n });\n } catch (error) {\n logger.error(`Failed to fetch issue #${issueNumber}: ${error}`);\n return;\n }\n\n // Verify issue has ai-ready label\n if (!issue.labels.includes(workflowLabels.ready)) {\n logger.warning(\n `Issue #${issueNumber} does not have the '${workflowLabels.ready}' label.`\n );\n const { proceed } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"proceed\",\n message: \"Continue anyway?\",\n default: false,\n },\n ]);\n if (!proceed) {\n return;\n }\n }\n\n logger.newline();\n logger.box(\n \"Issue Details\",\n `#${issue.number}: ${issue.title}\nLabels: ${issue.labels.join(\", \")}`\n );\n logger.newline();\n\n // Generate branch name\n const type = extractTypeFromLabels(issue.labels);\n const branchName = await generateBranchName(\n config,\n issueNumber,\n issue.title,\n type\n );\n\n // Handle branch\n const currentBranch = await getCurrentBranch();\n const onMain = await isOnMainBranch();\n\n if (await branchExists(branchName)) {\n logger.info(`Branch ${colors.branch(branchName)} already exists.`);\n const { action } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"action\",\n message: \"What would you like to do?\",\n choices: [\n { name: \"Continue on existing branch\", value: \"continue\" },\n { name: \"Delete and recreate branch\", value: \"recreate\" },\n { name: \"Cancel\", value: \"cancel\" },\n ],\n },\n ]);\n\n if (action === \"cancel\") {\n return;\n } else if (action === \"continue\") {\n await checkoutBranch(branchName);\n } else {\n // Recreate would require deleting first - for safety, just checkout\n await checkoutBranch(branchName);\n }\n } else {\n if (!onMain) {\n logger.warning(\n `Not on main branch (currently on ${colors.branch(currentBranch)}).`\n );\n const { fromMain } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"fromMain\",\n message: \"Create branch from main instead?\",\n default: true,\n },\n ]);\n\n if (fromMain) {\n await createBranch(branchName, \"main\");\n } else {\n await createBranch(branchName);\n }\n } else {\n await createBranch(branchName);\n }\n logger.success(`Created branch ${colors.branch(branchName)}`);\n }\n\n // Update issue labels\n try {\n await updateIssueLabels(issueNumber, {\n add: [workflowLabels.inProgress],\n remove: [workflowLabels.ready],\n });\n logger.success(\n `Updated issue labels: ${colors.label(workflowLabels.ready)} → ${colors.label(workflowLabels.inProgress)}`\n );\n } catch (error) {\n logger.warning(`Failed to update labels: ${error}`);\n }\n\n // Build implementation prompt\n const agentInstructions = loadAgentInstructions();\n const progressContent = readProgress(config);\n const prompt = buildImplementationPrompt(\n issue,\n agentInstructions,\n progressContent,\n config\n );\n\n logger.newline();\n const spinner = createSpinner(aiSpinnerText(providerName, \"implement ticket\"));\n spinner.start();\n\n // Capture commit SHA before AI runs\n const beforeSha = await getCurrentCommitSha();\n\n // Track if operation was cancelled\n let wasCancelled = false;\n const handleSignal = () => {\n wasCancelled = true;\n };\n process.on(\"SIGINT\", handleSignal);\n process.on(\"SIGTERM\", handleSignal);\n\n // Invoke AI interactively\n spinner.stop();\n let aiExitCode: number | undefined;\n let usedProvider = provider;\n try {\n const { result, provider: actualProvider } = await invokeAIInteractive(\n prompt,\n config,\n options.provider\n );\n usedProvider = actualProvider;\n aiExitCode = result.exitCode ?? undefined;\n } catch (error) {\n if (error && typeof error === \"object\" && \"exitCode\" in error) {\n aiExitCode = error.exitCode as number;\n }\n logger.error(\n `${getProviderDisplayName(usedProvider)} session failed: ${error}`\n );\n // Don't exit - allow user to see what happened\n } finally {\n // Clean up signal handlers\n process.off(\"SIGINT\", handleSignal);\n process.off(\"SIGTERM\", handleSignal);\n }\n\n // Post-completion\n logger.newline();\n\n // Check if any new commits were created\n const commitsCreated = await hasNewCommits(beforeSha);\n\n // Handle cancellation - don't change labels\n if (wasCancelled) {\n logger.warning(\"Operation was cancelled. Labels unchanged.\");\n return;\n }\n\n // Determine appropriate label based on whether work was done\n const usedProviderName = getProviderDisplayName(usedProvider);\n if (commitsCreated) {\n logger.success(`${usedProviderName} session completed with new commits.`);\n\n // Update labels to completed\n try {\n await updateIssueLabels(issueNumber, {\n add: [workflowLabels.completed],\n remove: [workflowLabels.inProgress],\n });\n logger.success(\n `Updated labels: ${colors.label(workflowLabels.inProgress)} → ${colors.label(workflowLabels.completed)}`\n );\n } catch (error) {\n logger.warning(`Failed to update labels: ${error}`);\n }\n\n // Post comment to issue\n try {\n await addIssueComment(\n issueNumber,\n `AI implementation completed on branch \\`${branchName}\\` using ${usedProviderName}.\\n\\nPlease review the changes and create a PR when ready.`\n );\n logger.success(\"Posted completion comment to issue\");\n } catch (error) {\n logger.warning(`Failed to post comment: ${error}`);\n }\n } else {\n // No commits created - check if it was a rate limit or other issue\n // Exit code 2 typically indicates rate limiting for the AI provider CLI\n // Gemini may use different patterns\n const isRateLimited = aiExitCode === 2;\n\n if (isRateLimited) {\n logger.warning(\n `${usedProviderName} session ended due to rate limits. No commits were created.`\n );\n\n // Set ai-blocked label\n try {\n await updateIssueLabels(issueNumber, {\n add: [workflowLabels.blocked],\n remove: [workflowLabels.inProgress],\n });\n logger.info(\n `Updated labels: ${colors.label(workflowLabels.inProgress)} → ${colors.label(workflowLabels.blocked)}`\n );\n } catch (error) {\n logger.warning(`Failed to update labels: ${error}`);\n }\n\n // Post comment about rate limiting\n try {\n await addIssueComment(\n issueNumber,\n `AI implementation was blocked due to API rate limits on branch \\`${branchName}\\` (${usedProviderName}).\\n\\nNo commits were created. Please retry later.`\n );\n logger.info(\"Posted rate-limit comment to issue\");\n } catch (error) {\n logger.warning(`Failed to post comment: ${error}`);\n }\n } else {\n logger.warning(\n `${usedProviderName} session completed but no commits were created. Labels unchanged.`\n );\n // Leave as ai-in-progress so it can be retried\n }\n\n return;\n }\n\n logger.newline();\n logger.box(\n \"Next Steps\",\n `1. Review changes: ${colors.command(\"git diff HEAD~1\")}\n2. Run tests: ${colors.command(\"npm test\")}\n3. Push branch: ${colors.command(\"git push -u origin \" + branchName)}\n4. Create PR: ${colors.command(\"gent pr\")}`\n );\n}\n","import { execa } from \"execa\";\n\n// UI file patterns that indicate UI changes\nconst UI_FILE_PATTERNS = [\n /\\.(tsx|jsx)$/,\n /\\.(vue|svelte)$/,\n /\\.css$/,\n /\\.scss$/,\n /\\.less$/,\n /\\.styled\\.(ts|js)$/,\n /components?\\//i,\n /pages?\\//i,\n /views?\\//i,\n /layouts?\\//i,\n /ui\\//i,\n /styles?\\//i,\n];\n\n/**\n * Check if Playwright is available (installed locally or globally).\n */\nexport async function isPlaywrightAvailable(): Promise<boolean> {\n try {\n const { exitCode } = await execa(\"npx\", [\"playwright\", \"--version\"], {\n reject: false,\n });\n return exitCode === 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Detect if the changed files indicate UI changes\n */\nexport function hasUIChanges(changedFiles: string[]): boolean {\n return changedFiles.some((file) =>\n UI_FILE_PATTERNS.some((pattern) => pattern.test(file))\n );\n}\n\n/**\n * Get list of changed files from git diff\n */\nexport async function getChangedFiles(\n baseBranch: string = \"main\"\n): Promise<string[]> {\n try {\n const { stdout } = await execa(\"git\", [\n \"diff\",\n `${baseBranch}...HEAD`,\n \"--name-only\",\n ]);\n return stdout.trim().split(\"\\n\").filter(Boolean);\n } catch {\n return [];\n }\n}\n","import { logger, colors } from \"../utils/logger.js\";\nimport { withSpinner, createSpinner, aiSpinnerText } from \"../utils/spinner.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport {\n getIssue,\n createPullRequest,\n getPrForBranch,\n assignIssue,\n getCurrentUser,\n updateIssueLabels,\n} from \"../lib/github.js\";\nimport { buildPrPrompt } from \"../lib/prompts.js\";\nimport {\n invokeAI,\n getProviderDisplayName,\n getOtherAvailableProviders,\n} from \"../lib/ai-provider.js\";\nimport {\n getCurrentBranch,\n isOnMainBranch,\n getDefaultBranch,\n getCommitsSinceBase,\n getDiffSummary,\n getUnpushedCommits,\n pushBranch,\n} from \"../lib/git.js\";\nimport { extractIssueNumber } from \"../lib/branch.js\";\nimport { getWorkflowLabels } from \"../lib/labels.js\";\nimport { checkGhAuth, checkAIProvider } from \"../utils/validators.js\";\nimport {\n isPlaywrightAvailable,\n hasUIChanges,\n getChangedFiles,\n} from \"../lib/playwright.js\";\nimport type { GitHubIssue, AIProvider } from \"../types/index.js\";\nimport inquirer from \"inquirer\";\n\nexport interface PrOptions {\n draft?: boolean;\n provider?: AIProvider;\n video?: boolean;\n}\n\nexport async function prCommand(options: PrOptions): Promise<void> {\n const config = loadConfig();\n\n // Determine which provider to use\n let currentProvider = options.provider ?? config.ai.provider;\n\n // Validate prerequisites\n const [ghAuth, aiOk] = await Promise.all([\n checkGhAuth(),\n checkAIProvider(currentProvider),\n ]);\n\n if (!ghAuth) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n return;\n }\n\n if (!aiOk) {\n logger.error(\n `${getProviderDisplayName(currentProvider)} CLI not found. Please install ${currentProvider} CLI first.`\n );\n return;\n }\n\n // Check we're not on main\n if (await isOnMainBranch()) {\n logger.error(\"Cannot create PR from main/master branch.\");\n return;\n }\n\n // Check for existing PR\n const existingPr = await getPrForBranch();\n if (existingPr) {\n logger.warning(\n `A PR already exists for this branch: ${colors.url(existingPr.url)}`\n );\n return;\n }\n\n const currentBranch = await getCurrentBranch();\n const baseBranch = await getDefaultBranch();\n\n logger.info(`Branch: ${colors.branch(currentBranch)}`);\n logger.info(`Base: ${colors.branch(baseBranch)}`);\n\n // Auto-push if needed\n const hasUnpushed = await getUnpushedCommits();\n if (hasUnpushed) {\n await withSpinner(\"Pushing branch...\", async () => {\n await pushBranch();\n });\n logger.success(\"Branch pushed\");\n }\n\n // Extract issue number from branch\n const issueNumber = extractIssueNumber(currentBranch);\n let issue: GitHubIssue | null = null;\n\n if (issueNumber) {\n try {\n issue = await getIssue(issueNumber);\n logger.info(\n `Linked issue: ${colors.issue(`#${issueNumber}`)} - ${issue.title}`\n );\n } catch {\n logger.warning(`Could not fetch issue #${issueNumber}`);\n }\n } else {\n logger.warning(\"Could not extract issue number from branch name.\");\n }\n\n // Get commits and diff\n const commits = await getCommitsSinceBase(baseBranch);\n const diffSummary = await getDiffSummary(baseBranch);\n\n if (commits.length === 0) {\n logger.error(\"No commits found since base branch.\");\n return;\n }\n\n logger.info(`Commits: ${commits.length}`);\n logger.newline();\n\n // Check for UI changes and video capture capability\n // Video is enabled by default (config.video.enabled), but can be disabled with --no-video\n const shouldCaptureVideo = options.video !== false && config.video.enabled;\n let captureVideoInstructions = \"\";\n\n if (shouldCaptureVideo) {\n const changedFiles = await getChangedFiles(baseBranch);\n const uiChangesDetected = hasUIChanges(changedFiles);\n\n if (uiChangesDetected) {\n logger.info(\"UI changes detected in this branch\");\n\n const playwrightAvailable = await isPlaywrightAvailable();\n if (!playwrightAvailable) {\n logger.warning(\"Playwright not available. Skipping video capture.\");\n logger.dim(\"Install Playwright with: npm install -D playwright\");\n } else {\n logger.info(\n \"Playwright available - AI will capture demo video via MCP\"\n );\n captureVideoInstructions = `\n\nIMPORTANT: This PR contains UI changes. Use the Playwright MCP plugin to:\n1. Start the dev server if needed\n2. Navigate to the relevant pages showing the UI changes\n3. Capture a short demo video (max ${config.video.max_duration}s) showcasing the changes\n4. Upload the video to GitHub and include it in the PR description under a \"## Demo Video\" section\n`;\n }\n }\n }\n\n // Generate PR description with AI\n const prompt =\n buildPrPrompt(issue, commits, diffSummary) + captureVideoInstructions;\n\n let prBody: string;\n let usedProvider = currentProvider;\n\n while (true) {\n const providerName = getProviderDisplayName(usedProvider);\n try {\n const spinner = createSpinner(aiSpinnerText(providerName, \"generate PR\"));\n spinner.start();\n const result = await invokeAI(\n { prompt, streamOutput: true, onFirstData: () => spinner.stop() },\n config,\n usedProvider\n );\n spinner.stop();\n prBody = result.output;\n logger.newline();\n break;\n } catch (error) {\n if (error && typeof error === \"object\" && \"rateLimited\" in error) {\n logger.warning(`${providerName} is rate limited.`);\n\n const others = await getOtherAvailableProviders(usedProvider);\n if (others.length > 0) {\n const { nextProvider } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"nextProvider\",\n message: \"Would you like to try another provider?\",\n choices: [\n ...others.map((p) => ({\n name: `Switch to ${getProviderDisplayName(p)}`,\n value: p,\n })),\n { name: \"Fall back to basic description\", value: \"fallback\" },\n ],\n },\n ]);\n\n if (nextProvider !== \"fallback\") {\n usedProvider = nextProvider as AIProvider;\n logger.info(\n `Switching to ${getProviderDisplayName(usedProvider)}...`\n );\n continue;\n }\n }\n }\n\n logger.warning(`${providerName} invocation failed: ${error}`);\n // Fall back to basic description\n prBody = generateFallbackBody(issue, commits);\n break;\n }\n }\n\n // Append signature footer\n prBody += `\\n\\n---\\n*Created with ${getProviderDisplayName(usedProvider)} by [gent](https://github.com/Rotorsoft/gent)*`;\n\n // Generate title\n const prTitle = issue?.title || commits[0] || currentBranch;\n\n // Create PR\n let prUrl: string;\n try {\n prUrl = await withSpinner(\"Creating pull request...\", async () => {\n return createPullRequest({\n title: prTitle,\n body: prBody,\n base: baseBranch,\n draft: options.draft,\n });\n });\n } catch (error) {\n logger.error(`Failed to create PR: ${error}`);\n return;\n }\n\n // Assign issue to current user if linked\n if (issueNumber) {\n try {\n const user = await getCurrentUser();\n await assignIssue(issueNumber, user);\n logger.success(`Assigned issue #${issueNumber} to ${user}`);\n } catch {\n // Non-critical, ignore\n }\n\n // Update issue labels to ai-completed\n const workflowLabels = getWorkflowLabels(config);\n try {\n await updateIssueLabels(issueNumber, {\n add: [workflowLabels.completed],\n remove: [workflowLabels.inProgress],\n });\n logger.success(\n `Updated labels: ${colors.label(workflowLabels.inProgress)} → ${colors.label(workflowLabels.completed)}`\n );\n } catch {\n // Non-critical, ignore\n }\n }\n\n logger.newline();\n logger.success(`Pull request created!`);\n logger.newline();\n logger.highlight(prUrl);\n logger.newline();\n\n if (options.draft) {\n logger.dim(\"Created as draft. Mark as ready for review when done.\");\n }\n\n // Suggest video creation if UI changes detected and Playwright available\n if (shouldCaptureVideo) {\n const changedFilesForHint =\n captureVideoInstructions !== \"\"\n ? [] // already checked above\n : await getChangedFiles(baseBranch);\n const uiChangesForHint =\n captureVideoInstructions !== \"\"\n ? true\n : hasUIChanges(changedFilesForHint);\n\n if (uiChangesForHint) {\n const playwrightOk = await isPlaywrightAvailable();\n if (playwrightOk) {\n logger.bold(\"Next Steps\");\n logger.info(\n \"Run `claude` with Playwright MCP to record a demo video of the changes.\"\n );\n logger.info(\n \"Upload the result to GitHub Assets to keep the repo light.\"\n );\n logger.newline();\n }\n }\n }\n}\n\nfunction generateFallbackBody(\n issue: GitHubIssue | null,\n commits: string[]\n): string {\n let body = \"## Summary\\n\\n\";\n\n if (issue) {\n body += `Implements #${issue.number}: ${issue.title}\\n\\n`;\n }\n\n body += \"## Changes\\n\\n\";\n for (const commit of commits.slice(0, 10)) {\n body += `- ${commit}\\n`;\n }\n\n body += \"\\n## Test Plan\\n\\n- [ ] Tests pass\\n- [ ] Manual verification\\n\\n\";\n\n if (issue) {\n body += `Closes #${issue.number}\\n`;\n }\n\n return body;\n}\n","import inquirer from \"inquirer\";\nimport { logger } from \"../utils/logger.js\";\nimport { withSpinner, createSpinner, aiSpinnerText } from \"../utils/spinner.js\";\nimport { loadConfig, loadAgentInstructions } from \"../lib/config.js\";\nimport {\n getIssue,\n getPrForBranch,\n getPrReviewData,\n replyToReviewComment,\n addPrComment,\n} from \"../lib/github.js\";\nimport { buildImplementationPrompt } from \"../lib/prompts.js\";\nimport {\n invokeAIInteractive,\n getProviderDisplayName,\n} from \"../lib/ai-provider.js\";\nimport {\n getCurrentBranch,\n isOnMainBranch,\n hasUncommittedChanges,\n getCurrentCommitSha,\n hasNewCommits,\n getLastCommitTimestamp,\n} from \"../lib/git.js\";\nimport { extractIssueNumber } from \"../lib/branch.js\";\nimport { readProgress } from \"../lib/progress.js\";\nimport {\n summarizeReviewFeedback,\n type ReviewFeedbackItem,\n} from \"../lib/review-feedback.js\";\nimport { checkGhAuth, checkAIProvider } from \"../utils/validators.js\";\nimport type { AIProvider, GitHubReviewData } from \"../types/index.js\";\n\nexport interface FixOptions {\n provider?: AIProvider;\n}\n\nexport async function fixCommand(options: FixOptions): Promise<void> {\n const config = loadConfig();\n const provider = options.provider ?? config.ai.provider;\n const providerName = getProviderDisplayName(provider);\n\n const [ghAuth, aiOk] = await Promise.all([\n checkGhAuth(),\n checkAIProvider(provider),\n ]);\n\n if (!ghAuth) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n process.exit(1);\n }\n\n if (!aiOk) {\n logger.error(\n `${providerName} CLI not found. Please install ${provider} CLI first.`\n );\n process.exit(1);\n }\n\n if (await isOnMainBranch()) {\n logger.error(\n \"Cannot apply fixes from main/master branch. Switch to the PR branch first.\"\n );\n process.exit(1);\n }\n\n const hasChanges = await hasUncommittedChanges();\n if (hasChanges) {\n logger.warning(\"You have uncommitted changes.\");\n const { proceed } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"proceed\",\n message: \"Continue anyway?\",\n default: false,\n },\n ]);\n if (!proceed) {\n logger.info(\"Aborting. Please commit or stash your changes first.\");\n process.exit(0);\n }\n }\n\n const pr = await withSpinner(\"Resolving pull request...\", async () => {\n return getPrForBranch();\n });\n\n if (!pr) {\n logger.error(\n \"No pull request found for the current branch. Create one with 'gent pr' first.\"\n );\n process.exit(1);\n }\n\n const lastCommitTimestamp = await getLastCommitTimestamp();\n\n const reviewData = await withSpinner(\n \"Fetching review feedback...\",\n async () => {\n return getPrReviewData(pr.number);\n }\n );\n\n const totalComments = countReviewComments(reviewData);\n if (totalComments === 0) {\n logger.error(`No review comments found for PR #${pr.number}.`);\n process.exit(1);\n }\n\n // Filter feedback to only show comments after the last commit (plus unresolved threads)\n const { items, summary } = summarizeReviewFeedback(reviewData, {\n afterTimestamp: lastCommitTimestamp,\n });\n if (items.length === 0 || !summary) {\n logger.error(\n \"No new actionable review feedback found since your last commit.\"\n );\n process.exit(1);\n }\n\n logger.newline();\n logger.box(\"Review Feedback Summary\", summary);\n logger.newline();\n\n const currentBranch = await getCurrentBranch();\n const issueNumber = extractIssueNumber(currentBranch);\n if (!issueNumber) {\n logger.error(\"Could not determine issue number from branch name.\");\n process.exit(1);\n }\n\n const issue = await withSpinner(\"Fetching linked issue...\", async () => {\n return getIssue(issueNumber);\n });\n\n const agentInstructions = loadAgentInstructions();\n const progressContent = readProgress(config);\n const prompt = buildImplementationPrompt(\n issue,\n agentInstructions,\n progressContent,\n config,\n `## Review Feedback\\n${summary}`\n );\n\n logger.newline();\n const spinner = createSpinner(aiSpinnerText(providerName, \"apply fixes\"));\n spinner.start();\n\n const beforeSha = await getCurrentCommitSha();\n\n let wasCancelled = false;\n const handleSignal = () => {\n wasCancelled = true;\n };\n process.on(\"SIGINT\", handleSignal);\n process.on(\"SIGTERM\", handleSignal);\n\n spinner.stop();\n let aiExitCode: number | undefined;\n try {\n const { result } = await invokeAIInteractive(\n prompt,\n config,\n options.provider\n );\n aiExitCode = result.exitCode ?? undefined;\n } catch (error) {\n if (error && typeof error === \"object\" && \"exitCode\" in error) {\n aiExitCode = error.exitCode as number;\n }\n logger.error(`${providerName} session failed: ${error}`);\n } finally {\n process.off(\"SIGINT\", handleSignal);\n process.off(\"SIGTERM\", handleSignal);\n }\n\n logger.newline();\n\n if (wasCancelled) {\n logger.warning(\"Operation was cancelled. No changes were recorded.\");\n return;\n }\n\n const commitsCreated = await hasNewCommits(beforeSha);\n if (commitsCreated) {\n logger.success(`${providerName} session completed with new commits.`);\n\n // Reply to feedback items to indicate they were addressed\n await replyToFeedbackItems(pr.number, items);\n\n return;\n }\n\n const isRateLimited = aiExitCode === 2;\n if (isRateLimited) {\n logger.warning(\n `${providerName} session ended due to rate limits. No commits were created.`\n );\n return;\n }\n\n logger.warning(\n `${providerName} session completed but no commits were created.`\n );\n}\n\nfunction countReviewComments(data: GitHubReviewData): number {\n const reviewBodies = data.reviews.filter((review) =>\n review.body?.trim()\n ).length;\n const threadBodies = data.reviewThreads.reduce((count, thread) => {\n const threadCount = (thread.comments ?? []).filter((comment) =>\n comment.body?.trim()\n ).length;\n return count + threadCount;\n }, 0);\n const prComments = (data.comments ?? []).filter((comment) =>\n comment.body?.trim()\n ).length;\n return reviewBodies + threadBodies + prComments;\n}\n\nasync function replyToFeedbackItems(\n prNumber: number,\n items: ReviewFeedbackItem[]\n): Promise<void> {\n const replyBody = \"Addressed in latest commit.\";\n let repliedCount = 0;\n\n for (const item of items) {\n try {\n if (item.source === \"thread\" && typeof item.commentId === \"number\") {\n await replyToReviewComment(prNumber, item.commentId, replyBody);\n repliedCount++;\n } else if (item.source === \"comment\" && item.commentId) {\n // PR comments don't support threading, so we add a general comment\n await addPrComment(prNumber, `@${item.author} ${replyBody}`);\n repliedCount++;\n }\n // Skip reviews - they don't have a direct reply mechanism\n } catch {\n // Silently ignore reply failures - non-critical\n }\n }\n\n if (repliedCount > 0) {\n logger.dim(\n `Replied to ${repliedCount} feedback item${repliedCount > 1 ? \"s\" : \"\"}.`\n );\n }\n}\n","import type { GitHubReviewData } from \"../types/index.js\";\n\nexport interface ReviewFeedbackItem {\n source: \"review\" | \"thread\" | \"comment\";\n author: string;\n body: string;\n state?: string;\n path?: string;\n line?: number | null;\n commentId?: number | string;\n}\n\nexport interface ReviewFeedbackOptions {\n afterTimestamp?: string;\n}\n\nconst ACTIONABLE_KEYWORDS = [\n \"todo\",\n \"fix\",\n \"should\",\n \"must\",\n \"needs\",\n \"please\",\n \"consider\",\n \"can you\",\n \"change\",\n \"update\",\n \"remove\",\n \"add\",\n];\n\nconst TRIVIAL_COMMENTS = [\"lgtm\", \"looks good\", \"approved\"];\n\nexport function summarizeReviewFeedback(\n data: GitHubReviewData,\n options?: ReviewFeedbackOptions\n): {\n items: ReviewFeedbackItem[];\n summary: string;\n} {\n const items = extractReviewFeedbackItems(data, options);\n return {\n items,\n summary: items.length > 0 ? formatReviewFeedbackSummary(items) : \"\",\n };\n}\n\nfunction isAfterTimestamp(\n itemTimestamp: string | undefined,\n afterTimestamp: string | undefined\n): boolean {\n if (!afterTimestamp || !itemTimestamp) {\n return true;\n }\n return new Date(itemTimestamp) > new Date(afterTimestamp);\n}\n\nexport function extractReviewFeedbackItems(\n data: GitHubReviewData,\n options?: ReviewFeedbackOptions\n): ReviewFeedbackItem[] {\n const items: ReviewFeedbackItem[] = [];\n const afterTimestamp = options?.afterTimestamp;\n\n for (const review of data.reviews) {\n const body = review.body?.trim() ?? \"\";\n if (!body || isTrivialComment(body)) {\n continue;\n }\n\n // Filter by timestamp if provided\n if (!isAfterTimestamp(review.submittedAt, afterTimestamp)) {\n continue;\n }\n\n const isChangesRequested = review.state === \"CHANGES_REQUESTED\";\n const actionable = isChangesRequested || isActionableText(body);\n if (!actionable) {\n continue;\n }\n\n items.push({\n source: \"review\",\n author: review.author,\n body,\n state: review.state,\n });\n }\n\n for (const thread of data.reviewThreads) {\n // Skip outdated threads (code has changed)\n if (thread.isOutdated) {\n continue;\n }\n\n const isUnresolved =\n thread.isResolved === false ||\n thread.isResolved === undefined ||\n thread.isResolved === null;\n\n const hasRecentComments = (thread.comments ?? []).some((c) =>\n isAfterTimestamp(c.createdAt, afterTimestamp)\n );\n\n // If resolved, must have recent comments\n if (!isUnresolved && !hasRecentComments) {\n continue;\n }\n\n // If unresolved AND we have a timestamp constraint, must have recent comments.\n // This allows skipping unresolved threads that were addressed in a recent commit (implied by timestamp).\n if (isUnresolved && afterTimestamp && !hasRecentComments) {\n continue;\n }\n\n if (!isActionableThread(thread)) {\n continue;\n }\n\n const comments = thread.comments ?? [];\n const latestComment = findLatestMeaningfulComment(comments);\n if (!latestComment) {\n continue;\n }\n\n items.push({\n source: \"thread\",\n author: latestComment.author,\n body: latestComment.body,\n path: thread.path ?? latestComment.path,\n line: thread.line ?? latestComment.line ?? null,\n commentId: latestComment.id,\n });\n }\n\n // Process PR comments\n for (const comment of data.comments ?? []) {\n const body = comment.body?.trim() ?? \"\";\n if (!body || isTrivialComment(body)) {\n continue;\n }\n\n // Filter by timestamp if provided\n if (!isAfterTimestamp(comment.createdAt, afterTimestamp)) {\n continue;\n }\n\n // Only include actionable comments\n if (!isActionableText(body)) {\n continue;\n }\n\n items.push({\n source: \"comment\",\n author: comment.author,\n body,\n commentId: comment.id,\n });\n }\n\n return items;\n}\n\nexport function formatReviewFeedbackSummary(\n items: ReviewFeedbackItem[]\n): string {\n return items\n .map((item) => {\n const location = formatLocation(item);\n const stateLabel = item.state ? formatState(item.state) : null;\n const author = item.author ? `@${item.author}` : \"Reviewer\";\n const body = truncateComment(item.body);\n let header: string;\n if (item.source === \"review\") {\n header = stateLabel ? `Review (${stateLabel})` : \"Review\";\n } else if (item.source === \"comment\") {\n header = \"Comment\";\n } else {\n header = location;\n }\n return `- [${header}] ${author}: ${body}`;\n })\n .join(\"\\n\");\n}\n\nfunction isActionableThread(thread: {\n isResolved?: boolean | null;\n comments?: { body: string }[];\n}): boolean {\n if (\n thread.isResolved === false ||\n thread.isResolved === undefined ||\n thread.isResolved === null\n ) {\n return true;\n }\n return (thread.comments ?? []).some((comment) =>\n isActionableText(comment.body)\n );\n}\n\nfunction isActionableText(text: string): boolean {\n const normalized = text.toLowerCase();\n return ACTIONABLE_KEYWORDS.some((keyword) => normalized.includes(keyword));\n}\n\nfunction isTrivialComment(text: string): boolean {\n const normalized = text.trim().toLowerCase();\n return TRIVIAL_COMMENTS.some((entry) => normalized === entry);\n}\n\nfunction findLatestMeaningfulComment<\n T extends { body: string; id?: number | string },\n>(comments: T[]): T | null {\n for (let i = comments.length - 1; i >= 0; i -= 1) {\n const body = comments[i].body?.trim() ?? \"\";\n if (body && !isTrivialComment(body)) {\n return comments[i];\n }\n }\n return null;\n}\n\nfunction formatLocation(item: { path?: string; line?: number | null }): string {\n if (item.path && item.line) {\n return `${item.path}:${item.line}`;\n }\n if (item.path) {\n return item.path;\n }\n return \"Thread\";\n}\n\nfunction formatState(state: string): string {\n return state.replace(/_/g, \" \").toLowerCase();\n}\n\nfunction truncateComment(body: string, maxLength = 200): string {\n const normalized = body.replace(/\\s+/g, \" \").trim();\n if (normalized.length <= maxLength) {\n return normalized;\n }\n return `${normalized.slice(0, maxLength - 3)}...`;\n}\n\nexport interface ReviewFeedbackCounts {\n total: number;\n unresolvedThreads: number;\n changesRequested: number;\n}\n\nexport function countActionableFeedback(\n data: GitHubReviewData,\n options?: ReviewFeedbackOptions\n): ReviewFeedbackCounts {\n const items = extractReviewFeedbackItems(data, options);\n\n let unresolvedThreads = 0;\n let changesRequested = 0;\n\n for (const item of items) {\n if (item.source === \"thread\") {\n unresolvedThreads++;\n } else if (item.source === \"review\" && item.state === \"CHANGES_REQUESTED\") {\n changesRequested++;\n }\n }\n\n return {\n total: items.length,\n unresolvedThreads,\n changesRequested,\n };\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport packageJson from \"../../package.json\" with { type: \"json\" };\n\nconst NPM_REGISTRY_URL = \"https://registry.npmjs.org/@rotorsoft/gent/latest\";\nconst CACHE_DIR = join(homedir(), \".gent\");\nconst CACHE_FILE = join(CACHE_DIR, \"version-check.json\");\nconst DEFAULT_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours\nconst FETCH_TIMEOUT_MS = 3000; // 3 seconds\n\nexport interface VersionCheckResult {\n currentVersion: string;\n latestVersion: string | null;\n updateAvailable: boolean;\n lastChecked: number | null;\n}\n\ninterface VersionCache {\n latestVersion: string;\n checkedAt: number;\n}\n\n/**\n * Reads the version from package.json\n */\nexport function getVersion(): string {\n return packageJson.version;\n}\n\n/**\n * Compares two semver versions\n * Returns: 1 if a > b, -1 if a < b, 0 if equal\n */\nexport function compareVersions(a: string, b: string): number {\n const parseVersion = (v: string) => {\n const [main] = v.split(\"-\"); // Ignore pre-release suffix\n return main.split(\".\").map((n) => parseInt(n, 10));\n };\n\n const aParts = parseVersion(a);\n const bParts = parseVersion(b);\n\n for (let i = 0; i < 3; i++) {\n const aVal = aParts[i] || 0;\n const bVal = bParts[i] || 0;\n if (aVal > bVal) return 1;\n if (aVal < bVal) return -1;\n }\n return 0;\n}\n\n/**\n * Reads cached version check result\n */\nfunction readCache(): VersionCache | null {\n try {\n if (!existsSync(CACHE_FILE)) return null;\n const content = readFileSync(CACHE_FILE, \"utf8\");\n return JSON.parse(content) as VersionCache;\n } catch {\n return null;\n }\n}\n\n/**\n * Writes version check result to cache\n */\nfunction writeCache(cache: VersionCache): void {\n try {\n if (!existsSync(CACHE_DIR)) {\n mkdirSync(CACHE_DIR, { recursive: true });\n }\n writeFileSync(CACHE_FILE, JSON.stringify(cache), \"utf8\");\n } catch {\n // Silently ignore cache write errors\n }\n}\n\n/**\n * Fetches the latest version from npm registry\n */\nasync function fetchLatestVersion(): Promise<string | null> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n\n const response = await fetch(NPM_REGISTRY_URL, {\n signal: controller.signal,\n headers: { Accept: \"application/json\" },\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) return null;\n\n const data = (await response.json()) as { version?: string };\n return data.version || null;\n } catch {\n // Network error, timeout, or parse error - fail silently\n return null;\n }\n}\n\n/**\n * Checks if a newer version is available\n * Uses caching to avoid excessive API calls\n */\nexport async function checkForUpdates(\n checkIntervalMs: number = DEFAULT_CHECK_INTERVAL_MS\n): Promise<VersionCheckResult> {\n const currentVersion = getVersion();\n const cache = readCache();\n const now = Date.now();\n\n // Use cached result if still valid\n if (cache && now - cache.checkedAt < checkIntervalMs) {\n const updateAvailable =\n compareVersions(cache.latestVersion, currentVersion) > 0;\n return {\n currentVersion,\n latestVersion: cache.latestVersion,\n updateAvailable,\n lastChecked: cache.checkedAt,\n };\n }\n\n // Fetch fresh version from npm\n const latestVersion = await fetchLatestVersion();\n\n if (latestVersion) {\n writeCache({ latestVersion, checkedAt: now });\n const updateAvailable = compareVersions(latestVersion, currentVersion) > 0;\n return {\n currentVersion,\n latestVersion,\n updateAvailable,\n lastChecked: now,\n };\n }\n\n // Fetch failed, return cached or unknown state\n return {\n currentVersion,\n latestVersion: cache?.latestVersion || null,\n updateAvailable: cache\n ? compareVersions(cache.latestVersion, currentVersion) > 0\n : false,\n lastChecked: cache?.checkedAt || null,\n };\n}\n\n/**\n * Formats the upgrade notification message\n */\nexport function formatUpgradeNotification(\n currentVersion: string,\n latestVersion: string\n): string {\n return `Update available: ${currentVersion} → ${latestVersion}\\nRun: npm install -g @rotorsoft/gent`;\n}\n","{\n \"name\": \"@rotorsoft/gent\",\n \"version\": \"1.21.0\",\n \"description\": \"AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs\",\n \"keywords\": [\n \"cli\",\n \"ai\",\n \"claude\",\n \"github\",\n \"workflow\",\n \"automation\",\n \"developer-tools\"\n ],\n \"homepage\": \"https://github.com/rotorsoft/gent#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/rotorsoft/gent/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/rotorsoft/gent.git\"\n },\n \"license\": \"MIT\",\n \"author\": \"Rotorsoft\",\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\"\n }\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"bin\": {\n \"gent\": \"./dist/index.js\"\n },\n \"files\": [\n \"dist\",\n \"templates\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsx src/index.ts\",\n \"watch\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"lint\": \"eslint src/\",\n \"lint:fix\": \"eslint src/ --fix\",\n \"format\": \"prettier --write \\\"src/**/*.ts\\\"\",\n \"format:check\": \"prettier --check \\\"src/**/*.ts\\\"\",\n \"typecheck\": \"tsc --noEmit\",\n \"prepublishOnly\": \"npm run build\",\n \"prepare\": \"npm run build\"\n },\n \"dependencies\": {\n \"chalk\": \"^5.3.0\",\n \"commander\": \"^12.1.0\",\n \"execa\": \"^9.5.2\",\n \"inquirer\": \"^12.2.0\",\n \"ora\": \"^8.1.1\",\n \"yaml\": \"^2.6.1\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.17.0\",\n \"@semantic-release/changelog\": \"^6.0.3\",\n \"@semantic-release/git\": \"^10.0.1\",\n \"@types/inquirer\": \"^9.0.7\",\n \"@types/node\": \"^22.10.5\",\n \"@typescript-eslint/eslint-plugin\": \"^8.19.1\",\n \"@typescript-eslint/parser\": \"^8.19.1\",\n \"@vitest/coverage-v8\": \"^2.1.8\",\n \"eslint\": \"^9.17.0\",\n \"eslint-config-prettier\": \"^9.1.0\",\n \"prettier\": \"^3.4.2\",\n \"semantic-release\": \"^24.2.1\",\n \"tsup\": \"^8.3.5\",\n \"tsx\": \"^4.21.0\",\n \"typescript\": \"^5.7.3\",\n \"vitest\": \"^2.1.8\"\n },\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}\n","import { logger, colors } from \"../utils/logger.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { getIssue, getPrStatus, getPrReviewData } from \"../lib/github.js\";\nimport {\n getCurrentBranch,\n isOnMainBranch,\n hasUncommittedChanges,\n getUnpushedCommits,\n getCommitsSinceBase,\n getDefaultBranch,\n getLastCommitTimestamp,\n} from \"../lib/git.js\";\nimport { extractIssueNumber, parseBranchName } from \"../lib/branch.js\";\nimport { getWorkflowLabels } from \"../lib/labels.js\";\nimport { progressExists, readProgress } from \"../lib/progress.js\";\nimport { configExists } from \"../lib/config.js\";\nimport {\n checkGhAuth,\n checkClaudeCli,\n checkGeminiCli,\n checkGitRepo,\n} from \"../utils/validators.js\";\nimport { getProviderDisplayName } from \"../lib/ai-provider.js\";\nimport { getVersion } from \"../lib/version.js\";\nimport {\n summarizeReviewFeedback,\n type ReviewFeedbackItem,\n} from \"../lib/review-feedback.js\";\n\nfunction formatPrState(\n state: \"open\" | \"closed\" | \"merged\",\n isDraft: boolean\n): string {\n if (state === \"merged\") {\n return \"Merged\";\n }\n if (state === \"closed\") {\n return \"Closed\";\n }\n return isDraft ? \"Open (Draft)\" : \"Open\";\n}\n\nfunction formatReviewDecision(decision: string): string {\n switch (decision) {\n case \"APPROVED\":\n return \"Approved\";\n case \"CHANGES_REQUESTED\":\n return \"Changes Requested\";\n case \"REVIEW_REQUIRED\":\n return \"Review Required\";\n default:\n return decision.replace(/_/g, \" \").toLowerCase();\n }\n}\n\nfunction formatFeedbackLocation(item: ReviewFeedbackItem): string {\n if (item.path && item.line) {\n return `${item.path}:${item.line}`;\n }\n if (item.path) {\n return item.path;\n }\n if (item.source === \"review\") {\n const stateLabel = item.state\n ? item.state.replace(/_/g, \" \").toLowerCase()\n : \"review\";\n return `[${stateLabel}]`;\n }\n return \"[comment]\";\n}\n\nfunction truncateFeedbackBody(body: string, maxLength: number): string {\n const normalized = body.replace(/\\s+/g, \" \").trim();\n if (normalized.length <= maxLength) {\n return normalized;\n }\n return `${normalized.slice(0, maxLength - 3)}...`;\n}\n\nexport async function statusCommand(): Promise<void> {\n const version = getVersion();\n logger.bold(`Gent Workflow Status ${colors.label(`v${version}`)}`);\n logger.newline();\n\n // Check prerequisites\n const gitRepo = await checkGitRepo();\n if (!gitRepo) {\n logger.error(\"Not a git repository.\");\n process.exit(1);\n }\n\n const config = loadConfig();\n const workflowLabels = getWorkflowLabels(config);\n\n // Configuration status\n logger.bold(\"Configuration:\");\n if (configExists()) {\n logger.success(\" .gent.yml found\");\n } else {\n logger.warning(\" .gent.yml not found - using defaults\");\n }\n\n if (progressExists(config)) {\n const progress = readProgress(config);\n const lines = progress.split(\"\\n\").length;\n logger.success(` ${config.progress.file} found (${lines} lines)`);\n } else {\n logger.warning(` ${config.progress.file} not found`);\n }\n\n logger.newline();\n\n // AI Provider status\n logger.bold(\"AI Provider:\");\n const providerName = getProviderDisplayName(config.ai.provider);\n logger.info(` Active: ${colors.provider(providerName)}`);\n if (config.ai.fallback_provider) {\n const fallbackName = getProviderDisplayName(config.ai.fallback_provider);\n logger.info(\n ` Fallback: ${fallbackName} (auto: ${config.ai.auto_fallback ? \"enabled\" : \"disabled\"})`\n );\n }\n logger.newline();\n\n // Prerequisites\n logger.bold(\"Prerequisites:\");\n const ghAuth = await checkGhAuth();\n if (ghAuth) {\n logger.success(\" GitHub CLI authenticated\");\n } else {\n logger.error(\" GitHub CLI not authenticated\");\n }\n\n // Check all AI providers\n const claudeOk = await checkClaudeCli();\n const geminiOk = await checkGeminiCli();\n\n const getProviderStatus = (provider: \"claude\" | \"gemini\"): string => {\n const isActive = config.ai.provider === provider;\n const isFallback = config.ai.fallback_provider === provider;\n const suffix = isActive ? \" (active)\" : isFallback ? \" (fallback)\" : \"\";\n return suffix;\n };\n\n if (claudeOk) {\n logger.success(` Claude CLI available${getProviderStatus(\"claude\")}`);\n } else {\n logger.error(` Claude CLI not found${getProviderStatus(\"claude\")}`);\n }\n\n if (geminiOk) {\n logger.success(` Gemini CLI available${getProviderStatus(\"gemini\")}`);\n } else {\n logger.error(` Gemini CLI not found${getProviderStatus(\"gemini\")}`);\n }\n\n logger.newline();\n\n // Git status\n logger.bold(\"Git Status:\");\n const currentBranch = await getCurrentBranch();\n const onMain = await isOnMainBranch();\n const uncommitted = await hasUncommittedChanges();\n const baseBranch = await getDefaultBranch();\n\n logger.info(` Branch: ${colors.branch(currentBranch)}`);\n\n if (onMain) {\n logger.info(\" On main branch - ready to start new work\");\n } else {\n const branchInfo = parseBranchName(currentBranch);\n if (branchInfo) {\n logger.info(` Issue: ${colors.issue(`#${branchInfo.issueNumber}`)}`);\n logger.info(` Type: ${branchInfo.type}`);\n }\n\n const commits = await getCommitsSinceBase(baseBranch);\n logger.info(` Commits ahead of ${baseBranch}: ${commits.length}`);\n\n const unpushed = await getUnpushedCommits();\n if (unpushed) {\n logger.warning(\" Has unpushed commits\");\n } else {\n logger.success(\" Up to date with remote\");\n }\n }\n\n if (uncommitted) {\n logger.warning(\" Has uncommitted changes\");\n }\n\n logger.newline();\n\n // Linked issue status and PR status (only when not on main)\n let prStatus: Awaited<ReturnType<typeof getPrStatus>> = null;\n let hasActionableFeedback = false;\n\n if (!onMain) {\n const issueNumber = extractIssueNumber(currentBranch);\n if (issueNumber) {\n logger.bold(\"Linked Issue:\");\n try {\n const issue = await getIssue(issueNumber);\n logger.info(` #${issue.number}: ${issue.title}`);\n logger.info(` State: ${issue.state}`);\n logger.info(` Labels: ${issue.labels.join(\", \")}`);\n\n // Check workflow status\n if (issue.labels.includes(workflowLabels.ready)) {\n logger.info(` Workflow: ${colors.label(\"ai-ready\")}`);\n } else if (issue.labels.includes(workflowLabels.inProgress)) {\n logger.info(` Workflow: ${colors.label(\"ai-in-progress\")}`);\n } else if (issue.labels.includes(workflowLabels.completed)) {\n logger.info(` Workflow: ${colors.label(\"ai-completed\")}`);\n } else if (issue.labels.includes(workflowLabels.blocked)) {\n logger.info(` Workflow: ${colors.label(\"ai-blocked\")}`);\n }\n } catch {\n logger.warning(` Could not fetch issue #${issueNumber}`);\n }\n logger.newline();\n }\n\n // PR status\n logger.bold(\"Pull Request:\");\n prStatus = await getPrStatus();\n if (prStatus) {\n const stateDisplay = formatPrState(prStatus.state, prStatus.isDraft);\n logger.info(` PR #${prStatus.number}: ${stateDisplay}`);\n logger.info(` ${colors.url(prStatus.url)}`);\n\n if (prStatus.state === \"open\") {\n // Fetch review data to show actionable feedback\n try {\n const lastCommitTimestamp = await getLastCommitTimestamp();\n const reviewData = await getPrReviewData(prStatus.number);\n const { items } = summarizeReviewFeedback(reviewData, {\n afterTimestamp: lastCommitTimestamp,\n });\n hasActionableFeedback = items.length > 0;\n\n if (prStatus.reviewDecision) {\n logger.info(\n ` Review: ${formatReviewDecision(prStatus.reviewDecision)}`\n );\n }\n\n if (items.length > 0) {\n logger.warning(\n ` ${items.length} actionable comment${items.length > 1 ? \"s\" : \"\"} to fix with ${colors.command(\"gent fix\")}:`\n );\n for (const item of items) {\n const location = formatFeedbackLocation(item);\n const body = truncateFeedbackBody(item.body, 60);\n logger.dim(` ${location}: ${body}`);\n }\n } else if (prStatus.reviewDecision === \"APPROVED\") {\n logger.success(\" Ready to merge!\");\n } else {\n logger.info(\" No actionable review comments\");\n }\n } catch {\n // Silently ignore review data fetch errors\n }\n } else if (prStatus.state === \"merged\") {\n logger.success(\" This PR has been merged!\");\n logger.dim(\n ` Run ${colors.command(\"git checkout main && git pull\")} to sync`\n );\n } else if (prStatus.state === \"closed\") {\n logger.warning(\" This PR was closed without merging\");\n logger.dim(\n ` Consider reopening or creating a new PR if changes are still needed`\n );\n }\n } else {\n logger.info(\" No PR created yet\");\n logger.dim(` Run ${colors.command(\"gent pr\")} to create one`);\n }\n logger.newline();\n }\n\n // Suggestions\n logger.bold(\"Suggested Actions:\");\n if (onMain) {\n logger.list([\n `${colors.command(\"gent list\")} - View ai-ready issues`,\n `${colors.command(\"gent run --auto\")} - Start working on highest priority issue`,\n `${colors.command(\"gent create <description>\")} - Create a new ticket`,\n ]);\n } else if (!prStatus) {\n logger.list([\n `${colors.command(\"gent pr\")} - Create a pull request`,\n `${colors.command(\"git push\")} - Push your changes`,\n ]);\n } else if (prStatus.state === \"merged\") {\n logger.list([\n `${colors.command(\"git checkout main && git pull\")} - Sync with merged changes`,\n ]);\n } else if (prStatus.state === \"closed\") {\n logger.list([\n `Reopen the PR if changes are still needed`,\n `${colors.command(\"git checkout main\")} - Return to main branch`,\n ]);\n } else if (hasActionableFeedback) {\n logger.list([\n `${colors.command(\"gent fix\")} - Address review comments with AI`,\n `${colors.command(\"git push\")} - Push any local changes`,\n ]);\n } else {\n logger.list([\n `Review and merge your PR`,\n `${colors.command(\"git checkout main\")} - Return to main branch`,\n ]);\n }\n}\n","import { execa } from \"execa\";\nimport { aggregateState, resetEnvCache, type TuiState } from \"../tui/state.js\";\nimport { getAvailableActions, type TuiAction } from \"../tui/actions.js\";\nimport {\n renderDashboard,\n buildDashboardLines,\n renderActionPanel,\n clearScreen,\n} from \"../tui/display.js\";\nimport {\n showConfirm,\n showSelect,\n showInput,\n showMultilineInput,\n showStatus,\n type SelectEntry,\n} from \"../tui/modal.js\";\nimport { checkForUpdates, type VersionCheckResult } from \"../lib/version.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { aiSpinnerText } from \"../utils/spinner.js\";\nimport { createCommand } from \"./create.js\";\nimport { initCommand } from \"./init.js\";\nimport { setupLabelsCommand } from \"./setup-labels.js\";\nimport { prCommand } from \"./pr.js\";\nimport { buildTicketChoices } from \"./list.js\";\nimport { githubRemoteCommand } from \"./github-remote.js\";\nimport {\n buildCommitMessagePrompt,\n buildImplementationPrompt,\n} from \"../lib/prompts.js\";\nimport {\n invokeAI,\n invokeAIInteractive,\n getProviderDisplayName,\n getProviderEmail,\n} from \"../lib/ai-provider.js\";\nimport {\n loadAgentInstructions,\n loadConfig,\n setRuntimeProvider,\n} from \"../lib/config.js\";\nimport { readProgress } from \"../lib/progress.js\";\nimport { listIssues, listOpenPrs } from \"../lib/github.js\";\nimport {\n getCurrentBranch,\n getDefaultBranch,\n hasUncommittedChanges,\n branchExists,\n checkoutBranch,\n createBranch,\n listLocalBranches,\n remoteBranchExists,\n fetchAndCheckout,\n} from \"../lib/git.js\";\nimport { getWorkflowLabels, sortByPriority } from \"../lib/labels.js\";\nimport { generateBranchName } from \"../lib/branch.js\";\nimport type { AIProvider } from \"../types/index.js\";\n\nconst CANCEL = Symbol(\"cancel\");\n\nasync function waitForKey(validKeys: string[]): Promise<string> {\n return new Promise((resolve) => {\n const { stdin } = process;\n const wasRaw = stdin.isRaw;\n stdin.setRawMode(true);\n stdin.resume();\n stdin.setEncoding(\"utf8\");\n\n const onData = (key: string) => {\n // Handle Ctrl+C\n if (key === \"\\x03\") {\n stdin.setRawMode(wasRaw ?? false);\n stdin.pause();\n stdin.removeListener(\"data\", onData);\n resolve(\"q\");\n return;\n }\n\n if (validKeys.includes(key)) {\n stdin.setRawMode(wasRaw ?? false);\n stdin.pause();\n stdin.removeListener(\"data\", onData);\n resolve(key);\n }\n };\n\n stdin.on(\"data\", onData);\n });\n}\n\nexport interface ActionResult {\n running: boolean;\n refresh: boolean;\n}\n\nconst CONTINUE: ActionResult = { running: true, refresh: true };\nconst SKIP_REFRESH: ActionResult = { running: true, refresh: false };\nconst QUIT: ActionResult = { running: false, refresh: false };\n\nexport async function executeAction(\n actionId: string,\n state: TuiState,\n dashboardLines: string[]\n): Promise<ActionResult> {\n switch (actionId) {\n case \"quit\":\n return QUIT;\n\n case \"list\": {\n const switched = await handleList(dashboardLines);\n return switched ? CONTINUE : SKIP_REFRESH;\n }\n\n case \"create\": {\n const description = await showMultilineInput({\n title: \"New Ticket\",\n label: \"Describe the ticket:\",\n dashboardLines,\n });\n if (!description) return SKIP_REFRESH;\n\n clearScreen();\n try {\n await createCommand(description, {});\n } catch (error) {\n logger.error(`Create failed: ${error}`);\n }\n return CONTINUE;\n }\n\n case \"commit\": {\n const committed = await handleCommit(state, dashboardLines);\n return committed ? CONTINUE : SKIP_REFRESH;\n }\n\n case \"push\":\n await handlePush(dashboardLines);\n return CONTINUE;\n\n case \"pr\": {\n clearScreen();\n await prCommand({});\n return CONTINUE;\n }\n\n case \"run\": {\n await handleRun(state);\n return CONTINUE;\n }\n\n case \"init\": {\n clearScreen();\n try {\n await initCommand({});\n } catch (error) {\n logger.error(`Init failed: ${error}`);\n }\n resetEnvCache();\n return CONTINUE;\n }\n\n case \"setup-labels\": {\n clearScreen();\n try {\n await setupLabelsCommand();\n } catch (error) {\n logger.error(`Setup labels failed: ${error}`);\n }\n resetEnvCache();\n return CONTINUE;\n }\n\n case \"github-remote\": {\n const confirmed = await showConfirm({\n title: \"Push to GitHub\",\n message: \"Create a private GitHub repo and push?\",\n dashboardLines,\n });\n if (!confirmed) return SKIP_REFRESH;\n showStatus(\"Pushing\", \"Creating GitHub repo and pushing...\", dashboardLines);\n await githubRemoteCommand();\n return CONTINUE;\n }\n\n case \"switch-provider\":\n await handleSwitchProvider(state, dashboardLines);\n return SKIP_REFRESH;\n\n case \"refresh\":\n return CONTINUE;\n\n default:\n return SKIP_REFRESH;\n }\n}\n\n/** Returns true if a commit was made. */\nasync function handleCommit(\n state: TuiState,\n dashboardLines: string[]\n): Promise<boolean> {\n try {\n const { stdout: status } = await execa(\"git\", [\"status\", \"--short\"]);\n if (!status.trim()) {\n showStatus(\"Commit\", \"No changes to commit\", dashboardLines);\n await new Promise((r) => setTimeout(r, 1500));\n return false;\n }\n\n // Stage all changes\n await execa(\"git\", [\"add\", \"-A\"]);\n\n // Get staged diff for AI commit message generation\n const { stdout: diffStat } = await execa(\"git\", [\n \"diff\",\n \"--cached\",\n \"--stat\",\n ]);\n const { stdout: diffPatch } = await execa(\"git\", [\"diff\", \"--cached\"]);\n const diffContent = (diffStat + \"\\n\\n\" + diffPatch).slice(0, 4000);\n\n const issueNumber = state.issue?.number ?? null;\n const issueTitle = state.issue?.title ?? null;\n const provider = state.config.ai.provider;\n const providerName = getProviderDisplayName(provider);\n\n // Modal select: AI or Manual\n const mode = await showSelect({\n title: \"Commit\",\n items: [\n { name: `Generate with ${providerName}`, value: \"ai\" },\n { name: \"Enter manually\", value: \"manual\" },\n ],\n dashboardLines,\n });\n\n if (!mode) {\n await execa(\"git\", [\"reset\", \"HEAD\"]);\n return false;\n }\n\n let message: string | typeof CANCEL;\n\n if (mode === \"manual\") {\n const input = await showInput({\n title: \"Commit Message\",\n label: \"Enter commit message:\",\n dashboardLines,\n });\n message = input || CANCEL;\n } else {\n showStatus(\"Generating\", aiSpinnerText(providerName, \"generate commit message\"), dashboardLines);\n message = await generateCommitMessage(\n diffContent,\n issueNumber,\n issueTitle,\n state,\n dashboardLines\n );\n }\n\n if (message === CANCEL) {\n await execa(\"git\", [\"reset\", \"HEAD\"]);\n return false;\n }\n\n // Confirm commit with generated message\n const confirmed = await showConfirm({\n title: \"Commit\",\n message: `Message: ${message.length > 50 ? message.slice(0, 50) + \"…\" : message}`,\n dashboardLines,\n });\n\n if (!confirmed) {\n await execa(\"git\", [\"reset\", \"HEAD\"]);\n return false;\n }\n\n const providerEmail = getProviderEmail(provider);\n const fullMessage = `${message}\\n\\nCo-Authored-By: ${providerName} <${providerEmail}>`;\n\n showStatus(\"Committing\", \"Committing changes...\", dashboardLines);\n await execa(\"git\", [\"commit\", \"-m\", fullMessage]);\n return true;\n } catch (error) {\n logger.error(`Commit failed: ${error}`);\n return false;\n }\n}\n\nasync function generateCommitMessage(\n diffContent: string,\n issueNumber: number | null,\n issueTitle: string | null,\n state: TuiState,\n dashboardLines: string[]\n): Promise<string | typeof CANCEL> {\n try {\n const prompt = buildCommitMessagePrompt(\n diffContent,\n issueNumber,\n issueTitle\n );\n const result = await invokeAI({ prompt, streamOutput: false }, state.config);\n let message = result.output.trim().split(\"\\n\")[0].trim();\n // Strip wrapping quotes, backticks, or code fences\n for (const q of ['\"', \"'\", \"`\"]) {\n if (message.startsWith(q) && message.endsWith(q)) {\n message = message.slice(1, -1);\n break;\n }\n }\n message = message.replace(/^```\\w*\\s*/, \"\").replace(/\\s*```$/, \"\");\n return message;\n } catch {\n // AI failed — fall back to manual input\n const input = await showInput({\n title: \"Commit Message\",\n label: \"AI generation failed. Enter commit message:\",\n dashboardLines,\n });\n return input || CANCEL;\n }\n}\n\nasync function handleRun(state: TuiState): Promise<void> {\n if (!state.issue) {\n logger.error(\"No linked issue found\");\n return;\n }\n\n const agentInstructions = loadAgentInstructions();\n const progressContent = readProgress(state.config);\n\n // Build context based on current state\n const contextParts: string[] = [];\n\n if (state.commits.length > 0) {\n contextParts.push(\n `## Current Progress\\nThere are ${state.commits.length} existing commit(s) on this branch:\\n${state.commits.map((c) => `- ${c}`).join(\"\\n\")}\\n\\nContinue the implementation from where it left off. Review the existing work and complete any remaining tasks.`\n );\n }\n\n if (state.hasActionableFeedback && state.reviewFeedback.length > 0) {\n const feedbackLines = state.reviewFeedback\n .map((f) => `- [${f.source}] ${f.body.slice(0, 200)}`)\n .join(\"\\n\");\n contextParts.push(`## Review Feedback\\n${feedbackLines}`);\n }\n\n const extraContext =\n contextParts.length > 0 ? contextParts.join(\"\\n\\n\") : null;\n\n const prompt = buildImplementationPrompt(\n state.issue,\n agentInstructions,\n progressContent,\n state.config,\n extraContext\n );\n\n const providerName = getProviderDisplayName(state.config.ai.provider);\n\n clearScreen();\n renderActionPanel(`${providerName} Session`, [\n `Implementing: #${state.issue.number} ${state.issue.title}`,\n state.commits.length > 0\n ? `Continuing from ${state.commits.length} existing commit(s)`\n : \"Starting fresh implementation\",\n ...(state.hasActionableFeedback\n ? [`Includes ${state.reviewFeedback.length} review feedback item(s)`]\n : []),\n ]);\n console.log();\n\n try {\n const { result } = await invokeAIInteractive(prompt, state.config);\n await result;\n } catch (error) {\n logger.error(`${providerName} session failed: ${error}`);\n }\n}\n\nasync function handlePush(dashboardLines: string[]): Promise<void> {\n try {\n const { stdout: branch } = await execa(\"git\", [\"branch\", \"--show-current\"]);\n const branchName = branch.trim();\n\n showStatus(\"Pushing\", `Pushing ${branchName} to remote...`, dashboardLines);\n await execa(\"git\", [\"push\", \"-u\", \"origin\", branchName]);\n } catch (error) {\n logger.error(`Push failed: ${error}`);\n }\n}\n\nconst PROVIDERS: AIProvider[] = [\"claude\", \"gemini\", \"codex\"];\n\nasync function handleSwitchProvider(\n state: TuiState,\n dashboardLines: string[]\n): Promise<void> {\n const current = state.config.ai.provider;\n const items = PROVIDERS.map((p) => ({\n name:\n p.charAt(0).toUpperCase() +\n p.slice(1) +\n (p === current ? \" (current)\" : \"\"),\n value: p,\n }));\n\n const provider = await showSelect({\n title: \"AI Provider\",\n items,\n dashboardLines,\n });\n\n if (!provider || provider === current) return;\n\n setRuntimeProvider(provider as AIProvider);\n // Update in-memory state so dashboard re-renders with new provider\n state.config.ai.provider = provider as AIProvider;\n}\n\n/** Returns true if a branch switch occurred. */\nasync function handleList(\n dashboardLines: string[]\n): Promise<boolean> {\n try {\n showStatus(\"Loading\", \"Fetching tickets...\", dashboardLines);\n\n const config = loadConfig();\n const workflowLabels = getWorkflowLabels(config);\n\n const [inProgress, ready, prs, localBranches, dirty] = await Promise.all([\n listIssues({\n labels: [workflowLabels.inProgress],\n state: \"open\",\n limit: 20,\n }),\n listIssues({\n labels: [workflowLabels.ready],\n state: \"open\",\n limit: 20,\n }),\n listOpenPrs(30),\n listLocalBranches(),\n hasUncommittedChanges(),\n ]);\n\n sortByPriority(inProgress);\n sortByPriority(ready);\n\n const choices = buildTicketChoices(inProgress, ready, prs, localBranches);\n const currentBranch = await getCurrentBranch();\n const defaultBranch = await getDefaultBranch();\n\n // Build modal select entries with category separators\n const items: SelectEntry[] = [];\n let initialIndex = 0;\n let selectableIdx = 0;\n\n // Main branch option\n const isMain = currentBranch === defaultBranch;\n const mainLabel = defaultBranch + (isMain ? \" (current)\" : \"\");\n\n if (dirty && !isMain) {\n items.push({\n name: `${mainLabel} (disabled - uncommitted changes)`,\n value: \"__main_disabled__\",\n });\n } else {\n items.push({ name: mainLabel, value: \"__main__\" });\n }\n if (isMain) initialIndex = selectableIdx;\n selectableIdx++;\n\n const inProgressChoices = choices.filter(\n (c) => c.category === \"in-progress\"\n );\n const openPrChoices = choices.filter((c) => c.category === \"open-pr\");\n const readyChoices = choices.filter((c) => c.category === \"ready\");\n\n const addChoices = (list: typeof choices) => {\n for (const c of list) {\n const isCurrent = c.branch === currentBranch;\n items.push({\n name: `#${c.issueNumber} ${c.title}`,\n value: String(c.issueNumber),\n });\n if (isCurrent) initialIndex = selectableIdx;\n selectableIdx++;\n }\n };\n\n if (inProgressChoices.length > 0) {\n items.push({ separator: \"── In Progress ──\" });\n addChoices(inProgressChoices);\n }\n if (openPrChoices.length > 0) {\n items.push({ separator: \"── Open PRs ──\" });\n addChoices(openPrChoices);\n }\n if (readyChoices.length > 0) {\n items.push({ separator: \"── Ready ──\" });\n addChoices(readyChoices);\n }\n\n const selected = await showSelect({\n title: \"Switch Ticket\",\n items,\n dashboardLines,\n initialIndex,\n currentIndex: initialIndex,\n });\n\n if (!selected) return false;\n\n // Handle disabled main\n if (selected === \"__main_disabled__\") {\n showStatus(\n \"Uncommitted Changes\",\n \"Commit or stash changes before switching to main\",\n dashboardLines\n );\n await new Promise((r) => setTimeout(r, 2000));\n return false;\n }\n\n // Handle main branch selection\n if (selected === \"__main__\") {\n if (currentBranch === defaultBranch) return false;\n showStatus(\"Switching\", `Switching to ${defaultBranch}...`, dashboardLines);\n await checkoutBranch(defaultBranch);\n return true;\n }\n\n // Find selected ticket\n const issueNumber = parseInt(selected, 10);\n const ticket = choices.find((c) => c.issueNumber === issueNumber);\n if (!ticket) return false;\n\n if (dirty) {\n const ok = await showConfirm({\n title: \"Uncommitted Changes\",\n message: \"You have uncommitted changes. Continue?\",\n dashboardLines,\n });\n if (!ok) return false;\n }\n\n const targetBranch = ticket.branch;\n\n if (targetBranch) {\n if (await branchExists(targetBranch)) {\n showStatus(\"Switching\", `Switching to ${targetBranch}...`, dashboardLines);\n await checkoutBranch(targetBranch);\n return true;\n } else if (await remoteBranchExists(targetBranch)) {\n showStatus(\"Fetching\", `Fetching ${targetBranch}...`, dashboardLines);\n await fetchAndCheckout(targetBranch);\n return true;\n } else {\n return await offerCreateBranch(\n issueNumber,\n ticket.title,\n dashboardLines\n );\n }\n } else {\n return await offerCreateBranch(\n issueNumber,\n ticket.title,\n dashboardLines\n );\n }\n } catch (error) {\n logger.error(`List failed: ${error}`);\n return false;\n }\n}\n\n/** Returns true if a branch was created. */\nasync function offerCreateBranch(\n issueNumber: number,\n title: string,\n dashboardLines: string[]\n): Promise<boolean> {\n const config = loadConfig();\n const branchName = await generateBranchName(\n config,\n issueNumber,\n title,\n \"feature\"\n );\n\n const create = await showConfirm({\n title: \"Create Branch\",\n message: `No branch found. Create ${branchName}?`,\n dashboardLines,\n });\n\n if (!create) return false;\n\n const defaultBranch = await getDefaultBranch();\n showStatus(\"Creating\", `Creating ${branchName}...`, dashboardLines);\n await createBranch(branchName, defaultBranch);\n return true;\n}\n\nconst VERSION_CHECK_INTERVAL_MS = 30 * 60 * 1000; // 30 minutes\n\nexport async function tuiCommand(): Promise<void> {\n let running = true;\n let lastActions: TuiAction[] = [];\n let lastDashboardLines: string[] = [];\n let versionCheck: VersionCheckResult | null = null;\n\n // Initial placeholder state for the first \"Loading...\" render\n const config = loadConfig();\n let lastState: TuiState = {\n isGitRepo: true,\n isGhAuthenticated: true,\n isAIProviderAvailable: true,\n config,\n hasConfig: true,\n hasProgress: false,\n branch: \"\",\n branchInfo: null,\n isOnMain: true,\n hasUncommittedChanges: false,\n hasUnpushedCommits: false,\n commits: [],\n baseBranch: \"main\",\n issue: null,\n workflowStatus: \"none\",\n pr: null,\n reviewFeedback: [],\n hasActionableFeedback: false,\n hasUIChanges: false,\n isPlaywrightAvailable: false,\n hasValidRemote: true,\n hasLabels: true,\n };\n\n let needsRefresh = true;\n let isFirstLoad = true;\n\n while (running) {\n if (needsRefresh) {\n // Show dashboard with refreshing indicator while loading new state\n clearScreen();\n renderDashboard(lastState, lastActions, undefined, true, versionCheck);\n\n // Fire version check in parallel with state aggregation (non-blocking)\n // Force a fresh check on first load (interval=0), then throttle subsequent checks\n const checkInterval = isFirstLoad ? 0 : VERSION_CHECK_INTERVAL_MS;\n isFirstLoad = false;\n const [state, versionResult] = await Promise.all([\n aggregateState(),\n checkForUpdates(checkInterval).catch(() => null),\n ]);\n const actions = getAvailableActions(state);\n\n // Save for next refresh cycle\n lastState = state;\n lastActions = actions;\n if (versionResult) versionCheck = versionResult;\n }\n\n // Contextual hint\n let hint: string | undefined;\n if (lastState.isOnMain) {\n hint = \"Select an action to get started\";\n } else if (lastState.hasUncommittedChanges && !lastState.pr) {\n hint = \"Commit your changes before creating a PR\";\n } else if (lastState.hasActionableFeedback) {\n hint = \"Review feedback needs attention\";\n }\n\n // Build and render dashboard, capturing lines for modal overlays\n lastDashboardLines = buildDashboardLines(lastState, lastActions, hint, false, versionCheck);\n clearScreen();\n for (const line of lastDashboardLines) {\n console.log(line);\n }\n\n // Wait for a valid keypress\n const validKeys = lastActions.map((a) => a.shortcut);\n const key = await waitForKey(validKeys);\n\n // Find the matching action\n const action = lastActions.find((a) => a.shortcut === key);\n if (action) {\n const result = await executeAction(action.id, lastState, lastDashboardLines);\n running = result.running;\n needsRefresh = result.refresh;\n }\n }\n}\n","import { loadConfig, configExists } from \"../lib/config.js\";\nimport {\n getIssue,\n getPrStatus,\n getPrReviewData,\n checkLabelsExist,\n type PrStatusInfo,\n} from \"../lib/github.js\";\nimport {\n getCurrentBranch,\n isOnMainBranch,\n hasUncommittedChanges,\n getUnpushedCommits,\n getCommitsSinceBase,\n getDefaultBranch,\n getLastCommitTimestamp,\n getRepoInfo,\n} from \"../lib/git.js\";\nimport { extractIssueNumber, parseBranchName } from \"../lib/branch.js\";\nimport { getWorkflowLabels } from \"../lib/labels.js\";\nimport { progressExists } from \"../lib/progress.js\";\nimport {\n checkGhAuth,\n checkAIProvider,\n checkGitRepo,\n} from \"../utils/validators.js\";\nimport {\n summarizeReviewFeedback,\n type ReviewFeedbackItem,\n} from \"../lib/review-feedback.js\";\nimport {\n hasUIChanges,\n getChangedFiles,\n isPlaywrightAvailable,\n} from \"../lib/playwright.js\";\nimport type { GentConfig, GitHubIssue, BranchInfo } from \"../types/index.js\";\n\nexport type WorkflowStatus =\n | \"ready\"\n | \"in-progress\"\n | \"completed\"\n | \"blocked\"\n | \"none\";\n\nexport interface TuiState {\n // Prerequisites\n isGitRepo: boolean;\n isGhAuthenticated: boolean;\n isAIProviderAvailable: boolean;\n\n // Configuration\n config: GentConfig;\n hasConfig: boolean;\n hasProgress: boolean;\n\n // Git state\n branch: string;\n branchInfo: BranchInfo | null;\n isOnMain: boolean;\n hasUncommittedChanges: boolean;\n hasUnpushedCommits: boolean;\n commits: string[];\n baseBranch: string;\n\n // Issue state\n issue: GitHubIssue | null;\n workflowStatus: WorkflowStatus;\n\n // PR state\n pr: PrStatusInfo | null;\n reviewFeedback: ReviewFeedbackItem[];\n hasActionableFeedback: boolean;\n\n // UI changes detection\n hasUIChanges: boolean;\n isPlaywrightAvailable: boolean;\n\n // Remote detection\n hasValidRemote: boolean;\n\n // Setup state\n hasLabels: boolean;\n}\n\n// Session-level cache for environment checks that don't change mid-session\nlet envCache: {\n isGhAuthenticated: boolean;\n isAIProviderAvailable: boolean;\n isPlaywrightAvailable: boolean;\n hasLabels: boolean | null; // null = not yet checked\n} | null = null;\n\n/** Reset the environment cache (for testing). */\nexport function resetEnvCache(): void {\n envCache = null;\n}\n\nexport async function aggregateState(): Promise<TuiState> {\n // Check prerequisites first\n const isGitRepo = await checkGitRepo();\n if (!isGitRepo) {\n // Return minimal state for non-git directories\n const config = loadConfig();\n return {\n isGitRepo: false,\n isGhAuthenticated: false,\n isAIProviderAvailable: false,\n config,\n hasConfig: false,\n hasProgress: false,\n branch: \"\",\n branchInfo: null,\n isOnMain: false,\n hasUncommittedChanges: false,\n hasUnpushedCommits: false,\n commits: [],\n baseBranch: \"main\",\n issue: null,\n workflowStatus: \"none\",\n pr: null,\n reviewFeedback: [],\n hasActionableFeedback: false,\n hasUIChanges: false,\n isPlaywrightAvailable: false,\n hasValidRemote: false,\n hasLabels: false,\n };\n }\n\n const config = loadConfig();\n const workflowLabels = getWorkflowLabels(config);\n\n // Check environment once per session (these don't change mid-session)\n if (!envCache) {\n const [ghAuth, aiAvail] = await Promise.all([\n checkGhAuth(),\n checkAIProvider(config.ai.provider),\n ]);\n envCache = {\n isGhAuthenticated: ghAuth,\n isAIProviderAvailable: aiAvail,\n isPlaywrightAvailable: false, // resolved below on first feature branch visit\n hasLabels: null, // resolved below when config and remote exist\n };\n }\n const { isGhAuthenticated, isAIProviderAvailable } = envCache;\n\n // Gather git state in parallel\n const [branch, isOnMain, uncommitted, baseBranch, repoInfo] =\n await Promise.all([\n getCurrentBranch(),\n isOnMainBranch(),\n hasUncommittedChanges(),\n getDefaultBranch(),\n getRepoInfo(),\n ]);\n\n const hasConfig = configExists();\n const hasProgress = progressExists(config);\n const branchInfo = parseBranchName(branch);\n\n // Get commits and unpushed status\n const [commits, unpushed] = await Promise.all([\n getCommitsSinceBase(baseBranch),\n getUnpushedCommits(),\n ]);\n\n // Check labels once per session (deferred until config and remote exist)\n const hasRemote = repoInfo !== null;\n if (hasConfig && hasRemote && envCache!.hasLabels === null) {\n envCache!.hasLabels = await checkLabelsExist().catch(() => false);\n }\n const hasLabels = envCache!.hasLabels ?? false;\n\n // Initialize state\n let issue: GitHubIssue | null = null;\n let workflowStatus: WorkflowStatus = \"none\";\n let pr: PrStatusInfo | null = null;\n let reviewFeedback: ReviewFeedbackItem[] = [];\n let hasActionableFeedback = false;\n let uiChanges = false;\n let playwrightAvailable = false;\n\n // If not on main, fetch issue and PR data\n if (!isOnMain) {\n const issueNumber = extractIssueNumber(branch);\n\n // Fetch issue, PR status, and UI change detection in parallel\n // Playwright availability is cached per session\n const needsPlaywrightCheck = !envCache!.isPlaywrightAvailable;\n const [issueResult, prResult, changedFiles, playwrightResult] =\n await Promise.all([\n issueNumber\n ? getIssue(issueNumber).catch(() => null)\n : Promise.resolve(null),\n getPrStatus().catch(() => null),\n getChangedFiles(baseBranch),\n needsPlaywrightCheck\n ? isPlaywrightAvailable()\n : Promise.resolve(envCache!.isPlaywrightAvailable),\n ]);\n\n issue = issueResult;\n pr = prResult;\n uiChanges = hasUIChanges(changedFiles);\n playwrightAvailable = playwrightResult;\n if (needsPlaywrightCheck) {\n envCache!.isPlaywrightAvailable = playwrightResult;\n }\n\n // Determine workflow status from labels\n if (issue) {\n if (issue.labels.includes(workflowLabels.ready)) {\n workflowStatus = \"ready\";\n } else if (issue.labels.includes(workflowLabels.inProgress)) {\n workflowStatus = \"in-progress\";\n } else if (issue.labels.includes(workflowLabels.completed)) {\n workflowStatus = \"completed\";\n } else if (issue.labels.includes(workflowLabels.blocked)) {\n workflowStatus = \"blocked\";\n }\n }\n\n // Fetch review feedback if PR exists and is open\n if (pr && pr.state === \"open\") {\n try {\n const lastCommitTimestamp = await getLastCommitTimestamp();\n const reviewData = await getPrReviewData(pr.number);\n const { items } = summarizeReviewFeedback(reviewData, {\n afterTimestamp: lastCommitTimestamp,\n });\n reviewFeedback = items;\n hasActionableFeedback = items.length > 0;\n } catch {\n // Ignore review data fetch errors\n }\n }\n }\n\n return {\n isGitRepo,\n isGhAuthenticated,\n isAIProviderAvailable,\n config,\n hasConfig,\n hasProgress,\n branch,\n branchInfo,\n isOnMain,\n hasUncommittedChanges: uncommitted,\n hasUnpushedCommits: unpushed,\n commits,\n baseBranch,\n issue,\n workflowStatus,\n pr,\n reviewFeedback,\n hasActionableFeedback,\n hasUIChanges: uiChanges,\n isPlaywrightAvailable: playwrightAvailable,\n hasValidRemote: hasRemote,\n hasLabels,\n };\n}\n","import type { TuiState } from \"./state.js\";\n\nexport interface TuiAction {\n id: string;\n label: string;\n shortcut: string;\n}\n\nexport function getAvailableActions(state: TuiState): TuiAction[] {\n const actions: TuiAction[] = [];\n\n if (!state.isGitRepo || !state.isGhAuthenticated) {\n actions.push({ id: \"quit\", label: \"quit\", shortcut: \"q\" });\n return actions;\n }\n\n // Setup actions when prerequisites are missing\n const needsInit = !state.hasConfig;\n const needsLabels = state.hasConfig && state.hasValidRemote && !state.hasLabels;\n\n if (needsInit) {\n actions.push({ id: \"init\", label: \"init\", shortcut: \"i\" });\n } else if (needsLabels) {\n actions.push({ id: \"setup-labels\", label: \"setup-labels\", shortcut: \"b\" });\n }\n\n // Only show workflow actions when fully set up\n const isSetUp = state.hasConfig && (!state.hasValidRemote || state.hasLabels);\n\n // Common actions available everywhere (gated on valid remote for GitHub-dependent actions)\n if (isSetUp && state.hasValidRemote) {\n actions.push({ id: \"create\", label: \"new\", shortcut: \"n\" });\n }\n\n // On feature branch - add context-aware actions BEFORE other common actions\n if (!state.isOnMain) {\n if (state.hasUncommittedChanges) {\n actions.push({ id: \"commit\", label: \"commit\", shortcut: \"c\" });\n }\n\n if (state.hasUnpushedCommits && state.commits.length > 0) {\n actions.push({ id: \"push\", label: \"push\", shortcut: \"s\" });\n }\n\n if (isSetUp && state.hasValidRemote && !state.pr && state.commits.length > 0) {\n actions.push({ id: \"pr\", label: \"pr\", shortcut: \"p\" });\n }\n\n if (isSetUp && state.issue && state.pr?.state !== \"merged\") {\n actions.push({ id: \"run\", label: \"run\", shortcut: \"r\" });\n }\n }\n\n // Common navigation/config actions\n if (isSetUp && state.hasValidRemote) {\n actions.push({ id: \"list\", label: \"list\", shortcut: \"l\" });\n } else if (!state.hasValidRemote) {\n actions.push({ id: \"github-remote\", label: \"github\", shortcut: \"g\" });\n }\n actions.push({ id: \"refresh\", label: \"refresh\", shortcut: \"f\" });\n actions.push({ id: \"switch-provider\", label: \"ai\", shortcut: \"a\" });\n actions.push({ id: \"quit\", label: \"quit\", shortcut: \"q\" });\n\n return actions;\n}\n","import chalk from \"chalk\";\nimport { getProviderDisplayName } from \"../lib/ai-provider.js\";\nimport { getVersion, type VersionCheckResult } from \"../lib/version.js\";\nimport type { TuiAction } from \"./actions.js\";\nimport type { TuiState } from \"./state.js\";\n\n// eslint-disable-next-line no-control-regex\nexport const stripAnsi = (str: string) => str.replace(/\\x1b\\[[0-9;]*m/g, \"\");\nexport const visibleLen = (str: string) => stripAnsi(str).length;\n\nexport function truncateAnsi(text: string, max: number): string {\n if (visibleLen(text) <= max) return text;\n // Walk through the string, tracking visible characters\n let visible = 0;\n let i = 0;\n while (i < text.length && visible < max - 1) {\n if (text[i] === \"\\x1b\") {\n // Skip ANSI escape sequence\n const end = text.indexOf(\"m\", i);\n if (end !== -1) {\n i = end + 1;\n continue;\n }\n }\n visible++;\n i++;\n }\n // Include any trailing ANSI reset sequences\n return text.slice(0, i) + \"\\x1b[0m…\";\n}\n\nexport function termWidth(): number {\n return Math.min(process.stdout.columns || 80, 90);\n}\n\nfunction truncate(text: string, max: number): string {\n if (text.length <= max) return text;\n return text.slice(0, max - 1) + \"…\";\n}\n\nfunction extractDescription(body: string, maxLen: number): string {\n const lines = body.split(\"\\n\");\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n if (trimmed.startsWith(\"#\")) continue;\n if (trimmed.startsWith(\"---\")) continue;\n if (trimmed.startsWith(\"META:\")) continue;\n if (trimmed.startsWith(\"**Type:**\")) continue;\n const clean = trimmed\n .replace(/\\*\\*/g, \"\")\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\");\n return truncate(clean, maxLen);\n }\n return \"\";\n}\n\n// ── Box drawing ─────────────────────────────────────────────────\n\nfunction topRow(title: string, w: number): string {\n const label = ` ${title} `;\n const fill = w - 2 - label.length;\n return (\n chalk.dim(\"┌\") +\n chalk.bold.cyan(label) +\n chalk.dim(\"─\".repeat(Math.max(0, fill)) + \"┐\")\n );\n}\n\nfunction midRow(title: string, w: number): string {\n const label = ` ${title} `;\n const fill = w - 2 - label.length;\n return (\n chalk.dim(\"├\") +\n chalk.bold.cyan(label) +\n chalk.dim(\"─\".repeat(Math.max(0, fill)) + \"┤\")\n );\n}\n\nfunction divRow(w: number): string {\n return chalk.dim(\"├\" + \"─\".repeat(w - 2) + \"┤\");\n}\n\nfunction botRow(w: number): string {\n return chalk.dim(\"└\" + \"─\".repeat(w - 2) + \"┘\");\n}\n\nfunction row(text: string, w: number): string {\n const inner = w - 4;\n const fitted = truncateAnsi(text, inner);\n const pad = Math.max(0, inner - visibleLen(fitted));\n return chalk.dim(\"│\") + \" \" + fitted + \" \".repeat(pad) + \" \" + chalk.dim(\"│\");\n}\n\n// ── Formatters ──────────────────────────────────────────────────\n\nfunction workflowBadge(status: string): string {\n switch (status) {\n case \"ready\":\n return chalk.bgGreen.black(\" READY \");\n case \"in-progress\":\n return chalk.bgYellow.black(\" IN PROGRESS \");\n case \"completed\":\n return chalk.bgBlue.white(\" COMPLETED \");\n case \"blocked\":\n return chalk.bgRed.white(\" BLOCKED \");\n default:\n return \"\";\n }\n}\n\nfunction prBadge(state: \"open\" | \"closed\" | \"merged\", draft: boolean): string {\n if (state === \"merged\") return chalk.bgMagenta.white(\" MERGED \");\n if (state === \"closed\") return chalk.bgRed.white(\" CLOSED \");\n return draft\n ? chalk.bgYellow.black(\" DRAFT \")\n : chalk.bgGreen.black(\" OPEN \");\n}\n\nfunction reviewBadge(decision: string | null): string {\n if (!decision) return \"\";\n switch (decision) {\n case \"APPROVED\":\n return \" \" + chalk.green(\"Approved\");\n case \"CHANGES_REQUESTED\":\n return \" \" + chalk.red(\"Changes requested\");\n case \"REVIEW_REQUIRED\":\n return \" \" + chalk.yellow(\"Review pending\");\n default:\n return \"\";\n }\n}\n\n// Rotating color palette for shortcut keys\nconst shortcutColors = [\n chalk.cyan.bold,\n chalk.green.bold,\n chalk.yellow.bold,\n chalk.magenta.bold,\n chalk.blue.bold,\n chalk.red.bold,\n];\n\nfunction formatAction(a: TuiAction, color: (s: string) => string): string {\n const idx = a.label.indexOf(a.shortcut);\n const styledKey = color(chalk.underline(a.shortcut));\n if (idx >= 0) {\n const before = a.label.slice(0, idx);\n const after = a.label.slice(idx + a.shortcut.length);\n return chalk.dim(before) + styledKey + chalk.dim(after);\n }\n return styledKey + \" \" + chalk.dim(a.label);\n}\n\nfunction formatCommandBar(actions: TuiAction[], w: number): string[] {\n const parts = actions.map((a, i) => {\n const color = shortcutColors[i % shortcutColors.length];\n return formatAction(a, color);\n });\n const inner = w - 4;\n const lines: string[] = [];\n let cur = \"\";\n for (const part of parts) {\n const next = cur + (cur.length > 0 ? \" \" : \"\") + part;\n if (visibleLen(next) > inner) {\n lines.push(cur);\n cur = part;\n } else {\n cur = next;\n }\n }\n if (cur.length > 0) lines.push(cur);\n return lines;\n}\n\n/**\n * Render a framed panel for action output.\n * Shows a titled box with multiline content, used for command results\n * and AI interaction status within the TUI.\n */\nexport function renderActionPanel(title: string, content: string[]): void {\n const w = termWidth();\n console.log(topRow(title, w));\n for (const line of content) {\n console.log(row(line, w));\n }\n console.log(botRow(w));\n}\n\n// ── Dashboard line builder ──────────────────────────────────────\n\ntype Out = (line: string) => void;\n\nfunction renderSettingsTo(\n state: TuiState,\n w: number,\n out: Out,\n versionCheck?: VersionCheckResult | null\n): void {\n const provider = getProviderDisplayName(state.config.ai.provider);\n const provTag = state.isAIProviderAvailable\n ? chalk.green(provider)\n : chalk.red(provider);\n const ghTag = state.isGhAuthenticated\n ? chalk.green(\"authenticated\")\n : chalk.red(\"not authenticated\");\n\n out(row(chalk.dim(\"Provider: \") + provTag, w));\n out(row(chalk.dim(\"GitHub: \") + ghTag, w));\n\n if (versionCheck?.updateAvailable && versionCheck.latestVersion) {\n out(\n row(\n chalk.yellow(\n `Update available: ${versionCheck.currentVersion} → ${versionCheck.latestVersion}`\n ) +\n chalk.dim(' — run \"npm install -g @rotorsoft/gent\" to upgrade'),\n w\n )\n );\n }\n}\n\n/**\n * Build dashboard output as an array of strings.\n * Used by modals to capture dashboard state for overlay rendering.\n */\nexport function buildDashboardLines(\n state: TuiState,\n actions: TuiAction[],\n hint?: string,\n refreshing?: boolean,\n versionCheck?: VersionCheckResult | null\n): string[] {\n const lines: string[] = [];\n const out: Out = (line: string) => lines.push(line);\n const w = termWidth();\n const descMax = w - 8;\n const version = getVersion();\n\n const titleLabel = `gent v${version}`;\n out(topRow(titleLabel, w));\n renderSettingsTo(state, w, out, versionCheck);\n\n // ── Error states ──────────────────────────────────────────────\n if (!state.isGitRepo) {\n out(row(chalk.yellow(\"Not a git repository\"), w));\n out(row(chalk.dim(\"Navigate to a git repository to get started\"), w));\n out(divRow(w));\n for (const line of formatCommandBar(actions, w)) {\n out(row(line, w));\n }\n out(botRow(w));\n return lines;\n }\n if (!state.isGhAuthenticated) {\n out(row(chalk.red(\"GitHub CLI not authenticated\"), w));\n out(row(chalk.dim(\"Run: gh auth login\"), w));\n out(divRow(w));\n for (const line of formatCommandBar(actions, w)) {\n out(row(line, w));\n }\n out(botRow(w));\n return lines;\n }\n\n const section = (title: string) => {\n out(midRow(title, w));\n };\n\n // Ticket\n if (state.issue || !state.isOnMain) {\n section(\"Ticket\");\n if (state.issue) {\n out(\n row(\n chalk.dim(\"· \") +\n chalk.cyan(`#${state.issue.number}`) +\n \" \" +\n chalk.bold(state.issue.title),\n w\n )\n );\n const desc = extractDescription(state.issue.body, descMax);\n if (desc) out(row(\" \" + chalk.dim(desc), w));\n const tags: string[] = [];\n if (state.workflowStatus !== \"none\")\n tags.push(workflowBadge(state.workflowStatus));\n for (const prefix of [\"type:\", \"priority:\", \"risk:\", \"area:\"]) {\n const l = state.issue.labels.find((x) => x.startsWith(prefix));\n if (l) tags.push(chalk.dim(l));\n }\n if (tags.length) out(row(\" \" + tags.join(\" \"), w));\n } else {\n out(row(chalk.dim(\" No linked issue\"), w));\n }\n }\n\n // Branch\n section(\"Branch\");\n let branchLine = chalk.dim(\"· \") + chalk.magenta(state.branch);\n if (state.isOnMain && !state.hasUncommittedChanges) {\n branchLine += chalk.dim(\" · ready to start new work\");\n }\n out(row(branchLine, w));\n\n const bits: string[] = [];\n if (state.commits.length > 0)\n bits.push(chalk.dim(`${state.commits.length} ahead`));\n if (state.hasUncommittedChanges) bits.push(chalk.yellow(\"● uncommitted\"));\n if (state.hasUnpushedCommits) bits.push(chalk.yellow(\"● unpushed\"));\n if (\n !state.hasUncommittedChanges &&\n !state.hasUnpushedCommits &&\n state.commits.length > 0\n ) {\n bits.push(chalk.green(\"● synced\"));\n }\n if (bits.length) out(row(\" \" + bits.join(chalk.dim(\" · \")), w));\n\n // Pull Request\n if (state.pr || !state.isOnMain) {\n section(\"Pull Request\");\n if (state.pr) {\n const titleText = state.pr.title ? \" \" + state.pr.title : \"\";\n out(\n row(\n chalk.dim(\"· \") + chalk.cyan(`#${state.pr.number}`) + titleText,\n w\n )\n );\n out(\n row(\n \" \" +\n prBadge(state.pr.state, state.pr.isDraft) +\n reviewBadge(state.pr.reviewDecision),\n w\n )\n );\n if (state.hasActionableFeedback) {\n const n = state.reviewFeedback.length;\n out(\n row(\n \" \" +\n chalk.yellow(`${n} actionable comment${n !== 1 ? \"s\" : \"\"} pending`),\n w\n )\n );\n }\n if (\n state.hasUIChanges &&\n state.isPlaywrightAvailable &&\n state.config.video.enabled &&\n state.pr.state === \"open\"\n ) {\n out(\n row(\n \" \" +\n chalk.cyan(\"UI changes detected\") +\n chalk.dim(\" · video capture available\"),\n w\n )\n );\n }\n out(row(\" \" + chalk.dim(state.pr.url), w));\n } else {\n out(row(chalk.dim(\" No PR created\"), w));\n }\n }\n\n // Commits\n if (state.commits.length > 0 || !state.isOnMain) {\n section(\"Commits\");\n if (state.commits.length > 0) {\n const max = 6;\n for (const c of state.commits.slice(0, max)) {\n out(row(chalk.dim(\"· \") + c, w));\n }\n if (state.commits.length > max) {\n out(row(chalk.dim(` … and ${state.commits.length - max} more`), w));\n }\n } else {\n out(row(chalk.dim(\" No commits\"), w));\n }\n }\n\n // Setup hints (take priority over other hints)\n if (!state.hasConfig) {\n section(\"Setup\");\n out(row(chalk.yellow('Run \"gent init\" to set up this repository'), w));\n out(row(chalk.dim(\"Press [i] to initialize\"), w));\n } else if (state.hasValidRemote && !state.hasLabels) {\n section(\"Setup\");\n out(row(chalk.yellow('Run \"gent setup-labels\" to create required GitHub labels'), w));\n out(row(chalk.dim(\"Press [b] to set up labels\"), w));\n } else if (!state.hasValidRemote) {\n section(\"Hint\");\n out(\n row(\n chalk.yellow(\n \"Press [g] to create a GitHub repo and push\"\n ),\n w\n )\n );\n } else if (hint) {\n section(\"Hint\");\n out(row(chalk.yellow(hint), w));\n }\n\n // Command bar (inside the frame)\n out(divRow(w));\n if (refreshing) {\n out(row(chalk.yellow(\"Refreshing…\"), w));\n } else {\n for (const line of formatCommandBar(actions, w)) {\n out(row(line, w));\n }\n }\n out(botRow(w));\n\n return lines;\n}\n\n// ── Main render ─────────────────────────────────────────────────\n\nexport function renderDashboard(\n state: TuiState,\n actions: TuiAction[],\n hint?: string,\n refreshing?: boolean,\n versionCheck?: VersionCheckResult | null\n): void {\n const lines = buildDashboardLines(state, actions, hint, refreshing, versionCheck);\n for (const line of lines) {\n console.log(line);\n }\n}\n\nexport function clearScreen(): void {\n process.stdout.write(\"\\x1B[2J\\x1B[0f\");\n}\n","import chalk from \"chalk\";\nimport { stripAnsi, visibleLen, truncateAnsi } from \"./display.js\";\n\n// ── Re-exports ──────────────────────────────────────────────────\n// Keep all dialog types accessible via modal.ts so existing\n// consumers (tui.ts, tui.test.ts) don't need import changes.\n\nexport { readKey, type KeyPress } from \"./key-reader.js\";\nexport { showSelect, buildSelectContent, type SelectItem, type SelectSeparator, type SelectEntry, type SelectOptions } from \"./select-dialog.js\";\nexport { showConfirm, buildConfirmContent, type ConfirmOptions } from \"./confirm-dialog.js\";\nexport { showInput, buildInputContent, type InputOptions } from \"./input-dialog.js\";\nexport { showMultilineInput, buildMultilineInputContent } from \"./multiline-input.js\";\n\n// ── Modal frame builders (pure, testable) ────────────────────────\n\nfunction modalTopRow(title: string, w: number): string {\n const label = ` ${title} `;\n const fill = w - 2 - label.length;\n return (\n chalk.bold(\"┌\") +\n chalk.bold.cyan(label) +\n chalk.bold(\"─\".repeat(Math.max(0, fill)) + \"┐\")\n );\n}\n\nfunction modalDivRow(w: number): string {\n return chalk.bold(\"├\" + \"─\".repeat(w - 2) + \"┤\");\n}\n\nfunction modalBotRow(w: number): string {\n return chalk.bold(\"└\" + \"─\".repeat(w - 2) + \"┘\");\n}\n\nfunction modalRow(text: string, w: number): string {\n const inner = w - 4;\n const fitted = truncateAnsi(text, inner);\n const pad = Math.max(0, inner - visibleLen(fitted));\n return chalk.bold(\"│\") + \" \" + fitted + \" \".repeat(pad) + \" \" + chalk.bold(\"│\");\n}\n\nfunction modalEmptyRow(w: number): string {\n return modalRow(\"\", w);\n}\n\n/**\n * Build modal frame lines (pure function for testing).\n */\nexport function buildModalFrame(\n title: string,\n contentLines: string[],\n footerText: string,\n width: number\n): string[] {\n const lines: string[] = [];\n lines.push(modalTopRow(title, width));\n lines.push(modalEmptyRow(width));\n for (const line of contentLines) {\n lines.push(modalRow(line, width));\n }\n lines.push(modalEmptyRow(width));\n lines.push(modalDivRow(width));\n lines.push(modalRow(chalk.dim(footerText), width));\n lines.push(modalBotRow(width));\n return lines;\n}\n\n// ── Terminal helpers ──────────────────────────────────────────────\n\nfunction termSize(): { cols: number; rows: number } {\n return {\n cols: process.stdout.columns || 80,\n rows: process.stdout.rows || 24,\n };\n}\n\nfunction moveTo(row: number, col: number): string {\n return `\\x1B[${row};${col}H`;\n}\n\nfunction hideCursor(): string {\n return \"\\x1B[?25l\";\n}\n\nexport function showCursor(): string {\n return \"\\x1B[?25h\";\n}\n\nexport function modalWidth(): number {\n const cols = process.stdout.columns || 80;\n return Math.min(60, cols - 4);\n}\n\n// ── Overlay rendering ────────────────────────────────────────────\n\n/**\n * Render dashboard lines dimmed with modal lines overlaid in center.\n */\nexport function renderOverlay(\n dashboardLines: string[],\n modalLines: string[],\n mWidth: number\n): void {\n const { cols, rows } = termSize();\n\n // Clear screen\n process.stdout.write(\"\\x1B[2J\\x1B[0f\");\n process.stdout.write(hideCursor());\n\n // Render dimmed dashboard\n for (let i = 0; i < dashboardLines.length && i < rows; i++) {\n process.stdout.write(\n moveTo(i + 1, 1) + chalk.dim(stripAnsi(dashboardLines[i]))\n );\n }\n\n // Calculate modal position (centered)\n const startRow = Math.max(1, Math.floor((rows - modalLines.length) / 2));\n const startCol = Math.max(1, Math.floor((cols - mWidth) / 2));\n\n // Render modal lines at position\n for (let i = 0; i < modalLines.length; i++) {\n process.stdout.write(moveTo(startRow + i, startCol) + modalLines[i]);\n }\n\n // Move cursor below modal\n process.stdout.write(moveTo(startRow + modalLines.length + 1, 1));\n}\n\n// ── Status dialog ────────────────────────────────────────────────\n\n/**\n * Show a brief status message in a modal overlay.\n * Auto-dismisses — caller controls when to re-render dashboard.\n */\nexport function showStatus(\n title: string,\n message: string,\n dashboardLines: string[]\n): void {\n const w = modalWidth();\n const content = [message];\n const footer = \"\";\n const lines = buildModalFrame(title, content, footer, w);\n renderOverlay(dashboardLines, lines, w);\n}\n","export interface KeyPress {\n name: string;\n raw: string;\n}\n\nexport function readKey(): Promise<KeyPress> {\n return new Promise((resolve) => {\n const { stdin } = process;\n const wasRaw = stdin.isRaw;\n stdin.setRawMode(true);\n stdin.resume();\n stdin.setEncoding(\"utf8\");\n\n const onData = (data: string) => {\n stdin.setRawMode(wasRaw ?? false);\n stdin.pause();\n stdin.removeListener(\"data\", onData);\n\n if (data === \"\\x03\") {\n resolve({ name: \"escape\", raw: data }); // Ctrl+C → escape\n } else if (data === \"\\x1b\" || data === \"\\x1b\\x1b\") {\n resolve({ name: \"escape\", raw: data });\n } else if (data === \"\\x1b[A\") {\n resolve({ name: \"up\", raw: data });\n } else if (data === \"\\x1b[B\") {\n resolve({ name: \"down\", raw: data });\n } else if (data === \"\\x1b[C\") {\n resolve({ name: \"right\", raw: data });\n } else if (data === \"\\x1b[D\") {\n resolve({ name: \"left\", raw: data });\n } else if (data === \"\\x1b[1;5C\" || data === \"\\x1b[5C\") {\n resolve({ name: \"ctrl-right\", raw: data });\n } else if (data === \"\\x1b[1;5D\" || data === \"\\x1b[5D\") {\n resolve({ name: \"ctrl-left\", raw: data });\n } else if (data === \"\\x1b[3~\") {\n resolve({ name: \"delete\", raw: data });\n } else if (data === \"\\x1b[H\" || data === \"\\x1b[1~\") {\n resolve({ name: \"home\", raw: data });\n } else if (data === \"\\x1b[F\" || data === \"\\x1b[4~\") {\n resolve({ name: \"end\", raw: data });\n } else if (data === \"\\x01\") {\n resolve({ name: \"home\", raw: data }); // Ctrl+A\n } else if (data === \"\\x05\") {\n resolve({ name: \"end\", raw: data }); // Ctrl+E\n } else if (data === \"\\r\" || data === \"\\n\") {\n resolve({ name: \"enter\", raw: data });\n } else if (data === \"\\x7f\" || data === \"\\x08\") {\n resolve({ name: \"backspace\", raw: data });\n } else if (data === \"\\t\") {\n resolve({ name: \"tab\", raw: data });\n } else if (data === \"\\x13\") {\n resolve({ name: \"ctrl-s\", raw: data }); // Ctrl+S\n } else if (data.length === 1 && data.charCodeAt(0) >= 32) {\n resolve({ name: data, raw: data });\n } else {\n // Unknown sequence — treat as no-op, read again\n stdin.setRawMode(true);\n stdin.resume();\n stdin.on(\"data\", onData);\n }\n };\n\n stdin.on(\"data\", onData);\n });\n}\n","import chalk from \"chalk\";\nimport { truncateAnsi } from \"./display.js\";\nimport { readKey } from \"./key-reader.js\";\nimport { buildModalFrame, renderOverlay, modalWidth, showCursor } from \"./modal.js\";\n\n// ── Types ────────────────────────────────────────────────────────\n\nexport interface SelectItem {\n name: string;\n value: string;\n}\n\nexport interface SelectSeparator {\n separator: string;\n}\n\nexport type SelectEntry = SelectItem | SelectSeparator;\n\nfunction isSeparator(entry: SelectEntry): entry is SelectSeparator {\n return \"separator\" in entry;\n}\n\n// ── Content builder (pure, testable) ─────────────────────────────\n\nexport function buildSelectContent(\n items: SelectEntry[],\n selectedIndex: number,\n maxWidth: number,\n currentIndex?: number\n): string[] {\n const lines: string[] = [];\n let selectableIdx = 0;\n\n for (const item of items) {\n if (isSeparator(item)) {\n lines.push(chalk.dim(item.separator));\n } else {\n const isSelected = selectableIdx === selectedIndex;\n const isCurrent = currentIndex != null && selectableIdx === currentIndex;\n const prefix = isSelected ? chalk.cyan.bold(\"> \") : \" \";\n const bullet = chalk.dim(\"· \");\n const label = truncateAnsi(item.name, maxWidth - 4);\n const styledLabel = isSelected\n ? chalk.bold(label)\n : isCurrent\n ? chalk.cyan(label)\n : label;\n lines.push(prefix + bullet + styledLabel);\n selectableIdx++;\n }\n }\n\n return lines;\n}\n\n// ── Dialog ───────────────────────────────────────────────────────\n\nexport interface SelectOptions {\n title: string;\n items: SelectEntry[];\n dashboardLines: string[];\n initialIndex?: number;\n currentIndex?: number;\n}\n\n/**\n * Get the selectable items count (excluding separators).\n */\nfunction selectableCount(items: SelectEntry[]): number {\n return items.filter((i) => !isSeparator(i)).length;\n}\n\n/**\n * Show a select dialog overlaying the dashboard.\n * Returns the selected value or null if cancelled.\n */\nexport async function showSelect(opts: SelectOptions): Promise<string | null> {\n const w = modalWidth();\n const maxItems = selectableCount(opts.items);\n if (maxItems === 0) return null;\n\n let selectedIndex = opts.initialIndex ?? 0;\n\n const render = () => {\n const content = buildSelectContent(opts.items, selectedIndex, w - 6, opts.currentIndex);\n const footer = \"↑↓ Navigate Enter Select Esc Cancel\";\n const lines = buildModalFrame(opts.title, content, footer, w);\n renderOverlay(opts.dashboardLines, lines, w);\n };\n\n render();\n\n while (true) {\n const key = await readKey();\n\n switch (key.name) {\n case \"up\":\n selectedIndex = (selectedIndex - 1 + maxItems) % maxItems;\n render();\n break;\n\n case \"down\":\n selectedIndex = (selectedIndex + 1) % maxItems;\n render();\n break;\n\n case \"enter\": {\n process.stdout.write(showCursor());\n // Find the nth selectable item\n let idx = 0;\n for (const item of opts.items) {\n if (!isSeparator(item)) {\n if (idx === selectedIndex) return item.value;\n idx++;\n }\n }\n return null;\n }\n\n case \"escape\":\n process.stdout.write(showCursor());\n return null;\n }\n }\n}\n","import chalk from \"chalk\";\nimport { readKey } from \"./key-reader.js\";\nimport { buildModalFrame, renderOverlay, modalWidth, showCursor } from \"./modal.js\";\n\n// ── Content builder (pure, testable) ─────────────────────────────\n\nexport function buildConfirmContent(\n message: string,\n selectedYes: boolean\n): string[] {\n const yes = selectedYes\n ? chalk.cyan.bold(\"> Yes\")\n : chalk.dim(\" Yes\");\n const no = !selectedYes\n ? chalk.cyan.bold(\"> No\")\n : chalk.dim(\" No\");\n return [message, \"\", yes, no];\n}\n\n// ── Dialog ───────────────────────────────────────────────────────\n\nexport interface ConfirmOptions {\n title: string;\n message: string;\n dashboardLines: string[];\n}\n\n/**\n * Show a confirm dialog overlaying the dashboard.\n * Returns true for yes, false for no/cancel.\n */\nexport async function showConfirm(opts: ConfirmOptions): Promise<boolean> {\n const w = modalWidth();\n let selectedYes = true;\n\n const render = () => {\n const content = buildConfirmContent(opts.message, selectedYes);\n const footer = \"↑↓ Select Enter Confirm Esc Cancel\";\n const lines = buildModalFrame(opts.title, content, footer, w);\n renderOverlay(opts.dashboardLines, lines, w);\n };\n\n render();\n\n while (true) {\n const key = await readKey();\n\n switch (key.name) {\n case \"up\":\n case \"down\":\n case \"tab\":\n selectedYes = !selectedYes;\n render();\n break;\n\n case \"enter\":\n process.stdout.write(showCursor());\n return selectedYes;\n\n case \"escape\":\n process.stdout.write(showCursor());\n return false;\n\n case \"y\":\n process.stdout.write(showCursor());\n return true;\n\n case \"n\":\n process.stdout.write(showCursor());\n return false;\n }\n }\n}\n","import chalk from \"chalk\";\nimport { readKey } from \"./key-reader.js\";\nimport { buildModalFrame, renderOverlay, modalWidth, showCursor } from \"./modal.js\";\n\n// ── Content builder (pure, testable) ─────────────────────────────\n\nexport function buildInputContent(\n label: string,\n value: string,\n cursorVisible: boolean\n): string[] {\n const cursorChar = cursorVisible ? chalk.inverse(\" \") : \"\";\n return [label, \"\", chalk.cyan(\"> \") + value + cursorChar];\n}\n\n// ── Dialog ───────────────────────────────────────────────────────\n\nexport interface InputOptions {\n title: string;\n label: string;\n dashboardLines: string[];\n}\n\n/**\n * Show a text input dialog overlaying the dashboard.\n * Returns the entered text or null if cancelled.\n */\nexport async function showInput(opts: InputOptions): Promise<string | null> {\n const w = modalWidth();\n let value = \"\";\n let cursorBlink = true;\n\n const render = () => {\n const maxLen = w - 10;\n const displayValue = value.length > maxLen\n ? value.slice(value.length - maxLen)\n : value;\n const content = buildInputContent(opts.label, displayValue, cursorBlink);\n const footer = \"Enter Submit Esc Cancel\";\n const lines = buildModalFrame(opts.title, content, footer, w);\n renderOverlay(opts.dashboardLines, lines, w);\n };\n\n render();\n\n while (true) {\n const key = await readKey();\n\n switch (key.name) {\n case \"enter\":\n process.stdout.write(showCursor());\n return value.trim() || null;\n\n case \"escape\":\n process.stdout.write(showCursor());\n return null;\n\n case \"backspace\":\n if (value.length > 0) {\n value = value.slice(0, -1);\n }\n render();\n break;\n\n default:\n // Single printable character\n if (key.raw.length === 1 && key.raw.charCodeAt(0) >= 32) {\n value += key.raw;\n cursorBlink = true;\n render();\n }\n break;\n }\n }\n}\n","import chalk from \"chalk\";\nimport { readKey } from \"./key-reader.js\";\nimport { type InputOptions } from \"./input-dialog.js\";\nimport { buildModalFrame, renderOverlay, modalWidth, showCursor } from \"./modal.js\";\n\n// ── Visual line mapping for cursor positioning ──────────────────\n\ninterface WrapSegment {\n text: string;\n offset: number; // start offset within the logical line\n}\n\nfunction wrapLineWithMap(text: string, width: number): WrapSegment[] {\n if (width <= 0) return [{ text, offset: 0 }];\n if (text.length <= width) return [{ text, offset: 0 }];\n\n const result: WrapSegment[] = [];\n let pos = 0;\n let remaining = text;\n while (remaining.length > width) {\n let breakAt = remaining.lastIndexOf(\" \", width);\n if (breakAt <= 0) breakAt = width;\n result.push({ text: remaining.slice(0, breakAt), offset: pos });\n pos += breakAt;\n remaining = remaining.slice(breakAt);\n if (remaining.startsWith(\" \")) {\n remaining = remaining.slice(1);\n pos += 1;\n }\n }\n if (remaining.length > 0 || result.length === 0) {\n result.push({ text: remaining, offset: pos });\n }\n return result;\n}\n\nexport interface VisualLine {\n text: string;\n globalOffset: number; // offset in the full value string\n length: number;\n}\n\nexport function getVisualLines(value: string, contentWidth: number): VisualLine[] {\n const inputLines = value.split(\"\\n\");\n const result: VisualLine[] = [];\n let globalPos = 0;\n\n for (let i = 0; i < inputLines.length; i++) {\n const raw = inputLines[i];\n const wrapped = wrapLineWithMap(raw, contentWidth);\n for (const seg of wrapped) {\n result.push({\n text: seg.text,\n globalOffset: globalPos + seg.offset,\n length: seg.text.length,\n });\n }\n globalPos += raw.length + 1; // +1 for the newline\n }\n\n return result;\n}\n\nexport function findCursorVisualPos(\n visualLines: VisualLine[],\n cursorPos: number\n): { row: number; col: number } {\n for (let i = 0; i < visualLines.length; i++) {\n const vl = visualLines[i];\n if (cursorPos >= vl.globalOffset && cursorPos <= vl.globalOffset + vl.length) {\n return { row: i, col: cursorPos - vl.globalOffset };\n }\n }\n const last = visualLines[visualLines.length - 1];\n return { row: visualLines.length - 1, col: last.length };\n}\n\n// ── Cursor movement helpers (pure, testable) ────────────────────\n\nexport function moveCursorVertical(\n value: string,\n cursorPos: number,\n contentWidth: number,\n direction: -1 | 1\n): number {\n const visualLines = getVisualLines(value, contentWidth);\n const { row, col } = findCursorVisualPos(visualLines, cursorPos);\n const newRow = row + direction;\n if (newRow < 0 || newRow >= visualLines.length) return cursorPos;\n const targetLine = visualLines[newRow];\n const newCol = Math.min(col, targetLine.length);\n return targetLine.globalOffset + newCol;\n}\n\nexport function moveCursorHome(\n value: string,\n cursorPos: number,\n contentWidth: number\n): number {\n const visualLines = getVisualLines(value, contentWidth);\n const { row } = findCursorVisualPos(visualLines, cursorPos);\n return visualLines[row].globalOffset;\n}\n\nexport function moveCursorEnd(\n value: string,\n cursorPos: number,\n contentWidth: number\n): number {\n const visualLines = getVisualLines(value, contentWidth);\n const { row } = findCursorVisualPos(visualLines, cursorPos);\n return visualLines[row].globalOffset + visualLines[row].length;\n}\n\nexport function moveCursorWordLeft(value: string, cursorPos: number): number {\n if (cursorPos <= 0) return 0;\n let pos = cursorPos - 1;\n // Skip non-word chars\n while (pos > 0 && !/\\w/.test(value[pos])) pos--;\n // Skip word chars\n while (pos > 0 && /\\w/.test(value[pos - 1])) pos--;\n return pos;\n}\n\nexport function moveCursorWordRight(value: string, cursorPos: number): number {\n if (cursorPos >= value.length) return value.length;\n let pos = cursorPos;\n // Skip word chars\n while (pos < value.length && /\\w/.test(value[pos])) pos++;\n // Skip non-word chars\n while (pos < value.length && !/\\w/.test(value[pos])) pos++;\n return pos;\n}\n\n// ── Content builder (pure, testable) ─────────────────────────────\n\n/**\n * Build multiline input content with word wrapping.\n * Cursor is rendered at cursorPos (defaults to end of text).\n */\nexport function buildMultilineInputContent(\n label: string,\n value: string,\n cursorVisible: boolean,\n maxWidth: number,\n cursorPos?: number\n): string[] {\n const cp = cursorPos ?? value.length;\n const lines: string[] = [label, \"\"];\n const contentWidth = maxWidth - 2;\n\n const visualLines = getVisualLines(value, contentWidth);\n const { row: cursorRow, col: cursorCol } = findCursorVisualPos(visualLines, cp);\n\n for (let i = 0; i < visualLines.length; i++) {\n const text = visualLines[i].text;\n if (i === cursorRow && cursorVisible) {\n const charUnderCursor = cursorCol < text.length ? text[cursorCol] : \" \";\n lines.push(\n chalk.cyan(\" \") +\n text.slice(0, cursorCol) +\n chalk.inverse(charUnderCursor) +\n text.slice(cursorCol + 1)\n );\n } else {\n lines.push(chalk.cyan(\" \") + text);\n }\n }\n\n return lines;\n}\n\n// ── Multiline input dialog ───────────────────────────────────────\n\n/**\n * Show a multiline text input dialog overlaying the dashboard.\n * Enter inserts a newline; Ctrl+S submits.\n * Returns the entered text or null if cancelled.\n */\nexport async function showMultilineInput(\n opts: InputOptions\n): Promise<string | null> {\n const w = modalWidth();\n let value = \"\";\n let cursorPos = 0;\n let cursorBlink = true;\n const contentWidth = w - 6; // inner width minus borders and padding\n\n const render = () => {\n const content = buildMultilineInputContent(\n opts.label,\n value,\n cursorBlink,\n contentWidth,\n cursorPos\n );\n const footer = \"Enter Newline Ctrl+S Submit Esc Cancel\";\n const lines = buildModalFrame(opts.title, content, footer, w);\n renderOverlay(opts.dashboardLines, lines, w);\n };\n\n render();\n\n while (true) {\n const key = await readKey();\n\n switch (key.name) {\n case \"ctrl-s\":\n process.stdout.write(showCursor());\n return value.trim() || null;\n\n case \"enter\":\n value = value.slice(0, cursorPos) + \"\\n\" + value.slice(cursorPos);\n cursorPos++;\n cursorBlink = true;\n render();\n break;\n\n case \"escape\":\n process.stdout.write(showCursor());\n return null;\n\n case \"backspace\":\n if (cursorPos > 0) {\n value = value.slice(0, cursorPos - 1) + value.slice(cursorPos);\n cursorPos--;\n }\n render();\n break;\n\n case \"delete\":\n if (cursorPos < value.length) {\n value = value.slice(0, cursorPos) + value.slice(cursorPos + 1);\n }\n render();\n break;\n\n case \"left\":\n if (cursorPos > 0) cursorPos--;\n render();\n break;\n\n case \"right\":\n if (cursorPos < value.length) cursorPos++;\n render();\n break;\n\n case \"up\":\n cursorPos = moveCursorVertical(value, cursorPos, contentWidth - 2, -1);\n render();\n break;\n\n case \"down\":\n cursorPos = moveCursorVertical(value, cursorPos, contentWidth - 2, 1);\n render();\n break;\n\n case \"home\":\n cursorPos = moveCursorHome(value, cursorPos, contentWidth - 2);\n render();\n break;\n\n case \"end\":\n cursorPos = moveCursorEnd(value, cursorPos, contentWidth - 2);\n render();\n break;\n\n case \"ctrl-left\":\n cursorPos = moveCursorWordLeft(value, cursorPos);\n render();\n break;\n\n case \"ctrl-right\":\n cursorPos = moveCursorWordRight(value, cursorPos);\n render();\n break;\n\n default:\n if (key.raw.length === 1 && key.raw.charCodeAt(0) >= 32) {\n value = value.slice(0, cursorPos) + key.raw + value.slice(cursorPos);\n cursorPos++;\n cursorBlink = true;\n render();\n }\n break;\n }\n }\n}\n","import { execa } from \"execa\";\nimport { logger } from \"../utils/logger.js\";\nimport { getCurrentBranch } from \"../lib/git.js\";\nimport { checkGhAuth } from \"../utils/validators.js\";\n\nexport async function githubRemoteCommand(): Promise<boolean> {\n const isAuthenticated = await checkGhAuth();\n if (!isAuthenticated) {\n logger.error(\"GitHub CLI is not authenticated. Run: gh auth login\");\n return false;\n }\n\n try {\n // Check if remote origin already exists\n try {\n const { stdout } = await execa(\"git\", [\n \"config\",\n \"--get\",\n \"remote.origin.url\",\n ]);\n if (stdout.trim()) {\n logger.error(\"Remote origin already exists: \" + stdout.trim());\n return false;\n }\n } catch {\n // No remote origin — expected\n }\n\n // Create a GitHub repo using gh CLI (uses current directory name)\n logger.info(\"Creating GitHub repository...\");\n await execa(\"gh\", [\"repo\", \"create\", \"--source=.\", \"--push\", \"--private\"]);\n\n const branch = await getCurrentBranch();\n logger.success(`Repository created and ${branch} pushed to GitHub`);\n return true;\n } catch (error) {\n logger.error(`Failed to create remote: ${error}`);\n return false;\n }\n}\n"],"mappings":"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","names":["writeFileSync","existsSync","join","writeFileSync","join","existsSync","setupLabelsCommand","inquirer","inquirer","chalk","inquirer","execa","chalk","localBranches","choices","inquirer","inquirer","inquirer","execa","inquirer","inquirer","inquirer","readFileSync","writeFileSync","existsSync","mkdirSync","join","join","existsSync","readFileSync","mkdirSync","writeFileSync","version","execa","config","chalk","chalk","version","chalk","chalk","chalk","chalk","chalk","chalk","chalk","chalk","row","chalk","chalk","row","execa","execa","execa","offerCreateBranch"]}
|