@rotorsoft/gent 1.13.3 → 1.13.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +7 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2188,7 +2188,7 @@ import { homedir } from "os";
|
|
|
2188
2188
|
// package.json
|
|
2189
2189
|
var package_default = {
|
|
2190
2190
|
name: "@rotorsoft/gent",
|
|
2191
|
-
version: "1.13.
|
|
2191
|
+
version: "1.13.4",
|
|
2192
2192
|
description: "AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs",
|
|
2193
2193
|
keywords: [
|
|
2194
2194
|
"cli",
|
|
@@ -2756,7 +2756,7 @@ function getAvailableActions(state) {
|
|
|
2756
2756
|
actions.push({ id: "pr", label: "pr", shortcut: "r" });
|
|
2757
2757
|
}
|
|
2758
2758
|
if (state.issue && state.pr?.state !== "merged") {
|
|
2759
|
-
actions.push({ id: "
|
|
2759
|
+
actions.push({ id: "run", label: "run", shortcut: "u" });
|
|
2760
2760
|
}
|
|
2761
2761
|
if (state.pr && state.pr.state === "open") {
|
|
2762
2762
|
if (state.hasUIChanges && state.isPlaywrightAvailable && state.config.video.enabled) {
|
|
@@ -3140,7 +3140,7 @@ async function executeAction(actionId, state) {
|
|
|
3140
3140
|
await promptContinue();
|
|
3141
3141
|
return true;
|
|
3142
3142
|
}
|
|
3143
|
-
case "
|
|
3143
|
+
case "run": {
|
|
3144
3144
|
clearScreen();
|
|
3145
3145
|
const hasCommits = state.commits.length > 0;
|
|
3146
3146
|
const hasFeedback = state.hasActionableFeedback;
|
|
@@ -3153,8 +3153,9 @@ async function executeAction(actionId, state) {
|
|
|
3153
3153
|
msg = "Start AI agent to implement this ticket from scratch?";
|
|
3154
3154
|
}
|
|
3155
3155
|
if (!await confirm(msg)) return true;
|
|
3156
|
-
await
|
|
3157
|
-
|
|
3156
|
+
await handleRun(state);
|
|
3157
|
+
await promptContinue();
|
|
3158
|
+
return true;
|
|
3158
3159
|
}
|
|
3159
3160
|
case "video": {
|
|
3160
3161
|
clearScreen();
|
|
@@ -3284,7 +3285,7 @@ async function generateCommitMessage(diffContent, issueNumber, issueTitle, state
|
|
|
3284
3285
|
return message.trim() || CANCEL;
|
|
3285
3286
|
}
|
|
3286
3287
|
}
|
|
3287
|
-
async function
|
|
3288
|
+
async function handleRun(state) {
|
|
3288
3289
|
if (!state.issue) {
|
|
3289
3290
|
logger.error("No linked issue found");
|
|
3290
3291
|
return;
|
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/commands/pr.ts","../src/lib/playwright.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"],"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 {\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(\"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 } 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 { invokeAI, getProviderDisplayName } 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 logger.bold(\"Creating AI-enhanced ticket...\");\n logger.newline();\n\n const config = loadConfig();\n\n // Determine which provider to use\n const provider = resolveProvider(options, config);\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 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 // Show visual indicator before AI output\n console.log(\n chalk.dim(\n `┌─ Generating ticket with ${providerName}... ──────────────────────────┐`\n )\n );\n logger.newline();\n const result = await invokeAI(\n { prompt, streamOutput: true },\n config,\n options.provider\n );\n aiOutput = result.output;\n logger.newline();\n console.log(\n chalk.dim(\n \"└────────────────────────────────────────────────────────────┘\"\n )\n );\n logger.newline();\n } catch (error) {\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 ${providerName} 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\nexport interface AIProviderOptions {\n prompt: string;\n permissionMode?: string;\n printOutput?: boolean;\n streamOutput?: boolean;\n}\n\nexport interface AIProviderResult {\n output: string;\n provider: AIProvider;\n rateLimited?: boolean;\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\n child.stdout.on(\"data\", (chunk: Buffer) => {\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\n child.stdout.on(\"data\", (chunk: Buffer) => {\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\n child.stdout.on(\"data\", (chunk: Buffer) => {\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 } 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 logger.bold(\"Running AI implementation workflow...\");\n logger.newline();\n\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 logger.info(\n `Starting ${colors.provider(providerName)} implementation session...`\n );\n logger.dim(`${providerName} will implement the feature and create a commit.`);\n logger.dim(\"Review the changes before pushing.\");\n logger.newline();\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 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 inquirer from \"inquirer\";\nimport { logger, colors } from \"../utils/logger.js\";\nimport { withSpinner } 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 { invokeAI, getProviderDisplayName } 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\";\n\nexport interface PrOptions {\n draft?: boolean;\n provider?: AIProvider;\n video?: boolean;\n}\n\nexport async function prCommand(options: PrOptions): Promise<void> {\n logger.bold(\"Creating AI-enhanced pull request...\");\n logger.newline();\n\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 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 // Check we're not on main\n if (await isOnMainBranch()) {\n logger.error(\"Cannot create PR from main/master branch.\");\n process.exit(1);\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 // Check if we need to push\n const hasUnpushed = await getUnpushedCommits();\n if (hasUnpushed) {\n logger.warning(\"Branch has unpushed commits.\");\n const { push } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"push\",\n message: \"Push to remote before creating PR?\",\n default: true,\n },\n ]);\n\n if (push) {\n await withSpinner(\"Pushing branch...\", async () => {\n await pushBranch();\n });\n logger.success(\"Branch pushed\");\n }\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 try {\n logger.info(\n `Generating PR description with ${colors.provider(providerName)}...`\n );\n logger.newline();\n const result = await invokeAI(\n { prompt, streamOutput: true },\n config,\n options.provider\n );\n prBody = result.output;\n logger.newline();\n } catch (error) {\n logger.warning(`${providerName} invocation failed: ${error}`);\n // Fall back to basic description\n prBody = generateFallbackBody(issue, commits);\n }\n\n // Append signature footer\n prBody += `\\n\\n---\\n*Created with ${providerName} 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\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 { 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 inquirer from \"inquirer\";\nimport { logger, colors } from \"../utils/logger.js\";\nimport { withSpinner } 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 logger.bold(\"Applying PR review feedback with AI...\");\n logger.newline();\n\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 logger.info(`Starting ${colors.provider(providerName)} fix session...`);\n logger.dim(\"Review feedback will be appended to the implementation prompt.\");\n logger.newline();\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 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.13.3\",\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 inquirer from \"inquirer\";\nimport { execa } from \"execa\";\nimport { aggregateState, type TuiState } from \"../tui/state.js\";\nimport { getAvailableActions, type TuiAction } from \"../tui/actions.js\";\nimport {\n renderDashboard,\n renderActionPanel,\n clearScreen,\n} from \"../tui/display.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { createSpinner } from \"../utils/spinner.js\";\nimport { createCommand } from \"./create.js\";\nimport { prCommand } from \"./pr.js\";\nimport { listCommand } from \"./list.js\";\nimport {\n buildVideoPrompt,\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 type { AIProvider } from \"../types/index.js\";\n\nconst CANCEL = Symbol(\"cancel\");\n\nasync function confirm(message: string): Promise<boolean> {\n const { ok } = await inquirer.prompt<{ ok: boolean }>([\n {\n type: \"confirm\",\n name: \"ok\",\n message,\n default: true,\n },\n ]);\n return ok;\n}\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\nasync function executeAction(\n actionId: string,\n state: TuiState\n): Promise<boolean> {\n switch (actionId) {\n case \"quit\":\n return false;\n\n case \"list\": {\n clearScreen();\n try {\n await listCommand({});\n } catch (error) {\n logger.error(`List failed: ${error}`);\n }\n await promptContinue();\n return true;\n }\n\n case \"create\": {\n clearScreen();\n const { description } = await inquirer.prompt<{ description: string }>([\n {\n type: \"input\",\n name: \"description\",\n message: \"Describe the ticket (empty to cancel):\",\n },\n ]);\n if (!description.trim()) {\n logger.info(\"Cancelled\");\n return true;\n }\n try {\n await createCommand(description, {});\n } catch (error) {\n logger.error(`Create failed: ${error}`);\n }\n await promptContinue();\n return true;\n }\n\n case \"commit\":\n clearScreen();\n await handleCommit(state);\n await promptContinue();\n return true;\n\n case \"push\":\n clearScreen();\n await handlePush();\n await promptContinue();\n return true;\n\n case \"pr\": {\n clearScreen();\n if (!(await confirm(\"Create a pull request?\"))) return true;\n await prCommand({});\n await promptContinue();\n return true;\n }\n\n case \"implement\": {\n clearScreen();\n const hasCommits = state.commits.length > 0;\n const hasFeedback = state.hasActionableFeedback;\n let msg: string;\n if (hasFeedback && hasCommits) {\n msg = \"Start AI agent to address review feedback?\";\n } else if (hasCommits) {\n msg =\n \"Start AI agent to continue implementation from existing commits?\";\n } else {\n msg = \"Start AI agent to implement this ticket from scratch?\";\n }\n if (!(await confirm(msg))) return true;\n await handleImplement(state);\n return false;\n }\n\n case \"video\": {\n clearScreen();\n if (!(await confirm(\"Record video of UI changes?\"))) return true;\n await handleVideoCapture(state);\n await promptContinue();\n return true;\n }\n\n case \"switch-provider\":\n clearScreen();\n await handleSwitchProvider(state);\n return true;\n\n case \"checkout-main\": {\n clearScreen();\n if (!(await confirm(\"Switch to main branch?\"))) return true;\n await handleCheckoutMain();\n return true;\n }\n\n default:\n return true;\n }\n}\n\nasync function handleCommit(state: TuiState): Promise<void> {\n try {\n const { stdout: status } = await execa(\"git\", [\"status\", \"--short\"]);\n if (!status.trim()) {\n logger.info(\"No changes to commit\");\n return;\n }\n\n logger.info(\"Changes:\");\n console.log(status);\n console.log();\n\n // Stage all changes first so we can get a clean cached diff\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 const { mode } = await inquirer.prompt<{ mode: \"ai\" | \"manual\" }>([\n {\n type: \"list\",\n name: \"mode\",\n message: \"How would you like to provide the commit message?\",\n choices: [\n { name: `Generate with ${providerName}`, value: \"ai\" },\n { name: \"Enter manually\", value: \"manual\" },\n ],\n },\n ]);\n\n let message: string | typeof CANCEL;\n\n if (mode === \"manual\") {\n const { manualInput } = await inquirer.prompt<{ manualInput: string }>([\n {\n type: \"input\",\n name: \"manualInput\",\n message: \"Commit message (empty to cancel):\",\n },\n ]);\n message = manualInput.trim() || CANCEL;\n } else {\n logger.info(`Generating commit message with ${providerName}...`);\n message = await generateCommitMessage(\n diffContent,\n issueNumber,\n issueTitle,\n state\n );\n }\n if (message === CANCEL) {\n await execa(\"git\", [\"reset\", \"HEAD\"]);\n logger.info(\"Cancelled\");\n return;\n }\n\n console.log();\n logger.info(`Message: ${message}`);\n console.log();\n\n if (!(await confirm(\"Commit with this message?\"))) {\n await execa(\"git\", [\"reset\", \"HEAD\"]);\n logger.info(\"Commit cancelled\");\n return;\n }\n\n const providerEmail = getProviderEmail(provider);\n const fullMessage = `${message}\\n\\nCo-Authored-By: ${providerName} <${providerEmail}>`;\n\n const spinner = createSpinner(\"Committing...\");\n spinner.start();\n await execa(\"git\", [\"commit\", \"-m\", fullMessage]);\n spinner.succeed(\"Changes committed\");\n } catch (error) {\n logger.error(`Commit failed: ${error}`);\n }\n}\n\nasync function generateCommitMessage(\n diffContent: string,\n issueNumber: number | null,\n issueTitle: string | null,\n state: TuiState\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: true }, 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 logger.warning(\"AI commit message generation failed\");\n console.log();\n const { message } = await inquirer.prompt<{ message: string }>([\n {\n type: \"input\",\n name: \"message\",\n message: \"Commit message (empty to cancel):\",\n },\n ]);\n return message.trim() || CANCEL;\n }\n}\n\nasync function handleImplement(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 await invokeAIInteractive(prompt, state.config);\n } catch (error) {\n logger.error(`${providerName} session failed: ${error}`);\n }\n}\n\nasync function handlePush(): Promise<void> {\n try {\n const { stdout: branch } = await execa(\"git\", [\"branch\", \"--show-current\"]);\n if (!(await confirm(`Push ${branch.trim()} to remote?`))) return;\n\n const spinner = createSpinner(\"Pushing...\");\n spinner.start();\n await execa(\"git\", [\"push\", \"-u\", \"origin\", branch.trim()]);\n spinner.succeed(\"Pushed to remote\");\n } catch (error) {\n logger.error(`Push failed: ${error}`);\n }\n}\n\nconst PROVIDERS: AIProvider[] = [\"claude\", \"gemini\", \"codex\"];\n\nasync function handleSwitchProvider(state: TuiState): Promise<void> {\n const current = state.config.ai.provider;\n const { provider } = await inquirer.prompt<{ provider: AIProvider }>([\n {\n type: \"list\",\n name: \"provider\",\n message: \"Select AI provider:\",\n choices: PROVIDERS.map((p) => ({\n name:\n p.charAt(0).toUpperCase() +\n p.slice(1) +\n (p === current ? \" (current)\" : \"\"),\n value: p,\n })),\n default: current,\n },\n ]);\n\n if (provider === current) return;\n\n setRuntimeProvider(provider);\n logger.success(`Provider switched to ${provider} (session only)`);\n}\n\nasync function handleCheckoutMain(): Promise<void> {\n try {\n const spinner = createSpinner(\"Switching to main...\");\n spinner.start();\n await execa(\"git\", [\"checkout\", \"main\"]);\n await execa(\"git\", [\"pull\"]);\n spinner.succeed(\"Switched to main\");\n } catch (error) {\n logger.error(`Checkout failed: ${error}`);\n }\n}\n\nasync function handleVideoCapture(state: TuiState): Promise<void> {\n if (!state.issue) {\n logger.error(\"No linked issue found\");\n return;\n }\n\n const providerName = getProviderDisplayName(state.config.ai.provider);\n\n clearScreen();\n renderActionPanel(\"Video Capture\", [\n `Recording: #${state.issue.number} ${state.issue.title}`,\n `Provider: ${providerName}`,\n ]);\n console.log();\n\n try {\n const agentInstructions = loadAgentInstructions();\n const videoPrompt = buildVideoPrompt(\n state.issue.number,\n state.issue.title,\n state.config.video,\n agentInstructions\n );\n await invokeAIInteractive(videoPrompt, state.config);\n logger.success(\"Video capture completed\");\n } catch (error) {\n logger.error(`Video capture failed: ${error}`);\n }\n}\n\nasync function promptContinue(): Promise<void> {\n console.log();\n await inquirer.prompt([\n {\n type: \"input\",\n name: \"continue\",\n message: \"Press Enter to continue...\",\n },\n ]);\n}\n\nexport async function tuiCommand(): Promise<void> {\n let running = true;\n let lastActions: TuiAction[] = [];\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 };\n\n while (running) {\n // Show dashboard with refreshing indicator while loading new state\n clearScreen();\n renderDashboard(lastState, lastActions, undefined, true);\n\n const state = await aggregateState();\n\n const actions = getAvailableActions(state);\n\n // Save for next refresh cycle\n lastState = state;\n lastActions = actions;\n\n clearScreen();\n\n // Contextual hint\n let hint: string | undefined;\n if (state.isOnMain) {\n hint = \"Select an action to get started\";\n } else if (state.hasUncommittedChanges && !state.pr) {\n hint = \"Commit your changes before creating a PR\";\n } else if (state.hasActionableFeedback) {\n hint = \"Review feedback needs attention\";\n }\n\n renderDashboard(state, actions, hint);\n\n // Wait for a valid keypress\n const validKeys = actions.map((a) => a.shortcut);\n const key = await waitForKey(validKeys);\n\n // Find the matching action\n const action = actions.find((a) => a.shortcut === key);\n if (action) {\n running = await executeAction(action.id, state);\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} 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\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 };\n }\n\n const config = loadConfig();\n const workflowLabels = getWorkflowLabels(config);\n\n // Gather prerequisites and git state in parallel\n const [\n isGhAuthenticated,\n isAIProviderAvailable,\n branch,\n isOnMain,\n uncommitted,\n baseBranch,\n ] = await Promise.all([\n checkGhAuth(),\n checkAIProvider(config.ai.provider),\n getCurrentBranch(),\n isOnMainBranch(),\n hasUncommittedChanges(),\n getDefaultBranch(),\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 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 isPlaywrightAvailable(),\n ]);\n\n issue = issueResult;\n pr = prResult;\n uiChanges = hasUIChanges(changedFiles);\n playwrightAvailable = playwrightResult;\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 };\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 // On main branch\n if (state.isOnMain) {\n actions.push({ id: \"create\", label: \"new\", shortcut: \"n\" });\n actions.push({ id: \"list\", label: \"list\", shortcut: \"l\" });\n actions.push({ id: \"switch-provider\", label: \"ai\", shortcut: \"a\" });\n actions.push({ id: \"quit\", label: \"quit\", shortcut: \"q\" });\n return actions;\n }\n\n // On feature branch - context-aware\n\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: \"p\" });\n }\n\n if (!state.pr && state.commits.length > 0) {\n actions.push({ id: \"pr\", label: \"pr\", shortcut: \"r\" });\n }\n\n if (state.issue && state.pr?.state !== \"merged\") {\n actions.push({ id: \"implement\", label: \"implement\", shortcut: \"i\" });\n }\n\n if (state.pr && state.pr.state === \"open\") {\n if (\n state.hasUIChanges &&\n state.isPlaywrightAvailable &&\n state.config.video.enabled\n ) {\n actions.push({ id: \"video\", label: \"video\", shortcut: \"v\" });\n }\n }\n\n if (\n state.pr &&\n (state.pr.state === \"merged\" || state.pr.state === \"closed\")\n ) {\n actions.push({ id: \"checkout-main\", label: \"main\", shortcut: \"m\" });\n }\n\n actions.push({ id: \"list\", label: \"list\", shortcut: \"l\" });\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 } 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\nconst stripAnsi = (str: string) => str.replace(/\\x1b\\[[0-9;]*m/g, \"\");\nconst visibleLen = (str: string) => stripAnsi(str).length;\n\nfunction 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 pad = Math.max(0, inner - visibleLen(text));\n return chalk.dim(\"│\") + \" \" + text + \" \".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 key = a.shortcut;\n const idx = a.label.indexOf(key);\n if (idx >= 0) {\n // Highlight the shortcut letter within the label\n const before = a.label.slice(0, idx);\n const after = a.label.slice(idx + key.length);\n return chalk.dim(before) + color(key) + chalk.dim(after);\n }\n // Shortcut not in label — show separately\n return color(key) + \" \" + 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// ── Settings ────────────────────────────────────────────────────\n\nfunction renderSettings(state: TuiState, w: number): 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 const videoTag = state.config.video.enabled\n ? chalk.green(\"on\")\n : chalk.dim(\"off\");\n\n console.log(row(chalk.dim(\"Provider: \") + provTag, w));\n console.log(row(chalk.dim(\"GitHub: \") + ghTag, w));\n console.log(row(chalk.dim(\"Video: \") + videoTag, w));\n}\n\n// ── Main render ─────────────────────────────────────────────────\n\nexport function renderDashboard(\n state: TuiState,\n actions: TuiAction[],\n hint?: string,\n refreshing?: boolean\n): void {\n const w = termWidth();\n const descMax = w - 8;\n const version = getVersion();\n\n const titleLabel = `gent v${version}`;\n console.log(topRow(titleLabel, w));\n renderSettings(state, w);\n\n // ── Error states ──────────────────────────────────────────────\n if (!state.isGitRepo) {\n console.log(row(chalk.red(\"Not a git repository\"), w));\n console.log(\n row(chalk.dim(\"Run gent init in a git repo to get started\"), w)\n );\n console.log(botRow(w));\n return;\n }\n if (!state.isGhAuthenticated) {\n console.log(row(chalk.red(\"GitHub CLI not authenticated\"), w));\n console.log(row(chalk.dim(\"Run: gh auth login\"), w));\n console.log(botRow(w));\n return;\n }\n\n // ── On main – nothing active ─────────────────────────────────\n if (state.isOnMain) {\n console.log(\n row(\n chalk.magenta(state.branch) + chalk.dim(\" · ready to start new work\"),\n w\n )\n );\n if (state.hasUncommittedChanges) {\n console.log(row(chalk.yellow(\"● uncommitted changes\"), w));\n }\n if (hint) {\n console.log(midRow(\"Hint\", w));\n console.log(row(chalk.yellow(hint), w));\n }\n console.log(divRow(w));\n if (refreshing) {\n console.log(row(chalk.yellow(\"Refreshing…\"), w));\n } else {\n for (const line of formatCommandBar(actions, w)) {\n console.log(row(line, w));\n }\n }\n console.log(botRow(w));\n console.log();\n return;\n }\n\n // ── Feature branch dashboard ──────────────────────────────────\n const section = (title: string) => {\n console.log(midRow(title, w));\n };\n\n // Ticket\n section(\"Ticket\");\n if (state.issue) {\n console.log(\n row(\n chalk.cyan(`#${state.issue.number}`) +\n \" \" +\n chalk.bold(truncate(state.issue.title, descMax - 6)),\n w\n )\n );\n const desc = extractDescription(state.issue.body, descMax);\n if (desc) console.log(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) console.log(row(tags.join(\" \"), w));\n } else {\n console.log(row(chalk.dim(\"No linked issue\"), w));\n }\n\n // Branch\n section(\"Branch\");\n console.log(row(chalk.magenta(state.branch), w));\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) console.log(row(bits.join(chalk.dim(\" · \")), w));\n\n // Pull Request\n section(\"Pull Request\");\n if (state.pr) {\n const titleText = state.pr.title\n ? \" \" + truncate(state.pr.title, descMax - 12)\n : \"\";\n console.log(row(chalk.cyan(`#${state.pr.number}`) + titleText, w));\n console.log(\n row(\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 console.log(\n row(\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 console.log(\n row(\n chalk.cyan(\"UI changes detected\") +\n chalk.dim(\" · video capture available\"),\n w\n )\n );\n }\n console.log(row(chalk.dim(state.pr.url), w));\n } else {\n console.log(row(chalk.dim(\"No PR created\"), w));\n }\n\n // Commits\n section(\"Commits\");\n if (state.commits.length > 0) {\n const max = 6;\n for (const c of state.commits.slice(0, max)) {\n console.log(row(c.substring(0, w - 5), w));\n }\n if (state.commits.length > max) {\n console.log(\n row(chalk.dim(`… and ${state.commits.length - max} more`), w)\n );\n }\n } else {\n console.log(row(chalk.dim(\"No commits\"), w));\n }\n\n // Hint\n if (hint) {\n section(\"Hint\");\n console.log(row(chalk.yellow(hint), w));\n }\n\n // Command bar (inside the frame)\n console.log(divRow(w));\n if (refreshing) {\n console.log(row(chalk.yellow(\"Refreshing…\"), w));\n } else {\n for (const line of formatCommandBar(actions, w)) {\n console.log(row(line, w));\n }\n }\n console.log(botRow(w));\n}\n\nexport function clearScreen(): void {\n process.stdout.write(\"\\x1B[2J\\x1B[0f\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAe;;;ACAxB,SAAS,iBAAAA,gBAAe,cAAAC,mBAAkB;AAC1C,SAAS,QAAAC,aAAY;AACrB,OAAO,cAAc;;;ACFrB,SAAS,YAAY,cAAc,eAAe,iBAAiB;AACnE,SAAS,MAAM,eAAe;AAGvB,SAAS,gBACd,QACA,MAAc,QAAQ,IAAI,GAClB;AACR,SAAO,KAAK,KAAK,OAAO,SAAS,IAAI;AACvC;AAEO,SAAS,eACd,QACA,MAAc,QAAQ,IAAI,GACjB;AACT,SAAO,WAAW,gBAAgB,QAAQ,GAAG,CAAC;AAChD;AAEO,SAAS,aACd,QACA,MAAc,QAAQ,IAAI,GAClB;AACR,QAAM,OAAO,gBAAgB,QAAQ,GAAG;AACxC,MAAI,CAAC,WAAW,IAAI,GAAG;AACrB,WAAO;AAAA,EACT;AACA,SAAO,aAAa,MAAM,OAAO;AACnC;AAgGO,SAAS,mBACd,QACA,MAAc,QAAQ,IAAI,GACpB;AACN,QAAM,OAAO,gBAAgB,QAAQ,GAAG;AAExC,MAAI,WAAW,IAAI,GAAG;AACpB;AAAA,EACF;AAEA,QAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQvB,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,CAAC,WAAW,GAAG,GAAG;AACpB,cAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,EACpC;AAEA,gBAAc,MAAM,gBAAgB,OAAO;AAC7C;;;ADtIA,IAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwDzB,eAAsB,YAAY,SAA6C;AAC7E,SAAO,KAAK,+BAA+B;AAC3C,SAAO,QAAQ;AAGf,QAAM,YAAY,MAAM,aAAa;AACrC,MAAI,CAAC,WAAW;AACd,WAAO,MAAM,oDAAoD;AACjE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,MAAM,QAAQ,IAAI;AAGxB,MAAI,aAAa,GAAG,KAAK,CAAC,QAAQ,OAAO;AACvC,UAAM,EAAE,UAAU,IAAI,MAAM,SAAS,OAAO;AAAA,MAC1C;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AAED,QAAI,CAAC,WAAW;AACd,aAAO,KAAK,2BAA2B;AACvC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,EAAE,SAAS,IAAI,MAAM,SAAS,OAAO;AAAA,IACzC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS,CAAC,UAAU,UAAU,OAAO;AAAA,MACrC,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAGD,QAAM,aAAa,cAAc,GAAG;AACpC,EAAAC,eAAc,YAAY,sBAAsB,QAAQ,GAAG,OAAO;AAClE,SAAO,QAAQ,WAAW,OAAO,KAAK,WAAW,CAAC,EAAE;AAGpD,QAAM,YAAYC,MAAK,KAAK,UAAU;AACtC,MAAI,CAACC,YAAW,SAAS,KAAK,QAAQ,OAAO;AAC3C,IAAAF,eAAc,WAAW,kBAAkB,OAAO;AAClD,WAAO,QAAQ,WAAW,OAAO,KAAK,UAAU,CAAC,EAAE;AAAA,EACrD,OAAO;AACL,WAAO,KAAK,GAAG,OAAO,KAAK,UAAU,CAAC,2BAA2B;AAAA,EACnE;AAGA,QAAM,SAAS,WAAW,GAAG;AAC7B,qBAAmB,QAAQ,GAAG;AAC9B,SAAO,QAAQ,WAAW,OAAO,KAAK,OAAO,SAAS,IAAI,CAAC,EAAE;AAE7D,SAAO,QAAQ;AACf,SAAO;AAAA,IACL;AAAA,IACA;AAAA,UACM,OAAO,KAAK,UAAU,CAAC;AAAA,UACvB,OAAO,KAAK,WAAW,CAAC;AAAA,SACzB,OAAO,QAAQ,mBAAmB,CAAC;AAAA,SACnC,OAAO,QAAQ,2BAA2B,CAAC;AAAA,EAClD;AAGA,QAAM,EAAE,YAAY,IAAI,MAAM,SAAS,OAAO;AAAA,IAC5C;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,MAAI,aAAa;AACf,UAAM,EAAE,oBAAAG,oBAAmB,IAAI,MAAM,OAAO,4BAAmB;AAC/D,UAAMA,oBAAmB;AAAA,EAC3B;AACF;;;AExJA,OAAOC,eAAc;AACrB,OAAO,WAAW;;;ACDlB,SAAS,aAAa;AACtB,SAAS,aAAiC;AAiB1C,eAAe,eACb,UACA,SACiB;AACjB,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO,qBAAqB,OAAO;AAAA,IACrC,KAAK;AACH,aAAO,qBAAqB,OAAO;AAAA,IACrC,KAAK;AACH,aAAO,oBAAoB,OAAO;AAAA,EACtC;AACF;AAMA,eAAsB,SACpB,SACA,QACA,kBAC2B;AAC3B,QAAM,WAAW,oBAAoB,OAAO,GAAG;AAE/C,MAAI;AACF,UAAM,SAAS,MAAM,eAAe,UAAU,OAAO;AAErD,WAAO,EAAE,QAAQ,SAAS;AAAA,EAC5B,SAAS,OAAO;AAEd,QAAI,iBAAiB,OAAO,QAAQ,GAAG;AAErC,UACE,OAAO,GAAG,iBACV,OAAO,GAAG,qBACV,CAAC,kBACD;AACA,cAAM,WAAW,OAAO,GAAG;AAC3B,eAAO;AAAA,UACL,yBAAyB,uBAAuB,QAAQ,CAAC,kBAAkB,uBAAuB,QAAQ,CAAC;AAAA,QAC7G;AAEA,cAAM,SAAS,MAAM,eAAe,UAAU,OAAO;AAErD,eAAO,EAAE,QAAQ,UAAU,SAAS;AAAA,MACtC;AAGA,YAAM,MAAM;AACZ,UAAI,UAAU,mBAAmB,uBAAuB,QAAQ,CAAC;AACjE,MAAC,IAAyC,cAAc;AACxD,YAAM;AAAA,IACR;AAEA,UAAM;AAAA,EACR;AACF;AAMA,eAAsB,oBACpB,QACA,QACA,kBAC0D;AAC1D,QAAM,WAAW,oBAAoB,OAAO,GAAG;AAE/C,UAAQ,UAAU;AAAA,IAChB,KAAK,UAAU;AACb,YAAM,OAAO,CAAC,qBAAqB,OAAO,OAAO,iBAAiB,MAAM;AACxE,aAAO;AAAA,QACL,QAAQ,MAAM,UAAU,MAAM,EAAE,OAAO,UAAU,CAAC;AAAA,QAClD;AAAA,MACF;AAAA,IACF;AAAA,IACA,KAAK,UAAU;AAGb,aAAO;AAAA,QACL,QAAQ,MAAM,UAAU,CAAC,MAAM,MAAM,GAAG,EAAE,OAAO,UAAU,CAAC;AAAA,QAC5D;AAAA,MACF;AAAA,IACF;AAAA,IACA,KAAK,SAAS;AAEZ,YAAM,OAAO,SAAS,CAAC,MAAM,IAAI,CAAC;AAClC,aAAO;AAAA,QACL,QAAQ,MAAM,SAAS,MAAM,EAAE,OAAO,UAAU,CAAC;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,uBAAuB,UAA8B;AACnE,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAKO,SAAS,iBAAiB,UAA8B;AAC7D,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAoBA,SAAS,iBAAiB,OAAgB,UAA+B;AACvE,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAGhD,OACG,aAAa,YAAY,aAAa,YACvC,cAAc,SACd,MAAM,aAAa,GACnB;AACA,WAAO;AAAA,EACT;AAIA,MAAI,aAAa,SAAS,OAAO,MAAM,YAAY,UAAU;AAC3D,UAAM,MAAM,MAAM,QAAQ,YAAY;AACtC,QACE,IAAI,SAAS,YAAY,KACzB,IAAI,SAAS,gBAAgB,KAC7B,IAAI,SAAS,mBAAmB,GAChC;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAKA,eAAe,qBACb,SACiB;AACjB,QAAM,OAAO,CAAC,SAAS;AAEvB,MAAI,QAAQ,gBAAgB;AAC1B,SAAK,KAAK,qBAAqB,QAAQ,cAAc;AAAA,EACvD;AAEA,OAAK,KAAK,QAAQ,MAAM;AAExB,MAAI,QAAQ,aAAa;AAEvB,UAAM,aAAa,MAAM,UAAU,MAAM;AAAA,MACvC,OAAO;AAAA,IACT,CAAC;AACD,UAAM;AACN,WAAO;AAAA,EACT,WAAW,QAAQ,cAAc;AAE/B,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,QAAQ,MAAM,UAAU,MAAM;AAAA,QAClC,OAAO,CAAC,WAAW,QAAQ,MAAM;AAAA,MACnC,CAAC;AAED,UAAI,SAAS;AAEb,YAAM,OAAO,GAAG,QAAQ,CAAC,UAAkB;AACzC,cAAM,OAAO,MAAM,SAAS;AAC5B,kBAAU;AACV,gBAAQ,OAAO,MAAM,IAAI;AAAA,MAC3B,CAAC;AAED,YAAM,OAAO,GAAG,QAAQ,CAAC,UAAkB;AACzC,gBAAQ,OAAO,MAAM,KAAK;AAAA,MAC5B,CAAC;AAED,YAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,YAAI,SAAS,GAAG;AACd,kBAAQ,MAAM;AAAA,QAChB,OAAO;AACL,gBAAM,QAAQ,IAAI,MAAM,2BAA2B,IAAI,EAAE;AACzD,UAAC,MAAuC,WAAW,QAAQ;AAC3D,iBAAO,KAAK;AAAA,QACd;AAAA,MACF,CAAC;AAED,YAAM,GAAG,SAAS,MAAM;AAAA,IAC1B,CAAC;AAAA,EACH,OAAO;AACL,UAAM,EAAE,OAAO,IAAI,MAAM,MAAM,UAAU,IAAI;AAC7C,WAAO;AAAA,EACT;AACF;AAKA,eAAe,qBACb,SACiB;AAEjB,QAAM,OAAiB,CAAC;AAGxB,OAAK,KAAK,QAAQ,MAAM;AAExB,MAAI,QAAQ,aAAa;AACvB,UAAM,aAAa,MAAM,UAAU,MAAM;AAAA,MACvC,OAAO;AAAA,IACT,CAAC;AACD,UAAM;AACN,WAAO;AAAA,EACT,WAAW,QAAQ,cAAc;AAC/B,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,QAAQ,MAAM,UAAU,MAAM;AAAA,QAClC,OAAO,CAAC,WAAW,QAAQ,MAAM;AAAA,MACnC,CAAC;AAED,UAAI,SAAS;AAEb,YAAM,OAAO,GAAG,QAAQ,CAAC,UAAkB;AACzC,cAAM,OAAO,MAAM,SAAS;AAC5B,kBAAU;AACV,gBAAQ,OAAO,MAAM,IAAI;AAAA,MAC3B,CAAC;AAED,YAAM,OAAO,GAAG,QAAQ,CAAC,UAAkB;AACzC,gBAAQ,OAAO,MAAM,KAAK;AAAA,MAC5B,CAAC;AAED,YAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,YAAI,SAAS,GAAG;AACd,kBAAQ,MAAM;AAAA,QAChB,OAAO;AACL,gBAAM,QAAQ,IAAI,MAAM,2BAA2B,IAAI,EAAE;AACzD,UAAC,MAAuC,WAAW,QAAQ;AAC3D,iBAAO,KAAK;AAAA,QACd;AAAA,MACF,CAAC;AAED,YAAM,GAAG,SAAS,MAAM;AAAA,IAC1B,CAAC;AAAA,EACH,OAAO;AACL,UAAM,EAAE,OAAO,IAAI,MAAM,MAAM,UAAU,IAAI;AAC7C,WAAO;AAAA,EACT;AACF;AAKA,eAAe,oBACb,SACiB;AAEjB,QAAM,OAAO,CAAC,QAAQ,QAAQ,MAAM;AAEpC,MAAI,QAAQ,aAAa;AACvB,UAAM,aAAa,MAAM,SAAS,MAAM;AAAA,MACtC,OAAO;AAAA,IACT,CAAC;AACD,UAAM;AACN,WAAO;AAAA,EACT,WAAW,QAAQ,cAAc;AAC/B,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,QAAQ,MAAM,SAAS,MAAM;AAAA,QACjC,OAAO,CAAC,WAAW,QAAQ,MAAM;AAAA,MACnC,CAAC;AAED,UAAI,SAAS;AAEb,YAAM,OAAO,GAAG,QAAQ,CAAC,UAAkB;AACzC,cAAM,OAAO,MAAM,SAAS;AAC5B,kBAAU;AACV,gBAAQ,OAAO,MAAM,IAAI;AAAA,MAC3B,CAAC;AAED,YAAM,OAAO,GAAG,QAAQ,CAAC,UAAkB;AACzC,gBAAQ,OAAO,MAAM,KAAK;AAAA,MAC5B,CAAC;AAED,YAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,YAAI,SAAS,GAAG;AACd,kBAAQ,MAAM;AAAA,QAChB,OAAO;AACL,gBAAM,QAAQ,IAAI,MAAM,0BAA0B,IAAI,EAAE;AACxD,UAAC,MAAuC,WAAW,QAAQ;AAC3D,iBAAO,KAAK;AAAA,QACd;AAAA,MACF,CAAC;AAED,YAAM,GAAG,SAAS,MAAM;AAAA,IAC1B,CAAC;AAAA,EACH,OAAO;AACL,UAAM,EAAE,OAAO,IAAI,MAAM,MAAM,SAAS,IAAI;AAC5C,WAAO;AAAA,EACT;AACF;;;AC3VO,SAAS,kBACd,aACA,mBACA,kBAAiC,MACzB;AACR,QAAM,aAAa;AAAA;AAAA,gBAEL,WAAW;AAAA;AAAA,EAEzB,oBAAoB;AAAA,EAAmC,iBAAiB;AAAA;AAAA,IAAS,EAAE,GAAG,kBAAkB;AAAA,EAA8B,eAAe;AAAA;AAAA,IAAS,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0ChK,SAAO;AACT;AAEO,SAAS,0BACd,OACA,mBACA,iBACA,QACA,eAA8B,MACtB;AACR,QAAM,eAAe,uBAAuB,OAAO,GAAG,QAAQ;AAC9D,QAAM,gBAAgB,iBAAiB,OAAO,GAAG,QAAQ;AAEzD,SAAO,iBAAiB,MAAM,MAAM,KAAK,MAAM,KAAK;AAAA;AAAA,EAEpD,MAAM,IAAI;AAAA;AAAA,EAEV,oBAAoB;AAAA,EAAqC,iBAAiB;AAAA;AAAA,IAAS,EAAE;AAAA,EACrF,kBAAkB;AAAA,EAAyB,eAAe;AAAA;AAAA,IAAS,EAAE;AAAA,EACrE,eAAe,GAAG,YAAY;AAAA;AAAA,IAAS,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOzC,OAAO,WAAW,IAAI,CAAC,QAAQ,QAAQ,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,wCAGlB,MAAM,MAAM;AAAA,iCACnB,YAAY,KAAK,aAAa;AAAA,cACjD,OAAO,SAAS,IAAI;AAAA,sBAEf,MAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAU/B;AAEO,SAAS,cACd,OACA,SACA,aACQ;AACR,SAAO;AAAA;AAAA,EAEP,QAAQ;AAAA,GAAsB,MAAM,MAAM,KAAK,MAAM,KAAK;AAAA;AAAA,EAAO,MAAM,IAAI;AAAA;AAAA,IAAS,EAAE;AAAA;AAAA;AAAA,EAGtF,QAAQ,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,EAGvC,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUX,QAAQ,WAAW,MAAM,MAAM,KAAK,EAAE;AAAA;AAAA;AAGxC;AAEO,SAAS,yBACd,MACA,aACA,YACQ;AACR,QAAM,eAAe,cACjB;AAAA,kBAAqB,WAAW,GAAG,aAAa,MAAM,UAAU,KAAK,EAAE;AAAA,IACvE;AAEJ,SAAO;AAAA,EACP,YAAY;AAAA;AAAA,EAEZ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQN;AAEO,SAAS,gBACd,QACuE;AACvE,QAAM,YAAY,OAAO;AAAA,IACvB;AAAA,EACF;AAEA,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,MAAM,UAAU,CAAC;AAAA,IACjB,UAAU,UAAU,CAAC;AAAA,IACrB,MAAM,UAAU,CAAC;AAAA,IACjB,MAAM,UAAU,CAAC;AAAA,EACnB;AACF;AAEO,SAAS,iBAAiB,QAAwB;AAEvD,MAAI,OAAO,OACR,QAAQ,uDAAuD,EAAE,EACjE,KAAK;AAGR,SAAO,KAAK,QAAQ,mBAAmB,EAAE;AAGzC,QAAM,mBAAmB,KAAK,QAAQ,gBAAgB;AACtD,MAAI,mBAAmB,GAAG;AACxB,WAAO,KAAK,UAAU,gBAAgB;AAAA,EACxC;AAEA,SAAO;AACT;AAMO,SAAS,aAAa,QAA+B;AAC1D,QAAM,QAAQ,OAAO,MAAM,kBAAkB;AAC7C,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,MAAM,CAAC,EAAE,KAAK;AAG1B,MACG,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,KAC3C,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,GAC5C;AACA,YAAQ,MAAM,MAAM,GAAG,EAAE;AAAA,EAC3B;AAGA,MAAI,MAAM,SAAS,GAAG,KAAK,MAAM,SAAS,GAAG,GAAG;AAC9C,WAAO;AAAA,EACT;AAGA,MAAI,MAAM,SAAS,KAAK,MAAM,SAAS,KAAK;AAC1C,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAMO,SAAS,sBAAsB,aAA6B;AACjE,QAAM,YAAY;AAClB,MAAI,YAAY,UAAU,WAAW;AACnC,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,YAAY,MAAM,GAAG,SAAS;AAChD,QAAM,YAAY,UAAU,YAAY,GAAG;AAC3C,MAAI,YAAY,YAAY,KAAK;AAC/B,WAAO,UAAU,MAAM,GAAG,SAAS;AAAA,EACrC;AACA,SAAO;AACT;AAMO,SAAS,iBACd,aACA,YACA,aACA,mBACQ;AACR,SAAO,4FAA4F,WAAW,KAAK,UAAU;AAAA;AAAA,EAE7H,oBAAoB;AAAA,EAAqC,iBAAiB;AAAA;AAAA,IAAS,EAAE;AAAA;AAAA;AAAA;AAAA,4BAI3D,YAAY,YAAY;AAAA;AAAA;AAAA,gBAGpC,YAAY,KAAK,IAAI,YAAY,MAAM;AAAA;AAAA,oBAEnC,YAAY,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwB5C;;;AFvPA,eAAsB,cACpB,aACA,SACe;AACf,SAAO,KAAK,gCAAgC;AAC5C,SAAO,QAAQ;AAEf,QAAM,SAAS,WAAW;AAG1B,QAAM,WAAW,gBAAgB,SAAS,MAAM;AAChD,QAAM,eAAe,uBAAuB,QAAQ;AAGpD,QAAM,CAAC,QAAQ,IAAI,IAAI,MAAM,QAAQ,IAAI;AAAA,IACvC,YAAY;AAAA,IACZ,gBAAgB,QAAQ;AAAA,EAC1B,CAAC;AAED,MAAI,CAAC,QAAQ;AACX,WAAO,MAAM,2DAA2D;AACxE;AAAA,EACF;AAEA,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,MACL,GAAG,YAAY,kCAAkC,QAAQ;AAAA,IAC3D;AACA;AAAA,EACF;AAEA,QAAM,oBAAoB,sBAAsB;AAGhD,MAAI;AACJ,MAAI,kBAAiC;AAErC,SAAO,MAAM;AAEX,UAAM,SAAS;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI;AAEF,cAAQ;AAAA,QACN,MAAM;AAAA,UACJ,uCAA6B,YAAY;AAAA,QAC3C;AAAA,MACF;AACA,aAAO,QAAQ;AACf,YAAM,SAAS,MAAM;AAAA,QACnB,EAAE,QAAQ,cAAc,KAAK;AAAA,QAC7B;AAAA,QACA,QAAQ;AAAA,MACV;AACA,iBAAW,OAAO;AAClB,aAAO,QAAQ;AACf,cAAQ;AAAA,QACN,MAAM;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AACA,aAAO,QAAQ;AAAA,IACjB,SAAS,OAAO;AACd,aAAO,MAAM,GAAG,YAAY,uBAAuB,KAAK,EAAE;AAC1D;AAAA,IACF;AAGA,UAAM,OAAO,gBAAgB,QAAQ;AACrC,QAAI,CAAC,MAAM;AACT,aAAO;AAAA,QACL;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAwB,QAAQ;AAAA,MACpC,MAAM;AAAA,MACN,UAAU;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAGA,UAAM,YACJ,iBAAiB,QAAQ,IACzB;AAAA;AAAA;AAAA,gBAA0B,YAAY;AAGxC,QAAI;AACJ,QAAI,QAAQ,OAAO;AACjB,cAAQ,QAAQ;AAAA,IAClB,OAAO;AACL,YAAM,UAAU,aAAa,QAAQ;AACrC,UAAI,SAAS;AACX,gBAAQ;AAAA,MACV,OAAO;AACL,gBAAQ,sBAAsB,WAAW;AACzC,eAAO,QAAQ,uDAAuD;AAAA,MACxE;AAAA,IACF;AAGA,UAAM,SAAS,iBAAiB,SAAS;AAGzC,yBAAqB,OAAO,WAAW,SAAS;AAGhD,QAAI,QAAQ,KAAK;AACf,YAAM,sBAAsB,OAAO,WAAW,QAAQ,SAAS;AAC/D;AAAA,IACF;AAGA,UAAM,EAAE,OAAO,IAAI,MAAMC,UAAS,OAAO;AAAA,MACvC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,UACP,EAAE,MAAM,gBAAgB,OAAO,SAAS;AAAA,UACxC,EAAE,MAAM,mCAAmC,OAAO,OAAO;AAAA,UACzD,EAAE,MAAM,UAAU,OAAO,SAAS;AAAA,QACpC;AAAA,MACF;AAAA,IACF,CAAC;AAED,QAAI,WAAW,UAAU;AACvB,aAAO,KAAK,2BAA2B;AACvC;AAAA,IACF;AAEA,QAAI,WAAW,UAAU;AACvB,YAAM,sBAAsB,OAAO,WAAW,QAAQ,SAAS;AAC/D;AAAA,IACF;AAGA,UAAM,EAAE,MAAM,IAAI,MAAMA,UAAS,OAAO;AAAA,MACtC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AAED,QAAI,MAAM,KAAK,GAAG;AAChB,wBAAkB,kBACd,GAAG,eAAe;AAAA,EAAK,MAAM,KAAK,CAAC,KACnC,MAAM,KAAK;AAAA,IACjB;AAEA,WAAO,QAAQ;AACf,WAAO,KAAK,gDAAgD;AAC5D,WAAO,QAAQ;AAAA,EACjB;AACF;AAEA,SAAS,qBACP,OACA,MACA,MACM;AAEN,QAAM,YAAY,KAAK,MAAM,IAAI,EAAE;AAGnC,QAAM,gBAAgB,CAAC,UACrB,QAAQ,IAAI,MAAM,KAAK,KAAK,GAAG,KAAK,EAAE,CAAC;AAGzC,UAAQ,IAAI,MAAM,KAAK,MAAM,sDAAwB,CAAC;AACtD,SAAO,QAAQ;AAEf,gBAAc,OAAO;AACrB,UAAQ,IAAI,KAAK,KAAK,EAAE;AACxB,SAAO,QAAQ;AAEf,gBAAc,QAAQ;AACtB,UAAQ;AAAA,IACN,KAAK,OAAO,MAAM,QAAQ,KAAK,IAAI,EAAE,CAAC,KAAK,OAAO,MAAM,YAAY,KAAK,QAAQ,EAAE,CAAC,KAAK,OAAO,MAAM,QAAQ,KAAK,IAAI,EAAE,CAAC,KAAK,OAAO,MAAM,QAAQ,KAAK,IAAI,EAAE,CAAC;AAAA,EAClK;AACA,SAAO,QAAQ;AAEf,gBAAc,SAAS,SAAS,SAAS;AAEzC,QAAM,YAAY,KAAK,MAAM,IAAI;AACjC,aAAW,QAAQ,WAAW;AAC5B,YAAQ,IAAI,KAAK,IAAI,EAAE;AAAA,EACzB;AAEA,SAAO,QAAQ;AACf,UAAQ,IAAI,MAAM,KAAK,MAAM,sIAAwB,CAAC;AACtD,SAAO,QAAQ;AACjB;AAEA,eAAe,sBACb,OACA,MACA,QACA,MACe;AACf,MAAI;AACJ,MAAI;AACF,kBAAc,MAAM,YAAY,4BAA4B,YAAY;AACtE,aAAO,YAAY;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH,SAAS,OAAO;AACd,WAAO,MAAM,2BAA2B,KAAK,EAAE;AAC/C;AAAA,EACF;AAEA,SAAO,QAAQ;AACf,SAAO,QAAQ,iBAAiB,OAAO,MAAM,IAAI,WAAW,EAAE,CAAC,EAAE;AACjE,SAAO,QAAQ;AAEf,SAAO;AAAA,IACL;AAAA,IACA,UAAU,OAAO,MAAM,IAAI,WAAW,EAAE,CAAC;AAAA,QACrC,OAAO,MAAM,QAAQ,KAAK,IAAI,EAAE,CAAC;AAAA,YAC7B,OAAO,MAAM,YAAY,KAAK,QAAQ,EAAE,CAAC;AAAA,QAC7C,OAAO,MAAM,QAAQ,KAAK,IAAI,EAAE,CAAC;AAAA,QACjC,OAAO,MAAM,QAAQ,KAAK,IAAI,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA,SAIhC,OAAO,QAAQ,YAAY,WAAW,EAAE,CAAC;AAAA,EAChD;AACF;;;AG/QA,OAAOC,YAAW;AAClB,OAAOC,eAAc;;;ACDrB,SAAS,SAAAC,cAAa;AAEtB,eAAsB,mBAAoC;AACxD,QAAM,EAAE,OAAO,IAAI,MAAMA,OAAM,OAAO,CAAC,UAAU,gBAAgB,CAAC;AAClE,SAAO,OAAO,KAAK;AACrB;AAEA,eAAsB,iBAAmC;AACvD,QAAM,SAAS,MAAM,iBAAiB;AACtC,SAAO,WAAW,UAAU,WAAW;AACzC;AAEA,eAAsB,mBAAoC;AACxD,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAMA,OAAM,OAAO;AAAA,MACpC;AAAA,MACA;AAAA,IACF,CAAC;AACD,WAAO,OAAO,KAAK,EAAE,QAAQ,wBAAwB,EAAE;AAAA,EACzD,QAAQ;AAEN,QAAI;AACF,YAAMA,OAAM,OAAO,CAAC,aAAa,YAAY,MAAM,CAAC;AACpD,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,eAAsB,aAAa,MAAgC;AACjE,MAAI;AACF,UAAMA,OAAM,OAAO,CAAC,aAAa,YAAY,IAAI,CAAC;AAClD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,aAAa,MAAc,MAA8B;AAC7E,MAAI,MAAM;AACR,UAAMA,OAAM,OAAO,CAAC,YAAY,MAAM,MAAM,IAAI,CAAC;AAAA,EACnD,OAAO;AACL,UAAMA,OAAM,OAAO,CAAC,YAAY,MAAM,IAAI,CAAC;AAAA,EAC7C;AACF;AAEA,eAAsB,eAAe,MAA6B;AAChE,QAAMA,OAAM,OAAO,CAAC,YAAY,IAAI,CAAC;AACvC;AAEA,eAAsB,wBAA0C;AAC9D,QAAM,EAAE,OAAO,IAAI,MAAMA,OAAM,OAAO,CAAC,UAAU,aAAa,CAAC;AAC/D,SAAO,OAAO,KAAK,EAAE,SAAS;AAChC;AAEA,eAAsB,qBAAuC;AAC3D,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAMA,OAAM,OAAO,CAAC,OAAO,cAAc,WAAW,CAAC;AACxE,WAAO,OAAO,KAAK,EAAE,SAAS;AAAA,EAChC,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,WAAW,QAAgC;AAC/D,QAAM,aAAa,UAAW,MAAM,iBAAiB;AACrD,QAAMA,OAAM,OAAO,CAAC,QAAQ,MAAM,UAAU,UAAU,CAAC;AACzD;AAEA,eAAsB,oBAAqC;AAEzD,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAMA,OAAM,OAAO,CAAC,UAAU,eAAe,CAAC;AACjE,QAAI,OAAO,KAAK,GAAG;AACjB,aAAO,OAAO,KAAK;AAAA,IACrB;AAAA,EACF,QAAQ;AAAA,EAER;AAGA,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAMA,OAAM,OAAO,CAAC,UAAU,WAAW,CAAC;AAC7D,UAAM,OAAO,OAAO,KAAK;AACzB,QAAI,MAAM;AAER,YAAM,QAAQ,KAAK,MAAM,KAAK;AAC9B,aAAO,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,YAAY,KAAK,EAAE,EAAE,KAAK,EAAE;AAAA,IAC5D;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,SAAO;AACT;AAgCA,eAAsB,oBACpB,OAAe,QACI;AACnB,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAMC,OAAM,OAAO;AAAA,MACpC;AAAA,MACA,GAAG,IAAI;AAAA,MACP;AAAA,IACF,CAAC;AACD,WAAO,OAAO,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO;AAAA,EACjD,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,eAAsB,eAAe,OAAe,QAAyB;AAC3E,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAMA,OAAM,OAAO,CAAC,QAAQ,GAAG,IAAI,WAAW,QAAQ,CAAC;AAC1E,WAAO,OAAO,KAAK;AAAA,EACrB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,sBAAuC;AAC3D,QAAM,EAAE,OAAO,IAAI,MAAMA,OAAM,OAAO,CAAC,aAAa,MAAM,CAAC;AAC3D,SAAO,OAAO,KAAK;AACrB;AAEA,eAAsB,cAAc,WAAqC;AACvE,QAAM,aAAa,MAAM,oBAAoB;AAC7C,SAAO,eAAe;AACxB;AAEA,eAAsB,yBAA0C;AAC9D,QAAM,EAAE,OAAO,IAAI,MAAMA,OAAM,OAAO,CAAC,OAAO,MAAM,cAAc,CAAC;AACnE,SAAO,OAAO,KAAK;AACrB;AAEA,eAAsB,oBAAuC;AAC3D,QAAM,EAAE,OAAO,IAAI,MAAMA,OAAM,OAAO;AAAA,IACpC;AAAA,IACA;AAAA,EACF,CAAC;AACD,SAAO,OAAO,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO;AACjD;AAEA,eAAsB,mBAAmB,MAAgC;AACvE,MAAI;AACF,UAAMA,OAAM,OAAO,CAAC,aAAa,eAAe,WAAW,UAAU,IAAI,CAAC;AAC1E,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,iBAAiB,MAA6B;AAClE,QAAMA,OAAM,OAAO,CAAC,SAAS,UAAU,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;AACzD,QAAMA,OAAM,OAAO,CAAC,YAAY,IAAI,CAAC;AACvC;;;ACvLA,eAAsB,mBACpB,QACA,aACA,YACA,MACiB;AACjB,QAAM,SAAS,MAAM,cAAc,MAAM;AACzC,QAAM,OAAO,aAAa,UAAU;AAEpC,SAAO,OAAO,OAAO,QAClB,QAAQ,YAAY,MAAM,EAC1B,QAAQ,UAAU,IAAI,EACtB,QAAQ,WAAW,OAAO,WAAW,CAAC,EACtC,QAAQ,UAAU,IAAI;AAC3B;AAEA,eAAe,cAAc,QAAqC;AAChE,UAAQ,OAAO,OAAO,eAAe;AAAA,IACnC,KAAK,OAAO;AACV,YAAM,WAAW,QAAQ,IAAI,OAAO,OAAO,cAAc;AACzD,UAAI,UAAU;AACZ,eAAO;AAAA,MACT;AAEA,aAAO,kBAAkB;AAAA,IAC3B;AAAA,IACA,KAAK;AAAA,IACL;AACE,aAAO,kBAAkB;AAAA,EAC7B;AACF;AAEO,SAAS,gBAAgB,YAAuC;AAErE,QAAM,WACJ;AACF,QAAM,SAAS,WAAW,MAAM,QAAQ;AACxC,MAAI,QAAQ;AACV,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,OAAO,CAAC;AAAA,MAChB,MAAM,OAAO,CAAC;AAAA,MACd,aAAa,SAAS,OAAO,CAAC,GAAG,EAAE;AAAA,MACnC,MAAM,OAAO,CAAC;AAAA,IAChB;AAAA,EACF;AAGA,QAAM,WAAW;AACjB,QAAM,SAAS,WAAW,MAAM,QAAQ;AACxC,MAAI,QAAQ;AACV,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,MAAM,OAAO,CAAC;AAAA,MACd,aAAa,SAAS,OAAO,CAAC,GAAG,EAAE;AAAA,MACnC,MAAM,OAAO,CAAC;AAAA,IAChB;AAAA,EACF;AAGA,QAAM,WAAW;AACjB,QAAM,SAAS,WAAW,MAAM,QAAQ;AACxC,MAAI,QAAQ;AACV,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,aAAa,SAAS,OAAO,CAAC,GAAG,EAAE;AAAA,MACnC,MAAM,OAAO,CAAC;AAAA,IAChB;AAAA,EACF;AAGA,QAAM,aAAa,WAAW,MAAM,OAAO;AAC3C,MAAI,YAAY;AACd,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,aAAa,SAAS,WAAW,CAAC,GAAG,EAAE;AAAA,MACvC,MAAM;AAAA,IACR;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,mBAAmB,YAAmC;AACpE,QAAM,OAAO,gBAAgB,UAAU;AACvC,SAAO,MAAM,eAAe;AAC9B;;;AFzDO,SAAS,mBACd,aACA,UACe;AACf,aAAW,UAAU,UAAU;AAC7B,UAAM,OAAO,gBAAgB,MAAM;AACnC,QAAI,QAAQ,KAAK,gBAAgB,aAAa;AAC5C,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAKO,SAAS,mBACd,kBACA,aACA,SACA,eACgB;AAChB,QAAM,UAA0B,CAAC;AACjC,QAAM,OAAO,oBAAI,IAAY;AAG7B,QAAM,YAAY,oBAAI,IAAoB;AAC1C,aAAW,MAAM,SAAS;AACxB,UAAM,OAAO,gBAAgB,GAAG,WAAW;AAC3C,QAAI,MAAM;AACR,gBAAU,IAAI,KAAK,aAAa,EAAE;AAAA,IACpC;AAAA,EACF;AAGA,aAAW,SAAS,kBAAkB;AACpC,QAAI,KAAK,IAAI,MAAM,MAAM,EAAG;AAC5B,SAAK,IAAI,MAAM,MAAM;AACrB,UAAM,SAAS,mBAAmB,MAAM,QAAQ,aAAa;AAC7D,UAAM,KAAK,UAAU,IAAI,MAAM,MAAM;AACrC,YAAQ,KAAK;AAAA,MACX,aAAa,MAAM;AAAA,MACnB,OAAO,MAAM;AAAA,MACb,QAAQ,UAAU,IAAI,eAAe;AAAA,MACrC,UAAU,KAAK,YAAY;AAAA,IAC7B,CAAC;AAAA,EACH;AAGA,aAAW,CAAC,aAAa,EAAE,KAAK,WAAW;AACzC,QAAI,KAAK,IAAI,WAAW,EAAG;AAC3B,SAAK,IAAI,WAAW;AACpB,UAAM,QAAQ,CAAC,GAAG,kBAAkB,GAAG,WAAW,EAAE;AAAA,MAClD,CAAC,MAAM,EAAE,WAAW;AAAA,IACtB;AACA,YAAQ,KAAK;AAAA,MACX;AAAA,MACA,OAAO,OAAO,SAAS,GAAG;AAAA,MAC1B,QAAQ,GAAG;AAAA,MACX,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAGA,aAAW,SAAS,aAAa;AAC/B,QAAI,KAAK,IAAI,MAAM,MAAM,EAAG;AAC5B,SAAK,IAAI,MAAM,MAAM;AACrB,UAAM,SAAS,mBAAmB,MAAM,QAAQ,aAAa;AAC7D,YAAQ,KAAK;AAAA,MACX,aAAa,MAAM;AAAA,MACnB,OAAO,MAAM;AAAA,MACb;AAAA,MACA,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,SAAS,cAAc,UAA4C;AACjE,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAOC,OAAM,OAAO,eAAe;AAAA,IACrC,KAAK;AACH,aAAOA,OAAM,KAAK,WAAW;AAAA,IAC/B,KAAK;AACH,aAAOA,OAAM,MAAM,SAAS;AAAA,EAChC;AACF;AAEA,SAAS,aAAa,QAA8B;AAClD,QAAM,MAAM,OAAO,MAAM,IAAI,OAAO,WAAW,EAAE;AACjD,QAAM,MAAM,cAAc,OAAO,QAAQ;AACzC,QAAM,QACJ,OAAO,MAAM,SAAS,KAAK,OAAO,MAAM,MAAM,GAAG,EAAE,IAAI,QAAQ,OAAO;AACxE,SAAO,GAAG,GAAG,IAAI,GAAG,IAAI,KAAK;AAC/B;AAEA,eAAsB,YAAY,SAAqC;AACrE,QAAM,WAAW,MAAM,YAAY;AACnC,MAAI,CAAC,UAAU;AACb,WAAO,MAAM,2DAA2D;AACxE;AAAA,EACF;AAEA,QAAM,SAAS,WAAW;AAC1B,QAAM,iBAAiB,kBAAkB,MAAM;AAC/C,QAAM,gBAAgB,MAAM,iBAAiB;AAC7C,QAAM,gBAAgB,MAAM,iBAAiB;AAG7C,QAAM,eAAe,QAAQ;AAC7B,QAAM,QAAQ,QAAQ,SAAS;AAE/B,MAAI,mBAAkC,CAAC;AACvC,MAAI,cAA6B,CAAC;AAElC,MAAI,gBAAgB,iBAAiB,OAAO;AAE1C,UAAM,SAAmB,CAAC;AAC1B,QAAI,QAAQ,MAAO,QAAO,KAAK,QAAQ,KAAK;AAE5C,YAAQ,cAAc;AAAA,MACpB,KAAK;AACH,eAAO,KAAK,eAAe,KAAK;AAChC;AAAA,MACF,KAAK;AACH,eAAO,KAAK,eAAe,UAAU;AACrC;AAAA,MACF,KAAK;AACH,eAAO,KAAK,eAAe,SAAS;AACpC;AAAA,MACF,KAAK;AACH,eAAO,KAAK,eAAe,OAAO;AAClC;AAAA,IACJ;AAEA,UAAM,CAAC,QAAQC,cAAa,IAAI,MAAM;AAAA,MACpC;AAAA,MACA,MACE,QAAQ,IAAI;AAAA,QACV,WAAW,EAAE,QAAQ,OAAO,QAAQ,MAAM,CAAC;AAAA,QAC3C,kBAAkB;AAAA,MACpB,CAAC;AAAA,IACL;AAEA,mBAAe,MAAM;AAGrB,QAAI,iBAAiB,eAAe;AAClC,yBAAmB;AAAA,IACrB,OAAO;AACL,oBAAc;AAAA,IAChB;AAEA,UAAMC,WAAU;AAAA,MACd;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACDD;AAAA,IACF;AAEA,QAAIC,SAAQ,WAAW,GAAG;AACxB,aAAO,KAAK,wCAAwC;AACpD;AAAA,IACF;AAEA,UAAM,gBAAgBA,UAAS,eAAe,eAAe,MAAM;AACnE;AAAA,EACF;AAGA,QAAM,cAAc,QAAQ,QAAQ,CAAC,QAAQ,KAAK,IAAI,CAAC;AACvD,QAAM,CAAC,YAAY,OAAO,KAAK,aAAa,IAAI,MAAM;AAAA,IACpD;AAAA,IACA,MACE,QAAQ,IAAI;AAAA,MACV,WAAW;AAAA,QACT,QAAQ,CAAC,eAAe,YAAY,GAAG,WAAW;AAAA,QAClD,OAAO;AAAA,QACP;AAAA,MACF,CAAC;AAAA,MACD,WAAW;AAAA,QACT,QAAQ,CAAC,eAAe,OAAO,GAAG,WAAW;AAAA,QAC7C,OAAO;AAAA,QACP;AAAA,MACF,CAAC;AAAA,MACD,YAAY,EAAE;AAAA,MACd,kBAAkB;AAAA,IACpB,CAAC;AAAA,EACL;AAEA,iBAAe,UAAU;AACzB,iBAAe,KAAK;AAEpB,QAAM,UAAU,mBAAmB,YAAY,OAAO,KAAK,aAAa;AAExE,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,KAAK,mBAAmB;AAC/B,WAAO;AAAA,MACL,wBAAwB,OAAO,QAAQ,aAAa,CAAC,gBAAgB,eAAe,KAAK;AAAA,IAC3F;AACA;AAAA,EACF;AAEA,QAAM,gBAAgB,SAAS,eAAe,eAAe,MAAM;AACrE;AAEA,eAAe,gBACb,SACA,eACA,eACA,QACe;AAEf,QAAM,QAAQ,MAAM,sBAAsB;AAI1C,QAAM,kBAAyB,CAAC;AAGhC,kBAAgB,KAAK;AAAA,IACnB,MAAM,GAAGF,OAAM,QAAQ,aAAa,CAAC,GAAG,kBAAkB,gBAAgBA,OAAM,IAAI,YAAY,IAAI,EAAE;AAAA,IACtG,OAAO;AAAA,EACT,CAAC;AACD,kBAAgB,KAAK,IAAIG,UAAS,UAAU,QAAG,CAAC;AAGhD,QAAM,aAAa,QAAQ,OAAO,CAAC,MAAM,EAAE,aAAa,aAAa;AACrE,QAAM,gBAAgB,QAAQ,OAAO,CAAC,MAAM,EAAE,aAAa,SAAS;AACpE,QAAM,QAAQ,QAAQ,OAAO,CAAC,MAAM,EAAE,aAAa,OAAO;AAE1D,MAAI,WAAW,SAAS,GAAG;AACzB,oBAAgB,KAAK,IAAIA,UAAS,UAAUH,OAAM,OAAO,cAAc,CAAC,CAAC;AACzE,eAAW,KAAK,YAAY;AAC1B,sBAAgB,KAAK;AAAA,QACnB,MAAM,aAAa,CAAC;AAAA,QACpB,OAAO,OAAO,EAAE,WAAW;AAAA,MAC7B,CAAC;AAAA,IACH;AAAA,EACF;AAEA,MAAI,cAAc,SAAS,GAAG;AAC5B,oBAAgB,KAAK,IAAIG,UAAS,UAAUH,OAAM,KAAK,WAAW,CAAC,CAAC;AACpE,eAAW,KAAK,eAAe;AAC7B,sBAAgB,KAAK;AAAA,QACnB,MAAM,aAAa,CAAC;AAAA,QACpB,OAAO,OAAO,EAAE,WAAW;AAAA,MAC7B,CAAC;AAAA,IACH;AAAA,EACF;AAEA,MAAI,MAAM,SAAS,GAAG;AACpB,oBAAgB,KAAK,IAAIG,UAAS,UAAUH,OAAM,MAAM,QAAQ,CAAC,CAAC;AAClE,eAAW,KAAK,OAAO;AACrB,sBAAgB,KAAK;AAAA,QACnB,MAAM,aAAa,CAAC;AAAA,QACpB,OAAO,OAAO,EAAE,WAAW;AAAA,MAC7B,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,EAAE,SAAS,IAAI,MAAMG,UAAS,OAAO;AAAA,IACzC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,MACT,UAAU;AAAA,IACZ;AAAA,EACF,CAAC;AAGD,MAAI,aAAa,YAAY;AAC3B,QAAI,kBAAkB,eAAe;AACnC,aAAO,KAAK,cAAc,OAAO,OAAO,aAAa,CAAC,EAAE;AACxD;AAAA,IACF;AACA,QAAI,OAAO;AACT,YAAM,KAAK,MAAM,aAAa;AAC9B,UAAI,CAAC,GAAI;AAAA,IACX;AACA,UAAM,YAAY,gBAAgB,aAAa,OAAO,YAAY;AAChE,YAAM,eAAe,aAAa;AAAA,IACpC,CAAC;AACD,WAAO,QAAQ,eAAe,OAAO,OAAO,aAAa,CAAC,EAAE;AAC5D;AAAA,EACF;AAGA,QAAM,cAAc,SAAS,UAAU,EAAE;AACzC,QAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,gBAAgB,WAAW;AAChE,MAAI,CAAC,OAAQ;AAEb,MAAI,OAAO;AACT,UAAM,KAAK,MAAM,aAAa;AAC9B,QAAI,CAAC,GAAI;AAAA,EACX;AAGA,QAAM,eAAe,OAAO;AAE5B,MAAI,cAAc;AAChB,QAAI,MAAM,aAAa,YAAY,GAAG;AACpC,YAAM,YAAY,gBAAgB,YAAY,OAAO,YAAY;AAC/D,cAAM,eAAe,YAAY;AAAA,MACnC,CAAC;AACD,aAAO,QAAQ,eAAe,OAAO,OAAO,YAAY,CAAC,EAAE;AAAA,IAC7D,WAAW,MAAM,mBAAmB,YAAY,GAAG;AACjD,YAAM,YAAY,YAAY,YAAY,mBAAmB,YAAY;AACvE,cAAM,iBAAiB,YAAY;AAAA,MACrC,CAAC;AACD,aAAO,QAAQ,2BAA2B,OAAO,OAAO,YAAY,CAAC,EAAE;AAAA,IACzE,OAAO;AACL,aAAO;AAAA,QACL,UAAU,OAAO,OAAO,YAAY,CAAC;AAAA,MACvC;AACA,YAAM,kBAAkB,QAAQ,aAAa,OAAO,KAAK;AAAA,IAC3D;AAAA,EACF,OAAO;AACL,UAAM,kBAAkB,QAAQ,aAAa,OAAO,KAAK;AAAA,EAC3D;AACF;AAEA,eAAe,eAAiC;AAC9C,SAAO,QAAQ,+BAA+B;AAC9C,QAAM,EAAE,QAAQ,IAAI,MAAMA,UAAS,OAAO;AAAA,IACxC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AACD,MAAI,CAAC,SAAS;AACZ,WAAO,KAAK,sDAAsD;AAAA,EACpE;AACA,SAAO;AACT;AAEA,eAAe,kBACb,QACA,aACA,OACe;AACf,QAAM,aAAa,MAAM;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,EAAE,OAAO,IAAI,MAAMA,UAAS,OAAO;AAAA,IACvC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,4BAA4B,OAAO,OAAO,UAAU,CAAC;AAAA,MAC9D,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,MAAI,CAAC,OAAQ;AAEb,QAAM,gBAAgB,MAAM,iBAAiB;AAC7C,QAAM,YAAY,mBAAmB,UAAU,OAAO,YAAY;AAChE,UAAM,aAAa,YAAY,aAAa;AAAA,EAC9C,CAAC;AACD,SAAO,QAAQ,2BAA2B,OAAO,OAAO,UAAU,CAAC,EAAE;AACvE;;;AGvZA,OAAOC,eAAc;AAkCrB,eAAsB,WACpB,gBACA,SACe;AACf,SAAO,KAAK,uCAAuC;AACnD,SAAO,QAAQ;AAEf,QAAM,SAAS,WAAW;AAG1B,QAAM,WAAW,QAAQ,YAAY,OAAO,GAAG;AAC/C,QAAM,eAAe,uBAAuB,QAAQ;AAGpD,QAAM,CAAC,QAAQ,IAAI,IAAI,MAAM,QAAQ,IAAI;AAAA,IACvC,YAAY;AAAA,IACZ,gBAAgB,QAAQ;AAAA,EAC1B,CAAC;AAED,MAAI,CAAC,QAAQ;AACX,WAAO,MAAM,2DAA2D;AACxE;AAAA,EACF;AAEA,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,MACL,GAAG,YAAY,kCAAkC,QAAQ;AAAA,IAC3D;AACA;AAAA,EACF;AAGA,QAAM,aAAa,MAAM,sBAAsB;AAC/C,MAAI,YAAY;AACd,WAAO,QAAQ,+BAA+B;AAC9C,UAAM,EAAE,QAAQ,IAAI,MAAMC,UAAS,OAAO;AAAA,MACxC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AACD,QAAI,CAAC,SAAS;AACZ,aAAO,KAAK,sDAAsD;AAClE;AAAA,IACF;AAAA,EACF;AAEA,QAAM,iBAAiB,kBAAkB,MAAM;AAG/C,MAAI;AAEJ,MAAI,gBAAgB;AAClB,QAAI,CAAC,mBAAmB,cAAc,GAAG;AACvC,aAAO,MAAM,uBAAuB;AACpC;AAAA,IACF;AACA,kBAAc,SAAS,gBAAgB,EAAE;AAAA,EAC3C,OAAO;AACL,WAAO;AAAA,MACL;AAAA,IACF;AACA;AAAA,EACF;AAGA,MAAI;AACJ,MAAI;AACF,YAAQ,MAAM,YAAY,qBAAqB,YAAY;AACzD,aAAO,SAAS,WAAW;AAAA,IAC7B,CAAC;AAAA,EACH,SAAS,OAAO;AACd,WAAO,MAAM,0BAA0B,WAAW,KAAK,KAAK,EAAE;AAC9D;AAAA,EACF;AAGA,MAAI,CAAC,MAAM,OAAO,SAAS,eAAe,KAAK,GAAG;AAChD,WAAO;AAAA,MACL,UAAU,WAAW,uBAAuB,eAAe,KAAK;AAAA,IAClE;AACA,UAAM,EAAE,QAAQ,IAAI,MAAMA,UAAS,OAAO;AAAA,MACxC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AACD,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAAA,EACF;AAEA,SAAO,QAAQ;AACf,SAAO;AAAA,IACL;AAAA,IACA,IAAI,MAAM,MAAM,KAAK,MAAM,KAAK;AAAA,UAC1B,MAAM,OAAO,KAAK,IAAI,CAAC;AAAA,EAC/B;AACA,SAAO,QAAQ;AAGf,QAAM,OAAO,sBAAsB,MAAM,MAAM;AAC/C,QAAM,aAAa,MAAM;AAAA,IACvB;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,EACF;AAGA,QAAM,gBAAgB,MAAM,iBAAiB;AAC7C,QAAM,SAAS,MAAM,eAAe;AAEpC,MAAI,MAAM,aAAa,UAAU,GAAG;AAClC,WAAO,KAAK,UAAU,OAAO,OAAO,UAAU,CAAC,kBAAkB;AACjE,UAAM,EAAE,OAAO,IAAI,MAAMA,UAAS,OAAO;AAAA,MACvC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,UACP,EAAE,MAAM,+BAA+B,OAAO,WAAW;AAAA,UACzD,EAAE,MAAM,8BAA8B,OAAO,WAAW;AAAA,UACxD,EAAE,MAAM,UAAU,OAAO,SAAS;AAAA,QACpC;AAAA,MACF;AAAA,IACF,CAAC;AAED,QAAI,WAAW,UAAU;AACvB;AAAA,IACF,WAAW,WAAW,YAAY;AAChC,YAAM,eAAe,UAAU;AAAA,IACjC,OAAO;AAEL,YAAM,eAAe,UAAU;AAAA,IACjC;AAAA,EACF,OAAO;AACL,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,QACL,oCAAoC,OAAO,OAAO,aAAa,CAAC;AAAA,MAClE;AACA,YAAM,EAAE,SAAS,IAAI,MAAMA,UAAS,OAAO;AAAA,QACzC;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,MACF,CAAC;AAED,UAAI,UAAU;AACZ,cAAM,aAAa,YAAY,MAAM;AAAA,MACvC,OAAO;AACL,cAAM,aAAa,UAAU;AAAA,MAC/B;AAAA,IACF,OAAO;AACL,YAAM,aAAa,UAAU;AAAA,IAC/B;AACA,WAAO,QAAQ,kBAAkB,OAAO,OAAO,UAAU,CAAC,EAAE;AAAA,EAC9D;AAGA,MAAI;AACF,UAAM,kBAAkB,aAAa;AAAA,MACnC,KAAK,CAAC,eAAe,UAAU;AAAA,MAC/B,QAAQ,CAAC,eAAe,KAAK;AAAA,IAC/B,CAAC;AACD,WAAO;AAAA,MACL,yBAAyB,OAAO,MAAM,eAAe,KAAK,CAAC,WAAM,OAAO,MAAM,eAAe,UAAU,CAAC;AAAA,IAC1G;AAAA,EACF,SAAS,OAAO;AACd,WAAO,QAAQ,4BAA4B,KAAK,EAAE;AAAA,EACpD;AAGA,QAAM,oBAAoB,sBAAsB;AAChD,QAAM,kBAAkB,aAAa,MAAM;AAC3C,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,QAAQ;AACf,SAAO;AAAA,IACL,YAAY,OAAO,SAAS,YAAY,CAAC;AAAA,EAC3C;AACA,SAAO,IAAI,GAAG,YAAY,kDAAkD;AAC5E,SAAO,IAAI,oCAAoC;AAC/C,SAAO,QAAQ;AAGf,QAAM,YAAY,MAAM,oBAAoB;AAG5C,MAAI,eAAe;AACnB,QAAM,eAAe,MAAM;AACzB,mBAAe;AAAA,EACjB;AACA,UAAQ,GAAG,UAAU,YAAY;AACjC,UAAQ,GAAG,WAAW,YAAY;AAGlC,MAAI;AACJ,MAAI,eAAe;AACnB,MAAI;AACF,UAAM,EAAE,QAAQ,UAAU,eAAe,IAAI,MAAM;AAAA,MACjD;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACV;AACA,mBAAe;AACf,iBAAa,OAAO,YAAY;AAAA,EAClC,SAAS,OAAO;AACd,QAAI,SAAS,OAAO,UAAU,YAAY,cAAc,OAAO;AAC7D,mBAAa,MAAM;AAAA,IACrB;AACA,WAAO;AAAA,MACL,GAAG,uBAAuB,YAAY,CAAC,oBAAoB,KAAK;AAAA,IAClE;AAAA,EAEF,UAAE;AAEA,YAAQ,IAAI,UAAU,YAAY;AAClC,YAAQ,IAAI,WAAW,YAAY;AAAA,EACrC;AAGA,SAAO,QAAQ;AAGf,QAAM,iBAAiB,MAAM,cAAc,SAAS;AAGpD,MAAI,cAAc;AAChB,WAAO,QAAQ,4CAA4C;AAC3D;AAAA,EACF;AAGA,QAAM,mBAAmB,uBAAuB,YAAY;AAC5D,MAAI,gBAAgB;AAClB,WAAO,QAAQ,GAAG,gBAAgB,sCAAsC;AAGxE,QAAI;AACF,YAAM,kBAAkB,aAAa;AAAA,QACnC,KAAK,CAAC,eAAe,SAAS;AAAA,QAC9B,QAAQ,CAAC,eAAe,UAAU;AAAA,MACpC,CAAC;AACD,aAAO;AAAA,QACL,mBAAmB,OAAO,MAAM,eAAe,UAAU,CAAC,WAAM,OAAO,MAAM,eAAe,SAAS,CAAC;AAAA,MACxG;AAAA,IACF,SAAS,OAAO;AACd,aAAO,QAAQ,4BAA4B,KAAK,EAAE;AAAA,IACpD;AAGA,QAAI;AACF,YAAM;AAAA,QACJ;AAAA,QACA,2CAA2C,UAAU,YAAY,gBAAgB;AAAA;AAAA;AAAA,MACnF;AACA,aAAO,QAAQ,oCAAoC;AAAA,IACrD,SAAS,OAAO;AACd,aAAO,QAAQ,2BAA2B,KAAK,EAAE;AAAA,IACnD;AAAA,EACF,OAAO;AAIL,UAAM,gBAAgB,eAAe;AAErC,QAAI,eAAe;AACjB,aAAO;AAAA,QACL,GAAG,gBAAgB;AAAA,MACrB;AAGA,UAAI;AACF,cAAM,kBAAkB,aAAa;AAAA,UACnC,KAAK,CAAC,eAAe,OAAO;AAAA,UAC5B,QAAQ,CAAC,eAAe,UAAU;AAAA,QACpC,CAAC;AACD,eAAO;AAAA,UACL,mBAAmB,OAAO,MAAM,eAAe,UAAU,CAAC,WAAM,OAAO,MAAM,eAAe,OAAO,CAAC;AAAA,QACtG;AAAA,MACF,SAAS,OAAO;AACd,eAAO,QAAQ,4BAA4B,KAAK,EAAE;AAAA,MACpD;AAGA,UAAI;AACF,cAAM;AAAA,UACJ;AAAA,UACA,oEAAoE,UAAU,OAAO,gBAAgB;AAAA;AAAA;AAAA,QACvG;AACA,eAAO,KAAK,oCAAoC;AAAA,MAClD,SAAS,OAAO;AACd,eAAO,QAAQ,2BAA2B,KAAK,EAAE;AAAA,MACnD;AAAA,IACF,OAAO;AACL,aAAO;AAAA,QACL,GAAG,gBAAgB;AAAA,MACrB;AAAA,IAEF;AAEA;AAAA,EACF;AAEA,SAAO,QAAQ;AACf,SAAO;AAAA,IACL;AAAA,IACA,sBAAsB,OAAO,QAAQ,iBAAiB,CAAC;AAAA,gBAC3C,OAAO,QAAQ,UAAU,CAAC;AAAA,kBACxB,OAAO,QAAQ,wBAAwB,UAAU,CAAC;AAAA,gBACpD,OAAO,QAAQ,SAAS,CAAC;AAAA,EACvC;AACF;;;ACtWA,OAAOC,eAAc;;;ACArB,SAAS,SAAAC,cAAa;AAGtB,IAAM,mBAAmB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKA,eAAsB,wBAA0C;AAC9D,MAAI;AACF,UAAM,EAAE,SAAS,IAAI,MAAMA,OAAM,OAAO,CAAC,cAAc,WAAW,GAAG;AAAA,MACnE,QAAQ;AAAA,IACV,CAAC;AACD,WAAO,aAAa;AAAA,EACtB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAAS,aAAa,cAAiC;AAC5D,SAAO,aAAa;AAAA,IAAK,CAAC,SACxB,iBAAiB,KAAK,CAAC,YAAY,QAAQ,KAAK,IAAI,CAAC;AAAA,EACvD;AACF;AAKA,eAAsB,gBACpB,aAAqB,QACF;AACnB,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAMA,OAAM,OAAO;AAAA,MACpC;AAAA,MACA,GAAG,UAAU;AAAA,MACb;AAAA,IACF,CAAC;AACD,WAAO,OAAO,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO;AAAA,EACjD,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;;;ADlBA,eAAsB,UAAU,SAAmC;AACjE,SAAO,KAAK,sCAAsC;AAClD,SAAO,QAAQ;AAEf,QAAM,SAAS,WAAW;AAG1B,QAAM,WAAW,QAAQ,YAAY,OAAO,GAAG;AAC/C,QAAM,eAAe,uBAAuB,QAAQ;AAGpD,QAAM,CAAC,QAAQ,IAAI,IAAI,MAAM,QAAQ,IAAI;AAAA,IACvC,YAAY;AAAA,IACZ,gBAAgB,QAAQ;AAAA,EAC1B,CAAC;AAED,MAAI,CAAC,QAAQ;AACX,WAAO,MAAM,2DAA2D;AACxE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,MACL,GAAG,YAAY,kCAAkC,QAAQ;AAAA,IAC3D;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,MAAI,MAAM,eAAe,GAAG;AAC1B,WAAO,MAAM,2CAA2C;AACxD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,aAAa,MAAM,eAAe;AACxC,MAAI,YAAY;AACd,WAAO;AAAA,MACL,wCAAwC,OAAO,IAAI,WAAW,GAAG,CAAC;AAAA,IACpE;AACA;AAAA,EACF;AAEA,QAAM,gBAAgB,MAAM,iBAAiB;AAC7C,QAAM,aAAa,MAAM,iBAAiB;AAE1C,SAAO,KAAK,WAAW,OAAO,OAAO,aAAa,CAAC,EAAE;AACrD,SAAO,KAAK,SAAS,OAAO,OAAO,UAAU,CAAC,EAAE;AAGhD,QAAM,cAAc,MAAM,mBAAmB;AAC7C,MAAI,aAAa;AACf,WAAO,QAAQ,8BAA8B;AAC7C,UAAM,EAAE,KAAK,IAAI,MAAMC,UAAS,OAAO;AAAA,MACrC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AAED,QAAI,MAAM;AACR,YAAM,YAAY,qBAAqB,YAAY;AACjD,cAAM,WAAW;AAAA,MACnB,CAAC;AACD,aAAO,QAAQ,eAAe;AAAA,IAChC;AAAA,EACF;AAGA,QAAM,cAAc,mBAAmB,aAAa;AACpD,MAAI,QAA4B;AAEhC,MAAI,aAAa;AACf,QAAI;AACF,cAAQ,MAAM,SAAS,WAAW;AAClC,aAAO;AAAA,QACL,iBAAiB,OAAO,MAAM,IAAI,WAAW,EAAE,CAAC,MAAM,MAAM,KAAK;AAAA,MACnE;AAAA,IACF,QAAQ;AACN,aAAO,QAAQ,0BAA0B,WAAW,EAAE;AAAA,IACxD;AAAA,EACF,OAAO;AACL,WAAO,QAAQ,kDAAkD;AAAA,EACnE;AAGA,QAAM,UAAU,MAAM,oBAAoB,UAAU;AACpD,QAAM,cAAc,MAAM,eAAe,UAAU;AAEnD,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,MAAM,qCAAqC;AAClD;AAAA,EACF;AAEA,SAAO,KAAK,YAAY,QAAQ,MAAM,EAAE;AACxC,SAAO,QAAQ;AAIf,QAAM,qBAAqB,QAAQ,UAAU,SAAS,OAAO,MAAM;AACnE,MAAI,2BAA2B;AAE/B,MAAI,oBAAoB;AACtB,UAAM,eAAe,MAAM,gBAAgB,UAAU;AACrD,UAAM,oBAAoB,aAAa,YAAY;AAEnD,QAAI,mBAAmB;AACrB,aAAO,KAAK,oCAAoC;AAEhD,YAAM,sBAAsB,MAAM,sBAAsB;AACxD,UAAI,CAAC,qBAAqB;AACxB,eAAO,QAAQ,mDAAmD;AAClE,eAAO,IAAI,oDAAoD;AAAA,MACjE,OAAO;AACL,eAAO;AAAA,UACL;AAAA,QACF;AACA,mCAA2B;AAAA;AAAA;AAAA;AAAA;AAAA,qCAKE,OAAO,MAAM,YAAY;AAAA;AAAA;AAAA,MAGxD;AAAA,IACF;AAAA,EACF;AAGA,QAAM,SACJ,cAAc,OAAO,SAAS,WAAW,IAAI;AAE/C,MAAI;AACJ,MAAI;AACF,WAAO;AAAA,MACL,kCAAkC,OAAO,SAAS,YAAY,CAAC;AAAA,IACjE;AACA,WAAO,QAAQ;AACf,UAAM,SAAS,MAAM;AAAA,MACnB,EAAE,QAAQ,cAAc,KAAK;AAAA,MAC7B;AAAA,MACA,QAAQ;AAAA,IACV;AACA,aAAS,OAAO;AAChB,WAAO,QAAQ;AAAA,EACjB,SAAS,OAAO;AACd,WAAO,QAAQ,GAAG,YAAY,uBAAuB,KAAK,EAAE;AAE5D,aAAS,qBAAqB,OAAO,OAAO;AAAA,EAC9C;AAGA,YAAU;AAAA;AAAA;AAAA,gBAA0B,YAAY;AAGhD,QAAM,UAAU,OAAO,SAAS,QAAQ,CAAC,KAAK;AAG9C,MAAI;AACJ,MAAI;AACF,YAAQ,MAAM,YAAY,4BAA4B,YAAY;AAChE,aAAO,kBAAkB;AAAA,QACvB,OAAO;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,MACjB,CAAC;AAAA,IACH,CAAC;AAAA,EACH,SAAS,OAAO;AACd,WAAO,MAAM,wBAAwB,KAAK,EAAE;AAC5C;AAAA,EACF;AAGA,MAAI,aAAa;AACf,QAAI;AACF,YAAM,OAAO,MAAM,eAAe;AAClC,YAAM,YAAY,aAAa,IAAI;AACnC,aAAO,QAAQ,mBAAmB,WAAW,OAAO,IAAI,EAAE;AAAA,IAC5D,QAAQ;AAAA,IAER;AAGA,UAAM,iBAAiB,kBAAkB,MAAM;AAC/C,QAAI;AACF,YAAM,kBAAkB,aAAa;AAAA,QACnC,KAAK,CAAC,eAAe,SAAS;AAAA,QAC9B,QAAQ,CAAC,eAAe,UAAU;AAAA,MACpC,CAAC;AACD,aAAO;AAAA,QACL,mBAAmB,OAAO,MAAM,eAAe,UAAU,CAAC,WAAM,OAAO,MAAM,eAAe,SAAS,CAAC;AAAA,MACxG;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SAAO,QAAQ;AACf,SAAO,QAAQ,uBAAuB;AACtC,SAAO,QAAQ;AACf,SAAO,UAAU,KAAK;AACtB,SAAO,QAAQ;AAEf,MAAI,QAAQ,OAAO;AACjB,WAAO,IAAI,uDAAuD;AAAA,EACpE;AACF;AAEA,SAAS,qBACP,OACA,SACQ;AACR,MAAI,OAAO;AAEX,MAAI,OAAO;AACT,YAAQ,eAAe,MAAM,MAAM,KAAK,MAAM,KAAK;AAAA;AAAA;AAAA,EACrD;AAEA,UAAQ;AACR,aAAW,UAAU,QAAQ,MAAM,GAAG,EAAE,GAAG;AACzC,YAAQ,KAAK,MAAM;AAAA;AAAA,EACrB;AAEA,UAAQ;AAER,MAAI,OAAO;AACT,YAAQ,WAAW,MAAM,MAAM;AAAA;AAAA,EACjC;AAEA,SAAO;AACT;;;AEjRA,OAAOC,eAAc;;;ACgBrB,IAAM,sBAAsB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,mBAAmB,CAAC,QAAQ,cAAc,UAAU;AAEnD,SAAS,wBACd,MACA,SAIA;AACA,QAAM,QAAQ,2BAA2B,MAAM,OAAO;AACtD,SAAO;AAAA,IACL;AAAA,IACA,SAAS,MAAM,SAAS,IAAI,4BAA4B,KAAK,IAAI;AAAA,EACnE;AACF;AAEA,SAAS,iBACP,eACA,gBACS;AACT,MAAI,CAAC,kBAAkB,CAAC,eAAe;AACrC,WAAO;AAAA,EACT;AACA,SAAO,IAAI,KAAK,aAAa,IAAI,IAAI,KAAK,cAAc;AAC1D;AAEO,SAAS,2BACd,MACA,SACsB;AACtB,QAAM,QAA8B,CAAC;AACrC,QAAM,iBAAiB,SAAS;AAEhC,aAAW,UAAU,KAAK,SAAS;AACjC,UAAM,OAAO,OAAO,MAAM,KAAK,KAAK;AACpC,QAAI,CAAC,QAAQ,iBAAiB,IAAI,GAAG;AACnC;AAAA,IACF;AAGA,QAAI,CAAC,iBAAiB,OAAO,aAAa,cAAc,GAAG;AACzD;AAAA,IACF;AAEA,UAAM,qBAAqB,OAAO,UAAU;AAC5C,UAAM,aAAa,sBAAsB,iBAAiB,IAAI;AAC9D,QAAI,CAAC,YAAY;AACf;AAAA,IACF;AAEA,UAAM,KAAK;AAAA,MACT,QAAQ;AAAA,MACR,QAAQ,OAAO;AAAA,MACf;AAAA,MACA,OAAO,OAAO;AAAA,IAChB,CAAC;AAAA,EACH;AAEA,aAAW,UAAU,KAAK,eAAe;AAEvC,QAAI,OAAO,YAAY;AACrB;AAAA,IACF;AAEA,UAAM,eACJ,OAAO,eAAe,SACtB,OAAO,eAAe,UACtB,OAAO,eAAe;AAExB,UAAM,qBAAqB,OAAO,YAAY,CAAC,GAAG;AAAA,MAAK,CAAC,MACtD,iBAAiB,EAAE,WAAW,cAAc;AAAA,IAC9C;AAGA,QAAI,CAAC,gBAAgB,CAAC,mBAAmB;AACvC;AAAA,IACF;AAIA,QAAI,gBAAgB,kBAAkB,CAAC,mBAAmB;AACxD;AAAA,IACF;AAEA,QAAI,CAAC,mBAAmB,MAAM,GAAG;AAC/B;AAAA,IACF;AAEA,UAAM,WAAW,OAAO,YAAY,CAAC;AACrC,UAAM,gBAAgB,4BAA4B,QAAQ;AAC1D,QAAI,CAAC,eAAe;AAClB;AAAA,IACF;AAEA,UAAM,KAAK;AAAA,MACT,QAAQ;AAAA,MACR,QAAQ,cAAc;AAAA,MACtB,MAAM,cAAc;AAAA,MACpB,MAAM,OAAO,QAAQ,cAAc;AAAA,MACnC,MAAM,OAAO,QAAQ,cAAc,QAAQ;AAAA,MAC3C,WAAW,cAAc;AAAA,IAC3B,CAAC;AAAA,EACH;AAGA,aAAW,WAAW,KAAK,YAAY,CAAC,GAAG;AACzC,UAAM,OAAO,QAAQ,MAAM,KAAK,KAAK;AACrC,QAAI,CAAC,QAAQ,iBAAiB,IAAI,GAAG;AACnC;AAAA,IACF;AAGA,QAAI,CAAC,iBAAiB,QAAQ,WAAW,cAAc,GAAG;AACxD;AAAA,IACF;AAGA,QAAI,CAAC,iBAAiB,IAAI,GAAG;AAC3B;AAAA,IACF;AAEA,UAAM,KAAK;AAAA,MACT,QAAQ;AAAA,MACR,QAAQ,QAAQ;AAAA,MAChB;AAAA,MACA,WAAW,QAAQ;AAAA,IACrB,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEO,SAAS,4BACd,OACQ;AACR,SAAO,MACJ,IAAI,CAAC,SAAS;AACb,UAAM,WAAW,eAAe,IAAI;AACpC,UAAM,aAAa,KAAK,QAAQ,YAAY,KAAK,KAAK,IAAI;AAC1D,UAAM,SAAS,KAAK,SAAS,IAAI,KAAK,MAAM,KAAK;AACjD,UAAM,OAAO,gBAAgB,KAAK,IAAI;AACtC,QAAI;AACJ,QAAI,KAAK,WAAW,UAAU;AAC5B,eAAS,aAAa,WAAW,UAAU,MAAM;AAAA,IACnD,WAAW,KAAK,WAAW,WAAW;AACpC,eAAS;AAAA,IACX,OAAO;AACL,eAAS;AAAA,IACX;AACA,WAAO,MAAM,MAAM,KAAK,MAAM,KAAK,IAAI;AAAA,EACzC,CAAC,EACA,KAAK,IAAI;AACd;AAEA,SAAS,mBAAmB,QAGhB;AACV,MACE,OAAO,eAAe,SACtB,OAAO,eAAe,UACtB,OAAO,eAAe,MACtB;AACA,WAAO;AAAA,EACT;AACA,UAAQ,OAAO,YAAY,CAAC,GAAG;AAAA,IAAK,CAAC,YACnC,iBAAiB,QAAQ,IAAI;AAAA,EAC/B;AACF;AAEA,SAAS,iBAAiB,MAAuB;AAC/C,QAAM,aAAa,KAAK,YAAY;AACpC,SAAO,oBAAoB,KAAK,CAAC,YAAY,WAAW,SAAS,OAAO,CAAC;AAC3E;AAEA,SAAS,iBAAiB,MAAuB;AAC/C,QAAM,aAAa,KAAK,KAAK,EAAE,YAAY;AAC3C,SAAO,iBAAiB,KAAK,CAAC,UAAU,eAAe,KAAK;AAC9D;AAEA,SAAS,4BAEP,UAAyB;AACzB,WAAS,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG;AAChD,UAAM,OAAO,SAAS,CAAC,EAAE,MAAM,KAAK,KAAK;AACzC,QAAI,QAAQ,CAAC,iBAAiB,IAAI,GAAG;AACnC,aAAO,SAAS,CAAC;AAAA,IACnB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,eAAe,MAAuD;AAC7E,MAAI,KAAK,QAAQ,KAAK,MAAM;AAC1B,WAAO,GAAG,KAAK,IAAI,IAAI,KAAK,IAAI;AAAA,EAClC;AACA,MAAI,KAAK,MAAM;AACb,WAAO,KAAK;AAAA,EACd;AACA,SAAO;AACT;AAEA,SAAS,YAAY,OAAuB;AAC1C,SAAO,MAAM,QAAQ,MAAM,GAAG,EAAE,YAAY;AAC9C;AAEA,SAAS,gBAAgB,MAAc,YAAY,KAAa;AAC9D,QAAM,aAAa,KAAK,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAClD,MAAI,WAAW,UAAU,WAAW;AAClC,WAAO;AAAA,EACT;AACA,SAAO,GAAG,WAAW,MAAM,GAAG,YAAY,CAAC,CAAC;AAC9C;;;AD9MA,eAAsB,WAAW,SAAoC;AACnE,SAAO,KAAK,wCAAwC;AACpD,SAAO,QAAQ;AAEf,QAAM,SAAS,WAAW;AAC1B,QAAM,WAAW,QAAQ,YAAY,OAAO,GAAG;AAC/C,QAAM,eAAe,uBAAuB,QAAQ;AAEpD,QAAM,CAAC,QAAQ,IAAI,IAAI,MAAM,QAAQ,IAAI;AAAA,IACvC,YAAY;AAAA,IACZ,gBAAgB,QAAQ;AAAA,EAC1B,CAAC;AAED,MAAI,CAAC,QAAQ;AACX,WAAO,MAAM,2DAA2D;AACxE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,MACL,GAAG,YAAY,kCAAkC,QAAQ;AAAA,IAC3D;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,MAAM,eAAe,GAAG;AAC1B,WAAO;AAAA,MACL;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,aAAa,MAAM,sBAAsB;AAC/C,MAAI,YAAY;AACd,WAAO,QAAQ,+BAA+B;AAC9C,UAAM,EAAE,QAAQ,IAAI,MAAMC,UAAS,OAAO;AAAA,MACxC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AACD,QAAI,CAAC,SAAS;AACZ,aAAO,KAAK,sDAAsD;AAClE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,KAAK,MAAM,YAAY,6BAA6B,YAAY;AACpE,WAAO,eAAe;AAAA,EACxB,CAAC;AAED,MAAI,CAAC,IAAI;AACP,WAAO;AAAA,MACL;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,sBAAsB,MAAM,uBAAuB;AAEzD,QAAM,aAAa,MAAM;AAAA,IACvB;AAAA,IACA,YAAY;AACV,aAAO,gBAAgB,GAAG,MAAM;AAAA,IAClC;AAAA,EACF;AAEA,QAAM,gBAAgB,oBAAoB,UAAU;AACpD,MAAI,kBAAkB,GAAG;AACvB,WAAO,MAAM,oCAAoC,GAAG,MAAM,GAAG;AAC7D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,EAAE,OAAO,QAAQ,IAAI,wBAAwB,YAAY;AAAA,IAC7D,gBAAgB;AAAA,EAClB,CAAC;AACD,MAAI,MAAM,WAAW,KAAK,CAAC,SAAS;AAClC,WAAO;AAAA,MACL;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,SAAO,QAAQ;AACf,SAAO,IAAI,2BAA2B,OAAO;AAC7C,SAAO,QAAQ;AAEf,QAAM,gBAAgB,MAAM,iBAAiB;AAC7C,QAAM,cAAc,mBAAmB,aAAa;AACpD,MAAI,CAAC,aAAa;AAChB,WAAO,MAAM,oDAAoD;AACjE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,QAAQ,MAAM,YAAY,4BAA4B,YAAY;AACtE,WAAO,SAAS,WAAW;AAAA,EAC7B,CAAC;AAED,QAAM,oBAAoB,sBAAsB;AAChD,QAAM,kBAAkB,aAAa,MAAM;AAC3C,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAuB,OAAO;AAAA,EAChC;AAEA,SAAO,QAAQ;AACf,SAAO,KAAK,YAAY,OAAO,SAAS,YAAY,CAAC,iBAAiB;AACtE,SAAO,IAAI,gEAAgE;AAC3E,SAAO,QAAQ;AAEf,QAAM,YAAY,MAAM,oBAAoB;AAE5C,MAAI,eAAe;AACnB,QAAM,eAAe,MAAM;AACzB,mBAAe;AAAA,EACjB;AACA,UAAQ,GAAG,UAAU,YAAY;AACjC,UAAQ,GAAG,WAAW,YAAY;AAElC,MAAI;AACJ,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM;AAAA,MACvB;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACV;AACA,iBAAa,OAAO,YAAY;AAAA,EAClC,SAAS,OAAO;AACd,QAAI,SAAS,OAAO,UAAU,YAAY,cAAc,OAAO;AAC7D,mBAAa,MAAM;AAAA,IACrB;AACA,WAAO,MAAM,GAAG,YAAY,oBAAoB,KAAK,EAAE;AAAA,EACzD,UAAE;AACA,YAAQ,IAAI,UAAU,YAAY;AAClC,YAAQ,IAAI,WAAW,YAAY;AAAA,EACrC;AAEA,SAAO,QAAQ;AAEf,MAAI,cAAc;AAChB,WAAO,QAAQ,oDAAoD;AACnE;AAAA,EACF;AAEA,QAAM,iBAAiB,MAAM,cAAc,SAAS;AACpD,MAAI,gBAAgB;AAClB,WAAO,QAAQ,GAAG,YAAY,sCAAsC;AAGpE,UAAM,qBAAqB,GAAG,QAAQ,KAAK;AAE3C;AAAA,EACF;AAEA,QAAM,gBAAgB,eAAe;AACrC,MAAI,eAAe;AACjB,WAAO;AAAA,MACL,GAAG,YAAY;AAAA,IACjB;AACA;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG,YAAY;AAAA,EACjB;AACF;AAEA,SAAS,oBAAoB,MAAgC;AAC3D,QAAM,eAAe,KAAK,QAAQ;AAAA,IAAO,CAAC,WACxC,OAAO,MAAM,KAAK;AAAA,EACpB,EAAE;AACF,QAAM,eAAe,KAAK,cAAc,OAAO,CAAC,OAAO,WAAW;AAChE,UAAM,eAAe,OAAO,YAAY,CAAC,GAAG;AAAA,MAAO,CAAC,YAClD,QAAQ,MAAM,KAAK;AAAA,IACrB,EAAE;AACF,WAAO,QAAQ;AAAA,EACjB,GAAG,CAAC;AACJ,QAAM,cAAc,KAAK,YAAY,CAAC,GAAG;AAAA,IAAO,CAAC,YAC/C,QAAQ,MAAM,KAAK;AAAA,EACrB,EAAE;AACF,SAAO,eAAe,eAAe;AACvC;AAEA,eAAe,qBACb,UACA,OACe;AACf,QAAM,YAAY;AAClB,MAAI,eAAe;AAEnB,aAAW,QAAQ,OAAO;AACxB,QAAI;AACF,UAAI,KAAK,WAAW,YAAY,OAAO,KAAK,cAAc,UAAU;AAClE,cAAM,qBAAqB,UAAU,KAAK,WAAW,SAAS;AAC9D;AAAA,MACF,WAAW,KAAK,WAAW,aAAa,KAAK,WAAW;AAEtD,cAAM,aAAa,UAAU,IAAI,KAAK,MAAM,IAAI,SAAS,EAAE;AAC3D;AAAA,MACF;AAAA,IAEF,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,MAAI,eAAe,GAAG;AACpB,WAAO;AAAA,MACL,cAAc,YAAY,iBAAiB,eAAe,IAAI,MAAM,EAAE;AAAA,IACxE;AAAA,EACF;AACF;;;AE9PA,SAAS,gBAAAC,eAAc,iBAAAC,gBAAe,cAAAC,aAAY,aAAAC,kBAAiB;AACnE,SAAS,QAAAC,aAAY;AACrB,SAAS,eAAe;;;ACFxB;AAAA,EACE,MAAQ;AAAA,EACR,SAAW;AAAA,EACX,aAAe;AAAA,EACf,UAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,UAAY;AAAA,EACZ,MAAQ;AAAA,IACN,KAAO;AAAA,EACT;AAAA,EACA,YAAc;AAAA,IACZ,MAAQ;AAAA,IACR,KAAO;AAAA,EACT;AAAA,EACA,SAAW;AAAA,EACX,QAAU;AAAA,EACV,MAAQ;AAAA,EACR,SAAW;AAAA,IACT,KAAK;AAAA,MACH,QAAU;AAAA,MACV,OAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,MAAQ;AAAA,EACR,OAAS;AAAA,EACT,KAAO;AAAA,IACL,MAAQ;AAAA,EACV;AAAA,EACA,OAAS;AAAA,IACP;AAAA,IACA;AAAA,EACF;AAAA,EACA,SAAW;AAAA,IACT,OAAS;AAAA,IACT,KAAO;AAAA,IACP,OAAS;AAAA,IACT,MAAQ;AAAA,IACR,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,MAAQ;AAAA,IACR,YAAY;AAAA,IACZ,QAAU;AAAA,IACV,gBAAgB;AAAA,IAChB,WAAa;AAAA,IACb,gBAAkB;AAAA,IAClB,SAAW;AAAA,EACb;AAAA,EACA,cAAgB;AAAA,IACd,OAAS;AAAA,IACT,WAAa;AAAA,IACb,OAAS;AAAA,IACT,UAAY;AAAA,IACZ,KAAO;AAAA,IACP,MAAQ;AAAA,EACV;AAAA,EACA,iBAAmB;AAAA,IACjB,cAAc;AAAA,IACd,+BAA+B;AAAA,IAC/B,yBAAyB;AAAA,IACzB,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,oCAAoC;AAAA,IACpC,6BAA6B;AAAA,IAC7B,uBAAuB;AAAA,IACvB,QAAU;AAAA,IACV,0BAA0B;AAAA,IAC1B,UAAY;AAAA,IACZ,oBAAoB;AAAA,IACpB,MAAQ;AAAA,IACR,KAAO;AAAA,IACP,YAAc;AAAA,IACd,QAAU;AAAA,EACZ;AAAA,EACA,SAAW;AAAA,IACT,MAAQ;AAAA,EACV;AAAA,EACA,eAAiB;AAAA,IACf,QAAU;AAAA,EACZ;AACF;;;ADjFA,IAAM,mBAAmB;AACzB,IAAM,YAAYC,MAAK,QAAQ,GAAG,OAAO;AACzC,IAAM,aAAaA,MAAK,WAAW,oBAAoB;AACvD,IAAM,4BAA4B,KAAK,KAAK,KAAK;AACjD,IAAM,mBAAmB;AAiBlB,SAAS,aAAqB;AACnC,SAAO,gBAAY;AACrB;AAMO,SAAS,gBAAgB,GAAW,GAAmB;AAC5D,QAAM,eAAe,CAAC,MAAc;AAClC,UAAM,CAAC,IAAI,IAAI,EAAE,MAAM,GAAG;AAC1B,WAAO,KAAK,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AAAA,EACnD;AAEA,QAAM,SAAS,aAAa,CAAC;AAC7B,QAAM,SAAS,aAAa,CAAC;AAE7B,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,OAAO,OAAO,CAAC,KAAK;AAC1B,UAAM,OAAO,OAAO,CAAC,KAAK;AAC1B,QAAI,OAAO,KAAM,QAAO;AACxB,QAAI,OAAO,KAAM,QAAO;AAAA,EAC1B;AACA,SAAO;AACT;AAKA,SAAS,YAAiC;AACxC,MAAI;AACF,QAAI,CAACC,YAAW,UAAU,EAAG,QAAO;AACpC,UAAM,UAAUC,cAAa,YAAY,MAAM;AAC/C,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,SAAS,WAAW,OAA2B;AAC7C,MAAI;AACF,QAAI,CAACD,YAAW,SAAS,GAAG;AAC1B,MAAAE,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,IAC1C;AACA,IAAAC,eAAc,YAAY,KAAK,UAAU,KAAK,GAAG,MAAM;AAAA,EACzD,QAAQ;AAAA,EAER;AACF;AAKA,eAAe,qBAA6C;AAC1D,MAAI;AACF,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,gBAAgB;AAEvE,UAAM,WAAW,MAAM,MAAM,kBAAkB;AAAA,MAC7C,QAAQ,WAAW;AAAA,MACnB,SAAS,EAAE,QAAQ,mBAAmB;AAAA,IACxC,CAAC;AAED,iBAAa,SAAS;AAEtB,QAAI,CAAC,SAAS,GAAI,QAAO;AAEzB,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,KAAK,WAAW;AAAA,EACzB,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAMA,eAAsB,gBACpB,kBAA0B,2BACG;AAC7B,QAAM,iBAAiB,WAAW;AAClC,QAAM,QAAQ,UAAU;AACxB,QAAM,MAAM,KAAK,IAAI;AAGrB,MAAI,SAAS,MAAM,MAAM,YAAY,iBAAiB;AACpD,UAAM,kBACJ,gBAAgB,MAAM,eAAe,cAAc,IAAI;AACzD,WAAO;AAAA,MACL;AAAA,MACA,eAAe,MAAM;AAAA,MACrB;AAAA,MACA,aAAa,MAAM;AAAA,IACrB;AAAA,EACF;AAGA,QAAM,gBAAgB,MAAM,mBAAmB;AAE/C,MAAI,eAAe;AACjB,eAAW,EAAE,eAAe,WAAW,IAAI,CAAC;AAC5C,UAAM,kBAAkB,gBAAgB,eAAe,cAAc,IAAI;AACzE,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa;AAAA,IACf;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA,eAAe,OAAO,iBAAiB;AAAA,IACvC,iBAAiB,QACb,gBAAgB,MAAM,eAAe,cAAc,IAAI,IACvD;AAAA,IACJ,aAAa,OAAO,aAAa;AAAA,EACnC;AACF;AAKO,SAAS,0BACd,gBACA,eACQ;AACR,SAAO,qBAAqB,cAAc,WAAM,aAAa;AAAA;AAC/D;;;AEnIA,SAAS,cACP,OACA,SACQ;AACR,MAAI,UAAU,UAAU;AACtB,WAAO;AAAA,EACT;AACA,MAAI,UAAU,UAAU;AACtB,WAAO;AAAA,EACT;AACA,SAAO,UAAU,iBAAiB;AACpC;AAEA,SAAS,qBAAqB,UAA0B;AACtD,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO,SAAS,QAAQ,MAAM,GAAG,EAAE,YAAY;AAAA,EACnD;AACF;AAEA,SAAS,uBAAuB,MAAkC;AAChE,MAAI,KAAK,QAAQ,KAAK,MAAM;AAC1B,WAAO,GAAG,KAAK,IAAI,IAAI,KAAK,IAAI;AAAA,EAClC;AACA,MAAI,KAAK,MAAM;AACb,WAAO,KAAK;AAAA,EACd;AACA,MAAI,KAAK,WAAW,UAAU;AAC5B,UAAM,aAAa,KAAK,QACpB,KAAK,MAAM,QAAQ,MAAM,GAAG,EAAE,YAAY,IAC1C;AACJ,WAAO,IAAI,UAAU;AAAA,EACvB;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,MAAc,WAA2B;AACrE,QAAM,aAAa,KAAK,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAClD,MAAI,WAAW,UAAU,WAAW;AAClC,WAAO;AAAA,EACT;AACA,SAAO,GAAG,WAAW,MAAM,GAAG,YAAY,CAAC,CAAC;AAC9C;AAEA,eAAsB,gBAA+B;AACnD,QAAMC,WAAU,WAAW;AAC3B,SAAO,KAAK,wBAAwB,OAAO,MAAM,IAAIA,QAAO,EAAE,CAAC,EAAE;AACjE,SAAO,QAAQ;AAGf,QAAM,UAAU,MAAM,aAAa;AACnC,MAAI,CAAC,SAAS;AACZ,WAAO,MAAM,uBAAuB;AACpC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,WAAW;AAC1B,QAAM,iBAAiB,kBAAkB,MAAM;AAG/C,SAAO,KAAK,gBAAgB;AAC5B,MAAI,aAAa,GAAG;AAClB,WAAO,QAAQ,mBAAmB;AAAA,EACpC,OAAO;AACL,WAAO,QAAQ,wCAAwC;AAAA,EACzD;AAEA,MAAI,eAAe,MAAM,GAAG;AAC1B,UAAM,WAAW,aAAa,MAAM;AACpC,UAAM,QAAQ,SAAS,MAAM,IAAI,EAAE;AACnC,WAAO,QAAQ,KAAK,OAAO,SAAS,IAAI,WAAW,KAAK,SAAS;AAAA,EACnE,OAAO;AACL,WAAO,QAAQ,KAAK,OAAO,SAAS,IAAI,YAAY;AAAA,EACtD;AAEA,SAAO,QAAQ;AAGf,SAAO,KAAK,cAAc;AAC1B,QAAM,eAAe,uBAAuB,OAAO,GAAG,QAAQ;AAC9D,SAAO,KAAK,aAAa,OAAO,SAAS,YAAY,CAAC,EAAE;AACxD,MAAI,OAAO,GAAG,mBAAmB;AAC/B,UAAM,eAAe,uBAAuB,OAAO,GAAG,iBAAiB;AACvE,WAAO;AAAA,MACL,eAAe,YAAY,WAAW,OAAO,GAAG,gBAAgB,YAAY,UAAU;AAAA,IACxF;AAAA,EACF;AACA,SAAO,QAAQ;AAGf,SAAO,KAAK,gBAAgB;AAC5B,QAAM,SAAS,MAAM,YAAY;AACjC,MAAI,QAAQ;AACV,WAAO,QAAQ,4BAA4B;AAAA,EAC7C,OAAO;AACL,WAAO,MAAM,gCAAgC;AAAA,EAC/C;AAGA,QAAM,WAAW,MAAM,eAAe;AACtC,QAAM,WAAW,MAAM,eAAe;AAEtC,QAAM,oBAAoB,CAAC,aAA0C;AACnE,UAAM,WAAW,OAAO,GAAG,aAAa;AACxC,UAAM,aAAa,OAAO,GAAG,sBAAsB;AACnD,UAAM,SAAS,WAAW,cAAc,aAAa,gBAAgB;AACrE,WAAO;AAAA,EACT;AAEA,MAAI,UAAU;AACZ,WAAO,QAAQ,yBAAyB,kBAAkB,QAAQ,CAAC,EAAE;AAAA,EACvE,OAAO;AACL,WAAO,MAAM,yBAAyB,kBAAkB,QAAQ,CAAC,EAAE;AAAA,EACrE;AAEA,MAAI,UAAU;AACZ,WAAO,QAAQ,yBAAyB,kBAAkB,QAAQ,CAAC,EAAE;AAAA,EACvE,OAAO;AACL,WAAO,MAAM,yBAAyB,kBAAkB,QAAQ,CAAC,EAAE;AAAA,EACrE;AAEA,SAAO,QAAQ;AAGf,SAAO,KAAK,aAAa;AACzB,QAAM,gBAAgB,MAAM,iBAAiB;AAC7C,QAAM,SAAS,MAAM,eAAe;AACpC,QAAM,cAAc,MAAM,sBAAsB;AAChD,QAAM,aAAa,MAAM,iBAAiB;AAE1C,SAAO,KAAK,aAAa,OAAO,OAAO,aAAa,CAAC,EAAE;AAEvD,MAAI,QAAQ;AACV,WAAO,KAAK,4CAA4C;AAAA,EAC1D,OAAO;AACL,UAAM,aAAa,gBAAgB,aAAa;AAChD,QAAI,YAAY;AACd,aAAO,KAAK,YAAY,OAAO,MAAM,IAAI,WAAW,WAAW,EAAE,CAAC,EAAE;AACpE,aAAO,KAAK,WAAW,WAAW,IAAI,EAAE;AAAA,IAC1C;AAEA,UAAM,UAAU,MAAM,oBAAoB,UAAU;AACpD,WAAO,KAAK,sBAAsB,UAAU,KAAK,QAAQ,MAAM,EAAE;AAEjE,UAAM,WAAW,MAAM,mBAAmB;AAC1C,QAAI,UAAU;AACZ,aAAO,QAAQ,wBAAwB;AAAA,IACzC,OAAO;AACL,aAAO,QAAQ,0BAA0B;AAAA,IAC3C;AAAA,EACF;AAEA,MAAI,aAAa;AACf,WAAO,QAAQ,2BAA2B;AAAA,EAC5C;AAEA,SAAO,QAAQ;AAGf,MAAI,WAAoD;AACxD,MAAI,wBAAwB;AAE5B,MAAI,CAAC,QAAQ;AACX,UAAM,cAAc,mBAAmB,aAAa;AACpD,QAAI,aAAa;AACf,aAAO,KAAK,eAAe;AAC3B,UAAI;AACF,cAAM,QAAQ,MAAM,SAAS,WAAW;AACxC,eAAO,KAAK,MAAM,MAAM,MAAM,KAAK,MAAM,KAAK,EAAE;AAChD,eAAO,KAAK,YAAY,MAAM,KAAK,EAAE;AACrC,eAAO,KAAK,aAAa,MAAM,OAAO,KAAK,IAAI,CAAC,EAAE;AAGlD,YAAI,MAAM,OAAO,SAAS,eAAe,KAAK,GAAG;AAC/C,iBAAO,KAAK,eAAe,OAAO,MAAM,UAAU,CAAC,EAAE;AAAA,QACvD,WAAW,MAAM,OAAO,SAAS,eAAe,UAAU,GAAG;AAC3D,iBAAO,KAAK,eAAe,OAAO,MAAM,gBAAgB,CAAC,EAAE;AAAA,QAC7D,WAAW,MAAM,OAAO,SAAS,eAAe,SAAS,GAAG;AAC1D,iBAAO,KAAK,eAAe,OAAO,MAAM,cAAc,CAAC,EAAE;AAAA,QAC3D,WAAW,MAAM,OAAO,SAAS,eAAe,OAAO,GAAG;AACxD,iBAAO,KAAK,eAAe,OAAO,MAAM,YAAY,CAAC,EAAE;AAAA,QACzD;AAAA,MACF,QAAQ;AACN,eAAO,QAAQ,4BAA4B,WAAW,EAAE;AAAA,MAC1D;AACA,aAAO,QAAQ;AAAA,IACjB;AAGA,WAAO,KAAK,eAAe;AAC3B,eAAW,MAAM,YAAY;AAC7B,QAAI,UAAU;AACZ,YAAM,eAAe,cAAc,SAAS,OAAO,SAAS,OAAO;AACnE,aAAO,KAAK,SAAS,SAAS,MAAM,KAAK,YAAY,EAAE;AACvD,aAAO,KAAK,KAAK,OAAO,IAAI,SAAS,GAAG,CAAC,EAAE;AAE3C,UAAI,SAAS,UAAU,QAAQ;AAE7B,YAAI;AACF,gBAAM,sBAAsB,MAAM,uBAAuB;AACzD,gBAAM,aAAa,MAAM,gBAAgB,SAAS,MAAM;AACxD,gBAAM,EAAE,MAAM,IAAI,wBAAwB,YAAY;AAAA,YACpD,gBAAgB;AAAA,UAClB,CAAC;AACD,kCAAwB,MAAM,SAAS;AAEvC,cAAI,SAAS,gBAAgB;AAC3B,mBAAO;AAAA,cACL,aAAa,qBAAqB,SAAS,cAAc,CAAC;AAAA,YAC5D;AAAA,UACF;AAEA,cAAI,MAAM,SAAS,GAAG;AACpB,mBAAO;AAAA,cACL,KAAK,MAAM,MAAM,sBAAsB,MAAM,SAAS,IAAI,MAAM,EAAE,gBAAgB,OAAO,QAAQ,UAAU,CAAC;AAAA,YAC9G;AACA,uBAAW,QAAQ,OAAO;AACxB,oBAAM,WAAW,uBAAuB,IAAI;AAC5C,oBAAM,OAAO,qBAAqB,KAAK,MAAM,EAAE;AAC/C,qBAAO,IAAI,OAAO,QAAQ,KAAK,IAAI,EAAE;AAAA,YACvC;AAAA,UACF,WAAW,SAAS,mBAAmB,YAAY;AACjD,mBAAO,QAAQ,mBAAmB;AAAA,UACpC,OAAO;AACL,mBAAO,KAAK,iCAAiC;AAAA,UAC/C;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF,WAAW,SAAS,UAAU,UAAU;AACtC,eAAO,QAAQ,4BAA4B;AAC3C,eAAO;AAAA,UACL,SAAS,OAAO,QAAQ,+BAA+B,CAAC;AAAA,QAC1D;AAAA,MACF,WAAW,SAAS,UAAU,UAAU;AACtC,eAAO,QAAQ,sCAAsC;AACrD,eAAO;AAAA,UACL;AAAA,QACF;AAAA,MACF;AAAA,IACF,OAAO;AACL,aAAO,KAAK,qBAAqB;AACjC,aAAO,IAAI,SAAS,OAAO,QAAQ,SAAS,CAAC,gBAAgB;AAAA,IAC/D;AACA,WAAO,QAAQ;AAAA,EACjB;AAGA,SAAO,KAAK,oBAAoB;AAChC,MAAI,QAAQ;AACV,WAAO,KAAK;AAAA,MACV,GAAG,OAAO,QAAQ,WAAW,CAAC;AAAA,MAC9B,GAAG,OAAO,QAAQ,iBAAiB,CAAC;AAAA,MACpC,GAAG,OAAO,QAAQ,2BAA2B,CAAC;AAAA,IAChD,CAAC;AAAA,EACH,WAAW,CAAC,UAAU;AACpB,WAAO,KAAK;AAAA,MACV,GAAG,OAAO,QAAQ,SAAS,CAAC;AAAA,MAC5B,GAAG,OAAO,QAAQ,UAAU,CAAC;AAAA,IAC/B,CAAC;AAAA,EACH,WAAW,SAAS,UAAU,UAAU;AACtC,WAAO,KAAK;AAAA,MACV,GAAG,OAAO,QAAQ,+BAA+B,CAAC;AAAA,IACpD,CAAC;AAAA,EACH,WAAW,SAAS,UAAU,UAAU;AACtC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,GAAG,OAAO,QAAQ,mBAAmB,CAAC;AAAA,IACxC,CAAC;AAAA,EACH,WAAW,uBAAuB;AAChC,WAAO,KAAK;AAAA,MACV,GAAG,OAAO,QAAQ,UAAU,CAAC;AAAA,MAC7B,GAAG,OAAO,QAAQ,UAAU,CAAC;AAAA,IAC/B,CAAC;AAAA,EACH,OAAO;AACL,WAAO,KAAK;AAAA,MACV;AAAA,MACA,GAAG,OAAO,QAAQ,mBAAmB,CAAC;AAAA,IACxC,CAAC;AAAA,EACH;AACF;;;AC3TA,OAAOC,eAAc;AACrB,SAAS,SAAAC,cAAa;;;AC2EtB,eAAsB,iBAAoC;AAExD,QAAM,YAAY,MAAM,aAAa;AACrC,MAAI,CAAC,WAAW;AAEd,UAAMC,UAAS,WAAW;AAC1B,WAAO;AAAA,MACL,WAAW;AAAA,MACX,mBAAmB;AAAA,MACnB,uBAAuB;AAAA,MACvB,QAAAA;AAAA,MACA,WAAW;AAAA,MACX,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,uBAAuB;AAAA,MACvB,oBAAoB;AAAA,MACpB,SAAS,CAAC;AAAA,MACV,YAAY;AAAA,MACZ,OAAO;AAAA,MACP,gBAAgB;AAAA,MAChB,IAAI;AAAA,MACJ,gBAAgB,CAAC;AAAA,MACjB,uBAAuB;AAAA,MACvB,cAAc;AAAA,MACd,uBAAuB;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,SAAS,WAAW;AAC1B,QAAM,iBAAiB,kBAAkB,MAAM;AAG/C,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,MAAM,QAAQ,IAAI;AAAA,IACpB,YAAY;AAAA,IACZ,gBAAgB,OAAO,GAAG,QAAQ;AAAA,IAClC,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,sBAAsB;AAAA,IACtB,iBAAiB;AAAA,EACnB,CAAC;AAED,QAAM,YAAY,aAAa;AAC/B,QAAM,cAAc,eAAe,MAAM;AACzC,QAAM,aAAa,gBAAgB,MAAM;AAGzC,QAAM,CAAC,SAAS,QAAQ,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC5C,oBAAoB,UAAU;AAAA,IAC9B,mBAAmB;AAAA,EACrB,CAAC;AAGD,MAAI,QAA4B;AAChC,MAAI,iBAAiC;AACrC,MAAI,KAA0B;AAC9B,MAAI,iBAAuC,CAAC;AAC5C,MAAI,wBAAwB;AAC5B,MAAI,YAAY;AAChB,MAAI,sBAAsB;AAG1B,MAAI,CAAC,UAAU;AACb,UAAM,cAAc,mBAAmB,MAAM;AAG7C,UAAM,CAAC,aAAa,UAAU,cAAc,gBAAgB,IAC1D,MAAM,QAAQ,IAAI;AAAA,MAChB,cACI,SAAS,WAAW,EAAE,MAAM,MAAM,IAAI,IACtC,QAAQ,QAAQ,IAAI;AAAA,MACxB,YAAY,EAAE,MAAM,MAAM,IAAI;AAAA,MAC9B,gBAAgB,UAAU;AAAA,MAC1B,sBAAsB;AAAA,IACxB,CAAC;AAEH,YAAQ;AACR,SAAK;AACL,gBAAY,aAAa,YAAY;AACrC,0BAAsB;AAGtB,QAAI,OAAO;AACT,UAAI,MAAM,OAAO,SAAS,eAAe,KAAK,GAAG;AAC/C,yBAAiB;AAAA,MACnB,WAAW,MAAM,OAAO,SAAS,eAAe,UAAU,GAAG;AAC3D,yBAAiB;AAAA,MACnB,WAAW,MAAM,OAAO,SAAS,eAAe,SAAS,GAAG;AAC1D,yBAAiB;AAAA,MACnB,WAAW,MAAM,OAAO,SAAS,eAAe,OAAO,GAAG;AACxD,yBAAiB;AAAA,MACnB;AAAA,IACF;AAGA,QAAI,MAAM,GAAG,UAAU,QAAQ;AAC7B,UAAI;AACF,cAAM,sBAAsB,MAAM,uBAAuB;AACzD,cAAM,aAAa,MAAM,gBAAgB,GAAG,MAAM;AAClD,cAAM,EAAE,MAAM,IAAI,wBAAwB,YAAY;AAAA,UACpD,gBAAgB;AAAA,QAClB,CAAC;AACD,yBAAiB;AACjB,gCAAwB,MAAM,SAAS;AAAA,MACzC,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,uBAAuB;AAAA,IACvB,oBAAoB;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,uBAAuB;AAAA,EACzB;AACF;;;AChNO,SAAS,oBAAoB,OAA8B;AAChE,QAAM,UAAuB,CAAC;AAE9B,MAAI,CAAC,MAAM,aAAa,CAAC,MAAM,mBAAmB;AAChD,YAAQ,KAAK,EAAE,IAAI,QAAQ,OAAO,QAAQ,UAAU,IAAI,CAAC;AACzD,WAAO;AAAA,EACT;AAGA,MAAI,MAAM,UAAU;AAClB,YAAQ,KAAK,EAAE,IAAI,UAAU,OAAO,OAAO,UAAU,IAAI,CAAC;AAC1D,YAAQ,KAAK,EAAE,IAAI,QAAQ,OAAO,QAAQ,UAAU,IAAI,CAAC;AACzD,YAAQ,KAAK,EAAE,IAAI,mBAAmB,OAAO,MAAM,UAAU,IAAI,CAAC;AAClE,YAAQ,KAAK,EAAE,IAAI,QAAQ,OAAO,QAAQ,UAAU,IAAI,CAAC;AACzD,WAAO;AAAA,EACT;AAIA,MAAI,MAAM,uBAAuB;AAC/B,YAAQ,KAAK,EAAE,IAAI,UAAU,OAAO,UAAU,UAAU,IAAI,CAAC;AAAA,EAC/D;AAEA,MAAI,MAAM,sBAAsB,MAAM,QAAQ,SAAS,GAAG;AACxD,YAAQ,KAAK,EAAE,IAAI,QAAQ,OAAO,QAAQ,UAAU,IAAI,CAAC;AAAA,EAC3D;AAEA,MAAI,CAAC,MAAM,MAAM,MAAM,QAAQ,SAAS,GAAG;AACzC,YAAQ,KAAK,EAAE,IAAI,MAAM,OAAO,MAAM,UAAU,IAAI,CAAC;AAAA,EACvD;AAEA,MAAI,MAAM,SAAS,MAAM,IAAI,UAAU,UAAU;AAC/C,YAAQ,KAAK,EAAE,IAAI,aAAa,OAAO,aAAa,UAAU,IAAI,CAAC;AAAA,EACrE;AAEA,MAAI,MAAM,MAAM,MAAM,GAAG,UAAU,QAAQ;AACzC,QACE,MAAM,gBACN,MAAM,yBACN,MAAM,OAAO,MAAM,SACnB;AACA,cAAQ,KAAK,EAAE,IAAI,SAAS,OAAO,SAAS,UAAU,IAAI,CAAC;AAAA,IAC7D;AAAA,EACF;AAEA,MACE,MAAM,OACL,MAAM,GAAG,UAAU,YAAY,MAAM,GAAG,UAAU,WACnD;AACA,YAAQ,KAAK,EAAE,IAAI,iBAAiB,OAAO,QAAQ,UAAU,IAAI,CAAC;AAAA,EACpE;AAEA,UAAQ,KAAK,EAAE,IAAI,QAAQ,OAAO,QAAQ,UAAU,IAAI,CAAC;AACzD,UAAQ,KAAK,EAAE,IAAI,mBAAmB,OAAO,MAAM,UAAU,IAAI,CAAC;AAClE,UAAQ,KAAK,EAAE,IAAI,QAAQ,OAAO,QAAQ,UAAU,IAAI,CAAC;AAEzD,SAAO;AACT;;;ACjEA,OAAOC,YAAW;AAOlB,IAAM,YAAY,CAAC,QAAgB,IAAI,QAAQ,mBAAmB,EAAE;AACpE,IAAM,aAAa,CAAC,QAAgB,UAAU,GAAG,EAAE;AAEnD,SAAS,YAAoB;AAC3B,SAAO,KAAK,IAAI,QAAQ,OAAO,WAAW,IAAI,EAAE;AAClD;AAEA,SAAS,SAAS,MAAc,KAAqB;AACnD,MAAI,KAAK,UAAU,IAAK,QAAO;AAC/B,SAAO,KAAK,MAAM,GAAG,MAAM,CAAC,IAAI;AAClC;AAEA,SAAS,mBAAmB,MAAc,QAAwB;AAChE,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,CAAC,QAAS;AACd,QAAI,QAAQ,WAAW,GAAG,EAAG;AAC7B,QAAI,QAAQ,WAAW,KAAK,EAAG;AAC/B,QAAI,QAAQ,WAAW,OAAO,EAAG;AACjC,QAAI,QAAQ,WAAW,WAAW,EAAG;AACrC,UAAM,QAAQ,QACX,QAAQ,SAAS,EAAE,EACnB,QAAQ,0BAA0B,IAAI;AACzC,WAAO,SAAS,OAAO,MAAM;AAAA,EAC/B;AACA,SAAO;AACT;AAIA,SAAS,OAAO,OAAe,GAAmB;AAChD,QAAM,QAAQ,IAAI,KAAK;AACvB,QAAM,OAAO,IAAI,IAAI,MAAM;AAC3B,SACEC,OAAM,IAAI,QAAG,IACbA,OAAM,KAAK,KAAK,KAAK,IACrBA,OAAM,IAAI,SAAI,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC,IAAI,QAAG;AAEjD;AAEA,SAAS,OAAO,OAAe,GAAmB;AAChD,QAAM,QAAQ,IAAI,KAAK;AACvB,QAAM,OAAO,IAAI,IAAI,MAAM;AAC3B,SACEA,OAAM,IAAI,QAAG,IACbA,OAAM,KAAK,KAAK,KAAK,IACrBA,OAAM,IAAI,SAAI,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC,IAAI,QAAG;AAEjD;AAEA,SAAS,OAAO,GAAmB;AACjC,SAAOA,OAAM,IAAI,WAAM,SAAI,OAAO,IAAI,CAAC,IAAI,QAAG;AAChD;AAEA,SAAS,OAAO,GAAmB;AACjC,SAAOA,OAAM,IAAI,WAAM,SAAI,OAAO,IAAI,CAAC,IAAI,QAAG;AAChD;AAEA,SAAS,IAAI,MAAc,GAAmB;AAC5C,QAAM,QAAQ,IAAI;AAClB,QAAM,MAAM,KAAK,IAAI,GAAG,QAAQ,WAAW,IAAI,CAAC;AAChD,SAAOA,OAAM,IAAI,QAAG,IAAI,MAAM,OAAO,IAAI,OAAO,GAAG,IAAI,MAAMA,OAAM,IAAI,QAAG;AAC5E;AAIA,SAAS,cAAc,QAAwB;AAC7C,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAOA,OAAM,QAAQ,MAAM,SAAS;AAAA,IACtC,KAAK;AACH,aAAOA,OAAM,SAAS,MAAM,eAAe;AAAA,IAC7C,KAAK;AACH,aAAOA,OAAM,OAAO,MAAM,aAAa;AAAA,IACzC,KAAK;AACH,aAAOA,OAAM,MAAM,MAAM,WAAW;AAAA,IACtC;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,QAAQ,OAAqC,OAAwB;AAC5E,MAAI,UAAU,SAAU,QAAOA,OAAM,UAAU,MAAM,UAAU;AAC/D,MAAI,UAAU,SAAU,QAAOA,OAAM,MAAM,MAAM,UAAU;AAC3D,SAAO,QACHA,OAAM,SAAS,MAAM,SAAS,IAC9BA,OAAM,QAAQ,MAAM,QAAQ;AAClC;AAEA,SAAS,YAAY,UAAiC;AACpD,MAAI,CAAC,SAAU,QAAO;AACtB,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO,OAAOA,OAAM,MAAM,UAAU;AAAA,IACtC,KAAK;AACH,aAAO,OAAOA,OAAM,IAAI,mBAAmB;AAAA,IAC7C,KAAK;AACH,aAAO,OAAOA,OAAM,OAAO,gBAAgB;AAAA,IAC7C;AACE,aAAO;AAAA,EACX;AACF;AAGA,IAAM,iBAAiB;AAAA,EACrBA,OAAM,KAAK;AAAA,EACXA,OAAM,MAAM;AAAA,EACZA,OAAM,OAAO;AAAA,EACbA,OAAM,QAAQ;AAAA,EACdA,OAAM,KAAK;AAAA,EACXA,OAAM,IAAI;AACZ;AAEA,SAAS,aAAa,GAAc,OAAsC;AACxE,QAAM,MAAM,EAAE;AACd,QAAM,MAAM,EAAE,MAAM,QAAQ,GAAG;AAC/B,MAAI,OAAO,GAAG;AAEZ,UAAM,SAAS,EAAE,MAAM,MAAM,GAAG,GAAG;AACnC,UAAM,QAAQ,EAAE,MAAM,MAAM,MAAM,IAAI,MAAM;AAC5C,WAAOA,OAAM,IAAI,MAAM,IAAI,MAAM,GAAG,IAAIA,OAAM,IAAI,KAAK;AAAA,EACzD;AAEA,SAAO,MAAM,GAAG,IAAI,MAAMA,OAAM,IAAI,EAAE,KAAK;AAC7C;AAEA,SAAS,iBAAiB,SAAsB,GAAqB;AACnE,QAAM,QAAQ,QAAQ,IAAI,CAAC,GAAG,MAAM;AAClC,UAAM,QAAQ,eAAe,IAAI,eAAe,MAAM;AACtD,WAAO,aAAa,GAAG,KAAK;AAAA,EAC9B,CAAC;AACD,QAAM,QAAQ,IAAI;AAClB,QAAM,QAAkB,CAAC;AACzB,MAAI,MAAM;AACV,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,OAAO,IAAI,SAAS,IAAI,QAAQ,MAAM;AACnD,QAAI,WAAW,IAAI,IAAI,OAAO;AAC5B,YAAM,KAAK,GAAG;AACd,YAAM;AAAA,IACR,OAAO;AACL,YAAM;AAAA,IACR;AAAA,EACF;AACA,MAAI,IAAI,SAAS,EAAG,OAAM,KAAK,GAAG;AAClC,SAAO;AACT;AAOO,SAAS,kBAAkB,OAAe,SAAyB;AACxE,QAAM,IAAI,UAAU;AACpB,UAAQ,IAAI,OAAO,OAAO,CAAC,CAAC;AAC5B,aAAW,QAAQ,SAAS;AAC1B,YAAQ,IAAI,IAAI,MAAM,CAAC,CAAC;AAAA,EAC1B;AACA,UAAQ,IAAI,OAAO,CAAC,CAAC;AACvB;AAIA,SAAS,eAAe,OAAiB,GAAiB;AACxD,QAAM,WAAW,uBAAuB,MAAM,OAAO,GAAG,QAAQ;AAChE,QAAM,UAAU,MAAM,wBAClBA,OAAM,MAAM,QAAQ,IACpBA,OAAM,IAAI,QAAQ;AACtB,QAAM,QAAQ,MAAM,oBAChBA,OAAM,MAAM,eAAe,IAC3BA,OAAM,IAAI,mBAAmB;AACjC,QAAM,WAAW,MAAM,OAAO,MAAM,UAChCA,OAAM,MAAM,IAAI,IAChBA,OAAM,IAAI,KAAK;AAEnB,UAAQ,IAAI,IAAIA,OAAM,IAAI,YAAY,IAAI,SAAS,CAAC,CAAC;AACrD,UAAQ,IAAI,IAAIA,OAAM,IAAI,YAAY,IAAI,OAAO,CAAC,CAAC;AACnD,UAAQ,IAAI,IAAIA,OAAM,IAAI,YAAY,IAAI,UAAU,CAAC,CAAC;AACxD;AAIO,SAAS,gBACd,OACA,SACA,MACA,YACM;AACN,QAAM,IAAI,UAAU;AACpB,QAAM,UAAU,IAAI;AACpB,QAAMC,WAAU,WAAW;AAE3B,QAAM,aAAa,SAASA,QAAO;AACnC,UAAQ,IAAI,OAAO,YAAY,CAAC,CAAC;AACjC,iBAAe,OAAO,CAAC;AAGvB,MAAI,CAAC,MAAM,WAAW;AACpB,YAAQ,IAAI,IAAID,OAAM,IAAI,sBAAsB,GAAG,CAAC,CAAC;AACrD,YAAQ;AAAA,MACN,IAAIA,OAAM,IAAI,4CAA4C,GAAG,CAAC;AAAA,IAChE;AACA,YAAQ,IAAI,OAAO,CAAC,CAAC;AACrB;AAAA,EACF;AACA,MAAI,CAAC,MAAM,mBAAmB;AAC5B,YAAQ,IAAI,IAAIA,OAAM,IAAI,8BAA8B,GAAG,CAAC,CAAC;AAC7D,YAAQ,IAAI,IAAIA,OAAM,IAAI,oBAAoB,GAAG,CAAC,CAAC;AACnD,YAAQ,IAAI,OAAO,CAAC,CAAC;AACrB;AAAA,EACF;AAGA,MAAI,MAAM,UAAU;AAClB,YAAQ;AAAA,MACN;AAAA,QACEA,OAAM,QAAQ,MAAM,MAAM,IAAIA,OAAM,IAAI,iCAA8B;AAAA,QACtE;AAAA,MACF;AAAA,IACF;AACA,QAAI,MAAM,uBAAuB;AAC/B,cAAQ,IAAI,IAAIA,OAAM,OAAO,4BAAuB,GAAG,CAAC,CAAC;AAAA,IAC3D;AACA,QAAI,MAAM;AACR,cAAQ,IAAI,OAAO,QAAQ,CAAC,CAAC;AAC7B,cAAQ,IAAI,IAAIA,OAAM,OAAO,IAAI,GAAG,CAAC,CAAC;AAAA,IACxC;AACA,YAAQ,IAAI,OAAO,CAAC,CAAC;AACrB,QAAI,YAAY;AACd,cAAQ,IAAI,IAAIA,OAAM,OAAO,kBAAa,GAAG,CAAC,CAAC;AAAA,IACjD,OAAO;AACL,iBAAW,QAAQ,iBAAiB,SAAS,CAAC,GAAG;AAC/C,gBAAQ,IAAI,IAAI,MAAM,CAAC,CAAC;AAAA,MAC1B;AAAA,IACF;AACA,YAAQ,IAAI,OAAO,CAAC,CAAC;AACrB,YAAQ,IAAI;AACZ;AAAA,EACF;AAGA,QAAM,UAAU,CAAC,UAAkB;AACjC,YAAQ,IAAI,OAAO,OAAO,CAAC,CAAC;AAAA,EAC9B;AAGA,UAAQ,QAAQ;AAChB,MAAI,MAAM,OAAO;AACf,YAAQ;AAAA,MACN;AAAA,QACEA,OAAM,KAAK,IAAI,MAAM,MAAM,MAAM,EAAE,IACjC,OACAA,OAAM,KAAK,SAAS,MAAM,MAAM,OAAO,UAAU,CAAC,CAAC;AAAA,QACrD;AAAA,MACF;AAAA,IACF;AACA,UAAM,OAAO,mBAAmB,MAAM,MAAM,MAAM,OAAO;AACzD,QAAI,KAAM,SAAQ,IAAI,IAAIA,OAAM,IAAI,IAAI,GAAG,CAAC,CAAC;AAC7C,UAAM,OAAiB,CAAC;AACxB,QAAI,MAAM,mBAAmB;AAC3B,WAAK,KAAK,cAAc,MAAM,cAAc,CAAC;AAC/C,eAAW,UAAU,CAAC,SAAS,aAAa,SAAS,OAAO,GAAG;AAC7D,YAAM,IAAI,MAAM,MAAM,OAAO,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM,CAAC;AAC7D,UAAI,EAAG,MAAK,KAAKA,OAAM,IAAI,CAAC,CAAC;AAAA,IAC/B;AACA,QAAI,KAAK,OAAQ,SAAQ,IAAI,IAAI,KAAK,KAAK,IAAI,GAAG,CAAC,CAAC;AAAA,EACtD,OAAO;AACL,YAAQ,IAAI,IAAIA,OAAM,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAAA,EAClD;AAGA,UAAQ,QAAQ;AAChB,UAAQ,IAAI,IAAIA,OAAM,QAAQ,MAAM,MAAM,GAAG,CAAC,CAAC;AAC/C,QAAM,OAAiB,CAAC;AACxB,MAAI,MAAM,QAAQ,SAAS;AACzB,SAAK,KAAKA,OAAM,IAAI,GAAG,MAAM,QAAQ,MAAM,QAAQ,CAAC;AACtD,MAAI,MAAM,sBAAuB,MAAK,KAAKA,OAAM,OAAO,oBAAe,CAAC;AACxE,MAAI,MAAM,mBAAoB,MAAK,KAAKA,OAAM,OAAO,iBAAY,CAAC;AAClE,MACE,CAAC,MAAM,yBACP,CAAC,MAAM,sBACP,MAAM,QAAQ,SAAS,GACvB;AACA,SAAK,KAAKA,OAAM,MAAM,eAAU,CAAC;AAAA,EACnC;AACA,MAAI,KAAK,OAAQ,SAAQ,IAAI,IAAI,KAAK,KAAKA,OAAM,IAAI,UAAO,CAAC,GAAG,CAAC,CAAC;AAGlE,UAAQ,cAAc;AACtB,MAAI,MAAM,IAAI;AACZ,UAAM,YAAY,MAAM,GAAG,QACvB,OAAO,SAAS,MAAM,GAAG,OAAO,UAAU,EAAE,IAC5C;AACJ,YAAQ,IAAI,IAAIA,OAAM,KAAK,IAAI,MAAM,GAAG,MAAM,EAAE,IAAI,WAAW,CAAC,CAAC;AACjE,YAAQ;AAAA,MACN;AAAA,QACE,QAAQ,MAAM,GAAG,OAAO,MAAM,GAAG,OAAO,IACtC,YAAY,MAAM,GAAG,cAAc;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AACA,QAAI,MAAM,uBAAuB;AAC/B,YAAM,IAAI,MAAM,eAAe;AAC/B,cAAQ;AAAA,QACN;AAAA,UACEA,OAAM,OAAO,GAAG,CAAC,sBAAsB,MAAM,IAAI,MAAM,EAAE,UAAU;AAAA,UACnE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,QACE,MAAM,gBACN,MAAM,yBACN,MAAM,OAAO,MAAM,WACnB,MAAM,GAAG,UAAU,QACnB;AACA,cAAQ;AAAA,QACN;AAAA,UACEA,OAAM,KAAK,qBAAqB,IAC9BA,OAAM,IAAI,+BAA4B;AAAA,UACxC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,YAAQ,IAAI,IAAIA,OAAM,IAAI,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC;AAAA,EAC7C,OAAO;AACL,YAAQ,IAAI,IAAIA,OAAM,IAAI,eAAe,GAAG,CAAC,CAAC;AAAA,EAChD;AAGA,UAAQ,SAAS;AACjB,MAAI,MAAM,QAAQ,SAAS,GAAG;AAC5B,UAAM,MAAM;AACZ,eAAW,KAAK,MAAM,QAAQ,MAAM,GAAG,GAAG,GAAG;AAC3C,cAAQ,IAAI,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;AAAA,IAC3C;AACA,QAAI,MAAM,QAAQ,SAAS,KAAK;AAC9B,cAAQ;AAAA,QACN,IAAIA,OAAM,IAAI,cAAS,MAAM,QAAQ,SAAS,GAAG,OAAO,GAAG,CAAC;AAAA,MAC9D;AAAA,IACF;AAAA,EACF,OAAO;AACL,YAAQ,IAAI,IAAIA,OAAM,IAAI,YAAY,GAAG,CAAC,CAAC;AAAA,EAC7C;AAGA,MAAI,MAAM;AACR,YAAQ,MAAM;AACd,YAAQ,IAAI,IAAIA,OAAM,OAAO,IAAI,GAAG,CAAC,CAAC;AAAA,EACxC;AAGA,UAAQ,IAAI,OAAO,CAAC,CAAC;AACrB,MAAI,YAAY;AACd,YAAQ,IAAI,IAAIA,OAAM,OAAO,kBAAa,GAAG,CAAC,CAAC;AAAA,EACjD,OAAO;AACL,eAAW,QAAQ,iBAAiB,SAAS,CAAC,GAAG;AAC/C,cAAQ,IAAI,IAAI,MAAM,CAAC,CAAC;AAAA,IAC1B;AAAA,EACF;AACA,UAAQ,IAAI,OAAO,CAAC,CAAC;AACvB;AAEO,SAAS,cAAoB;AAClC,UAAQ,OAAO,MAAM,gBAAgB;AACvC;;;AHpVA,IAAM,SAAS,uBAAO,QAAQ;AAE9B,eAAe,QAAQ,SAAmC;AACxD,QAAM,EAAE,GAAG,IAAI,MAAME,UAAS,OAAwB;AAAA,IACpD;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAEA,eAAe,WAAW,WAAsC;AAC9D,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,EAAE,MAAM,IAAI;AAClB,UAAM,SAAS,MAAM;AACrB,UAAM,WAAW,IAAI;AACrB,UAAM,OAAO;AACb,UAAM,YAAY,MAAM;AAExB,UAAM,SAAS,CAAC,QAAgB;AAE9B,UAAI,QAAQ,KAAQ;AAClB,cAAM,WAAW,UAAU,KAAK;AAChC,cAAM,MAAM;AACZ,cAAM,eAAe,QAAQ,MAAM;AACnC,gBAAQ,GAAG;AACX;AAAA,MACF;AAEA,UAAI,UAAU,SAAS,GAAG,GAAG;AAC3B,cAAM,WAAW,UAAU,KAAK;AAChC,cAAM,MAAM;AACZ,cAAM,eAAe,QAAQ,MAAM;AACnC,gBAAQ,GAAG;AAAA,MACb;AAAA,IACF;AAEA,UAAM,GAAG,QAAQ,MAAM;AAAA,EACzB,CAAC;AACH;AAEA,eAAe,cACb,UACA,OACkB;AAClB,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO;AAAA,IAET,KAAK,QAAQ;AACX,kBAAY;AACZ,UAAI;AACF,cAAM,YAAY,CAAC,CAAC;AAAA,MACtB,SAAS,OAAO;AACd,eAAO,MAAM,gBAAgB,KAAK,EAAE;AAAA,MACtC;AACA,YAAM,eAAe;AACrB,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,UAAU;AACb,kBAAY;AACZ,YAAM,EAAE,YAAY,IAAI,MAAMA,UAAS,OAAgC;AAAA,QACrE;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF,CAAC;AACD,UAAI,CAAC,YAAY,KAAK,GAAG;AACvB,eAAO,KAAK,WAAW;AACvB,eAAO;AAAA,MACT;AACA,UAAI;AACF,cAAM,cAAc,aAAa,CAAC,CAAC;AAAA,MACrC,SAAS,OAAO;AACd,eAAO,MAAM,kBAAkB,KAAK,EAAE;AAAA,MACxC;AACA,YAAM,eAAe;AACrB,aAAO;AAAA,IACT;AAAA,IAEA,KAAK;AACH,kBAAY;AACZ,YAAM,aAAa,KAAK;AACxB,YAAM,eAAe;AACrB,aAAO;AAAA,IAET,KAAK;AACH,kBAAY;AACZ,YAAM,WAAW;AACjB,YAAM,eAAe;AACrB,aAAO;AAAA,IAET,KAAK,MAAM;AACT,kBAAY;AACZ,UAAI,CAAE,MAAM,QAAQ,wBAAwB,EAAI,QAAO;AACvD,YAAM,UAAU,CAAC,CAAC;AAClB,YAAM,eAAe;AACrB,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,aAAa;AAChB,kBAAY;AACZ,YAAM,aAAa,MAAM,QAAQ,SAAS;AAC1C,YAAM,cAAc,MAAM;AAC1B,UAAI;AACJ,UAAI,eAAe,YAAY;AAC7B,cAAM;AAAA,MACR,WAAW,YAAY;AACrB,cACE;AAAA,MACJ,OAAO;AACL,cAAM;AAAA,MACR;AACA,UAAI,CAAE,MAAM,QAAQ,GAAG,EAAI,QAAO;AAClC,YAAM,gBAAgB,KAAK;AAC3B,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,SAAS;AACZ,kBAAY;AACZ,UAAI,CAAE,MAAM,QAAQ,6BAA6B,EAAI,QAAO;AAC5D,YAAM,mBAAmB,KAAK;AAC9B,YAAM,eAAe;AACrB,aAAO;AAAA,IACT;AAAA,IAEA,KAAK;AACH,kBAAY;AACZ,YAAM,qBAAqB,KAAK;AAChC,aAAO;AAAA,IAET,KAAK,iBAAiB;AACpB,kBAAY;AACZ,UAAI,CAAE,MAAM,QAAQ,wBAAwB,EAAI,QAAO;AACvD,YAAM,mBAAmB;AACzB,aAAO;AAAA,IACT;AAAA,IAEA;AACE,aAAO;AAAA,EACX;AACF;AAEA,eAAe,aAAa,OAAgC;AAC1D,MAAI;AACF,UAAM,EAAE,QAAQ,OAAO,IAAI,MAAMC,OAAM,OAAO,CAAC,UAAU,SAAS,CAAC;AACnE,QAAI,CAAC,OAAO,KAAK,GAAG;AAClB,aAAO,KAAK,sBAAsB;AAClC;AAAA,IACF;AAEA,WAAO,KAAK,UAAU;AACtB,YAAQ,IAAI,MAAM;AAClB,YAAQ,IAAI;AAGZ,UAAMA,OAAM,OAAO,CAAC,OAAO,IAAI,CAAC;AAGhC,UAAM,EAAE,QAAQ,SAAS,IAAI,MAAMA,OAAM,OAAO;AAAA,MAC9C;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,UAAM,EAAE,QAAQ,UAAU,IAAI,MAAMA,OAAM,OAAO,CAAC,QAAQ,UAAU,CAAC;AACrE,UAAM,eAAe,WAAW,SAAS,WAAW,MAAM,GAAG,GAAI;AAEjE,UAAM,cAAc,MAAM,OAAO,UAAU;AAC3C,UAAM,aAAa,MAAM,OAAO,SAAS;AACzC,UAAM,WAAW,MAAM,OAAO,GAAG;AACjC,UAAM,eAAe,uBAAuB,QAAQ;AAEpD,UAAM,EAAE,KAAK,IAAI,MAAMD,UAAS,OAAkC;AAAA,MAChE;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,UACP,EAAE,MAAM,iBAAiB,YAAY,IAAI,OAAO,KAAK;AAAA,UACrD,EAAE,MAAM,kBAAkB,OAAO,SAAS;AAAA,QAC5C;AAAA,MACF;AAAA,IACF,CAAC;AAED,QAAI;AAEJ,QAAI,SAAS,UAAU;AACrB,YAAM,EAAE,YAAY,IAAI,MAAMA,UAAS,OAAgC;AAAA,QACrE;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF,CAAC;AACD,gBAAU,YAAY,KAAK,KAAK;AAAA,IAClC,OAAO;AACL,aAAO,KAAK,kCAAkC,YAAY,KAAK;AAC/D,gBAAU,MAAM;AAAA,QACd;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,QAAI,YAAY,QAAQ;AACtB,YAAMC,OAAM,OAAO,CAAC,SAAS,MAAM,CAAC;AACpC,aAAO,KAAK,WAAW;AACvB;AAAA,IACF;AAEA,YAAQ,IAAI;AACZ,WAAO,KAAK,YAAY,OAAO,EAAE;AACjC,YAAQ,IAAI;AAEZ,QAAI,CAAE,MAAM,QAAQ,2BAA2B,GAAI;AACjD,YAAMA,OAAM,OAAO,CAAC,SAAS,MAAM,CAAC;AACpC,aAAO,KAAK,kBAAkB;AAC9B;AAAA,IACF;AAEA,UAAM,gBAAgB,iBAAiB,QAAQ;AAC/C,UAAM,cAAc,GAAG,OAAO;AAAA;AAAA,kBAAuB,YAAY,KAAK,aAAa;AAEnF,UAAM,UAAU,cAAc,eAAe;AAC7C,YAAQ,MAAM;AACd,UAAMA,OAAM,OAAO,CAAC,UAAU,MAAM,WAAW,CAAC;AAChD,YAAQ,QAAQ,mBAAmB;AAAA,EACrC,SAAS,OAAO;AACd,WAAO,MAAM,kBAAkB,KAAK,EAAE;AAAA,EACxC;AACF;AAEA,eAAe,sBACb,aACA,aACA,YACA,OACiC;AACjC,MAAI;AACF,UAAM,SAAS;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,SAAS,MAAM,SAAS,EAAE,QAAQ,cAAc,KAAK,GAAG,MAAM,MAAM;AAC1E,QAAI,UAAU,OAAO,OAAO,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC,EAAE,KAAK;AAEvD,eAAW,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG;AAC/B,UAAI,QAAQ,WAAW,CAAC,KAAK,QAAQ,SAAS,CAAC,GAAG;AAChD,kBAAU,QAAQ,MAAM,GAAG,EAAE;AAC7B;AAAA,MACF;AAAA,IACF;AACA,cAAU,QAAQ,QAAQ,cAAc,EAAE,EAAE,QAAQ,WAAW,EAAE;AACjE,WAAO;AAAA,EACT,QAAQ;AACN,WAAO,QAAQ,qCAAqC;AACpD,YAAQ,IAAI;AACZ,UAAM,EAAE,QAAQ,IAAI,MAAMD,UAAS,OAA4B;AAAA,MAC7D;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AACD,WAAO,QAAQ,KAAK,KAAK;AAAA,EAC3B;AACF;AAEA,eAAe,gBAAgB,OAAgC;AAC7D,MAAI,CAAC,MAAM,OAAO;AAChB,WAAO,MAAM,uBAAuB;AACpC;AAAA,EACF;AAEA,QAAM,oBAAoB,sBAAsB;AAChD,QAAM,kBAAkB,aAAa,MAAM,MAAM;AAGjD,QAAM,eAAyB,CAAC;AAEhC,MAAI,MAAM,QAAQ,SAAS,GAAG;AAC5B,iBAAa;AAAA,MACX;AAAA,YAAkC,MAAM,QAAQ,MAAM;AAAA,EAAwC,MAAM,QAAQ,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,IAC7I;AAAA,EACF;AAEA,MAAI,MAAM,yBAAyB,MAAM,eAAe,SAAS,GAAG;AAClE,UAAM,gBAAgB,MAAM,eACzB,IAAI,CAAC,MAAM,MAAM,EAAE,MAAM,KAAK,EAAE,KAAK,MAAM,GAAG,GAAG,CAAC,EAAE,EACpD,KAAK,IAAI;AACZ,iBAAa,KAAK;AAAA,EAAuB,aAAa,EAAE;AAAA,EAC1D;AAEA,QAAM,eACJ,aAAa,SAAS,IAAI,aAAa,KAAK,MAAM,IAAI;AAExD,QAAM,SAAS;AAAA,IACb,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,EACF;AAEA,QAAM,eAAe,uBAAuB,MAAM,OAAO,GAAG,QAAQ;AAEpE,cAAY;AACZ,oBAAkB,GAAG,YAAY,YAAY;AAAA,IAC3C,kBAAkB,MAAM,MAAM,MAAM,IAAI,MAAM,MAAM,KAAK;AAAA,IACzD,MAAM,QAAQ,SAAS,IACnB,mBAAmB,MAAM,QAAQ,MAAM,wBACvC;AAAA,IACJ,GAAI,MAAM,wBACN,CAAC,YAAY,MAAM,eAAe,MAAM,0BAA0B,IAClE,CAAC;AAAA,EACP,CAAC;AACD,UAAQ,IAAI;AAEZ,MAAI;AACF,UAAM,oBAAoB,QAAQ,MAAM,MAAM;AAAA,EAChD,SAAS,OAAO;AACd,WAAO,MAAM,GAAG,YAAY,oBAAoB,KAAK,EAAE;AAAA,EACzD;AACF;AAEA,eAAe,aAA4B;AACzC,MAAI;AACF,UAAM,EAAE,QAAQ,OAAO,IAAI,MAAMC,OAAM,OAAO,CAAC,UAAU,gBAAgB,CAAC;AAC1E,QAAI,CAAE,MAAM,QAAQ,QAAQ,OAAO,KAAK,CAAC,aAAa,EAAI;AAE1D,UAAM,UAAU,cAAc,YAAY;AAC1C,YAAQ,MAAM;AACd,UAAMA,OAAM,OAAO,CAAC,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,CAAC;AAC1D,YAAQ,QAAQ,kBAAkB;AAAA,EACpC,SAAS,OAAO;AACd,WAAO,MAAM,gBAAgB,KAAK,EAAE;AAAA,EACtC;AACF;AAEA,IAAM,YAA0B,CAAC,UAAU,UAAU,OAAO;AAE5D,eAAe,qBAAqB,OAAgC;AAClE,QAAM,UAAU,MAAM,OAAO,GAAG;AAChC,QAAM,EAAE,SAAS,IAAI,MAAMD,UAAS,OAAiC;AAAA,IACnE;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS,UAAU,IAAI,CAAC,OAAO;AAAA,QAC7B,MACE,EAAE,OAAO,CAAC,EAAE,YAAY,IACxB,EAAE,MAAM,CAAC,KACR,MAAM,UAAU,eAAe;AAAA,QAClC,OAAO;AAAA,MACT,EAAE;AAAA,MACF,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,MAAI,aAAa,QAAS;AAE1B,qBAAmB,QAAQ;AAC3B,SAAO,QAAQ,wBAAwB,QAAQ,iBAAiB;AAClE;AAEA,eAAe,qBAAoC;AACjD,MAAI;AACF,UAAM,UAAU,cAAc,sBAAsB;AACpD,YAAQ,MAAM;AACd,UAAMC,OAAM,OAAO,CAAC,YAAY,MAAM,CAAC;AACvC,UAAMA,OAAM,OAAO,CAAC,MAAM,CAAC;AAC3B,YAAQ,QAAQ,kBAAkB;AAAA,EACpC,SAAS,OAAO;AACd,WAAO,MAAM,oBAAoB,KAAK,EAAE;AAAA,EAC1C;AACF;AAEA,eAAe,mBAAmB,OAAgC;AAChE,MAAI,CAAC,MAAM,OAAO;AAChB,WAAO,MAAM,uBAAuB;AACpC;AAAA,EACF;AAEA,QAAM,eAAe,uBAAuB,MAAM,OAAO,GAAG,QAAQ;AAEpE,cAAY;AACZ,oBAAkB,iBAAiB;AAAA,IACjC,eAAe,MAAM,MAAM,MAAM,IAAI,MAAM,MAAM,KAAK;AAAA,IACtD,aAAa,YAAY;AAAA,EAC3B,CAAC;AACD,UAAQ,IAAI;AAEZ,MAAI;AACF,UAAM,oBAAoB,sBAAsB;AAChD,UAAM,cAAc;AAAA,MAClB,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,MACZ,MAAM,OAAO;AAAA,MACb;AAAA,IACF;AACA,UAAM,oBAAoB,aAAa,MAAM,MAAM;AACnD,WAAO,QAAQ,yBAAyB;AAAA,EAC1C,SAAS,OAAO;AACd,WAAO,MAAM,yBAAyB,KAAK,EAAE;AAAA,EAC/C;AACF;AAEA,eAAe,iBAAgC;AAC7C,UAAQ,IAAI;AACZ,QAAMD,UAAS,OAAO;AAAA,IACpB;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,aAA4B;AAChD,MAAI,UAAU;AACd,MAAI,cAA2B,CAAC;AAGhC,QAAM,SAAS,WAAW;AAC1B,MAAI,YAAsB;AAAA,IACxB,WAAW;AAAA,IACX,mBAAmB;AAAA,IACnB,uBAAuB;AAAA,IACvB;AAAA,IACA,WAAW;AAAA,IACX,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,uBAAuB;AAAA,IACvB,oBAAoB;AAAA,IACpB,SAAS,CAAC;AAAA,IACV,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,gBAAgB;AAAA,IAChB,IAAI;AAAA,IACJ,gBAAgB,CAAC;AAAA,IACjB,uBAAuB;AAAA,IACvB,cAAc;AAAA,IACd,uBAAuB;AAAA,EACzB;AAEA,SAAO,SAAS;AAEd,gBAAY;AACZ,oBAAgB,WAAW,aAAa,QAAW,IAAI;AAEvD,UAAM,QAAQ,MAAM,eAAe;AAEnC,UAAM,UAAU,oBAAoB,KAAK;AAGzC,gBAAY;AACZ,kBAAc;AAEd,gBAAY;AAGZ,QAAI;AACJ,QAAI,MAAM,UAAU;AAClB,aAAO;AAAA,IACT,WAAW,MAAM,yBAAyB,CAAC,MAAM,IAAI;AACnD,aAAO;AAAA,IACT,WAAW,MAAM,uBAAuB;AACtC,aAAO;AAAA,IACT;AAEA,oBAAgB,OAAO,SAAS,IAAI;AAGpC,UAAM,YAAY,QAAQ,IAAI,CAAC,MAAM,EAAE,QAAQ;AAC/C,UAAM,MAAM,MAAM,WAAW,SAAS;AAGtC,UAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,aAAa,GAAG;AACrD,QAAI,QAAQ;AACV,gBAAU,MAAM,cAAc,OAAO,IAAI,KAAK;AAAA,IAChD;AAAA,EACF;AACF;;;AjB1fA,IAAM,UAAU,WAAW;AAE3B,SAAS,oBAA0B;AAEjC,MAAI,QAAQ,IAAI,2BAA2B,IAAK;AAEhD,kBAAgB,EACb,KAAK,CAAC,WAAW;AAChB,QAAI,OAAO,mBAAmB,OAAO,eAAe;AAClD,aAAO,QAAQ;AACf,aAAO;AAAA,QACL,0BAA0B,OAAO,gBAAgB,OAAO,aAAa;AAAA,MACvE;AAAA,IACF;AAAA,EACF,CAAC,EACA,MAAM,MAAM;AAAA,EAEb,CAAC;AACL;AAEA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,MAAM,EACX;AAAA,EACC;AACF,EACC,QAAQ,OAAO,EACf,OAAO,uBAAuB,+BAA+B,EAC7D,KAAK,aAAa,CAAC,gBAAgB;AAElC,MAAI,CAAC,YAAY,KAAK,EAAE,iBAAiB;AACvC,sBAAkB;AAAA,EACpB;AACF,CAAC;AAEH,QACG,QAAQ,MAAM,EACd,YAAY,gDAAgD,EAC5D,OAAO,eAAe,kCAAkC,EACxD,OAAO,OAAO,YAAY;AACzB,QAAM,YAAY,OAAO;AAC3B,CAAC;AAEH,QACG,QAAQ,cAAc,EACtB,YAAY,qCAAqC,EACjD,OAAO,YAAY;AAClB,QAAM,mBAAmB;AAC3B,CAAC;AAEH,QACG,QAAQ,sBAAsB,EAC9B,YAAY,oCAAoC,EAChD,OAAO,aAAa,gDAAgD,EACpE;AAAA,EACC;AAAA,EACA;AACF,EACC,OAAO,uBAAuB,oCAAoC,EAClE,OAAO,OAAO,aAAa,YAAY;AACtC,QAAM,cAAc,aAAa;AAAA,IAC/B,KAAK,QAAQ;AAAA,IACb,UAAU,QAAQ;AAAA,IAClB,OAAO,QAAQ;AAAA,EACjB,CAAC;AACH,CAAC;AAEH,QACG,QAAQ,MAAM,EACd,YAAY,kCAAkC,EAC9C,OAAO,uBAAuB,iBAAiB,EAC/C;AAAA,EACC;AAAA,EACA;AACF,EACC,OAAO,wBAAwB,oCAAoC,IAAI,EACvE,OAAO,OAAO,YAAY;AACzB,QAAM,YAAY;AAAA,IAChB,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,IAChB,OAAO,SAAS,QAAQ,OAAO,EAAE;AAAA,EACnC,CAAC;AACH,CAAC;AAEH,QACG,QAAQ,oBAAoB,EAC5B,YAAY,oCAAoC,EAChD;AAAA,EACC;AAAA,EACA;AACF,EACC,OAAO,OAAO,aAAa,YAAY;AACtC,QAAM,WAAW,aAAa,EAAE,UAAU,QAAQ,SAAS,CAAC;AAC9D,CAAC;AAEH,QACG,QAAQ,IAAI,EACZ,YAAY,oCAAoC,EAChD,OAAO,eAAe,oBAAoB,EAC1C;AAAA,EACC;AAAA,EACA;AACF,EACC,OAAO,cAAc,sCAAsC,EAC3D,OAAO,OAAO,YAAY;AACzB,QAAM,UAAU;AAAA,IACd,OAAO,QAAQ;AAAA,IACf,UAAU,QAAQ;AAAA,IAClB,OAAO,QAAQ;AAAA,EACjB,CAAC;AACH,CAAC;AAEH,QACG,QAAQ,KAAK,EACb,YAAY,mCAAmC,EAC/C;AAAA,EACC;AAAA,EACA;AACF,EACC,OAAO,OAAO,YAAY;AACzB,QAAM,WAAW,EAAE,UAAU,QAAQ,SAAS,CAAC;AACjD,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,8BAA8B,EAC1C,OAAO,YAAY;AAClB,QAAM,cAAc;AACtB,CAAC;AAEH,QACG,QAAQ,IAAI,EACZ,YAAY,8BAA8B,EAC1C,OAAO,YAAY;AAClB,QAAM,WAAW;AACnB,CAAC;AAGH,QAAQ,OAAO,YAAY;AACzB,QAAM,WAAW;AACnB,CAAC;AAED,QAAQ,MAAM;","names":["writeFileSync","existsSync","join","writeFileSync","join","existsSync","setupLabelsCommand","inquirer","inquirer","chalk","inquirer","execa","execa","chalk","localBranches","choices","inquirer","inquirer","inquirer","inquirer","execa","inquirer","inquirer","inquirer","readFileSync","writeFileSync","existsSync","mkdirSync","join","join","existsSync","readFileSync","mkdirSync","writeFileSync","version","inquirer","execa","config","chalk","chalk","version","inquirer","execa"]}
|
|
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/commands/pr.ts","../src/lib/playwright.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"],"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 {\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(\"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 } 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 { invokeAI, getProviderDisplayName } 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 logger.bold(\"Creating AI-enhanced ticket...\");\n logger.newline();\n\n const config = loadConfig();\n\n // Determine which provider to use\n const provider = resolveProvider(options, config);\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 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 // Show visual indicator before AI output\n console.log(\n chalk.dim(\n `┌─ Generating ticket with ${providerName}... ──────────────────────────┐`\n )\n );\n logger.newline();\n const result = await invokeAI(\n { prompt, streamOutput: true },\n config,\n options.provider\n );\n aiOutput = result.output;\n logger.newline();\n console.log(\n chalk.dim(\n \"└────────────────────────────────────────────────────────────┘\"\n )\n );\n logger.newline();\n } catch (error) {\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 ${providerName} 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\nexport interface AIProviderOptions {\n prompt: string;\n permissionMode?: string;\n printOutput?: boolean;\n streamOutput?: boolean;\n}\n\nexport interface AIProviderResult {\n output: string;\n provider: AIProvider;\n rateLimited?: boolean;\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\n child.stdout.on(\"data\", (chunk: Buffer) => {\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\n child.stdout.on(\"data\", (chunk: Buffer) => {\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\n child.stdout.on(\"data\", (chunk: Buffer) => {\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 } 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 logger.bold(\"Running AI implementation workflow...\");\n logger.newline();\n\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 logger.info(\n `Starting ${colors.provider(providerName)} implementation session...`\n );\n logger.dim(`${providerName} will implement the feature and create a commit.`);\n logger.dim(\"Review the changes before pushing.\");\n logger.newline();\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 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 inquirer from \"inquirer\";\nimport { logger, colors } from \"../utils/logger.js\";\nimport { withSpinner } 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 { invokeAI, getProviderDisplayName } 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\";\n\nexport interface PrOptions {\n draft?: boolean;\n provider?: AIProvider;\n video?: boolean;\n}\n\nexport async function prCommand(options: PrOptions): Promise<void> {\n logger.bold(\"Creating AI-enhanced pull request...\");\n logger.newline();\n\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 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 // Check we're not on main\n if (await isOnMainBranch()) {\n logger.error(\"Cannot create PR from main/master branch.\");\n process.exit(1);\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 // Check if we need to push\n const hasUnpushed = await getUnpushedCommits();\n if (hasUnpushed) {\n logger.warning(\"Branch has unpushed commits.\");\n const { push } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"push\",\n message: \"Push to remote before creating PR?\",\n default: true,\n },\n ]);\n\n if (push) {\n await withSpinner(\"Pushing branch...\", async () => {\n await pushBranch();\n });\n logger.success(\"Branch pushed\");\n }\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 try {\n logger.info(\n `Generating PR description with ${colors.provider(providerName)}...`\n );\n logger.newline();\n const result = await invokeAI(\n { prompt, streamOutput: true },\n config,\n options.provider\n );\n prBody = result.output;\n logger.newline();\n } catch (error) {\n logger.warning(`${providerName} invocation failed: ${error}`);\n // Fall back to basic description\n prBody = generateFallbackBody(issue, commits);\n }\n\n // Append signature footer\n prBody += `\\n\\n---\\n*Created with ${providerName} 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\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 { 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 inquirer from \"inquirer\";\nimport { logger, colors } from \"../utils/logger.js\";\nimport { withSpinner } 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 logger.bold(\"Applying PR review feedback with AI...\");\n logger.newline();\n\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 logger.info(`Starting ${colors.provider(providerName)} fix session...`);\n logger.dim(\"Review feedback will be appended to the implementation prompt.\");\n logger.newline();\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 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.13.4\",\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 inquirer from \"inquirer\";\nimport { execa } from \"execa\";\nimport { aggregateState, type TuiState } from \"../tui/state.js\";\nimport { getAvailableActions, type TuiAction } from \"../tui/actions.js\";\nimport {\n renderDashboard,\n renderActionPanel,\n clearScreen,\n} from \"../tui/display.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { createSpinner } from \"../utils/spinner.js\";\nimport { createCommand } from \"./create.js\";\nimport { prCommand } from \"./pr.js\";\nimport { listCommand } from \"./list.js\";\nimport {\n buildVideoPrompt,\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 type { AIProvider } from \"../types/index.js\";\n\nconst CANCEL = Symbol(\"cancel\");\n\nasync function confirm(message: string): Promise<boolean> {\n const { ok } = await inquirer.prompt<{ ok: boolean }>([\n {\n type: \"confirm\",\n name: \"ok\",\n message,\n default: true,\n },\n ]);\n return ok;\n}\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 async function executeAction(\n actionId: string,\n state: TuiState\n): Promise<boolean> {\n switch (actionId) {\n case \"quit\":\n return false;\n\n case \"list\": {\n clearScreen();\n try {\n await listCommand({});\n } catch (error) {\n logger.error(`List failed: ${error}`);\n }\n await promptContinue();\n return true;\n }\n\n case \"create\": {\n clearScreen();\n const { description } = await inquirer.prompt<{ description: string }>([\n {\n type: \"input\",\n name: \"description\",\n message: \"Describe the ticket (empty to cancel):\",\n },\n ]);\n if (!description.trim()) {\n logger.info(\"Cancelled\");\n return true;\n }\n try {\n await createCommand(description, {});\n } catch (error) {\n logger.error(`Create failed: ${error}`);\n }\n await promptContinue();\n return true;\n }\n\n case \"commit\":\n clearScreen();\n await handleCommit(state);\n await promptContinue();\n return true;\n\n case \"push\":\n clearScreen();\n await handlePush();\n await promptContinue();\n return true;\n\n case \"pr\": {\n clearScreen();\n if (!(await confirm(\"Create a pull request?\"))) return true;\n await prCommand({});\n await promptContinue();\n return true;\n }\n\n case \"run\": {\n clearScreen();\n const hasCommits = state.commits.length > 0;\n const hasFeedback = state.hasActionableFeedback;\n let msg: string;\n if (hasFeedback && hasCommits) {\n msg = \"Start AI agent to address review feedback?\";\n } else if (hasCommits) {\n msg =\n \"Start AI agent to continue implementation from existing commits?\";\n } else {\n msg = \"Start AI agent to implement this ticket from scratch?\";\n }\n if (!(await confirm(msg))) return true;\n await handleRun(state);\n await promptContinue();\n return true;\n }\n\n case \"video\": {\n clearScreen();\n if (!(await confirm(\"Record video of UI changes?\"))) return true;\n await handleVideoCapture(state);\n await promptContinue();\n return true;\n }\n\n case \"switch-provider\":\n clearScreen();\n await handleSwitchProvider(state);\n return true;\n\n case \"checkout-main\": {\n clearScreen();\n if (!(await confirm(\"Switch to main branch?\"))) return true;\n await handleCheckoutMain();\n return true;\n }\n\n default:\n return true;\n }\n}\n\nasync function handleCommit(state: TuiState): Promise<void> {\n try {\n const { stdout: status } = await execa(\"git\", [\"status\", \"--short\"]);\n if (!status.trim()) {\n logger.info(\"No changes to commit\");\n return;\n }\n\n logger.info(\"Changes:\");\n console.log(status);\n console.log();\n\n // Stage all changes first so we can get a clean cached diff\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 const { mode } = await inquirer.prompt<{ mode: \"ai\" | \"manual\" }>([\n {\n type: \"list\",\n name: \"mode\",\n message: \"How would you like to provide the commit message?\",\n choices: [\n { name: `Generate with ${providerName}`, value: \"ai\" },\n { name: \"Enter manually\", value: \"manual\" },\n ],\n },\n ]);\n\n let message: string | typeof CANCEL;\n\n if (mode === \"manual\") {\n const { manualInput } = await inquirer.prompt<{ manualInput: string }>([\n {\n type: \"input\",\n name: \"manualInput\",\n message: \"Commit message (empty to cancel):\",\n },\n ]);\n message = manualInput.trim() || CANCEL;\n } else {\n logger.info(`Generating commit message with ${providerName}...`);\n message = await generateCommitMessage(\n diffContent,\n issueNumber,\n issueTitle,\n state\n );\n }\n if (message === CANCEL) {\n await execa(\"git\", [\"reset\", \"HEAD\"]);\n logger.info(\"Cancelled\");\n return;\n }\n\n console.log();\n logger.info(`Message: ${message}`);\n console.log();\n\n if (!(await confirm(\"Commit with this message?\"))) {\n await execa(\"git\", [\"reset\", \"HEAD\"]);\n logger.info(\"Commit cancelled\");\n return;\n }\n\n const providerEmail = getProviderEmail(provider);\n const fullMessage = `${message}\\n\\nCo-Authored-By: ${providerName} <${providerEmail}>`;\n\n const spinner = createSpinner(\"Committing...\");\n spinner.start();\n await execa(\"git\", [\"commit\", \"-m\", fullMessage]);\n spinner.succeed(\"Changes committed\");\n } catch (error) {\n logger.error(`Commit failed: ${error}`);\n }\n}\n\nasync function generateCommitMessage(\n diffContent: string,\n issueNumber: number | null,\n issueTitle: string | null,\n state: TuiState\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: true }, 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 logger.warning(\"AI commit message generation failed\");\n console.log();\n const { message } = await inquirer.prompt<{ message: string }>([\n {\n type: \"input\",\n name: \"message\",\n message: \"Commit message (empty to cancel):\",\n },\n ]);\n return message.trim() || 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 await invokeAIInteractive(prompt, state.config);\n } catch (error) {\n logger.error(`${providerName} session failed: ${error}`);\n }\n}\n\nasync function handlePush(): Promise<void> {\n try {\n const { stdout: branch } = await execa(\"git\", [\"branch\", \"--show-current\"]);\n if (!(await confirm(`Push ${branch.trim()} to remote?`))) return;\n\n const spinner = createSpinner(\"Pushing...\");\n spinner.start();\n await execa(\"git\", [\"push\", \"-u\", \"origin\", branch.trim()]);\n spinner.succeed(\"Pushed to remote\");\n } catch (error) {\n logger.error(`Push failed: ${error}`);\n }\n}\n\nconst PROVIDERS: AIProvider[] = [\"claude\", \"gemini\", \"codex\"];\n\nasync function handleSwitchProvider(state: TuiState): Promise<void> {\n const current = state.config.ai.provider;\n const { provider } = await inquirer.prompt<{ provider: AIProvider }>([\n {\n type: \"list\",\n name: \"provider\",\n message: \"Select AI provider:\",\n choices: PROVIDERS.map((p) => ({\n name:\n p.charAt(0).toUpperCase() +\n p.slice(1) +\n (p === current ? \" (current)\" : \"\"),\n value: p,\n })),\n default: current,\n },\n ]);\n\n if (provider === current) return;\n\n setRuntimeProvider(provider);\n logger.success(`Provider switched to ${provider} (session only)`);\n}\n\nasync function handleCheckoutMain(): Promise<void> {\n try {\n const spinner = createSpinner(\"Switching to main...\");\n spinner.start();\n await execa(\"git\", [\"checkout\", \"main\"]);\n await execa(\"git\", [\"pull\"]);\n spinner.succeed(\"Switched to main\");\n } catch (error) {\n logger.error(`Checkout failed: ${error}`);\n }\n}\n\nasync function handleVideoCapture(state: TuiState): Promise<void> {\n if (!state.issue) {\n logger.error(\"No linked issue found\");\n return;\n }\n\n const providerName = getProviderDisplayName(state.config.ai.provider);\n\n clearScreen();\n renderActionPanel(\"Video Capture\", [\n `Recording: #${state.issue.number} ${state.issue.title}`,\n `Provider: ${providerName}`,\n ]);\n console.log();\n\n try {\n const agentInstructions = loadAgentInstructions();\n const videoPrompt = buildVideoPrompt(\n state.issue.number,\n state.issue.title,\n state.config.video,\n agentInstructions\n );\n await invokeAIInteractive(videoPrompt, state.config);\n logger.success(\"Video capture completed\");\n } catch (error) {\n logger.error(`Video capture failed: ${error}`);\n }\n}\n\nasync function promptContinue(): Promise<void> {\n console.log();\n await inquirer.prompt([\n {\n type: \"input\",\n name: \"continue\",\n message: \"Press Enter to continue...\",\n },\n ]);\n}\n\nexport async function tuiCommand(): Promise<void> {\n let running = true;\n let lastActions: TuiAction[] = [];\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 };\n\n while (running) {\n // Show dashboard with refreshing indicator while loading new state\n clearScreen();\n renderDashboard(lastState, lastActions, undefined, true);\n\n const state = await aggregateState();\n\n const actions = getAvailableActions(state);\n\n // Save for next refresh cycle\n lastState = state;\n lastActions = actions;\n\n clearScreen();\n\n // Contextual hint\n let hint: string | undefined;\n if (state.isOnMain) {\n hint = \"Select an action to get started\";\n } else if (state.hasUncommittedChanges && !state.pr) {\n hint = \"Commit your changes before creating a PR\";\n } else if (state.hasActionableFeedback) {\n hint = \"Review feedback needs attention\";\n }\n\n renderDashboard(state, actions, hint);\n\n // Wait for a valid keypress\n const validKeys = actions.map((a) => a.shortcut);\n const key = await waitForKey(validKeys);\n\n // Find the matching action\n const action = actions.find((a) => a.shortcut === key);\n if (action) {\n running = await executeAction(action.id, state);\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} 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\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 };\n }\n\n const config = loadConfig();\n const workflowLabels = getWorkflowLabels(config);\n\n // Gather prerequisites and git state in parallel\n const [\n isGhAuthenticated,\n isAIProviderAvailable,\n branch,\n isOnMain,\n uncommitted,\n baseBranch,\n ] = await Promise.all([\n checkGhAuth(),\n checkAIProvider(config.ai.provider),\n getCurrentBranch(),\n isOnMainBranch(),\n hasUncommittedChanges(),\n getDefaultBranch(),\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 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 isPlaywrightAvailable(),\n ]);\n\n issue = issueResult;\n pr = prResult;\n uiChanges = hasUIChanges(changedFiles);\n playwrightAvailable = playwrightResult;\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 };\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 // On main branch\n if (state.isOnMain) {\n actions.push({ id: \"create\", label: \"new\", shortcut: \"n\" });\n actions.push({ id: \"list\", label: \"list\", shortcut: \"l\" });\n actions.push({ id: \"switch-provider\", label: \"ai\", shortcut: \"a\" });\n actions.push({ id: \"quit\", label: \"quit\", shortcut: \"q\" });\n return actions;\n }\n\n // On feature branch - context-aware\n\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: \"p\" });\n }\n\n if (!state.pr && state.commits.length > 0) {\n actions.push({ id: \"pr\", label: \"pr\", shortcut: \"r\" });\n }\n\n if (state.issue && state.pr?.state !== \"merged\") {\n actions.push({ id: \"run\", label: \"run\", shortcut: \"u\" });\n }\n\n if (state.pr && state.pr.state === \"open\") {\n if (\n state.hasUIChanges &&\n state.isPlaywrightAvailable &&\n state.config.video.enabled\n ) {\n actions.push({ id: \"video\", label: \"video\", shortcut: \"v\" });\n }\n }\n\n if (\n state.pr &&\n (state.pr.state === \"merged\" || state.pr.state === \"closed\")\n ) {\n actions.push({ id: \"checkout-main\", label: \"main\", shortcut: \"m\" });\n }\n\n actions.push({ id: \"list\", label: \"list\", shortcut: \"l\" });\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 } 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\nconst stripAnsi = (str: string) => str.replace(/\\x1b\\[[0-9;]*m/g, \"\");\nconst visibleLen = (str: string) => stripAnsi(str).length;\n\nfunction 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 pad = Math.max(0, inner - visibleLen(text));\n return chalk.dim(\"│\") + \" \" + text + \" \".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 key = a.shortcut;\n const idx = a.label.indexOf(key);\n if (idx >= 0) {\n // Highlight the shortcut letter within the label\n const before = a.label.slice(0, idx);\n const after = a.label.slice(idx + key.length);\n return chalk.dim(before) + color(key) + chalk.dim(after);\n }\n // Shortcut not in label — show separately\n return color(key) + \" \" + 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// ── Settings ────────────────────────────────────────────────────\n\nfunction renderSettings(state: TuiState, w: number): 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 const videoTag = state.config.video.enabled\n ? chalk.green(\"on\")\n : chalk.dim(\"off\");\n\n console.log(row(chalk.dim(\"Provider: \") + provTag, w));\n console.log(row(chalk.dim(\"GitHub: \") + ghTag, w));\n console.log(row(chalk.dim(\"Video: \") + videoTag, w));\n}\n\n// ── Main render ─────────────────────────────────────────────────\n\nexport function renderDashboard(\n state: TuiState,\n actions: TuiAction[],\n hint?: string,\n refreshing?: boolean\n): void {\n const w = termWidth();\n const descMax = w - 8;\n const version = getVersion();\n\n const titleLabel = `gent v${version}`;\n console.log(topRow(titleLabel, w));\n renderSettings(state, w);\n\n // ── Error states ──────────────────────────────────────────────\n if (!state.isGitRepo) {\n console.log(row(chalk.red(\"Not a git repository\"), w));\n console.log(\n row(chalk.dim(\"Run gent init in a git repo to get started\"), w)\n );\n console.log(botRow(w));\n return;\n }\n if (!state.isGhAuthenticated) {\n console.log(row(chalk.red(\"GitHub CLI not authenticated\"), w));\n console.log(row(chalk.dim(\"Run: gh auth login\"), w));\n console.log(botRow(w));\n return;\n }\n\n // ── On main – nothing active ─────────────────────────────────\n if (state.isOnMain) {\n console.log(\n row(\n chalk.magenta(state.branch) + chalk.dim(\" · ready to start new work\"),\n w\n )\n );\n if (state.hasUncommittedChanges) {\n console.log(row(chalk.yellow(\"● uncommitted changes\"), w));\n }\n if (hint) {\n console.log(midRow(\"Hint\", w));\n console.log(row(chalk.yellow(hint), w));\n }\n console.log(divRow(w));\n if (refreshing) {\n console.log(row(chalk.yellow(\"Refreshing…\"), w));\n } else {\n for (const line of formatCommandBar(actions, w)) {\n console.log(row(line, w));\n }\n }\n console.log(botRow(w));\n console.log();\n return;\n }\n\n // ── Feature branch dashboard ──────────────────────────────────\n const section = (title: string) => {\n console.log(midRow(title, w));\n };\n\n // Ticket\n section(\"Ticket\");\n if (state.issue) {\n console.log(\n row(\n chalk.cyan(`#${state.issue.number}`) +\n \" \" +\n chalk.bold(truncate(state.issue.title, descMax - 6)),\n w\n )\n );\n const desc = extractDescription(state.issue.body, descMax);\n if (desc) console.log(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) console.log(row(tags.join(\" \"), w));\n } else {\n console.log(row(chalk.dim(\"No linked issue\"), w));\n }\n\n // Branch\n section(\"Branch\");\n console.log(row(chalk.magenta(state.branch), w));\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) console.log(row(bits.join(chalk.dim(\" · \")), w));\n\n // Pull Request\n section(\"Pull Request\");\n if (state.pr) {\n const titleText = state.pr.title\n ? \" \" + truncate(state.pr.title, descMax - 12)\n : \"\";\n console.log(row(chalk.cyan(`#${state.pr.number}`) + titleText, w));\n console.log(\n row(\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 console.log(\n row(\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 console.log(\n row(\n chalk.cyan(\"UI changes detected\") +\n chalk.dim(\" · video capture available\"),\n w\n )\n );\n }\n console.log(row(chalk.dim(state.pr.url), w));\n } else {\n console.log(row(chalk.dim(\"No PR created\"), w));\n }\n\n // Commits\n section(\"Commits\");\n if (state.commits.length > 0) {\n const max = 6;\n for (const c of state.commits.slice(0, max)) {\n console.log(row(c.substring(0, w - 5), w));\n }\n if (state.commits.length > max) {\n console.log(\n row(chalk.dim(`… and ${state.commits.length - max} more`), w)\n );\n }\n } else {\n console.log(row(chalk.dim(\"No commits\"), w));\n }\n\n // Hint\n if (hint) {\n section(\"Hint\");\n console.log(row(chalk.yellow(hint), w));\n }\n\n // Command bar (inside the frame)\n console.log(divRow(w));\n if (refreshing) {\n console.log(row(chalk.yellow(\"Refreshing…\"), w));\n } else {\n for (const line of formatCommandBar(actions, w)) {\n console.log(row(line, w));\n }\n }\n console.log(botRow(w));\n}\n\nexport function clearScreen(): void {\n process.stdout.write(\"\\x1B[2J\\x1B[0f\");\n}\n"],"mappings":"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","names":["writeFileSync","existsSync","join","writeFileSync","join","existsSync","setupLabelsCommand","inquirer","inquirer","chalk","inquirer","execa","execa","chalk","localBranches","choices","inquirer","inquirer","inquirer","inquirer","execa","inquirer","inquirer","inquirer","readFileSync","writeFileSync","existsSync","mkdirSync","join","join","existsSync","readFileSync","mkdirSync","writeFileSync","version","inquirer","execa","config","chalk","chalk","version","inquirer","execa"]}
|
package/package.json
CHANGED