@rotorsoft/gent 1.10.1 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-6O2G7EPT.js → chunk-3N6U3NTN.js} +18 -1
- package/dist/chunk-3N6U3NTN.js.map +1 -0
- package/dist/index.js +80 -6
- package/dist/index.js.map +1 -1
- package/dist/{setup-labels-PZK2T3WA.js → setup-labels-HKXXO65J.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-6O2G7EPT.js.map +0 -1
- /package/dist/{setup-labels-PZK2T3WA.js.map → setup-labels-HKXXO65J.js.map} +0 -0
|
@@ -120,6 +120,12 @@ var DEFAULT_CONFIG = {
|
|
|
120
120
|
provider: "claude",
|
|
121
121
|
auto_fallback: true
|
|
122
122
|
},
|
|
123
|
+
video: {
|
|
124
|
+
enabled: true,
|
|
125
|
+
max_duration: 30,
|
|
126
|
+
width: 1280,
|
|
127
|
+
height: 720
|
|
128
|
+
},
|
|
123
129
|
validation: ["npm run typecheck", "npm run lint", "npm run test"]
|
|
124
130
|
};
|
|
125
131
|
function getConfigPath(cwd = process.cwd()) {
|
|
@@ -199,6 +205,10 @@ function mergeConfig(defaults, user) {
|
|
|
199
205
|
// Environment variable takes precedence
|
|
200
206
|
...envProvider && { provider: envProvider }
|
|
201
207
|
},
|
|
208
|
+
video: {
|
|
209
|
+
...defaults.video,
|
|
210
|
+
...user.video
|
|
211
|
+
},
|
|
202
212
|
validation: user.validation ?? defaults.validation
|
|
203
213
|
};
|
|
204
214
|
}
|
|
@@ -272,6 +282,13 @@ ai:
|
|
|
272
282
|
# fallback_provider: "gemini" # optional fallback when rate limited
|
|
273
283
|
auto_fallback: true # automatically switch to fallback on rate limit
|
|
274
284
|
|
|
285
|
+
# Video capture for UI changes (requires Playwright)
|
|
286
|
+
video:
|
|
287
|
+
enabled: true # set to false to disable video capture for PRs with UI changes
|
|
288
|
+
max_duration: 30 # maximum video duration in seconds
|
|
289
|
+
width: 1280 # video width
|
|
290
|
+
height: 720 # video height
|
|
291
|
+
|
|
275
292
|
# Validation commands (run before commit)
|
|
276
293
|
validation:
|
|
277
294
|
- "npm run typecheck"
|
|
@@ -832,4 +849,4 @@ export {
|
|
|
832
849
|
addPrComment,
|
|
833
850
|
setupLabelsCommand
|
|
834
851
|
};
|
|
835
|
-
//# sourceMappingURL=chunk-
|
|
852
|
+
//# sourceMappingURL=chunk-3N6U3NTN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/logger.ts","../src/utils/spinner.ts","../src/lib/config.ts","../src/types/index.ts","../src/lib/labels.ts","../src/lib/github.ts","../src/utils/validators.ts","../src/commands/setup-labels.ts"],"sourcesContent":["import chalk from \"chalk\";\n\nexport const logger = {\n info: (message: string) => console.log(chalk.blue(\"ℹ\"), message),\n success: (message: string) => console.log(chalk.green(\"✓\"), message),\n warning: (message: string) => console.log(chalk.yellow(\"⚠\"), message),\n error: (message: string) => console.log(chalk.red(\"✗\"), message),\n debug: (message: string) => {\n if (process.env.DEBUG) {\n console.log(chalk.gray(\"⋯\"), message);\n }\n },\n dim: (message: string) => console.log(chalk.dim(message)),\n bold: (message: string) => console.log(chalk.bold(message)),\n highlight: (message: string) => console.log(chalk.cyan(message)),\n\n box: (title: string, content: string) => {\n const lines = content.split(\"\\n\");\n // Calculate visible length (strips ANSI codes) for proper alignment\n // eslint-disable-next-line no-control-regex\n const stripAnsi = (str: string) => str.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n const visibleLength = (str: string) => stripAnsi(str).length;\n const maxLen =\n Math.max(title.length, ...lines.map((l) => visibleLength(l))) + 4;\n const border = \"─\".repeat(maxLen);\n\n // Pad string to target length accounting for ANSI codes\n const padVisible = (str: string, len: number) => {\n const visible = visibleLength(str);\n return str + \" \".repeat(Math.max(0, len - visible));\n };\n\n console.log(chalk.dim(`┌${border}┐`));\n console.log(\n `${chalk.dim(\"│\")} ${chalk.bold(title.padEnd(maxLen - 2))} ${chalk.dim(\"│\")}`\n );\n console.log(chalk.dim(`├${border}┤`));\n for (const line of lines) {\n console.log(\n `${chalk.dim(\"│\")} ${padVisible(line, maxLen - 2)} ${chalk.dim(\"│\")}`\n );\n }\n console.log(chalk.dim(`└${border}┘`));\n },\n\n list: (items: string[], bullet = \"•\") => {\n for (const item of items) {\n console.log(chalk.dim(bullet), item);\n }\n },\n\n newline: () => console.log(),\n};\n\nexport const colors = {\n issue: chalk.cyan,\n branch: chalk.magenta,\n label: chalk.yellow,\n file: chalk.green,\n command: chalk.blue,\n url: chalk.underline.blue,\n provider: chalk.cyan.bold,\n};\n","import ora, { Ora } from \"ora\";\n\nexport function createSpinner(text: string): Ora {\n return ora({\n text,\n spinner: \"dots\",\n });\n}\n\nexport async function withSpinner<T>(\n text: string,\n fn: () => Promise<T>\n): Promise<T> {\n const spinner = createSpinner(text);\n spinner.start();\n\n try {\n const result = await fn();\n spinner.succeed();\n return result;\n } catch (error) {\n spinner.fail();\n throw error;\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport type { GentConfig, AIProvider } from \"../types/index.js\";\n\nconst DEFAULT_CONFIG: GentConfig = {\n version: 1,\n github: {\n labels: {\n workflow: {\n ready: \"ai-ready\",\n in_progress: \"ai-in-progress\",\n completed: \"ai-completed\",\n blocked: \"ai-blocked\",\n },\n types: [\"feature\", \"fix\", \"refactor\", \"chore\", \"docs\", \"test\"],\n priorities: [\"critical\", \"high\", \"medium\", \"low\"],\n risks: [\"low\", \"medium\", \"high\"],\n areas: [\"ui\", \"api\", \"database\", \"workers\", \"shared\", \"testing\", \"infra\"],\n },\n },\n branch: {\n pattern: \"{author}/{type}-{issue}-{slug}\",\n author_source: \"git\",\n author_env_var: \"GENT_AUTHOR\",\n },\n progress: {\n file: \"progress.txt\",\n archive_threshold: 500,\n archive_dir: \".gent/archive\",\n },\n claude: {\n permission_mode: \"acceptEdits\",\n agent_file: \"AGENT.md\",\n },\n gemini: {\n sandbox_mode: \"on\",\n agent_file: \"AGENT.md\",\n },\n codex: {\n agent_file: \"AGENT.md\",\n },\n ai: {\n provider: \"claude\",\n auto_fallback: true,\n },\n video: {\n enabled: true,\n max_duration: 30,\n width: 1280,\n height: 720,\n },\n validation: [\"npm run typecheck\", \"npm run lint\", \"npm run test\"],\n};\n\nexport function getConfigPath(cwd: string = process.cwd()): string {\n return join(cwd, \".gent.yml\");\n}\n\nexport function getAgentPath(cwd: string = process.cwd()): string | null {\n const config = loadConfig(cwd);\n // Use claude.agent_file for backward compatibility\n const agentPath = join(cwd, config.claude.agent_file);\n return existsSync(agentPath) ? agentPath : null;\n}\n\nexport function loadConfig(cwd: string = process.cwd()): GentConfig {\n const configPath = getConfigPath(cwd);\n\n if (!existsSync(configPath)) {\n return DEFAULT_CONFIG;\n }\n\n try {\n const content = readFileSync(configPath, \"utf-8\");\n const userConfig = parseYaml(content) as Partial<GentConfig>;\n\n return mergeConfig(DEFAULT_CONFIG, userConfig);\n } catch {\n return DEFAULT_CONFIG;\n }\n}\n\nexport function loadAgentInstructions(cwd: string = process.cwd()): string | null {\n const agentPath = getAgentPath(cwd);\n\n if (!agentPath) {\n return null;\n }\n\n try {\n return readFileSync(agentPath, \"utf-8\");\n } catch {\n return null;\n }\n}\n\nexport function configExists(cwd: string = process.cwd()): boolean {\n return existsSync(getConfigPath(cwd));\n}\n\nfunction mergeConfig(\n defaults: GentConfig,\n user: Partial<GentConfig>\n): GentConfig {\n // Support GENT_AI_PROVIDER environment variable override\n const envProvider = process.env.GENT_AI_PROVIDER as\n | \"claude\"\n | \"gemini\"\n | \"codex\"\n | undefined;\n\n return {\n version: user.version ?? defaults.version,\n github: {\n labels: {\n workflow: {\n ...defaults.github.labels.workflow,\n ...user.github?.labels?.workflow,\n },\n types: user.github?.labels?.types ?? defaults.github.labels.types,\n priorities:\n user.github?.labels?.priorities ?? defaults.github.labels.priorities,\n risks: user.github?.labels?.risks ?? defaults.github.labels.risks,\n areas: user.github?.labels?.areas ?? defaults.github.labels.areas,\n },\n },\n branch: {\n ...defaults.branch,\n ...user.branch,\n },\n progress: {\n ...defaults.progress,\n ...user.progress,\n },\n claude: {\n ...defaults.claude,\n ...user.claude,\n },\n gemini: {\n ...defaults.gemini,\n ...user.gemini,\n },\n codex: {\n ...defaults.codex,\n ...user.codex,\n },\n ai: {\n ...defaults.ai,\n ...user.ai,\n // Environment variable takes precedence\n ...(envProvider && { provider: envProvider }),\n },\n video: {\n ...defaults.video,\n ...user.video,\n },\n validation: user.validation ?? defaults.validation,\n };\n}\n\nexport function generateDefaultConfig(provider: AIProvider = \"claude\"): string {\n return `# Gent Configuration\n# See https://github.com/rotorsoft/gent for documentation\nversion: 1\n\n# GitHub settings\ngithub:\n labels:\n workflow:\n ready: \"ai-ready\"\n in_progress: \"ai-in-progress\"\n completed: \"ai-completed\"\n blocked: \"ai-blocked\"\n types:\n - feature\n - fix\n - refactor\n - chore\n - docs\n - test\n priorities:\n - critical\n - high\n - medium\n - low\n risks:\n - low\n - medium\n - high\n areas:\n - ui\n - api\n - database\n - workers\n - shared\n - testing\n - infra\n\n# Branch naming convention\nbranch:\n pattern: \"{author}/{type}-{issue}-{slug}\"\n author_source: \"git\" # git | env | prompt\n author_env_var: \"GENT_AUTHOR\"\n\n# Progress tracking\nprogress:\n file: \"progress.txt\"\n archive_threshold: 500\n archive_dir: \".gent/archive\"\n\n# Claude settings\nclaude:\n permission_mode: \"acceptEdits\"\n agent_file: \"AGENT.md\"\n\n# Gemini settings\ngemini:\n sandbox_mode: \"on\"\n agent_file: \"AGENT.md\"\n\n# Codex settings\ncodex:\n agent_file: \"AGENT.md\"\n\n# AI provider settings\nai:\n provider: \"${provider}\" # claude | gemini | codex\n # fallback_provider: \"gemini\" # optional fallback when rate limited\n auto_fallback: true # automatically switch to fallback on rate limit\n\n# Video capture for UI changes (requires Playwright)\nvideo:\n enabled: true # set to false to disable video capture for PRs with UI changes\n max_duration: 30 # maximum video duration in seconds\n width: 1280 # video width\n height: 720 # video height\n\n# Validation commands (run before commit)\nvalidation:\n - \"npm run typecheck\"\n - \"npm run lint\"\n - \"npm run test\"\n`;\n}\n","export type AIProvider = \"claude\" | \"gemini\" | \"codex\";\n\nexport interface GentConfig {\n version: number;\n github: GitHubConfig;\n branch: BranchConfig;\n progress: ProgressConfig;\n claude: ClaudeConfig;\n gemini: GeminiConfig;\n codex: CodexConfig;\n ai: AIConfig;\n video: VideoConfig;\n validation: string[];\n}\n\nexport interface VideoConfig {\n enabled: boolean;\n max_duration: number; // seconds\n width: number;\n height: number;\n}\n\nexport interface AIConfig {\n provider: AIProvider;\n fallback_provider?: AIProvider;\n auto_fallback: boolean;\n}\n\nexport interface GitHubConfig {\n labels: {\n workflow: WorkflowLabels;\n types: string[];\n priorities: string[];\n risks: string[];\n areas: string[];\n };\n}\n\nexport interface WorkflowLabels {\n ready: string;\n in_progress: string;\n completed: string;\n blocked: string;\n}\n\nexport interface BranchConfig {\n pattern: string;\n author_source: \"git\" | \"env\" | \"prompt\";\n author_env_var: string;\n}\n\nexport interface ProgressConfig {\n file: string;\n archive_threshold: number;\n archive_dir: string;\n}\n\nexport interface ClaudeConfig {\n permission_mode: string;\n agent_file: string;\n}\n\nexport interface GeminiConfig {\n sandbox_mode: string;\n agent_file: string;\n}\n\nexport interface CodexConfig {\n agent_file: string;\n}\n\nexport interface GitHubIssue {\n number: number;\n title: string;\n body: string;\n labels: string[];\n state: \"open\" | \"closed\";\n assignee?: string;\n url: string;\n}\n\nexport interface GitHubLabel {\n name: string;\n color: string;\n description?: string;\n}\n\nexport interface GitHubReviewComment {\n id?: number;\n author: string;\n body: string;\n path?: string;\n line?: number | null;\n createdAt?: string;\n}\n\nexport interface GitHubReview {\n author: string;\n body: string;\n state: string;\n submittedAt?: string;\n}\n\nexport interface GitHubReviewThread {\n isResolved?: boolean | null;\n isOutdated?: boolean;\n path?: string;\n line?: number | null;\n comments: GitHubReviewComment[];\n}\n\nexport interface GitHubPRComment {\n id?: string;\n author: string;\n body: string;\n createdAt?: string;\n}\n\nexport interface GitHubReviewData {\n reviews: GitHubReview[];\n reviewThreads: GitHubReviewThread[];\n comments: GitHubPRComment[];\n}\n\nexport interface ProgressEntry {\n date: string;\n type: string;\n description: string;\n issue?: number;\n decisions: string[];\n files: string[];\n tests: string[];\n concerns: string[];\n followUp: string[];\n commit?: string;\n}\n\nexport interface BranchInfo {\n name: string;\n author: string;\n type: string;\n issueNumber: number;\n slug: string;\n}\n\nexport const DEFAULT_LABELS: Record<string, GitHubLabel[]> = {\n workflow: [\n {\n name: \"ai-ready\",\n color: \"0E8A16\",\n description: \"Issue ready for AI implementation\",\n },\n {\n name: \"ai-in-progress\",\n color: \"FFA500\",\n description: \"AI currently working on this\",\n },\n {\n name: \"ai-completed\",\n color: \"1D76DB\",\n description: \"AI done, needs human review\",\n },\n {\n name: \"ai-blocked\",\n color: \"D93F0B\",\n description: \"AI couldn't complete, needs help\",\n },\n ],\n priority: [\n {\n name: \"priority:critical\",\n color: \"B60205\",\n description: \"Blocking production\",\n },\n {\n name: \"priority:high\",\n color: \"D93F0B\",\n description: \"Important features/bugs\",\n },\n {\n name: \"priority:medium\",\n color: \"FBCA04\",\n description: \"Nice-to-have improvements\",\n },\n { name: \"priority:low\", color: \"0E8A16\", description: \"Minor tweaks\" },\n ],\n risk: [\n {\n name: \"risk:low\",\n color: \"C2E0C6\",\n description: \"UI changes, tests, non-critical\",\n },\n {\n name: \"risk:medium\",\n color: \"FEF2C0\",\n description: \"API changes, new features\",\n },\n {\n name: \"risk:high\",\n color: \"F9D0C4\",\n description: \"Migrations, auth, security\",\n },\n ],\n type: [\n { name: \"type:feature\", color: \"1D76DB\", description: \"New feature\" },\n { name: \"type:fix\", color: \"D73A4A\", description: \"Bug fix\" },\n {\n name: \"type:refactor\",\n color: \"5319E7\",\n description: \"Code improvement\",\n },\n { name: \"type:chore\", color: \"FEF2C0\", description: \"Maintenance\" },\n { name: \"type:docs\", color: \"0075CA\", description: \"Documentation\" },\n { name: \"type:test\", color: \"D4C5F9\", description: \"Testing\" },\n ],\n area: [\n { name: \"area:ui\", color: \"C5DEF5\", description: \"User interface\" },\n { name: \"area:api\", color: \"D4C5F9\", description: \"API/Backend\" },\n { name: \"area:database\", color: \"FEF2C0\", description: \"Database/Models\" },\n {\n name: \"area:workers\",\n color: \"F9D0C4\",\n description: \"Background workers\",\n },\n { name: \"area:shared\", color: \"C2E0C6\", description: \"Shared libraries\" },\n { name: \"area:testing\", color: \"E99695\", description: \"Test infrastructure\" },\n { name: \"area:infra\", color: \"BFD4F2\", description: \"Infrastructure/DevOps\" },\n ],\n};\n","import type { GentConfig, GitHubLabel } from \"../types/index.js\";\nimport { DEFAULT_LABELS } from \"../types/index.js\";\n\nexport function getAllLabels(config: GentConfig): GitHubLabel[] {\n const labels: GitHubLabel[] = [];\n\n // Workflow labels\n labels.push(...DEFAULT_LABELS.workflow);\n\n // Priority labels\n for (const priority of config.github.labels.priorities) {\n const defaultLabel = DEFAULT_LABELS.priority.find(\n (l) => l.name === `priority:${priority}`\n );\n if (defaultLabel) {\n labels.push(defaultLabel);\n } else {\n labels.push({\n name: `priority:${priority}`,\n color: \"FBCA04\",\n description: `Priority: ${priority}`,\n });\n }\n }\n\n // Risk labels\n for (const risk of config.github.labels.risks) {\n const defaultLabel = DEFAULT_LABELS.risk.find(\n (l) => l.name === `risk:${risk}`\n );\n if (defaultLabel) {\n labels.push(defaultLabel);\n } else {\n labels.push({\n name: `risk:${risk}`,\n color: \"FEF2C0\",\n description: `Risk: ${risk}`,\n });\n }\n }\n\n // Type labels\n for (const type of config.github.labels.types) {\n const defaultLabel = DEFAULT_LABELS.type.find(\n (l) => l.name === `type:${type}`\n );\n if (defaultLabel) {\n labels.push(defaultLabel);\n } else {\n labels.push({\n name: `type:${type}`,\n color: \"1D76DB\",\n description: `Type: ${type}`,\n });\n }\n }\n\n // Area labels\n for (const area of config.github.labels.areas) {\n const defaultLabel = DEFAULT_LABELS.area.find(\n (l) => l.name === `area:${area}`\n );\n if (defaultLabel) {\n labels.push(defaultLabel);\n } else {\n labels.push({\n name: `area:${area}`,\n color: \"C5DEF5\",\n description: `Area: ${area}`,\n });\n }\n }\n\n return labels;\n}\n\nexport function getWorkflowLabels(config: GentConfig): {\n ready: string;\n inProgress: string;\n completed: string;\n blocked: string;\n} {\n return {\n ready: config.github.labels.workflow.ready,\n inProgress: config.github.labels.workflow.in_progress,\n completed: config.github.labels.workflow.completed,\n blocked: config.github.labels.workflow.blocked,\n };\n}\n\nexport function buildIssueLabels(meta: {\n type: string;\n priority: string;\n risk: string;\n area: string;\n}): string[] {\n return [\n \"ai-ready\",\n `type:${meta.type}`,\n `priority:${meta.priority}`,\n `risk:${meta.risk}`,\n `area:${meta.area}`,\n ];\n}\n\nexport function extractTypeFromLabels(labels: string[]): string {\n for (const label of labels) {\n if (label.startsWith(\"type:\")) {\n return label.replace(\"type:\", \"\");\n }\n }\n return \"feature\";\n}\n\nexport function extractPriorityFromLabels(labels: string[]): string {\n for (const label of labels) {\n if (label.startsWith(\"priority:\")) {\n return label.replace(\"priority:\", \"\");\n }\n }\n return \"medium\";\n}\n\nexport function hasWorkflowLabel(\n labels: string[],\n workflowLabel: string\n): boolean {\n return labels.includes(workflowLabel);\n}\n\nexport function sortByPriority(issues: { labels: string[] }[]): void {\n const priorityOrder = [\"critical\", \"high\", \"medium\", \"low\"];\n\n issues.sort((a, b) => {\n const aPriority = extractPriorityFromLabels(a.labels);\n const bPriority = extractPriorityFromLabels(b.labels);\n return priorityOrder.indexOf(aPriority) - priorityOrder.indexOf(bPriority);\n });\n}\n","import { execa } from \"execa\";\nimport type { GitHubIssue, GitHubLabel, GitHubReviewData } from \"../types/index.js\";\n\nexport async function getIssue(issueNumber: number): Promise<GitHubIssue> {\n const { stdout } = await execa(\"gh\", [\n \"issue\",\n \"view\",\n String(issueNumber),\n \"--json\",\n \"number,title,body,labels,state,assignees,url\",\n ]);\n\n const data = JSON.parse(stdout);\n return {\n number: data.number,\n title: data.title,\n body: data.body || \"\",\n labels: data.labels.map((l: { name: string }) => l.name),\n state: data.state.toLowerCase(),\n assignee: data.assignees?.[0]?.login,\n url: data.url,\n };\n}\n\nexport async function listIssues(options: {\n labels?: string[];\n state?: \"open\" | \"closed\" | \"all\";\n limit?: number;\n}): Promise<GitHubIssue[]> {\n const args = [\"issue\", \"list\", \"--json\", \"number,title,body,labels,state,url\"];\n\n if (options.labels?.length) {\n args.push(\"--label\", options.labels.join(\",\"));\n }\n\n if (options.state) {\n args.push(\"--state\", options.state);\n }\n\n args.push(\"--limit\", String(options.limit || 50));\n\n const { stdout } = await execa(\"gh\", args);\n const data = JSON.parse(stdout);\n\n return data.map(\n (d: {\n number: number;\n title: string;\n body: string;\n labels: { name: string }[];\n state: string;\n url: string;\n }) => ({\n number: d.number,\n title: d.title,\n body: d.body || \"\",\n labels: d.labels.map((l) => l.name),\n state: d.state.toLowerCase() as \"open\" | \"closed\",\n url: d.url,\n })\n );\n}\n\nexport async function createIssue(options: {\n title: string;\n body: string;\n labels?: string[];\n}): Promise<number> {\n const args = [\"issue\", \"create\", \"--title\", options.title, \"--body\", options.body];\n\n if (options.labels?.length) {\n args.push(\"--label\", options.labels.join(\",\"));\n }\n\n const { stdout } = await execa(\"gh\", args);\n\n // Extract issue number from URL\n const match = stdout.match(/\\/issues\\/(\\d+)/);\n if (!match) {\n throw new Error(\"Failed to extract issue number from gh output\");\n }\n\n return parseInt(match[1], 10);\n}\n\nexport async function updateIssueLabels(\n issueNumber: number,\n options: {\n add?: string[];\n remove?: string[];\n }\n): Promise<void> {\n const promises: Promise<unknown>[] = [];\n\n if (options.add?.length) {\n promises.push(\n execa(\"gh\", [\n \"issue\",\n \"edit\",\n String(issueNumber),\n \"--add-label\",\n options.add.join(\",\"),\n ])\n );\n }\n\n if (options.remove?.length) {\n promises.push(\n execa(\"gh\", [\n \"issue\",\n \"edit\",\n String(issueNumber),\n \"--remove-label\",\n options.remove.join(\",\"),\n ])\n );\n }\n\n await Promise.all(promises);\n}\n\nexport async function addIssueComment(\n issueNumber: number,\n body: string\n): Promise<void> {\n await execa(\"gh\", [\"issue\", \"comment\", String(issueNumber), \"--body\", body]);\n}\n\nexport async function assignIssue(\n issueNumber: number,\n assignee: string\n): Promise<void> {\n await execa(\"gh\", [\n \"issue\",\n \"edit\",\n String(issueNumber),\n \"--add-assignee\",\n assignee,\n ]);\n}\n\nexport async function createLabel(label: GitHubLabel): Promise<void> {\n try {\n await execa(\"gh\", [\n \"label\",\n \"create\",\n label.name,\n \"--color\",\n label.color,\n \"--description\",\n label.description || \"\",\n \"--force\",\n ]);\n } catch {\n // Label might already exist, ignore error\n }\n}\n\nexport async function createPullRequest(options: {\n title: string;\n body: string;\n base?: string;\n draft?: boolean;\n}): Promise<string> {\n const args = [\n \"pr\",\n \"create\",\n \"--title\",\n options.title,\n \"--body\",\n options.body,\n \"--assignee\",\n \"@me\",\n ];\n\n if (options.base) {\n args.push(\"--base\", options.base);\n }\n\n if (options.draft) {\n args.push(\"--draft\");\n }\n\n const { stdout } = await execa(\"gh\", args);\n return stdout.trim();\n}\n\nexport interface PrBasicInfo {\n number: number;\n url: string;\n}\n\nexport interface PrStatusInfo {\n number: number;\n url: string;\n state: \"open\" | \"closed\" | \"merged\";\n reviewDecision: string | null;\n isDraft: boolean;\n}\n\nexport async function getPrForBranch(): Promise<PrBasicInfo | null> {\n try {\n const { stdout } = await execa(\"gh\", [\n \"pr\",\n \"view\",\n \"--json\",\n \"number,url\",\n ]);\n const data = JSON.parse(stdout);\n return { number: data.number, url: data.url };\n } catch {\n return null;\n }\n}\n\nexport async function getPrStatus(): Promise<PrStatusInfo | null> {\n try {\n const { stdout } = await execa(\"gh\", [\n \"pr\",\n \"view\",\n \"--json\",\n \"number,url,state,reviewDecision,isDraft\",\n ]);\n const data = JSON.parse(stdout);\n // gh pr view returns state as OPEN, CLOSED, or MERGED (uppercase)\n const state = (data.state?.toLowerCase() ?? \"open\") as \"open\" | \"closed\" | \"merged\";\n return {\n number: data.number,\n url: data.url,\n state,\n reviewDecision: data.reviewDecision ?? null,\n isDraft: data.isDraft ?? false,\n };\n } catch {\n return null;\n }\n}\n\nexport async function getPrReviewData(prNumber?: number): Promise<GitHubReviewData> {\n // Fetch reviews and comments using gh pr view (both are supported JSON fields)\n const prArgs = [\"pr\", \"view\"];\n if (prNumber) {\n prArgs.push(String(prNumber));\n }\n prArgs.push(\"--json\", \"reviews,comments\");\n\n const { stdout: prStdout } = await execa(\"gh\", prArgs);\n const prData = JSON.parse(prStdout);\n\n // Fetch review threads using GraphQL API (not available via gh pr view --json)\n // First get repo owner and name since GraphQL doesn't support {owner}/{repo} placeholders\n let reviewThreads: Array<{\n isResolved?: boolean | null;\n isOutdated?: boolean;\n path?: string;\n line?: number | null;\n comments: Array<{\n author: string;\n body: string;\n path?: string;\n line?: number | null;\n createdAt?: string;\n }>;\n }> = [];\n\n try {\n const { stdout: repoStdout } = await execa(\"gh\", [\"repo\", \"view\", \"--json\", \"owner,name\"]);\n const repoData = JSON.parse(repoStdout);\n const owner = repoData.owner?.login ?? repoData.owner;\n const repo = repoData.name;\n\n const graphqlQuery = `query { repository(owner: \"${owner}\", name: \"${repo}\") { pullRequest(number: ${prNumber}) { reviewThreads(first: 100) { nodes { isResolved isOutdated path line comments(first: 100) { nodes { databaseId author { login } body path line createdAt } } } } } } }`;\n\n const { stdout: graphqlStdout } = await execa(\"gh\", [\"api\", \"graphql\", \"-f\", `query=${graphqlQuery}`]);\n const graphqlData = JSON.parse(graphqlStdout);\n const prNode = graphqlData.data?.repository?.pullRequest;\n const threadNodes = prNode?.reviewThreads?.nodes ?? [];\n\n reviewThreads = threadNodes.map((thread: {\n isResolved?: boolean | null;\n isOutdated?: boolean;\n path?: string;\n line?: number | null;\n comments?: { nodes?: Array<{\n databaseId?: number;\n author?: { login?: string };\n body?: string;\n path?: string;\n line?: number | null;\n createdAt?: string;\n }> };\n }) => ({\n isResolved: thread.isResolved ?? null,\n isOutdated: thread.isOutdated ?? false,\n path: thread.path,\n line: thread.line ?? null,\n comments: (thread.comments?.nodes ?? []).map((comment) => ({\n id: comment.databaseId,\n author: comment.author?.login ?? \"unknown\",\n body: comment.body ?? \"\",\n path: comment.path ?? thread.path,\n line: comment.line ?? thread.line ?? null,\n createdAt: comment.createdAt,\n })),\n }));\n } catch {\n // If GraphQL fails (e.g., no permissions), continue with empty threads\n reviewThreads = [];\n }\n\n return {\n reviews: (prData.reviews ?? []).map((review: {\n author?: { login?: string };\n body?: string;\n state?: string;\n submittedAt?: string;\n }) => ({\n author: review.author?.login ?? \"unknown\",\n body: review.body ?? \"\",\n state: review.state ?? \"UNKNOWN\",\n submittedAt: review.submittedAt,\n })),\n reviewThreads,\n comments: (prData.comments ?? []).map((comment: {\n id?: string;\n author?: { login?: string };\n body?: string;\n createdAt?: string;\n }) => ({\n id: comment.id,\n author: comment.author?.login ?? \"unknown\",\n body: comment.body ?? \"\",\n createdAt: comment.createdAt,\n })),\n };\n}\n\nexport async function getCurrentUser(): Promise<string> {\n const { stdout } = await execa(\"gh\", [\"api\", \"user\", \"--jq\", \".login\"]);\n return stdout.trim();\n}\n\nexport async function replyToReviewComment(\n prNumber: number,\n commentId: number,\n body: string\n): Promise<void> {\n await execa(\"gh\", [\n \"api\",\n `repos/{owner}/{repo}/pulls/${prNumber}/comments/${commentId}/replies`,\n \"-f\",\n `body=${body}`,\n ]);\n}\n\nexport async function addPrComment(prNumber: number, body: string): Promise<void> {\n await execa(\"gh\", [\"pr\", \"comment\", String(prNumber), \"--body\", body]);\n}\n","import { execa } from \"execa\";\nimport type { GentConfig, AIProvider } from \"../types/index.js\";\n\nexport async function checkGhCli(): Promise<boolean> {\n try {\n await execa(\"gh\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function checkGhAuth(): Promise<boolean> {\n try {\n await execa(\"gh\", [\"auth\", \"status\"]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function checkClaudeCli(): Promise<boolean> {\n try {\n await execa(\"claude\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function checkGeminiCli(): Promise<boolean> {\n try {\n await execa(\"gemini\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function checkCodexCLI(): Promise<boolean> {\n try {\n await execa(\"codex\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function checkAIProvider(provider: AIProvider): Promise<boolean> {\n switch (provider) {\n case \"claude\":\n return checkClaudeCli();\n case \"gemini\":\n return checkGeminiCli();\n case \"codex\":\n return checkCodexCLI();\n }\n}\n\nexport async function checkGitRepo(): Promise<boolean> {\n try {\n await execa(\"git\", [\"rev-parse\", \"--git-dir\"]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function validatePrerequisites(config?: GentConfig): Promise<{\n valid: boolean;\n missing: string[];\n}> {\n const checks = [\n { name: \"gh CLI\", check: checkGhCli },\n { name: \"gh auth\", check: checkGhAuth },\n { name: \"git repository\", check: checkGitRepo },\n ];\n\n const getProviderName = (provider: AIProvider) => {\n switch (provider) {\n case \"claude\":\n return \"claude CLI\";\n case \"gemini\":\n return \"gemini CLI\";\n case \"codex\":\n return \"codex CLI\";\n }\n };\n\n // Add AI provider check based on config\n if (config) {\n const provider = config.ai.provider;\n checks.push({\n name: getProviderName(provider),\n check: () => checkAIProvider(provider),\n });\n\n // Also check fallback if configured\n if (config.ai.fallback_provider) {\n const fallback = config.ai.fallback_provider;\n checks.push({\n name: `${getProviderName(fallback)} (fallback)`,\n check: () => checkAIProvider(fallback),\n });\n }\n } else {\n // Default to checking claude for backward compatibility\n checks.push({ name: \"claude CLI\", check: checkClaudeCli });\n }\n\n const missing: string[] = [];\n\n for (const { name, check } of checks) {\n const passed = await check();\n if (!passed) {\n missing.push(name);\n }\n }\n\n return {\n valid: missing.length === 0,\n missing,\n };\n}\n\nexport function isValidIssueNumber(value: string): boolean {\n const num = parseInt(value, 10);\n return !isNaN(num) && num > 0;\n}\n\nexport function sanitizeSlug(title: string, maxLength = 40): string {\n return title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, maxLength);\n}\n","import { logger, colors } from \"../utils/logger.js\";\nimport { withSpinner } from \"../utils/spinner.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { getAllLabels } from \"../lib/labels.js\";\nimport { createLabel } from \"../lib/github.js\";\nimport { checkGhAuth } from \"../utils/validators.js\";\n\nexport async function setupLabelsCommand(): Promise<void> {\n logger.bold(\"Setting up GitHub labels...\");\n logger.newline();\n\n // Check gh auth\n const isAuthed = await checkGhAuth();\n if (!isAuthed) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n process.exit(1);\n }\n\n const config = loadConfig();\n const labels = getAllLabels(config);\n\n logger.info(`Creating ${labels.length} labels...`);\n logger.newline();\n\n let created = 0;\n let failed = 0;\n\n for (const label of labels) {\n try {\n await withSpinner(`Creating ${colors.label(label.name)}`, async () => {\n await createLabel(label);\n });\n created++;\n } catch (error) {\n logger.error(`Failed to create ${label.name}: ${error}`);\n failed++;\n }\n }\n\n logger.newline();\n logger.success(`Created ${created} labels`);\n if (failed > 0) {\n logger.warning(`Failed to create ${failed} labels`);\n }\n\n logger.newline();\n logger.info(\"Labels are ready. You can now create AI-ready issues.\");\n}\n"],"mappings":"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","names":["execa","execa"]}
|
package/dist/index.js
CHANGED
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
sortByPriority,
|
|
35
35
|
updateIssueLabels,
|
|
36
36
|
withSpinner
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-3N6U3NTN.js";
|
|
38
38
|
|
|
39
39
|
// src/index.ts
|
|
40
40
|
import { Command } from "commander";
|
|
@@ -195,7 +195,7 @@ async function initCommand(options) {
|
|
|
195
195
|
}
|
|
196
196
|
]);
|
|
197
197
|
if (setupLabels) {
|
|
198
|
-
const { setupLabelsCommand: setupLabelsCommand2 } = await import("./setup-labels-
|
|
198
|
+
const { setupLabelsCommand: setupLabelsCommand2 } = await import("./setup-labels-HKXXO65J.js");
|
|
199
199
|
await setupLabelsCommand2();
|
|
200
200
|
}
|
|
201
201
|
}
|
|
@@ -1300,6 +1300,52 @@ async function autoSelectIssue(readyLabel) {
|
|
|
1300
1300
|
|
|
1301
1301
|
// src/commands/pr.ts
|
|
1302
1302
|
import inquirer4 from "inquirer";
|
|
1303
|
+
|
|
1304
|
+
// src/lib/playwright.ts
|
|
1305
|
+
import { execa as execa3 } from "execa";
|
|
1306
|
+
var UI_FILE_PATTERNS = [
|
|
1307
|
+
/\.(tsx|jsx)$/,
|
|
1308
|
+
/\.(vue|svelte)$/,
|
|
1309
|
+
/\.css$/,
|
|
1310
|
+
/\.scss$/,
|
|
1311
|
+
/\.less$/,
|
|
1312
|
+
/\.styled\.(ts|js)$/,
|
|
1313
|
+
/components?\//i,
|
|
1314
|
+
/pages?\//i,
|
|
1315
|
+
/views?\//i,
|
|
1316
|
+
/layouts?\//i,
|
|
1317
|
+
/ui\//i,
|
|
1318
|
+
/styles?\//i
|
|
1319
|
+
];
|
|
1320
|
+
async function isPlaywrightAvailable() {
|
|
1321
|
+
try {
|
|
1322
|
+
const { exitCode } = await execa3("npx", ["playwright", "--version"], {
|
|
1323
|
+
reject: false
|
|
1324
|
+
});
|
|
1325
|
+
return exitCode === 0;
|
|
1326
|
+
} catch {
|
|
1327
|
+
return false;
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
function hasUIChanges(changedFiles) {
|
|
1331
|
+
return changedFiles.some(
|
|
1332
|
+
(file) => UI_FILE_PATTERNS.some((pattern) => pattern.test(file))
|
|
1333
|
+
);
|
|
1334
|
+
}
|
|
1335
|
+
async function getChangedFiles(baseBranch = "main") {
|
|
1336
|
+
try {
|
|
1337
|
+
const { stdout } = await execa3("git", [
|
|
1338
|
+
"diff",
|
|
1339
|
+
`${baseBranch}...HEAD`,
|
|
1340
|
+
"--name-only"
|
|
1341
|
+
]);
|
|
1342
|
+
return stdout.trim().split("\n").filter(Boolean);
|
|
1343
|
+
} catch {
|
|
1344
|
+
return [];
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
// src/commands/pr.ts
|
|
1303
1349
|
async function prCommand(options) {
|
|
1304
1350
|
logger.bold("Creating AI-enhanced pull request...");
|
|
1305
1351
|
logger.newline();
|
|
@@ -1369,7 +1415,31 @@ async function prCommand(options) {
|
|
|
1369
1415
|
}
|
|
1370
1416
|
logger.info(`Commits: ${commits.length}`);
|
|
1371
1417
|
logger.newline();
|
|
1372
|
-
const
|
|
1418
|
+
const shouldCaptureVideo = options.video !== false && config.video.enabled;
|
|
1419
|
+
let captureVideoInstructions = "";
|
|
1420
|
+
if (shouldCaptureVideo) {
|
|
1421
|
+
const changedFiles = await getChangedFiles(baseBranch);
|
|
1422
|
+
const uiChangesDetected = hasUIChanges(changedFiles);
|
|
1423
|
+
if (uiChangesDetected) {
|
|
1424
|
+
logger.info("UI changes detected in this branch");
|
|
1425
|
+
const playwrightAvailable = await isPlaywrightAvailable();
|
|
1426
|
+
if (!playwrightAvailable) {
|
|
1427
|
+
logger.warning("Playwright not available. Skipping video capture.");
|
|
1428
|
+
logger.dim("Install Playwright with: npm install -D playwright");
|
|
1429
|
+
} else {
|
|
1430
|
+
logger.info("Playwright available - AI will capture demo video via MCP");
|
|
1431
|
+
captureVideoInstructions = `
|
|
1432
|
+
|
|
1433
|
+
IMPORTANT: This PR contains UI changes. Use the Playwright MCP plugin to:
|
|
1434
|
+
1. Start the dev server if needed
|
|
1435
|
+
2. Navigate to the relevant pages showing the UI changes
|
|
1436
|
+
3. Capture a short demo video (max ${config.video.max_duration}s) showcasing the changes
|
|
1437
|
+
4. Upload the video to GitHub and include it in the PR description under a "## Demo Video" section
|
|
1438
|
+
`;
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
const prompt = buildPrPrompt(issue, commits, diffSummary) + captureVideoInstructions;
|
|
1373
1443
|
let prBody;
|
|
1374
1444
|
try {
|
|
1375
1445
|
logger.info(`Generating PR description with ${colors.provider(providerName)}...`);
|
|
@@ -1766,7 +1836,7 @@ import { homedir } from "os";
|
|
|
1766
1836
|
// package.json
|
|
1767
1837
|
var package_default = {
|
|
1768
1838
|
name: "@rotorsoft/gent",
|
|
1769
|
-
version: "1.
|
|
1839
|
+
version: "1.11.0",
|
|
1770
1840
|
description: "AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs",
|
|
1771
1841
|
keywords: [
|
|
1772
1842
|
"cli",
|
|
@@ -2212,8 +2282,12 @@ program.command("list").description("List GitHub issues by label/status").option
|
|
|
2212
2282
|
program.command("run [issue-number]").description("Run AI to implement a GitHub issue").option("-a, --auto", "Auto-select highest priority ai-ready issue").option("-p, --provider <provider>", "AI provider to use (claude, gemini, or codex)").action(async (issueNumber, options) => {
|
|
2213
2283
|
await runCommand(issueNumber, { auto: options.auto, provider: options.provider });
|
|
2214
2284
|
});
|
|
2215
|
-
program.command("pr").description("Create an AI-enhanced pull request").option("-d, --draft", "Create as draft PR").option("-p, --provider <provider>", "AI provider to use (claude, gemini, or codex)").action(async (options) => {
|
|
2216
|
-
await prCommand({
|
|
2285
|
+
program.command("pr").description("Create an AI-enhanced pull request").option("-d, --draft", "Create as draft PR").option("-p, --provider <provider>", "AI provider to use (claude, gemini, or codex)").option("--no-video", "Disable video capture for UI changes").action(async (options) => {
|
|
2286
|
+
await prCommand({
|
|
2287
|
+
draft: options.draft,
|
|
2288
|
+
provider: options.provider,
|
|
2289
|
+
video: options.video
|
|
2290
|
+
});
|
|
2217
2291
|
});
|
|
2218
2292
|
program.command("fix").description("Apply PR review feedback using AI").option("-p, --provider <provider>", "AI provider to use (claude, gemini, or codex)").action(async (options) => {
|
|
2219
2293
|
await fixCommand({ provider: options.provider });
|
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/commands/run.ts","../src/lib/git.ts","../src/lib/branch.ts","../src/commands/pr.ts","../src/commands/fix.ts","../src/lib/review-feedback.ts","../src/lib/version.ts","../package.json","../src/commands/status.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 { getVersion, checkForUpdates, formatUpgradeNotification } 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(formatUpgradeNotification(result.currentVersion, result.latestVersion));\n }\n })\n .catch(() => {\n // Silently ignore errors\n });\n}\n\nconst program = new Command();\n\nprogram\n .name(\"gent\")\n .description(\"AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs\")\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(\"-p, --provider <provider>\", \"AI provider to use (claude, gemini, or codex)\")\n .option(\"-t, --title <title>\", \"Override the generated issue title\")\n .action(async (description, options) => {\n await createCommand(description, { yes: options.yes, provider: options.provider, title: options.title });\n });\n\nprogram\n .command(\"list\")\n .description(\"List GitHub issues by label/status\")\n .option(\"-l, --label <label>\", \"Filter by label\")\n .option(\"-s, --status <status>\", \"Filter by workflow status (ready, in-progress, completed, blocked, all)\")\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(\"-a, --auto\", \"Auto-select highest priority ai-ready issue\")\n .option(\"-p, --provider <provider>\", \"AI provider to use (claude, gemini, or codex)\")\n .action(async (issueNumber, options) => {\n await runCommand(issueNumber, { auto: options.auto, 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(\"-p, --provider <provider>\", \"AI provider to use (claude, gemini, or codex)\")\n .action(async (options) => {\n await prCommand({ draft: options.draft, provider: options.provider });\n });\n\nprogram\n .command(\"fix\")\n .description(\"Apply PR review feedback using AI\")\n .option(\"-p, --provider <provider>\", \"AI provider to use (claude, gemini, or codex)\")\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.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 { configExists, generateDefaultConfig, getConfigPath } 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(\"Setup Complete\", `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 // 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 { loadConfig, loadAgentInstructions } 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 = 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(`${providerName} CLI not found. Please install ${provider} CLI first.`);\n process.exit(1);\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(description, agentInstructions, additionalHints);\n\n try {\n // Show visual indicator before AI output\n console.log(chalk.dim(`┌─ Generating ticket with ${providerName}... ──────────────────────────┐`));\n logger.newline();\n const result = await invokeAI({ prompt, streamOutput: true }, config, options.provider);\n aiOutput = result.output;\n logger.newline();\n console.log(chalk.dim(\"└────────────────────────────────────────────────────────────┘\"));\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(\"Could not parse metadata from AI output. Using defaults.\");\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 = extractIssueBody(aiOutput) + `\\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\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\n return { output, provider };\n } catch (error) {\n // Check for rate limiting\n if (isRateLimitError(error, provider)) {\n // Try fallback if configured\n if (config.ai.auto_fallback && config.ai.fallback_provider && !providerOverride) {\n const fallback = config.ai.fallback_provider;\n logger.warning(`Rate limit reached on ${getProviderDisplayName(provider)}, switching to ${getProviderDisplayName(fallback)}...`);\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 (msg.includes(\"rate limit\") || msg.includes(\"quota exceeded\") || msg.includes(\"too many requests\")) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Internal Claude invocation\n */\nasync function invokeClaudeInternal(options: AIProviderOptions): 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(options: AIProviderOptions): 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(options: AIProviderOptions): 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 reviewFeedback: 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${reviewFeedback ? `## Review Feedback\\n${reviewFeedback}\\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 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.replace(/\\n?META:type=\\w+,priority=\\w+,risk=\\w+,area=\\w+\\s*$/, \"\").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 ((title.startsWith('\"') && title.endsWith('\"')) ||\n (title.startsWith(\"'\") && title.endsWith(\"'\"))) {\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","import chalk from \"chalk\";\nimport { logger, colors } from \"../utils/logger.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { listIssues } from \"../lib/github.js\";\nimport { getWorkflowLabels, sortByPriority, extractPriorityFromLabels, extractTypeFromLabels } 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 async function listCommand(options: ListOptions): Promise<void> {\n // Check gh auth\n const isAuthed = await checkGhAuth();\n if (!isAuthed) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n process.exit(1);\n }\n\n const config = loadConfig();\n const workflowLabels = getWorkflowLabels(config);\n\n // Build label filter\n const labels: string[] = [];\n\n if (options.label) {\n labels.push(options.label);\n }\n\n if (options.status && options.status !== \"all\") {\n switch (options.status) {\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 } else if (!options.status) {\n // Default to showing ai-ready issues\n labels.push(workflowLabels.ready);\n }\n\n let issues: GitHubIssue[];\n try {\n issues = await listIssues({\n labels: labels.length > 0 ? labels : undefined,\n state: \"open\",\n limit: options.limit || 20,\n });\n } catch (error) {\n logger.error(`Failed to fetch issues: ${error}`);\n return;\n }\n\n if (issues.length === 0) {\n logger.info(\"No issues found matching the criteria.\");\n return;\n }\n\n // Sort by priority\n sortByPriority(issues);\n\n logger.bold(`Found ${issues.length} issue(s):`);\n logger.newline();\n\n for (const issue of issues) {\n const type = extractTypeFromLabels(issue.labels);\n const priority = extractPriorityFromLabels(issue.labels);\n const status = getIssueStatus(issue.labels, workflowLabels);\n\n const priorityColor = getPriorityColor(priority);\n const statusColor = getStatusColor(status);\n\n console.log(\n ` ${colors.issue(`#${issue.number.toString().padStart(4)}`)} ` +\n `${priorityColor(`[${priority}]`.padEnd(10))} ` +\n `${statusColor(`[${status}]`.padEnd(14))} ` +\n `${colors.label(`[${type}]`.padEnd(10))} ` +\n issue.title.slice(0, 50) +\n (issue.title.length > 50 ? \"...\" : \"\")\n );\n }\n\n logger.newline();\n logger.dim(`Run ${colors.command(\"gent run <issue-number>\")} to implement an issue`);\n logger.dim(`Run ${colors.command(\"gent run --auto\")} to auto-select highest priority`);\n}\n\nfunction getIssueStatus(\n labels: string[],\n workflowLabels: ReturnType<typeof getWorkflowLabels>\n): string {\n if (labels.includes(workflowLabels.ready)) return \"ready\";\n if (labels.includes(workflowLabels.inProgress)) return \"in-progress\";\n if (labels.includes(workflowLabels.completed)) return \"completed\";\n if (labels.includes(workflowLabels.blocked)) return \"blocked\";\n return \"unknown\";\n}\n\nfunction getPriorityColor(priority: string): (text: string) => string {\n switch (priority) {\n case \"critical\":\n return chalk.red;\n case \"high\":\n return chalk.yellow;\n case \"medium\":\n return chalk.blue;\n case \"low\":\n return chalk.green;\n default:\n return chalk.gray;\n }\n}\n\nfunction getStatusColor(status: string): (text: string) => string {\n switch (status) {\n case \"ready\":\n return chalk.green;\n case \"in-progress\":\n return chalk.yellow;\n case \"completed\":\n return chalk.blue;\n case \"blocked\":\n return chalk.red;\n default:\n return chalk.gray;\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 { getIssue, listIssues, updateIssueLabels, addIssueComment } from \"../lib/github.js\";\nimport { buildImplementationPrompt } from \"../lib/prompts.js\";\nimport { invokeAIInteractive, getProviderDisplayName } from \"../lib/ai-provider.js\";\nimport { getCurrentBranch, isOnMainBranch, createBranch, branchExists, checkoutBranch, hasUncommittedChanges, getCurrentCommitSha, hasNewCommits } from \"../lib/git.js\";\nimport { generateBranchName } from \"../lib/branch.js\";\nimport { getWorkflowLabels, extractTypeFromLabels, sortByPriority } from \"../lib/labels.js\";\nimport { readProgress } from \"../lib/progress.js\";\nimport { checkGhAuth, checkAIProvider, isValidIssueNumber } from \"../utils/validators.js\";\nimport type { GitHubIssue, AIProvider } from \"../types/index.js\";\n\nexport interface RunOptions {\n auto?: boolean;\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 process.exit(1);\n }\n\n if (!aiOk) {\n logger.error(`${providerName} CLI not found. Please install ${provider} CLI first.`);\n process.exit(1);\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 process.exit(0);\n }\n }\n\n const workflowLabels = getWorkflowLabels(config);\n\n // Get issue number\n let issueNumber: number;\n\n if (options.auto) {\n // Auto-select highest priority ai-ready issue\n const autoIssue = await autoSelectIssue(workflowLabels.ready);\n if (!autoIssue) {\n logger.error(\"No ai-ready issues found.\");\n process.exit(1);\n }\n issueNumber = autoIssue.number;\n logger.info(`Auto-selected: ${colors.issue(`#${issueNumber}`)} - ${autoIssue.title}`);\n } else if (issueNumberArg) {\n if (!isValidIssueNumber(issueNumberArg)) {\n logger.error(\"Invalid issue number.\");\n process.exit(1);\n }\n issueNumber = parseInt(issueNumberArg, 10);\n } else {\n logger.error(\"Please provide an issue number or use --auto\");\n process.exit(1);\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(`Issue #${issueNumber} does not have the '${workflowLabels.ready}' label.`);\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(\"Issue Details\", `#${issue.number}: ${issue.title}\nLabels: ${issue.labels.join(\", \")}`);\n logger.newline();\n\n // Generate branch name\n const type = extractTypeFromLabels(issue.labels);\n const branchName = await generateBranchName(config, issueNumber, issue.title, type);\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(`Not on main branch (currently on ${colors.branch(currentBranch)}).`);\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(`Updated issue labels: ${colors.label(workflowLabels.ready)} → ${colors.label(workflowLabels.inProgress)}`);\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(issue, agentInstructions, progressContent, config);\n\n logger.newline();\n logger.info(`Starting ${colors.provider(providerName)} implementation session...`);\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(prompt, config, options.provider);\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(`${getProviderDisplayName(usedProvider)} session failed: ${error}`);\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(`Updated labels: ${colors.label(workflowLabels.inProgress)} → ${colors.label(workflowLabels.completed)}`);\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(`${usedProviderName} session ended due to rate limits. No commits were created.`);\n\n // Set ai-blocked label\n try {\n await updateIssueLabels(issueNumber, {\n add: [workflowLabels.blocked],\n remove: [workflowLabels.inProgress],\n });\n logger.info(`Updated labels: ${colors.label(workflowLabels.inProgress)} → ${colors.label(workflowLabels.blocked)}`);\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(`${usedProviderName} session completed but no commits were created. Labels unchanged.`);\n // Leave as ai-in-progress so it can be retried\n }\n\n return;\n }\n\n logger.newline();\n logger.box(\"Next Steps\", `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\nasync function autoSelectIssue(readyLabel: string): Promise<GitHubIssue | null> {\n // Try critical first\n let issues = await listIssues({\n labels: [readyLabel, \"priority:critical\"],\n state: \"open\",\n limit: 1,\n });\n if (issues.length > 0) return issues[0];\n\n // Try high\n issues = await listIssues({\n labels: [readyLabel, \"priority:high\"],\n state: \"open\",\n limit: 1,\n });\n if (issues.length > 0) return issues[0];\n\n // Get any ai-ready and sort\n issues = await listIssues({\n labels: [readyLabel],\n state: \"open\",\n limit: 10,\n });\n\n if (issues.length === 0) return null;\n\n sortByPriority(issues);\n return issues[0];\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\", [\n \"log\",\n \"@{u}..HEAD\",\n \"--oneline\",\n ]);\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\", [\n \"diff\",\n `${base}...HEAD`,\n \"--stat\",\n ]);\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","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 = /^([^/]+)\\/(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 } from \"../lib/config.js\";\nimport { getIssue, createPullRequest, getPrForBranch, assignIssue, getCurrentUser, updateIssueLabels } from \"../lib/github.js\";\nimport { buildPrPrompt } from \"../lib/prompts.js\";\nimport { invokeAI, getProviderDisplayName } from \"../lib/ai-provider.js\";\nimport { getCurrentBranch, isOnMainBranch, getDefaultBranch, getCommitsSinceBase, getDiffSummary, getUnpushedCommits, pushBranch } from \"../lib/git.js\";\nimport { extractIssueNumber } from \"../lib/branch.js\";\nimport { getWorkflowLabels } from \"../lib/labels.js\";\nimport { checkGhAuth, checkAIProvider } from \"../utils/validators.js\";\nimport type { GitHubIssue, AIProvider } from \"../types/index.js\";\n\nexport interface PrOptions {\n draft?: boolean;\n provider?: AIProvider;\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(`${providerName} CLI not found. Please install ${provider} CLI first.`);\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(`A PR already exists for this branch: ${colors.url(existingPr.url)}`);\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(`Linked issue: ${colors.issue(`#${issueNumber}`)} - ${issue.title}`);\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 // Generate PR description with AI\n const prompt = buildPrPrompt(issue, commits, diffSummary);\n\n let prBody: string;\n try {\n logger.info(`Generating PR description with ${colors.provider(providerName)}...`);\n logger.newline();\n const result = await invokeAI({ prompt, streamOutput: true }, config, options.provider);\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(`Updated labels: ${colors.label(workflowLabels.inProgress)} → ${colors.label(workflowLabels.completed)}`);\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 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, getPrForBranch, getPrReviewData, replyToReviewComment, addPrComment } from \"../lib/github.js\";\nimport { buildImplementationPrompt } from \"../lib/prompts.js\";\nimport { invokeAIInteractive, getProviderDisplayName } from \"../lib/ai-provider.js\";\nimport { getCurrentBranch, isOnMainBranch, hasUncommittedChanges, getCurrentCommitSha, hasNewCommits, getLastCommitTimestamp } from \"../lib/git.js\";\nimport { extractIssueNumber } from \"../lib/branch.js\";\nimport { readProgress } from \"../lib/progress.js\";\nimport { summarizeReviewFeedback, type ReviewFeedbackItem } 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(`${providerName} CLI not found. Please install ${provider} CLI first.`);\n process.exit(1);\n }\n\n if (await isOnMainBranch()) {\n logger.error(\"Cannot apply fixes from main/master branch. Switch to the PR branch first.\");\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(\"No pull request found for the current branch. Create one with 'gent pr' first.\");\n process.exit(1);\n }\n\n const lastCommitTimestamp = await getLastCommitTimestamp();\n\n const reviewData = await withSpinner(\"Fetching review feedback...\", async () => {\n return getPrReviewData(pr.number);\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, { afterTimestamp: lastCommitTimestamp });\n if (items.length === 0 || !summary) {\n logger.error(\"No new actionable review feedback found since your last commit.\");\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(issue, agentInstructions, progressContent, config, summary);\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(prompt, config, options.provider);\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(`${providerName} session ended due to rate limits. No commits were created.`);\n return;\n }\n\n logger.warning(`${providerName} session completed but no commits were created.`);\n}\n\nfunction countReviewComments(data: GitHubReviewData): number {\n const reviewBodies = data.reviews.filter((review) => review.body?.trim()).length;\n const threadBodies = data.reviewThreads.reduce((count, thread) => {\n const threadCount = (thread.comments ?? []).filter((comment) => comment.body?.trim()).length;\n return count + threadCount;\n }, 0);\n const prComments = (data.comments ?? []).filter((comment) => comment.body?.trim()).length;\n return reviewBodies + threadBodies + prComments;\n}\n\nasync function replyToFeedbackItems(prNumber: number, items: ReviewFeedbackItem[]): 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(`Replied to ${repliedCount} feedback item${repliedCount > 1 ? \"s\" : \"\"}.`);\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(data: GitHubReviewData, options?: ReviewFeedbackOptions): {\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(itemTimestamp: string | undefined, afterTimestamp: string | undefined): boolean {\n if (!afterTimestamp || !itemTimestamp) {\n return true;\n }\n return new Date(itemTimestamp) > new Date(afterTimestamp);\n}\n\nexport function extractReviewFeedbackItems(data: GitHubReviewData, options?: ReviewFeedbackOptions): 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 = thread.isResolved === false || thread.isResolved === undefined || thread.isResolved === null;\n\n const hasRecentComments = (thread.comments ?? []).some(\n (c) => 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(items: ReviewFeedbackItem[]): 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: { isResolved?: boolean | null; comments?: { body: string }[] }): boolean {\n if (thread.isResolved === false || thread.isResolved === undefined || thread.isResolved === null) {\n return true;\n }\n return (thread.comments ?? []).some((comment) => isActionableText(comment.body));\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<T extends { body: string; id?: number | string }>(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 = 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 ? compareVersions(cache.latestVersion, currentVersion) > 0 : 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.10.1\",\n \"description\": \"AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs\",\n \"keywords\": [\n \"cli\",\n \"ai\",\n \"claude\",\n \"github\",\n \"workflow\",\n \"automation\",\n \"developer-tools\"\n ],\n \"homepage\": \"https://github.com/rotorsoft/gent#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/rotorsoft/gent/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/rotorsoft/gent.git\"\n },\n \"license\": \"MIT\",\n \"author\": \"Rotorsoft\",\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\"\n }\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"bin\": {\n \"gent\": \"./dist/index.js\"\n },\n \"files\": [\n \"dist\",\n \"templates\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsx src/index.ts\",\n \"watch\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"lint\": \"eslint src/\",\n \"lint:fix\": \"eslint src/ --fix\",\n \"format\": \"prettier --write \\\"src/**/*.ts\\\"\",\n \"format:check\": \"prettier --check \\\"src/**/*.ts\\\"\",\n \"typecheck\": \"tsc --noEmit\",\n \"prepublishOnly\": \"npm run build\",\n \"prepare\": \"npm run build\"\n },\n \"dependencies\": {\n \"chalk\": \"^5.3.0\",\n \"commander\": \"^12.1.0\",\n \"execa\": \"^9.5.2\",\n \"inquirer\": \"^12.2.0\",\n \"ora\": \"^8.1.1\",\n \"yaml\": \"^2.6.1\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.17.0\",\n \"@semantic-release/changelog\": \"^6.0.3\",\n \"@semantic-release/git\": \"^10.0.1\",\n \"@types/inquirer\": \"^9.0.7\",\n \"@types/node\": \"^22.10.5\",\n \"@typescript-eslint/eslint-plugin\": \"^8.19.1\",\n \"@typescript-eslint/parser\": \"^8.19.1\",\n \"@vitest/coverage-v8\": \"^2.1.8\",\n \"eslint\": \"^9.17.0\",\n \"eslint-config-prettier\": \"^9.1.0\",\n \"prettier\": \"^3.4.2\",\n \"semantic-release\": \"^24.2.1\",\n \"tsup\": \"^8.3.5\",\n \"tsx\": \"^4.21.0\",\n \"typescript\": \"^5.7.3\",\n \"vitest\": \"^2.1.8\"\n },\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}\n","import { logger, colors } from \"../utils/logger.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { getIssue, getPrStatus, getPrReviewData } from \"../lib/github.js\";\nimport { getCurrentBranch, isOnMainBranch, hasUncommittedChanges, getUnpushedCommits, getCommitsSinceBase, getDefaultBranch, getLastCommitTimestamp } 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 { checkGhAuth, checkClaudeCli, checkGeminiCli, checkGitRepo } from \"../utils/validators.js\";\nimport { getProviderDisplayName } from \"../lib/ai-provider.js\";\nimport { getVersion } from \"../lib/version.js\";\nimport { summarizeReviewFeedback, type ReviewFeedbackItem } from \"../lib/review-feedback.js\";\n\nfunction formatPrState(state: \"open\" | \"closed\" | \"merged\", isDraft: boolean): 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 ? item.state.replace(/_/g, \" \").toLowerCase() : \"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(` Fallback: ${fallbackName} (auto: ${config.ai.auto_fallback ? \"enabled\" : \"disabled\"})`);\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, { afterTimestamp: lastCommitTimestamp });\n hasActionableFeedback = items.length > 0;\n\n if (prStatus.reviewDecision) {\n logger.info(` Review: ${formatReviewDecision(prStatus.reviewDecision)}`);\n }\n\n if (items.length > 0) {\n logger.warning(` ${items.length} actionable comment${items.length > 1 ? \"s\" : \"\"} to fix with ${colors.command(\"gent fix\")}:`);\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(` Run ${colors.command(\"git checkout main && git pull\")} to sync`);\n } else if (prStatus.state === \"closed\") {\n logger.warning(\" This PR was closed without merging\");\n logger.dim(` Consider reopening or creating a new PR if changes are still needed`);\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"],"mappings":"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","names":["writeFileSync","existsSync","join","writeFileSync","join","existsSync","setupLabelsCommand","inquirer","inquirer","chalk","chalk","inquirer","execa","execa","inquirer","inquirer","inquirer","inquirer","inquirer","readFileSync","writeFileSync","existsSync","mkdirSync","join","join","existsSync","readFileSync","mkdirSync","writeFileSync","version"]}
|
|
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/commands/run.ts","../src/lib/git.ts","../src/lib/branch.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"],"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 { getVersion, checkForUpdates, formatUpgradeNotification } 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(formatUpgradeNotification(result.currentVersion, result.latestVersion));\n }\n })\n .catch(() => {\n // Silently ignore errors\n });\n}\n\nconst program = new Command();\n\nprogram\n .name(\"gent\")\n .description(\"AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs\")\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(\"-p, --provider <provider>\", \"AI provider to use (claude, gemini, or codex)\")\n .option(\"-t, --title <title>\", \"Override the generated issue title\")\n .action(async (description, options) => {\n await createCommand(description, { yes: options.yes, provider: options.provider, title: options.title });\n });\n\nprogram\n .command(\"list\")\n .description(\"List GitHub issues by label/status\")\n .option(\"-l, --label <label>\", \"Filter by label\")\n .option(\"-s, --status <status>\", \"Filter by workflow status (ready, in-progress, completed, blocked, all)\")\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(\"-a, --auto\", \"Auto-select highest priority ai-ready issue\")\n .option(\"-p, --provider <provider>\", \"AI provider to use (claude, gemini, or codex)\")\n .action(async (issueNumber, options) => {\n await runCommand(issueNumber, { auto: options.auto, 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(\"-p, --provider <provider>\", \"AI provider to use (claude, gemini, or codex)\")\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(\"-p, --provider <provider>\", \"AI provider to use (claude, gemini, or codex)\")\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.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 { configExists, generateDefaultConfig, getConfigPath } 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(\"Setup Complete\", `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 // 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 { loadConfig, loadAgentInstructions } 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 = 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(`${providerName} CLI not found. Please install ${provider} CLI first.`);\n process.exit(1);\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(description, agentInstructions, additionalHints);\n\n try {\n // Show visual indicator before AI output\n console.log(chalk.dim(`┌─ Generating ticket with ${providerName}... ──────────────────────────┐`));\n logger.newline();\n const result = await invokeAI({ prompt, streamOutput: true }, config, options.provider);\n aiOutput = result.output;\n logger.newline();\n console.log(chalk.dim(\"└────────────────────────────────────────────────────────────┘\"));\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(\"Could not parse metadata from AI output. Using defaults.\");\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 = extractIssueBody(aiOutput) + `\\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\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\n return { output, provider };\n } catch (error) {\n // Check for rate limiting\n if (isRateLimitError(error, provider)) {\n // Try fallback if configured\n if (config.ai.auto_fallback && config.ai.fallback_provider && !providerOverride) {\n const fallback = config.ai.fallback_provider;\n logger.warning(`Rate limit reached on ${getProviderDisplayName(provider)}, switching to ${getProviderDisplayName(fallback)}...`);\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 (msg.includes(\"rate limit\") || msg.includes(\"quota exceeded\") || msg.includes(\"too many requests\")) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Internal Claude invocation\n */\nasync function invokeClaudeInternal(options: AIProviderOptions): 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(options: AIProviderOptions): 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(options: AIProviderOptions): 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 reviewFeedback: 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${reviewFeedback ? `## Review Feedback\\n${reviewFeedback}\\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 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.replace(/\\n?META:type=\\w+,priority=\\w+,risk=\\w+,area=\\w+\\s*$/, \"\").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 ((title.startsWith('\"') && title.endsWith('\"')) ||\n (title.startsWith(\"'\") && title.endsWith(\"'\"))) {\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","import chalk from \"chalk\";\nimport { logger, colors } from \"../utils/logger.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { listIssues } from \"../lib/github.js\";\nimport { getWorkflowLabels, sortByPriority, extractPriorityFromLabels, extractTypeFromLabels } 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 async function listCommand(options: ListOptions): Promise<void> {\n // Check gh auth\n const isAuthed = await checkGhAuth();\n if (!isAuthed) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n process.exit(1);\n }\n\n const config = loadConfig();\n const workflowLabels = getWorkflowLabels(config);\n\n // Build label filter\n const labels: string[] = [];\n\n if (options.label) {\n labels.push(options.label);\n }\n\n if (options.status && options.status !== \"all\") {\n switch (options.status) {\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 } else if (!options.status) {\n // Default to showing ai-ready issues\n labels.push(workflowLabels.ready);\n }\n\n let issues: GitHubIssue[];\n try {\n issues = await listIssues({\n labels: labels.length > 0 ? labels : undefined,\n state: \"open\",\n limit: options.limit || 20,\n });\n } catch (error) {\n logger.error(`Failed to fetch issues: ${error}`);\n return;\n }\n\n if (issues.length === 0) {\n logger.info(\"No issues found matching the criteria.\");\n return;\n }\n\n // Sort by priority\n sortByPriority(issues);\n\n logger.bold(`Found ${issues.length} issue(s):`);\n logger.newline();\n\n for (const issue of issues) {\n const type = extractTypeFromLabels(issue.labels);\n const priority = extractPriorityFromLabels(issue.labels);\n const status = getIssueStatus(issue.labels, workflowLabels);\n\n const priorityColor = getPriorityColor(priority);\n const statusColor = getStatusColor(status);\n\n console.log(\n ` ${colors.issue(`#${issue.number.toString().padStart(4)}`)} ` +\n `${priorityColor(`[${priority}]`.padEnd(10))} ` +\n `${statusColor(`[${status}]`.padEnd(14))} ` +\n `${colors.label(`[${type}]`.padEnd(10))} ` +\n issue.title.slice(0, 50) +\n (issue.title.length > 50 ? \"...\" : \"\")\n );\n }\n\n logger.newline();\n logger.dim(`Run ${colors.command(\"gent run <issue-number>\")} to implement an issue`);\n logger.dim(`Run ${colors.command(\"gent run --auto\")} to auto-select highest priority`);\n}\n\nfunction getIssueStatus(\n labels: string[],\n workflowLabels: ReturnType<typeof getWorkflowLabels>\n): string {\n if (labels.includes(workflowLabels.ready)) return \"ready\";\n if (labels.includes(workflowLabels.inProgress)) return \"in-progress\";\n if (labels.includes(workflowLabels.completed)) return \"completed\";\n if (labels.includes(workflowLabels.blocked)) return \"blocked\";\n return \"unknown\";\n}\n\nfunction getPriorityColor(priority: string): (text: string) => string {\n switch (priority) {\n case \"critical\":\n return chalk.red;\n case \"high\":\n return chalk.yellow;\n case \"medium\":\n return chalk.blue;\n case \"low\":\n return chalk.green;\n default:\n return chalk.gray;\n }\n}\n\nfunction getStatusColor(status: string): (text: string) => string {\n switch (status) {\n case \"ready\":\n return chalk.green;\n case \"in-progress\":\n return chalk.yellow;\n case \"completed\":\n return chalk.blue;\n case \"blocked\":\n return chalk.red;\n default:\n return chalk.gray;\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 { getIssue, listIssues, updateIssueLabels, addIssueComment } from \"../lib/github.js\";\nimport { buildImplementationPrompt } from \"../lib/prompts.js\";\nimport { invokeAIInteractive, getProviderDisplayName } from \"../lib/ai-provider.js\";\nimport { getCurrentBranch, isOnMainBranch, createBranch, branchExists, checkoutBranch, hasUncommittedChanges, getCurrentCommitSha, hasNewCommits } from \"../lib/git.js\";\nimport { generateBranchName } from \"../lib/branch.js\";\nimport { getWorkflowLabels, extractTypeFromLabels, sortByPriority } from \"../lib/labels.js\";\nimport { readProgress } from \"../lib/progress.js\";\nimport { checkGhAuth, checkAIProvider, isValidIssueNumber } from \"../utils/validators.js\";\nimport type { GitHubIssue, AIProvider } from \"../types/index.js\";\n\nexport interface RunOptions {\n auto?: boolean;\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 process.exit(1);\n }\n\n if (!aiOk) {\n logger.error(`${providerName} CLI not found. Please install ${provider} CLI first.`);\n process.exit(1);\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 process.exit(0);\n }\n }\n\n const workflowLabels = getWorkflowLabels(config);\n\n // Get issue number\n let issueNumber: number;\n\n if (options.auto) {\n // Auto-select highest priority ai-ready issue\n const autoIssue = await autoSelectIssue(workflowLabels.ready);\n if (!autoIssue) {\n logger.error(\"No ai-ready issues found.\");\n process.exit(1);\n }\n issueNumber = autoIssue.number;\n logger.info(`Auto-selected: ${colors.issue(`#${issueNumber}`)} - ${autoIssue.title}`);\n } else if (issueNumberArg) {\n if (!isValidIssueNumber(issueNumberArg)) {\n logger.error(\"Invalid issue number.\");\n process.exit(1);\n }\n issueNumber = parseInt(issueNumberArg, 10);\n } else {\n logger.error(\"Please provide an issue number or use --auto\");\n process.exit(1);\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(`Issue #${issueNumber} does not have the '${workflowLabels.ready}' label.`);\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(\"Issue Details\", `#${issue.number}: ${issue.title}\nLabels: ${issue.labels.join(\", \")}`);\n logger.newline();\n\n // Generate branch name\n const type = extractTypeFromLabels(issue.labels);\n const branchName = await generateBranchName(config, issueNumber, issue.title, type);\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(`Not on main branch (currently on ${colors.branch(currentBranch)}).`);\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(`Updated issue labels: ${colors.label(workflowLabels.ready)} → ${colors.label(workflowLabels.inProgress)}`);\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(issue, agentInstructions, progressContent, config);\n\n logger.newline();\n logger.info(`Starting ${colors.provider(providerName)} implementation session...`);\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(prompt, config, options.provider);\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(`${getProviderDisplayName(usedProvider)} session failed: ${error}`);\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(`Updated labels: ${colors.label(workflowLabels.inProgress)} → ${colors.label(workflowLabels.completed)}`);\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(`${usedProviderName} session ended due to rate limits. No commits were created.`);\n\n // Set ai-blocked label\n try {\n await updateIssueLabels(issueNumber, {\n add: [workflowLabels.blocked],\n remove: [workflowLabels.inProgress],\n });\n logger.info(`Updated labels: ${colors.label(workflowLabels.inProgress)} → ${colors.label(workflowLabels.blocked)}`);\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(`${usedProviderName} session completed but no commits were created. Labels unchanged.`);\n // Leave as ai-in-progress so it can be retried\n }\n\n return;\n }\n\n logger.newline();\n logger.box(\"Next Steps\", `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\nasync function autoSelectIssue(readyLabel: string): Promise<GitHubIssue | null> {\n // Try critical first\n let issues = await listIssues({\n labels: [readyLabel, \"priority:critical\"],\n state: \"open\",\n limit: 1,\n });\n if (issues.length > 0) return issues[0];\n\n // Try high\n issues = await listIssues({\n labels: [readyLabel, \"priority:high\"],\n state: \"open\",\n limit: 1,\n });\n if (issues.length > 0) return issues[0];\n\n // Get any ai-ready and sort\n issues = await listIssues({\n labels: [readyLabel],\n state: \"open\",\n limit: 10,\n });\n\n if (issues.length === 0) return null;\n\n sortByPriority(issues);\n return issues[0];\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\", [\n \"log\",\n \"@{u}..HEAD\",\n \"--oneline\",\n ]);\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\", [\n \"diff\",\n `${base}...HEAD`,\n \"--stat\",\n ]);\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","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 = /^([^/]+)\\/(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 } from \"../lib/config.js\";\nimport { getIssue, createPullRequest, getPrForBranch, assignIssue, getCurrentUser, updateIssueLabels } from \"../lib/github.js\";\nimport { buildPrPrompt } from \"../lib/prompts.js\";\nimport { invokeAI, getProviderDisplayName } from \"../lib/ai-provider.js\";\nimport { getCurrentBranch, isOnMainBranch, getDefaultBranch, getCommitsSinceBase, getDiffSummary, getUnpushedCommits, pushBranch } from \"../lib/git.js\";\nimport { extractIssueNumber } from \"../lib/branch.js\";\nimport { getWorkflowLabels } from \"../lib/labels.js\";\nimport { checkGhAuth, checkAIProvider } from \"../utils/validators.js\";\nimport { isPlaywrightAvailable, hasUIChanges, getChangedFiles } 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(`${providerName} CLI not found. Please install ${provider} CLI first.`);\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(`A PR already exists for this branch: ${colors.url(existingPr.url)}`);\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(`Linked issue: ${colors.issue(`#${issueNumber}`)} - ${issue.title}`);\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(\"Playwright available - AI will capture demo video via MCP\");\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 = buildPrPrompt(issue, commits, diffSummary) + captureVideoInstructions;\n\n let prBody: string;\n try {\n logger.info(`Generating PR description with ${colors.provider(providerName)}...`);\n logger.newline();\n const result = await invokeAI({ prompt, streamOutput: true }, config, options.provider);\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(`Updated labels: ${colors.label(workflowLabels.inProgress)} → ${colors.label(workflowLabels.completed)}`);\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(baseBranch: string = \"main\"): 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 { getIssue, getPrForBranch, getPrReviewData, replyToReviewComment, addPrComment } from \"../lib/github.js\";\nimport { buildImplementationPrompt } from \"../lib/prompts.js\";\nimport { invokeAIInteractive, getProviderDisplayName } from \"../lib/ai-provider.js\";\nimport { getCurrentBranch, isOnMainBranch, hasUncommittedChanges, getCurrentCommitSha, hasNewCommits, getLastCommitTimestamp } from \"../lib/git.js\";\nimport { extractIssueNumber } from \"../lib/branch.js\";\nimport { readProgress } from \"../lib/progress.js\";\nimport { summarizeReviewFeedback, type ReviewFeedbackItem } 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(`${providerName} CLI not found. Please install ${provider} CLI first.`);\n process.exit(1);\n }\n\n if (await isOnMainBranch()) {\n logger.error(\"Cannot apply fixes from main/master branch. Switch to the PR branch first.\");\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(\"No pull request found for the current branch. Create one with 'gent pr' first.\");\n process.exit(1);\n }\n\n const lastCommitTimestamp = await getLastCommitTimestamp();\n\n const reviewData = await withSpinner(\"Fetching review feedback...\", async () => {\n return getPrReviewData(pr.number);\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, { afterTimestamp: lastCommitTimestamp });\n if (items.length === 0 || !summary) {\n logger.error(\"No new actionable review feedback found since your last commit.\");\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(issue, agentInstructions, progressContent, config, summary);\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(prompt, config, options.provider);\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(`${providerName} session ended due to rate limits. No commits were created.`);\n return;\n }\n\n logger.warning(`${providerName} session completed but no commits were created.`);\n}\n\nfunction countReviewComments(data: GitHubReviewData): number {\n const reviewBodies = data.reviews.filter((review) => review.body?.trim()).length;\n const threadBodies = data.reviewThreads.reduce((count, thread) => {\n const threadCount = (thread.comments ?? []).filter((comment) => comment.body?.trim()).length;\n return count + threadCount;\n }, 0);\n const prComments = (data.comments ?? []).filter((comment) => comment.body?.trim()).length;\n return reviewBodies + threadBodies + prComments;\n}\n\nasync function replyToFeedbackItems(prNumber: number, items: ReviewFeedbackItem[]): 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(`Replied to ${repliedCount} feedback item${repliedCount > 1 ? \"s\" : \"\"}.`);\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(data: GitHubReviewData, options?: ReviewFeedbackOptions): {\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(itemTimestamp: string | undefined, afterTimestamp: string | undefined): boolean {\n if (!afterTimestamp || !itemTimestamp) {\n return true;\n }\n return new Date(itemTimestamp) > new Date(afterTimestamp);\n}\n\nexport function extractReviewFeedbackItems(data: GitHubReviewData, options?: ReviewFeedbackOptions): 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 = thread.isResolved === false || thread.isResolved === undefined || thread.isResolved === null;\n\n const hasRecentComments = (thread.comments ?? []).some(\n (c) => 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(items: ReviewFeedbackItem[]): 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: { isResolved?: boolean | null; comments?: { body: string }[] }): boolean {\n if (thread.isResolved === false || thread.isResolved === undefined || thread.isResolved === null) {\n return true;\n }\n return (thread.comments ?? []).some((comment) => isActionableText(comment.body));\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<T extends { body: string; id?: number | string }>(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 = 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 ? compareVersions(cache.latestVersion, currentVersion) > 0 : 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.11.0\",\n \"description\": \"AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs\",\n \"keywords\": [\n \"cli\",\n \"ai\",\n \"claude\",\n \"github\",\n \"workflow\",\n \"automation\",\n \"developer-tools\"\n ],\n \"homepage\": \"https://github.com/rotorsoft/gent#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/rotorsoft/gent/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/rotorsoft/gent.git\"\n },\n \"license\": \"MIT\",\n \"author\": \"Rotorsoft\",\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\"\n }\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"bin\": {\n \"gent\": \"./dist/index.js\"\n },\n \"files\": [\n \"dist\",\n \"templates\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsx src/index.ts\",\n \"watch\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"lint\": \"eslint src/\",\n \"lint:fix\": \"eslint src/ --fix\",\n \"format\": \"prettier --write \\\"src/**/*.ts\\\"\",\n \"format:check\": \"prettier --check \\\"src/**/*.ts\\\"\",\n \"typecheck\": \"tsc --noEmit\",\n \"prepublishOnly\": \"npm run build\",\n \"prepare\": \"npm run build\"\n },\n \"dependencies\": {\n \"chalk\": \"^5.3.0\",\n \"commander\": \"^12.1.0\",\n \"execa\": \"^9.5.2\",\n \"inquirer\": \"^12.2.0\",\n \"ora\": \"^8.1.1\",\n \"yaml\": \"^2.6.1\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.17.0\",\n \"@semantic-release/changelog\": \"^6.0.3\",\n \"@semantic-release/git\": \"^10.0.1\",\n \"@types/inquirer\": \"^9.0.7\",\n \"@types/node\": \"^22.10.5\",\n \"@typescript-eslint/eslint-plugin\": \"^8.19.1\",\n \"@typescript-eslint/parser\": \"^8.19.1\",\n \"@vitest/coverage-v8\": \"^2.1.8\",\n \"eslint\": \"^9.17.0\",\n \"eslint-config-prettier\": \"^9.1.0\",\n \"prettier\": \"^3.4.2\",\n \"semantic-release\": \"^24.2.1\",\n \"tsup\": \"^8.3.5\",\n \"tsx\": \"^4.21.0\",\n \"typescript\": \"^5.7.3\",\n \"vitest\": \"^2.1.8\"\n },\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}\n","import { logger, colors } from \"../utils/logger.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { getIssue, getPrStatus, getPrReviewData } from \"../lib/github.js\";\nimport { getCurrentBranch, isOnMainBranch, hasUncommittedChanges, getUnpushedCommits, getCommitsSinceBase, getDefaultBranch, getLastCommitTimestamp } 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 { checkGhAuth, checkClaudeCli, checkGeminiCli, checkGitRepo } from \"../utils/validators.js\";\nimport { getProviderDisplayName } from \"../lib/ai-provider.js\";\nimport { getVersion } from \"../lib/version.js\";\nimport { summarizeReviewFeedback, type ReviewFeedbackItem } from \"../lib/review-feedback.js\";\n\nfunction formatPrState(state: \"open\" | \"closed\" | \"merged\", isDraft: boolean): 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 ? item.state.replace(/_/g, \" \").toLowerCase() : \"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(` Fallback: ${fallbackName} (auto: ${config.ai.auto_fallback ? \"enabled\" : \"disabled\"})`);\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, { afterTimestamp: lastCommitTimestamp });\n hasActionableFeedback = items.length > 0;\n\n if (prStatus.reviewDecision) {\n logger.info(` Review: ${formatReviewDecision(prStatus.reviewDecision)}`);\n }\n\n if (items.length > 0) {\n logger.warning(` ${items.length} actionable comment${items.length > 1 ? \"s\" : \"\"} to fix with ${colors.command(\"gent fix\")}:`);\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(` Run ${colors.command(\"git checkout main && git pull\")} to sync`);\n } else if (prStatus.state === \"closed\") {\n logger.warning(\" This PR was closed without merging\");\n logger.dim(` Consider reopening or creating a new PR if changes are still needed`);\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"],"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;;;AD1IA,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,IAAI,kBAAkB;AAAA,UACrB,OAAO,KAAK,UAAU,CAAC;AAAA,UACvB,OAAO,KAAK,WAAW,CAAC;AAAA,SACzB,OAAO,QAAQ,mBAAmB,CAAC;AAAA,SACnC,OAAO,QAAQ,2BAA2B,CAAC,8BAA8B;AAGhF,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;;;AEjJA,OAAOC,eAAc;AACrB,OAAO,WAAW;;;ACDlB,SAAS,aAAa;AACtB,SAAS,aAAiC;AAkB1C,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;AAGrD,WAAO,EAAE,QAAQ,SAAS;AAAA,EAC5B,SAAS,OAAO;AAEd,QAAI,iBAAiB,OAAO,QAAQ,GAAG;AAErC,UAAI,OAAO,GAAG,iBAAiB,OAAO,GAAG,qBAAqB,CAAC,kBAAkB;AAC/E,cAAM,WAAW,OAAO,GAAG;AAC3B,eAAO,QAAQ,yBAAyB,uBAAuB,QAAQ,CAAC,kBAAkB,uBAAuB,QAAQ,CAAC,KAAK;AAE/H,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,QAAI,IAAI,SAAS,YAAY,KAAK,IAAI,SAAS,gBAAgB,KAAK,IAAI,SAAS,mBAAmB,GAAG;AACrG,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAKA,eAAe,qBAAqB,SAA6C;AAC/E,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,qBAAqB,SAA6C;AAE/E,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,oBAAoB,SAA6C;AAE9E,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;;;AC7UO,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,iBAAgC,MACxB;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,iBAAiB;AAAA,EAAuB,cAAc;AAAA;AAAA,IAAS,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjE,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,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,OAAO,QAAQ,uDAAuD,EAAE,EAAE,KAAK;AAG1F,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,MAAK,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,KAC3C,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,GAAI;AAClD,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;;;AFlLA,eAAsB,cACpB,aACA,SACe;AACf,SAAO,KAAK,gCAAgC;AAC5C,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,MAAM,GAAG,YAAY,kCAAkC,QAAQ,aAAa;AACnF,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,oBAAoB,sBAAsB;AAGhD,MAAI;AACJ,MAAI,kBAAiC;AAErC,SAAO,MAAM;AAEX,UAAM,SAAS,kBAAkB,aAAa,mBAAmB,eAAe;AAEhF,QAAI;AAEF,cAAQ,IAAI,MAAM,IAAI,uCAA6B,YAAY,wKAAiC,CAAC;AACjG,aAAO,QAAQ;AACf,YAAM,SAAS,MAAM,SAAS,EAAE,QAAQ,cAAc,KAAK,GAAG,QAAQ,QAAQ,QAAQ;AACtF,iBAAW,OAAO;AAClB,aAAO,QAAQ;AACf,cAAQ,IAAI,MAAM,IAAI,sXAAgE,CAAC;AACvF,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,QAAQ,0DAA0D;AAAA,IAC3E;AAEA,UAAM,YAAwB,QAAQ;AAAA,MACpC,MAAM;AAAA,MACN,UAAU;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAGA,UAAM,YAAY,iBAAiB,QAAQ,IAAI;AAAA;AAAA;AAAA,gBAA0B,YAAY;AAGrF,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;;;AGrPA,OAAOC,YAAW;AAclB,eAAsB,YAAY,SAAqC;AAErE,QAAM,WAAW,MAAM,YAAY;AACnC,MAAI,CAAC,UAAU;AACb,WAAO,MAAM,2DAA2D;AACxE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,WAAW;AAC1B,QAAM,iBAAiB,kBAAkB,MAAM;AAG/C,QAAM,SAAmB,CAAC;AAE1B,MAAI,QAAQ,OAAO;AACjB,WAAO,KAAK,QAAQ,KAAK;AAAA,EAC3B;AAEA,MAAI,QAAQ,UAAU,QAAQ,WAAW,OAAO;AAC9C,YAAQ,QAAQ,QAAQ;AAAA,MACtB,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;AAAA,EACF,WAAW,CAAC,QAAQ,QAAQ;AAE1B,WAAO,KAAK,eAAe,KAAK;AAAA,EAClC;AAEA,MAAI;AACJ,MAAI;AACF,aAAS,MAAM,WAAW;AAAA,MACxB,QAAQ,OAAO,SAAS,IAAI,SAAS;AAAA,MACrC,OAAO;AAAA,MACP,OAAO,QAAQ,SAAS;AAAA,IAC1B,CAAC;AAAA,EACH,SAAS,OAAO;AACd,WAAO,MAAM,2BAA2B,KAAK,EAAE;AAC/C;AAAA,EACF;AAEA,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO,KAAK,wCAAwC;AACpD;AAAA,EACF;AAGA,iBAAe,MAAM;AAErB,SAAO,KAAK,SAAS,OAAO,MAAM,YAAY;AAC9C,SAAO,QAAQ;AAEf,aAAW,SAAS,QAAQ;AAC1B,UAAM,OAAO,sBAAsB,MAAM,MAAM;AAC/C,UAAM,WAAW,0BAA0B,MAAM,MAAM;AACvD,UAAM,SAAS,eAAe,MAAM,QAAQ,cAAc;AAE1D,UAAM,gBAAgB,iBAAiB,QAAQ;AAC/C,UAAM,cAAc,eAAe,MAAM;AAEzC,YAAQ;AAAA,MACN,KAAK,OAAO,MAAM,IAAI,MAAM,OAAO,SAAS,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,IACvD,cAAc,IAAI,QAAQ,IAAI,OAAO,EAAE,CAAC,CAAC,IACzC,YAAY,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC,IACrC,OAAO,MAAM,IAAI,IAAI,IAAI,OAAO,EAAE,CAAC,CAAC,MACvC,MAAM,MAAM,MAAM,GAAG,EAAE,KACtB,MAAM,MAAM,SAAS,KAAK,QAAQ;AAAA,IACvC;AAAA,EACF;AAEA,SAAO,QAAQ;AACf,SAAO,IAAI,OAAO,OAAO,QAAQ,yBAAyB,CAAC,wBAAwB;AACnF,SAAO,IAAI,OAAO,OAAO,QAAQ,iBAAiB,CAAC,kCAAkC;AACvF;AAEA,SAAS,eACP,QACA,gBACQ;AACR,MAAI,OAAO,SAAS,eAAe,KAAK,EAAG,QAAO;AAClD,MAAI,OAAO,SAAS,eAAe,UAAU,EAAG,QAAO;AACvD,MAAI,OAAO,SAAS,eAAe,SAAS,EAAG,QAAO;AACtD,MAAI,OAAO,SAAS,eAAe,OAAO,EAAG,QAAO;AACpD,SAAO;AACT;AAEA,SAAS,iBAAiB,UAA4C;AACpE,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAOC,OAAM;AAAA,IACf,KAAK;AACH,aAAOA,OAAM;AAAA,IACf,KAAK;AACH,aAAOA,OAAM;AAAA,IACf,KAAK;AACH,aAAOA,OAAM;AAAA,IACf;AACE,aAAOA,OAAM;AAAA,EACjB;AACF;AAEA,SAAS,eAAe,QAA0C;AAChE,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAOA,OAAM;AAAA,IACf,KAAK;AACH,aAAOA,OAAM;AAAA,IACf,KAAK;AACH,aAAOA,OAAM;AAAA,IACf,KAAK;AACH,aAAOA,OAAM;AAAA,IACf;AACE,aAAOA,OAAM;AAAA,EACjB;AACF;;;ACzIA,OAAOC,eAAc;;;ACArB,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;AAAA,MACpC;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,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;AAAA,MACpC;AAAA,MACA,GAAG,IAAI;AAAA,MACP;AAAA,IACF,CAAC;AACD,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;;;ACzKA,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,WAAW;AACjB,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;;;AF3EA,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,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,CAAC,MAAM;AACT,WAAO,MAAM,GAAG,YAAY,kCAAkC,QAAQ,aAAa;AACnF,YAAQ,KAAK,CAAC;AAAA,EAChB;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,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,iBAAiB,kBAAkB,MAAM;AAG/C,MAAI;AAEJ,MAAI,QAAQ,MAAM;AAEhB,UAAM,YAAY,MAAM,gBAAgB,eAAe,KAAK;AAC5D,QAAI,CAAC,WAAW;AACd,aAAO,MAAM,2BAA2B;AACxC,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,kBAAc,UAAU;AACxB,WAAO,KAAK,kBAAkB,OAAO,MAAM,IAAI,WAAW,EAAE,CAAC,MAAM,UAAU,KAAK,EAAE;AAAA,EACtF,WAAW,gBAAgB;AACzB,QAAI,CAAC,mBAAmB,cAAc,GAAG;AACvC,aAAO,MAAM,uBAAuB;AACpC,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,kBAAc,SAAS,gBAAgB,EAAE;AAAA,EAC3C,OAAO;AACL,WAAO,MAAM,8CAA8C;AAC3D,YAAQ,KAAK,CAAC;AAAA,EAChB;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,QAAQ,UAAU,WAAW,uBAAuB,eAAe,KAAK,UAAU;AACzF,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,IAAI,iBAAiB,IAAI,MAAM,MAAM,KAAK,MAAM,KAAK;AAAA,UACpD,MAAM,OAAO,KAAK,IAAI,CAAC,EAAE;AACjC,SAAO,QAAQ;AAGf,QAAM,OAAO,sBAAsB,MAAM,MAAM;AAC/C,QAAM,aAAa,MAAM,mBAAmB,QAAQ,aAAa,MAAM,OAAO,IAAI;AAGlF,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,QAAQ,oCAAoC,OAAO,OAAO,aAAa,CAAC,IAAI;AACnF,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,QAAQ,yBAAyB,OAAO,MAAM,eAAe,KAAK,CAAC,WAAM,OAAO,MAAM,eAAe,UAAU,CAAC,EAAE;AAAA,EAC3H,SAAS,OAAO;AACd,WAAO,QAAQ,4BAA4B,KAAK,EAAE;AAAA,EACpD;AAGA,QAAM,oBAAoB,sBAAsB;AAChD,QAAM,kBAAkB,aAAa,MAAM;AAC3C,QAAM,SAAS,0BAA0B,OAAO,mBAAmB,iBAAiB,MAAM;AAE1F,SAAO,QAAQ;AACf,SAAO,KAAK,YAAY,OAAO,SAAS,YAAY,CAAC,4BAA4B;AACjF,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,oBAAoB,QAAQ,QAAQ,QAAQ,QAAQ;AACvG,mBAAe;AACf,iBAAa,OAAO,YAAY;AAAA,EAClC,SAAS,OAAO;AACd,QAAI,SAAS,OAAO,UAAU,YAAY,cAAc,OAAO;AAC7D,mBAAa,MAAM;AAAA,IACrB;AACA,WAAO,MAAM,GAAG,uBAAuB,YAAY,CAAC,oBAAoB,KAAK,EAAE;AAAA,EAEjF,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,QAAQ,mBAAmB,OAAO,MAAM,eAAe,UAAU,CAAC,WAAM,OAAO,MAAM,eAAe,SAAS,CAAC,EAAE;AAAA,IACzH,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,QAAQ,GAAG,gBAAgB,6DAA6D;AAG/F,UAAI;AACF,cAAM,kBAAkB,aAAa;AAAA,UACnC,KAAK,CAAC,eAAe,OAAO;AAAA,UAC5B,QAAQ,CAAC,eAAe,UAAU;AAAA,QACpC,CAAC;AACD,eAAO,KAAK,mBAAmB,OAAO,MAAM,eAAe,UAAU,CAAC,WAAM,OAAO,MAAM,eAAe,OAAO,CAAC,EAAE;AAAA,MACpH,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,QAAQ,GAAG,gBAAgB,mEAAmE;AAAA,IAEvG;AAEA;AAAA,EACF;AAEA,SAAO,QAAQ;AACf,SAAO,IAAI,cAAc,sBAAsB,OAAO,QAAQ,iBAAiB,CAAC;AAAA,gBAClE,OAAO,QAAQ,UAAU,CAAC;AAAA,kBACxB,OAAO,QAAQ,wBAAwB,UAAU,CAAC;AAAA,gBACpD,OAAO,QAAQ,SAAS,CAAC,EAAE;AAC3C;AAEA,eAAe,gBAAgB,YAAiD;AAE9E,MAAI,SAAS,MAAM,WAAW;AAAA,IAC5B,QAAQ,CAAC,YAAY,mBAAmB;AAAA,IACxC,OAAO;AAAA,IACP,OAAO;AAAA,EACT,CAAC;AACD,MAAI,OAAO,SAAS,EAAG,QAAO,OAAO,CAAC;AAGtC,WAAS,MAAM,WAAW;AAAA,IACxB,QAAQ,CAAC,YAAY,eAAe;AAAA,IACpC,OAAO;AAAA,IACP,OAAO;AAAA,EACT,CAAC;AACD,MAAI,OAAO,SAAS,EAAG,QAAO,OAAO,CAAC;AAGtC,WAAS,MAAM,WAAW;AAAA,IACxB,QAAQ,CAAC,UAAU;AAAA,IACnB,OAAO;AAAA,IACP,OAAO;AAAA,EACT,CAAC;AAED,MAAI,OAAO,WAAW,EAAG,QAAO;AAEhC,iBAAe,MAAM;AACrB,SAAO,OAAO,CAAC;AACjB;;;AGpVA,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,gBAAgB,aAAqB,QAA2B;AACpF,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;;;ADnCA,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,MAAM,GAAG,YAAY,kCAAkC,QAAQ,aAAa;AACnF,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,QAAQ,wCAAwC,OAAO,IAAI,WAAW,GAAG,CAAC,EAAE;AACnF;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,KAAK,iBAAiB,OAAO,MAAM,IAAI,WAAW,EAAE,CAAC,MAAM,MAAM,KAAK,EAAE;AAAA,IACjF,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,KAAK,2DAA2D;AACvE,mCAA2B;AAAA;AAAA;AAAA;AAAA;AAAA,qCAKE,OAAO,MAAM,YAAY;AAAA;AAAA;AAAA,MAGxD;AAAA,IACF;AAAA,EACF;AAGA,QAAM,SAAS,cAAc,OAAO,SAAS,WAAW,IAAI;AAE5D,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,kCAAkC,OAAO,SAAS,YAAY,CAAC,KAAK;AAChF,WAAO,QAAQ;AACf,UAAM,SAAS,MAAM,SAAS,EAAE,QAAQ,cAAc,KAAK,GAAG,QAAQ,QAAQ,QAAQ;AACtF,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,QAAQ,mBAAmB,OAAO,MAAM,eAAe,UAAU,CAAC,WAAM,OAAO,MAAM,eAAe,SAAS,CAAC,EAAE;AAAA,IACzH,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;;;AE7OA,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,wBAAwB,MAAwB,SAG9D;AACA,QAAM,QAAQ,2BAA2B,MAAM,OAAO;AACtD,SAAO;AAAA,IACL;AAAA,IACA,SAAS,MAAM,SAAS,IAAI,4BAA4B,KAAK,IAAI;AAAA,EACnE;AACF;AAEA,SAAS,iBAAiB,eAAmC,gBAA6C;AACxG,MAAI,CAAC,kBAAkB,CAAC,eAAe;AACrC,WAAO;AAAA,EACT;AACA,SAAO,IAAI,KAAK,aAAa,IAAI,IAAI,KAAK,cAAc;AAC1D;AAEO,SAAS,2BAA2B,MAAwB,SAAuD;AACxH,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,eAAe,OAAO,eAAe,SAAS,OAAO,eAAe,UAAa,OAAO,eAAe;AAE7G,UAAM,qBAAqB,OAAO,YAAY,CAAC,GAAG;AAAA,MAChD,CAAC,MAAM,iBAAiB,EAAE,WAAW,cAAc;AAAA,IACrD;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,4BAA4B,OAAqC;AAC/E,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,QAAiF;AAC3G,MAAI,OAAO,eAAe,SAAS,OAAO,eAAe,UAAa,OAAO,eAAe,MAAM;AAChG,WAAO;AAAA,EACT;AACA,UAAQ,OAAO,YAAY,CAAC,GAAG,KAAK,CAAC,YAAY,iBAAiB,QAAQ,IAAI,CAAC;AACjF;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,4BAA8E,UAAyB;AAC9G,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;;;ADxMA,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,MAAM,GAAG,YAAY,kCAAkC,QAAQ,aAAa;AACnF,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,MAAM,eAAe,GAAG;AAC1B,WAAO,MAAM,4EAA4E;AACzF,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,MAAM,gFAAgF;AAC7F,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,sBAAsB,MAAM,uBAAuB;AAEzD,QAAM,aAAa,MAAM,YAAY,+BAA+B,YAAY;AAC9E,WAAO,gBAAgB,GAAG,MAAM;AAAA,EAClC,CAAC;AAED,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,EAAE,gBAAgB,oBAAoB,CAAC;AACtG,MAAI,MAAM,WAAW,KAAK,CAAC,SAAS;AAClC,WAAO,MAAM,iEAAiE;AAC9E,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,0BAA0B,OAAO,mBAAmB,iBAAiB,QAAQ,OAAO;AAEnG,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,oBAAoB,QAAQ,QAAQ,QAAQ,QAAQ;AAC7E,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,QAAQ,GAAG,YAAY,6DAA6D;AAC3F;AAAA,EACF;AAEA,SAAO,QAAQ,GAAG,YAAY,iDAAiD;AACjF;AAEA,SAAS,oBAAoB,MAAgC;AAC3D,QAAM,eAAe,KAAK,QAAQ,OAAO,CAAC,WAAW,OAAO,MAAM,KAAK,CAAC,EAAE;AAC1E,QAAM,eAAe,KAAK,cAAc,OAAO,CAAC,OAAO,WAAW;AAChE,UAAM,eAAe,OAAO,YAAY,CAAC,GAAG,OAAO,CAAC,YAAY,QAAQ,MAAM,KAAK,CAAC,EAAE;AACtF,WAAO,QAAQ;AAAA,EACjB,GAAG,CAAC;AACJ,QAAM,cAAc,KAAK,YAAY,CAAC,GAAG,OAAO,CAAC,YAAY,QAAQ,MAAM,KAAK,CAAC,EAAE;AACnF,SAAO,eAAe,eAAe;AACvC;AAEA,eAAe,qBAAqB,UAAkB,OAA4C;AAChG,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,IAAI,cAAc,YAAY,iBAAiB,eAAe,IAAI,MAAM,EAAE,GAAG;AAAA,EACtF;AACF;;;AErMA,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,kBAAkB,gBAAgB,MAAM,eAAe,cAAc,IAAI;AAC/E,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,QAAQ,gBAAgB,MAAM,eAAe,cAAc,IAAI,IAAI;AAAA,IACpF,aAAa,OAAO,aAAa;AAAA,EACnC;AACF;AAKO,SAAS,0BACd,gBACA,eACQ;AACR,SAAO,qBAAqB,cAAc,WAAM,aAAa;AAAA;AAC/D;;;AEhJA,SAAS,cAAc,OAAqC,SAA0B;AACpF,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,QAAQ,KAAK,MAAM,QAAQ,MAAM,GAAG,EAAE,YAAY,IAAI;AAC9E,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,KAAK,eAAe,YAAY,WAAW,OAAO,GAAG,gBAAgB,YAAY,UAAU,GAAG;AAAA,EACvG;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,EAAE,gBAAgB,oBAAoB,CAAC;AAC7F,kCAAwB,MAAM,SAAS;AAEvC,cAAI,SAAS,gBAAgB;AAC3B,mBAAO,KAAK,aAAa,qBAAqB,SAAS,cAAc,CAAC,EAAE;AAAA,UAC1E;AAEA,cAAI,MAAM,SAAS,GAAG;AACpB,mBAAO,QAAQ,KAAK,MAAM,MAAM,sBAAsB,MAAM,SAAS,IAAI,MAAM,EAAE,gBAAgB,OAAO,QAAQ,UAAU,CAAC,GAAG;AAC9H,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,IAAI,SAAS,OAAO,QAAQ,+BAA+B,CAAC,UAAU;AAAA,MAC/E,WAAW,SAAS,UAAU,UAAU;AACtC,eAAO,QAAQ,sCAAsC;AACrD,eAAO,IAAI,uEAAuE;AAAA,MACpF;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;;;AhB9QA,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,QAAQ,0BAA0B,OAAO,gBAAgB,OAAO,aAAa,CAAC;AAAA,IACvF;AAAA,EACF,CAAC,EACA,MAAM,MAAM;AAAA,EAEb,CAAC;AACL;AAEA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,MAAM,EACX,YAAY,+HAA+H,EAC3I,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,OAAO,6BAA6B,+CAA+C,EACnF,OAAO,uBAAuB,oCAAoC,EAClE,OAAO,OAAO,aAAa,YAAY;AACtC,QAAM,cAAc,aAAa,EAAE,KAAK,QAAQ,KAAK,UAAU,QAAQ,UAAU,OAAO,QAAQ,MAAM,CAAC;AACzG,CAAC;AAEH,QACG,QAAQ,MAAM,EACd,YAAY,oCAAoC,EAChD,OAAO,uBAAuB,iBAAiB,EAC/C,OAAO,yBAAyB,yEAAyE,EACzG,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,OAAO,cAAc,6CAA6C,EAClE,OAAO,6BAA6B,+CAA+C,EACnF,OAAO,OAAO,aAAa,YAAY;AACtC,QAAM,WAAW,aAAa,EAAE,MAAM,QAAQ,MAAM,UAAU,QAAQ,SAAS,CAAC;AAClF,CAAC;AAEH,QACG,QAAQ,IAAI,EACZ,YAAY,oCAAoC,EAChD,OAAO,eAAe,oBAAoB,EAC1C,OAAO,6BAA6B,+CAA+C,EACnF,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,OAAO,6BAA6B,+CAA+C,EACnF,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,QAAQ,MAAM;","names":["writeFileSync","existsSync","join","writeFileSync","join","existsSync","setupLabelsCommand","inquirer","inquirer","chalk","chalk","inquirer","execa","execa","inquirer","inquirer","execa","inquirer","inquirer","inquirer","readFileSync","writeFileSync","existsSync","mkdirSync","join","join","existsSync","readFileSync","mkdirSync","writeFileSync","version"]}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/logger.ts","../src/utils/spinner.ts","../src/lib/config.ts","../src/types/index.ts","../src/lib/labels.ts","../src/lib/github.ts","../src/utils/validators.ts","../src/commands/setup-labels.ts"],"sourcesContent":["import chalk from \"chalk\";\n\nexport const logger = {\n info: (message: string) => console.log(chalk.blue(\"ℹ\"), message),\n success: (message: string) => console.log(chalk.green(\"✓\"), message),\n warning: (message: string) => console.log(chalk.yellow(\"⚠\"), message),\n error: (message: string) => console.log(chalk.red(\"✗\"), message),\n debug: (message: string) => {\n if (process.env.DEBUG) {\n console.log(chalk.gray(\"⋯\"), message);\n }\n },\n dim: (message: string) => console.log(chalk.dim(message)),\n bold: (message: string) => console.log(chalk.bold(message)),\n highlight: (message: string) => console.log(chalk.cyan(message)),\n\n box: (title: string, content: string) => {\n const lines = content.split(\"\\n\");\n // Calculate visible length (strips ANSI codes) for proper alignment\n // eslint-disable-next-line no-control-regex\n const stripAnsi = (str: string) => str.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n const visibleLength = (str: string) => stripAnsi(str).length;\n const maxLen =\n Math.max(title.length, ...lines.map((l) => visibleLength(l))) + 4;\n const border = \"─\".repeat(maxLen);\n\n // Pad string to target length accounting for ANSI codes\n const padVisible = (str: string, len: number) => {\n const visible = visibleLength(str);\n return str + \" \".repeat(Math.max(0, len - visible));\n };\n\n console.log(chalk.dim(`┌${border}┐`));\n console.log(\n `${chalk.dim(\"│\")} ${chalk.bold(title.padEnd(maxLen - 2))} ${chalk.dim(\"│\")}`\n );\n console.log(chalk.dim(`├${border}┤`));\n for (const line of lines) {\n console.log(\n `${chalk.dim(\"│\")} ${padVisible(line, maxLen - 2)} ${chalk.dim(\"│\")}`\n );\n }\n console.log(chalk.dim(`└${border}┘`));\n },\n\n list: (items: string[], bullet = \"•\") => {\n for (const item of items) {\n console.log(chalk.dim(bullet), item);\n }\n },\n\n newline: () => console.log(),\n};\n\nexport const colors = {\n issue: chalk.cyan,\n branch: chalk.magenta,\n label: chalk.yellow,\n file: chalk.green,\n command: chalk.blue,\n url: chalk.underline.blue,\n provider: chalk.cyan.bold,\n};\n","import ora, { Ora } from \"ora\";\n\nexport function createSpinner(text: string): Ora {\n return ora({\n text,\n spinner: \"dots\",\n });\n}\n\nexport async function withSpinner<T>(\n text: string,\n fn: () => Promise<T>\n): Promise<T> {\n const spinner = createSpinner(text);\n spinner.start();\n\n try {\n const result = await fn();\n spinner.succeed();\n return result;\n } catch (error) {\n spinner.fail();\n throw error;\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport type { GentConfig, AIProvider } from \"../types/index.js\";\n\nconst DEFAULT_CONFIG: GentConfig = {\n version: 1,\n github: {\n labels: {\n workflow: {\n ready: \"ai-ready\",\n in_progress: \"ai-in-progress\",\n completed: \"ai-completed\",\n blocked: \"ai-blocked\",\n },\n types: [\"feature\", \"fix\", \"refactor\", \"chore\", \"docs\", \"test\"],\n priorities: [\"critical\", \"high\", \"medium\", \"low\"],\n risks: [\"low\", \"medium\", \"high\"],\n areas: [\"ui\", \"api\", \"database\", \"workers\", \"shared\", \"testing\", \"infra\"],\n },\n },\n branch: {\n pattern: \"{author}/{type}-{issue}-{slug}\",\n author_source: \"git\",\n author_env_var: \"GENT_AUTHOR\",\n },\n progress: {\n file: \"progress.txt\",\n archive_threshold: 500,\n archive_dir: \".gent/archive\",\n },\n claude: {\n permission_mode: \"acceptEdits\",\n agent_file: \"AGENT.md\",\n },\n gemini: {\n sandbox_mode: \"on\",\n agent_file: \"AGENT.md\",\n },\n codex: {\n agent_file: \"AGENT.md\",\n },\n ai: {\n provider: \"claude\",\n auto_fallback: true,\n },\n validation: [\"npm run typecheck\", \"npm run lint\", \"npm run test\"],\n};\n\nexport function getConfigPath(cwd: string = process.cwd()): string {\n return join(cwd, \".gent.yml\");\n}\n\nexport function getAgentPath(cwd: string = process.cwd()): string | null {\n const config = loadConfig(cwd);\n // Use claude.agent_file for backward compatibility\n const agentPath = join(cwd, config.claude.agent_file);\n return existsSync(agentPath) ? agentPath : null;\n}\n\nexport function loadConfig(cwd: string = process.cwd()): GentConfig {\n const configPath = getConfigPath(cwd);\n\n if (!existsSync(configPath)) {\n return DEFAULT_CONFIG;\n }\n\n try {\n const content = readFileSync(configPath, \"utf-8\");\n const userConfig = parseYaml(content) as Partial<GentConfig>;\n\n return mergeConfig(DEFAULT_CONFIG, userConfig);\n } catch {\n return DEFAULT_CONFIG;\n }\n}\n\nexport function loadAgentInstructions(cwd: string = process.cwd()): string | null {\n const agentPath = getAgentPath(cwd);\n\n if (!agentPath) {\n return null;\n }\n\n try {\n return readFileSync(agentPath, \"utf-8\");\n } catch {\n return null;\n }\n}\n\nexport function configExists(cwd: string = process.cwd()): boolean {\n return existsSync(getConfigPath(cwd));\n}\n\nfunction mergeConfig(\n defaults: GentConfig,\n user: Partial<GentConfig>\n): GentConfig {\n // Support GENT_AI_PROVIDER environment variable override\n const envProvider = process.env.GENT_AI_PROVIDER as\n | \"claude\"\n | \"gemini\"\n | \"codex\"\n | undefined;\n\n return {\n version: user.version ?? defaults.version,\n github: {\n labels: {\n workflow: {\n ...defaults.github.labels.workflow,\n ...user.github?.labels?.workflow,\n },\n types: user.github?.labels?.types ?? defaults.github.labels.types,\n priorities:\n user.github?.labels?.priorities ?? defaults.github.labels.priorities,\n risks: user.github?.labels?.risks ?? defaults.github.labels.risks,\n areas: user.github?.labels?.areas ?? defaults.github.labels.areas,\n },\n },\n branch: {\n ...defaults.branch,\n ...user.branch,\n },\n progress: {\n ...defaults.progress,\n ...user.progress,\n },\n claude: {\n ...defaults.claude,\n ...user.claude,\n },\n gemini: {\n ...defaults.gemini,\n ...user.gemini,\n },\n codex: {\n ...defaults.codex,\n ...user.codex,\n },\n ai: {\n ...defaults.ai,\n ...user.ai,\n // Environment variable takes precedence\n ...(envProvider && { provider: envProvider }),\n },\n validation: user.validation ?? defaults.validation,\n };\n}\n\nexport function generateDefaultConfig(provider: AIProvider = \"claude\"): string {\n return `# Gent Configuration\n# See https://github.com/rotorsoft/gent for documentation\nversion: 1\n\n# GitHub settings\ngithub:\n labels:\n workflow:\n ready: \"ai-ready\"\n in_progress: \"ai-in-progress\"\n completed: \"ai-completed\"\n blocked: \"ai-blocked\"\n types:\n - feature\n - fix\n - refactor\n - chore\n - docs\n - test\n priorities:\n - critical\n - high\n - medium\n - low\n risks:\n - low\n - medium\n - high\n areas:\n - ui\n - api\n - database\n - workers\n - shared\n - testing\n - infra\n\n# Branch naming convention\nbranch:\n pattern: \"{author}/{type}-{issue}-{slug}\"\n author_source: \"git\" # git | env | prompt\n author_env_var: \"GENT_AUTHOR\"\n\n# Progress tracking\nprogress:\n file: \"progress.txt\"\n archive_threshold: 500\n archive_dir: \".gent/archive\"\n\n# Claude settings\nclaude:\n permission_mode: \"acceptEdits\"\n agent_file: \"AGENT.md\"\n\n# Gemini settings\ngemini:\n sandbox_mode: \"on\"\n agent_file: \"AGENT.md\"\n\n# Codex settings\ncodex:\n agent_file: \"AGENT.md\"\n\n# AI provider settings\nai:\n provider: \"${provider}\" # claude | gemini | codex\n # fallback_provider: \"gemini\" # optional fallback when rate limited\n auto_fallback: true # automatically switch to fallback on rate limit\n\n# Validation commands (run before commit)\nvalidation:\n - \"npm run typecheck\"\n - \"npm run lint\"\n - \"npm run test\"\n`;\n}\n","export type AIProvider = \"claude\" | \"gemini\" | \"codex\";\n\nexport interface GentConfig {\n version: number;\n github: GitHubConfig;\n branch: BranchConfig;\n progress: ProgressConfig;\n claude: ClaudeConfig;\n gemini: GeminiConfig;\n codex: CodexConfig;\n ai: AIConfig;\n validation: string[];\n}\n\nexport interface AIConfig {\n provider: AIProvider;\n fallback_provider?: AIProvider;\n auto_fallback: boolean;\n}\n\nexport interface GitHubConfig {\n labels: {\n workflow: WorkflowLabels;\n types: string[];\n priorities: string[];\n risks: string[];\n areas: string[];\n };\n}\n\nexport interface WorkflowLabels {\n ready: string;\n in_progress: string;\n completed: string;\n blocked: string;\n}\n\nexport interface BranchConfig {\n pattern: string;\n author_source: \"git\" | \"env\" | \"prompt\";\n author_env_var: string;\n}\n\nexport interface ProgressConfig {\n file: string;\n archive_threshold: number;\n archive_dir: string;\n}\n\nexport interface ClaudeConfig {\n permission_mode: string;\n agent_file: string;\n}\n\nexport interface GeminiConfig {\n sandbox_mode: string;\n agent_file: string;\n}\n\nexport interface CodexConfig {\n agent_file: string;\n}\n\nexport interface GitHubIssue {\n number: number;\n title: string;\n body: string;\n labels: string[];\n state: \"open\" | \"closed\";\n assignee?: string;\n url: string;\n}\n\nexport interface GitHubLabel {\n name: string;\n color: string;\n description?: string;\n}\n\nexport interface GitHubReviewComment {\n id?: number;\n author: string;\n body: string;\n path?: string;\n line?: number | null;\n createdAt?: string;\n}\n\nexport interface GitHubReview {\n author: string;\n body: string;\n state: string;\n submittedAt?: string;\n}\n\nexport interface GitHubReviewThread {\n isResolved?: boolean | null;\n isOutdated?: boolean;\n path?: string;\n line?: number | null;\n comments: GitHubReviewComment[];\n}\n\nexport interface GitHubPRComment {\n id?: string;\n author: string;\n body: string;\n createdAt?: string;\n}\n\nexport interface GitHubReviewData {\n reviews: GitHubReview[];\n reviewThreads: GitHubReviewThread[];\n comments: GitHubPRComment[];\n}\n\nexport interface ProgressEntry {\n date: string;\n type: string;\n description: string;\n issue?: number;\n decisions: string[];\n files: string[];\n tests: string[];\n concerns: string[];\n followUp: string[];\n commit?: string;\n}\n\nexport interface BranchInfo {\n name: string;\n author: string;\n type: string;\n issueNumber: number;\n slug: string;\n}\n\nexport const DEFAULT_LABELS: Record<string, GitHubLabel[]> = {\n workflow: [\n {\n name: \"ai-ready\",\n color: \"0E8A16\",\n description: \"Issue ready for AI implementation\",\n },\n {\n name: \"ai-in-progress\",\n color: \"FFA500\",\n description: \"AI currently working on this\",\n },\n {\n name: \"ai-completed\",\n color: \"1D76DB\",\n description: \"AI done, needs human review\",\n },\n {\n name: \"ai-blocked\",\n color: \"D93F0B\",\n description: \"AI couldn't complete, needs help\",\n },\n ],\n priority: [\n {\n name: \"priority:critical\",\n color: \"B60205\",\n description: \"Blocking production\",\n },\n {\n name: \"priority:high\",\n color: \"D93F0B\",\n description: \"Important features/bugs\",\n },\n {\n name: \"priority:medium\",\n color: \"FBCA04\",\n description: \"Nice-to-have improvements\",\n },\n { name: \"priority:low\", color: \"0E8A16\", description: \"Minor tweaks\" },\n ],\n risk: [\n {\n name: \"risk:low\",\n color: \"C2E0C6\",\n description: \"UI changes, tests, non-critical\",\n },\n {\n name: \"risk:medium\",\n color: \"FEF2C0\",\n description: \"API changes, new features\",\n },\n {\n name: \"risk:high\",\n color: \"F9D0C4\",\n description: \"Migrations, auth, security\",\n },\n ],\n type: [\n { name: \"type:feature\", color: \"1D76DB\", description: \"New feature\" },\n { name: \"type:fix\", color: \"D73A4A\", description: \"Bug fix\" },\n {\n name: \"type:refactor\",\n color: \"5319E7\",\n description: \"Code improvement\",\n },\n { name: \"type:chore\", color: \"FEF2C0\", description: \"Maintenance\" },\n { name: \"type:docs\", color: \"0075CA\", description: \"Documentation\" },\n { name: \"type:test\", color: \"D4C5F9\", description: \"Testing\" },\n ],\n area: [\n { name: \"area:ui\", color: \"C5DEF5\", description: \"User interface\" },\n { name: \"area:api\", color: \"D4C5F9\", description: \"API/Backend\" },\n { name: \"area:database\", color: \"FEF2C0\", description: \"Database/Models\" },\n {\n name: \"area:workers\",\n color: \"F9D0C4\",\n description: \"Background workers\",\n },\n { name: \"area:shared\", color: \"C2E0C6\", description: \"Shared libraries\" },\n { name: \"area:testing\", color: \"E99695\", description: \"Test infrastructure\" },\n { name: \"area:infra\", color: \"BFD4F2\", description: \"Infrastructure/DevOps\" },\n ],\n};\n","import type { GentConfig, GitHubLabel } from \"../types/index.js\";\nimport { DEFAULT_LABELS } from \"../types/index.js\";\n\nexport function getAllLabels(config: GentConfig): GitHubLabel[] {\n const labels: GitHubLabel[] = [];\n\n // Workflow labels\n labels.push(...DEFAULT_LABELS.workflow);\n\n // Priority labels\n for (const priority of config.github.labels.priorities) {\n const defaultLabel = DEFAULT_LABELS.priority.find(\n (l) => l.name === `priority:${priority}`\n );\n if (defaultLabel) {\n labels.push(defaultLabel);\n } else {\n labels.push({\n name: `priority:${priority}`,\n color: \"FBCA04\",\n description: `Priority: ${priority}`,\n });\n }\n }\n\n // Risk labels\n for (const risk of config.github.labels.risks) {\n const defaultLabel = DEFAULT_LABELS.risk.find(\n (l) => l.name === `risk:${risk}`\n );\n if (defaultLabel) {\n labels.push(defaultLabel);\n } else {\n labels.push({\n name: `risk:${risk}`,\n color: \"FEF2C0\",\n description: `Risk: ${risk}`,\n });\n }\n }\n\n // Type labels\n for (const type of config.github.labels.types) {\n const defaultLabel = DEFAULT_LABELS.type.find(\n (l) => l.name === `type:${type}`\n );\n if (defaultLabel) {\n labels.push(defaultLabel);\n } else {\n labels.push({\n name: `type:${type}`,\n color: \"1D76DB\",\n description: `Type: ${type}`,\n });\n }\n }\n\n // Area labels\n for (const area of config.github.labels.areas) {\n const defaultLabel = DEFAULT_LABELS.area.find(\n (l) => l.name === `area:${area}`\n );\n if (defaultLabel) {\n labels.push(defaultLabel);\n } else {\n labels.push({\n name: `area:${area}`,\n color: \"C5DEF5\",\n description: `Area: ${area}`,\n });\n }\n }\n\n return labels;\n}\n\nexport function getWorkflowLabels(config: GentConfig): {\n ready: string;\n inProgress: string;\n completed: string;\n blocked: string;\n} {\n return {\n ready: config.github.labels.workflow.ready,\n inProgress: config.github.labels.workflow.in_progress,\n completed: config.github.labels.workflow.completed,\n blocked: config.github.labels.workflow.blocked,\n };\n}\n\nexport function buildIssueLabels(meta: {\n type: string;\n priority: string;\n risk: string;\n area: string;\n}): string[] {\n return [\n \"ai-ready\",\n `type:${meta.type}`,\n `priority:${meta.priority}`,\n `risk:${meta.risk}`,\n `area:${meta.area}`,\n ];\n}\n\nexport function extractTypeFromLabels(labels: string[]): string {\n for (const label of labels) {\n if (label.startsWith(\"type:\")) {\n return label.replace(\"type:\", \"\");\n }\n }\n return \"feature\";\n}\n\nexport function extractPriorityFromLabels(labels: string[]): string {\n for (const label of labels) {\n if (label.startsWith(\"priority:\")) {\n return label.replace(\"priority:\", \"\");\n }\n }\n return \"medium\";\n}\n\nexport function hasWorkflowLabel(\n labels: string[],\n workflowLabel: string\n): boolean {\n return labels.includes(workflowLabel);\n}\n\nexport function sortByPriority(issues: { labels: string[] }[]): void {\n const priorityOrder = [\"critical\", \"high\", \"medium\", \"low\"];\n\n issues.sort((a, b) => {\n const aPriority = extractPriorityFromLabels(a.labels);\n const bPriority = extractPriorityFromLabels(b.labels);\n return priorityOrder.indexOf(aPriority) - priorityOrder.indexOf(bPriority);\n });\n}\n","import { execa } from \"execa\";\nimport type { GitHubIssue, GitHubLabel, GitHubReviewData } from \"../types/index.js\";\n\nexport async function getIssue(issueNumber: number): Promise<GitHubIssue> {\n const { stdout } = await execa(\"gh\", [\n \"issue\",\n \"view\",\n String(issueNumber),\n \"--json\",\n \"number,title,body,labels,state,assignees,url\",\n ]);\n\n const data = JSON.parse(stdout);\n return {\n number: data.number,\n title: data.title,\n body: data.body || \"\",\n labels: data.labels.map((l: { name: string }) => l.name),\n state: data.state.toLowerCase(),\n assignee: data.assignees?.[0]?.login,\n url: data.url,\n };\n}\n\nexport async function listIssues(options: {\n labels?: string[];\n state?: \"open\" | \"closed\" | \"all\";\n limit?: number;\n}): Promise<GitHubIssue[]> {\n const args = [\"issue\", \"list\", \"--json\", \"number,title,body,labels,state,url\"];\n\n if (options.labels?.length) {\n args.push(\"--label\", options.labels.join(\",\"));\n }\n\n if (options.state) {\n args.push(\"--state\", options.state);\n }\n\n args.push(\"--limit\", String(options.limit || 50));\n\n const { stdout } = await execa(\"gh\", args);\n const data = JSON.parse(stdout);\n\n return data.map(\n (d: {\n number: number;\n title: string;\n body: string;\n labels: { name: string }[];\n state: string;\n url: string;\n }) => ({\n number: d.number,\n title: d.title,\n body: d.body || \"\",\n labels: d.labels.map((l) => l.name),\n state: d.state.toLowerCase() as \"open\" | \"closed\",\n url: d.url,\n })\n );\n}\n\nexport async function createIssue(options: {\n title: string;\n body: string;\n labels?: string[];\n}): Promise<number> {\n const args = [\"issue\", \"create\", \"--title\", options.title, \"--body\", options.body];\n\n if (options.labels?.length) {\n args.push(\"--label\", options.labels.join(\",\"));\n }\n\n const { stdout } = await execa(\"gh\", args);\n\n // Extract issue number from URL\n const match = stdout.match(/\\/issues\\/(\\d+)/);\n if (!match) {\n throw new Error(\"Failed to extract issue number from gh output\");\n }\n\n return parseInt(match[1], 10);\n}\n\nexport async function updateIssueLabels(\n issueNumber: number,\n options: {\n add?: string[];\n remove?: string[];\n }\n): Promise<void> {\n const promises: Promise<unknown>[] = [];\n\n if (options.add?.length) {\n promises.push(\n execa(\"gh\", [\n \"issue\",\n \"edit\",\n String(issueNumber),\n \"--add-label\",\n options.add.join(\",\"),\n ])\n );\n }\n\n if (options.remove?.length) {\n promises.push(\n execa(\"gh\", [\n \"issue\",\n \"edit\",\n String(issueNumber),\n \"--remove-label\",\n options.remove.join(\",\"),\n ])\n );\n }\n\n await Promise.all(promises);\n}\n\nexport async function addIssueComment(\n issueNumber: number,\n body: string\n): Promise<void> {\n await execa(\"gh\", [\"issue\", \"comment\", String(issueNumber), \"--body\", body]);\n}\n\nexport async function assignIssue(\n issueNumber: number,\n assignee: string\n): Promise<void> {\n await execa(\"gh\", [\n \"issue\",\n \"edit\",\n String(issueNumber),\n \"--add-assignee\",\n assignee,\n ]);\n}\n\nexport async function createLabel(label: GitHubLabel): Promise<void> {\n try {\n await execa(\"gh\", [\n \"label\",\n \"create\",\n label.name,\n \"--color\",\n label.color,\n \"--description\",\n label.description || \"\",\n \"--force\",\n ]);\n } catch {\n // Label might already exist, ignore error\n }\n}\n\nexport async function createPullRequest(options: {\n title: string;\n body: string;\n base?: string;\n draft?: boolean;\n}): Promise<string> {\n const args = [\n \"pr\",\n \"create\",\n \"--title\",\n options.title,\n \"--body\",\n options.body,\n \"--assignee\",\n \"@me\",\n ];\n\n if (options.base) {\n args.push(\"--base\", options.base);\n }\n\n if (options.draft) {\n args.push(\"--draft\");\n }\n\n const { stdout } = await execa(\"gh\", args);\n return stdout.trim();\n}\n\nexport interface PrBasicInfo {\n number: number;\n url: string;\n}\n\nexport interface PrStatusInfo {\n number: number;\n url: string;\n state: \"open\" | \"closed\" | \"merged\";\n reviewDecision: string | null;\n isDraft: boolean;\n}\n\nexport async function getPrForBranch(): Promise<PrBasicInfo | null> {\n try {\n const { stdout } = await execa(\"gh\", [\n \"pr\",\n \"view\",\n \"--json\",\n \"number,url\",\n ]);\n const data = JSON.parse(stdout);\n return { number: data.number, url: data.url };\n } catch {\n return null;\n }\n}\n\nexport async function getPrStatus(): Promise<PrStatusInfo | null> {\n try {\n const { stdout } = await execa(\"gh\", [\n \"pr\",\n \"view\",\n \"--json\",\n \"number,url,state,reviewDecision,isDraft\",\n ]);\n const data = JSON.parse(stdout);\n // gh pr view returns state as OPEN, CLOSED, or MERGED (uppercase)\n const state = (data.state?.toLowerCase() ?? \"open\") as \"open\" | \"closed\" | \"merged\";\n return {\n number: data.number,\n url: data.url,\n state,\n reviewDecision: data.reviewDecision ?? null,\n isDraft: data.isDraft ?? false,\n };\n } catch {\n return null;\n }\n}\n\nexport async function getPrReviewData(prNumber?: number): Promise<GitHubReviewData> {\n // Fetch reviews and comments using gh pr view (both are supported JSON fields)\n const prArgs = [\"pr\", \"view\"];\n if (prNumber) {\n prArgs.push(String(prNumber));\n }\n prArgs.push(\"--json\", \"reviews,comments\");\n\n const { stdout: prStdout } = await execa(\"gh\", prArgs);\n const prData = JSON.parse(prStdout);\n\n // Fetch review threads using GraphQL API (not available via gh pr view --json)\n // First get repo owner and name since GraphQL doesn't support {owner}/{repo} placeholders\n let reviewThreads: Array<{\n isResolved?: boolean | null;\n isOutdated?: boolean;\n path?: string;\n line?: number | null;\n comments: Array<{\n author: string;\n body: string;\n path?: string;\n line?: number | null;\n createdAt?: string;\n }>;\n }> = [];\n\n try {\n const { stdout: repoStdout } = await execa(\"gh\", [\"repo\", \"view\", \"--json\", \"owner,name\"]);\n const repoData = JSON.parse(repoStdout);\n const owner = repoData.owner?.login ?? repoData.owner;\n const repo = repoData.name;\n\n const graphqlQuery = `query { repository(owner: \"${owner}\", name: \"${repo}\") { pullRequest(number: ${prNumber}) { reviewThreads(first: 100) { nodes { isResolved isOutdated path line comments(first: 100) { nodes { databaseId author { login } body path line createdAt } } } } } } }`;\n\n const { stdout: graphqlStdout } = await execa(\"gh\", [\"api\", \"graphql\", \"-f\", `query=${graphqlQuery}`]);\n const graphqlData = JSON.parse(graphqlStdout);\n const prNode = graphqlData.data?.repository?.pullRequest;\n const threadNodes = prNode?.reviewThreads?.nodes ?? [];\n\n reviewThreads = threadNodes.map((thread: {\n isResolved?: boolean | null;\n isOutdated?: boolean;\n path?: string;\n line?: number | null;\n comments?: { nodes?: Array<{\n databaseId?: number;\n author?: { login?: string };\n body?: string;\n path?: string;\n line?: number | null;\n createdAt?: string;\n }> };\n }) => ({\n isResolved: thread.isResolved ?? null,\n isOutdated: thread.isOutdated ?? false,\n path: thread.path,\n line: thread.line ?? null,\n comments: (thread.comments?.nodes ?? []).map((comment) => ({\n id: comment.databaseId,\n author: comment.author?.login ?? \"unknown\",\n body: comment.body ?? \"\",\n path: comment.path ?? thread.path,\n line: comment.line ?? thread.line ?? null,\n createdAt: comment.createdAt,\n })),\n }));\n } catch {\n // If GraphQL fails (e.g., no permissions), continue with empty threads\n reviewThreads = [];\n }\n\n return {\n reviews: (prData.reviews ?? []).map((review: {\n author?: { login?: string };\n body?: string;\n state?: string;\n submittedAt?: string;\n }) => ({\n author: review.author?.login ?? \"unknown\",\n body: review.body ?? \"\",\n state: review.state ?? \"UNKNOWN\",\n submittedAt: review.submittedAt,\n })),\n reviewThreads,\n comments: (prData.comments ?? []).map((comment: {\n id?: string;\n author?: { login?: string };\n body?: string;\n createdAt?: string;\n }) => ({\n id: comment.id,\n author: comment.author?.login ?? \"unknown\",\n body: comment.body ?? \"\",\n createdAt: comment.createdAt,\n })),\n };\n}\n\nexport async function getCurrentUser(): Promise<string> {\n const { stdout } = await execa(\"gh\", [\"api\", \"user\", \"--jq\", \".login\"]);\n return stdout.trim();\n}\n\nexport async function replyToReviewComment(\n prNumber: number,\n commentId: number,\n body: string\n): Promise<void> {\n await execa(\"gh\", [\n \"api\",\n `repos/{owner}/{repo}/pulls/${prNumber}/comments/${commentId}/replies`,\n \"-f\",\n `body=${body}`,\n ]);\n}\n\nexport async function addPrComment(prNumber: number, body: string): Promise<void> {\n await execa(\"gh\", [\"pr\", \"comment\", String(prNumber), \"--body\", body]);\n}\n","import { execa } from \"execa\";\nimport type { GentConfig, AIProvider } from \"../types/index.js\";\n\nexport async function checkGhCli(): Promise<boolean> {\n try {\n await execa(\"gh\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function checkGhAuth(): Promise<boolean> {\n try {\n await execa(\"gh\", [\"auth\", \"status\"]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function checkClaudeCli(): Promise<boolean> {\n try {\n await execa(\"claude\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function checkGeminiCli(): Promise<boolean> {\n try {\n await execa(\"gemini\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function checkCodexCLI(): Promise<boolean> {\n try {\n await execa(\"codex\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function checkAIProvider(provider: AIProvider): Promise<boolean> {\n switch (provider) {\n case \"claude\":\n return checkClaudeCli();\n case \"gemini\":\n return checkGeminiCli();\n case \"codex\":\n return checkCodexCLI();\n }\n}\n\nexport async function checkGitRepo(): Promise<boolean> {\n try {\n await execa(\"git\", [\"rev-parse\", \"--git-dir\"]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function validatePrerequisites(config?: GentConfig): Promise<{\n valid: boolean;\n missing: string[];\n}> {\n const checks = [\n { name: \"gh CLI\", check: checkGhCli },\n { name: \"gh auth\", check: checkGhAuth },\n { name: \"git repository\", check: checkGitRepo },\n ];\n\n const getProviderName = (provider: AIProvider) => {\n switch (provider) {\n case \"claude\":\n return \"claude CLI\";\n case \"gemini\":\n return \"gemini CLI\";\n case \"codex\":\n return \"codex CLI\";\n }\n };\n\n // Add AI provider check based on config\n if (config) {\n const provider = config.ai.provider;\n checks.push({\n name: getProviderName(provider),\n check: () => checkAIProvider(provider),\n });\n\n // Also check fallback if configured\n if (config.ai.fallback_provider) {\n const fallback = config.ai.fallback_provider;\n checks.push({\n name: `${getProviderName(fallback)} (fallback)`,\n check: () => checkAIProvider(fallback),\n });\n }\n } else {\n // Default to checking claude for backward compatibility\n checks.push({ name: \"claude CLI\", check: checkClaudeCli });\n }\n\n const missing: string[] = [];\n\n for (const { name, check } of checks) {\n const passed = await check();\n if (!passed) {\n missing.push(name);\n }\n }\n\n return {\n valid: missing.length === 0,\n missing,\n };\n}\n\nexport function isValidIssueNumber(value: string): boolean {\n const num = parseInt(value, 10);\n return !isNaN(num) && num > 0;\n}\n\nexport function sanitizeSlug(title: string, maxLength = 40): string {\n return title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, maxLength);\n}\n","import { logger, colors } from \"../utils/logger.js\";\nimport { withSpinner } from \"../utils/spinner.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { getAllLabels } from \"../lib/labels.js\";\nimport { createLabel } from \"../lib/github.js\";\nimport { checkGhAuth } from \"../utils/validators.js\";\n\nexport async function setupLabelsCommand(): Promise<void> {\n logger.bold(\"Setting up GitHub labels...\");\n logger.newline();\n\n // Check gh auth\n const isAuthed = await checkGhAuth();\n if (!isAuthed) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n process.exit(1);\n }\n\n const config = loadConfig();\n const labels = getAllLabels(config);\n\n logger.info(`Creating ${labels.length} labels...`);\n logger.newline();\n\n let created = 0;\n let failed = 0;\n\n for (const label of labels) {\n try {\n await withSpinner(`Creating ${colors.label(label.name)}`, async () => {\n await createLabel(label);\n });\n created++;\n } catch (error) {\n logger.error(`Failed to create ${label.name}: ${error}`);\n failed++;\n }\n }\n\n logger.newline();\n logger.success(`Created ${created} labels`);\n if (failed > 0) {\n logger.warning(`Failed to create ${failed} labels`);\n }\n\n logger.newline();\n logger.info(\"Labels are ready. You can now create AI-ready issues.\");\n}\n"],"mappings":"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","names":["execa","execa"]}
|
|
File without changes
|