@rotorsoft/gent 1.7.1 → 1.8.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/README.md +16 -7
- package/dist/{chunk-2LGYNV6S.js → chunk-XQJWUAG6.js} +30 -4
- package/dist/chunk-XQJWUAG6.js.map +1 -0
- package/dist/index.js +106 -25
- package/dist/index.js.map +1 -1
- package/dist/{setup-labels-3IMSEEKN.js → setup-labels-WXNPB6OD.js} +2 -2
- package/package.json +2 -2
- package/dist/chunk-2LGYNV6S.js.map +0 -1
- /package/dist/{setup-labels-3IMSEEKN.js.map → setup-labels-WXNPB6OD.js.map} +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @rotorsoft/gent
|
|
2
2
|
|
|
3
|
-
AI-powered GitHub workflow CLI - leverage AI (Claude or
|
|
3
|
+
AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
@@ -21,15 +21,17 @@ pnpm add -g @rotorsoft/gent
|
|
|
21
21
|
|
|
22
22
|
- **Node.js** 20 or higher
|
|
23
23
|
- **GitHub CLI** (`gh`) - [Install](https://cli.github.com/)
|
|
24
|
-
- **AI CLI** (one or
|
|
24
|
+
- **AI CLI** (one or more):
|
|
25
25
|
- **Claude CLI** - [Install](https://claude.ai/code)
|
|
26
26
|
- **Gemini CLI** - [Install](https://github.com/google-gemini/gemini-cli)
|
|
27
|
+
- **Codex CLI** - [Install](https://github.com/openai/codex)
|
|
27
28
|
|
|
28
29
|
Verify prerequisites:
|
|
29
30
|
```bash
|
|
30
31
|
gh auth status # Should show authenticated
|
|
31
32
|
claude --version # Should show version (if using Claude)
|
|
32
33
|
gemini --version # Should show version (if using Gemini)
|
|
34
|
+
codex --version # Should show version (if using Codex)
|
|
33
35
|
```
|
|
34
36
|
|
|
35
37
|
## Quick Start
|
|
@@ -133,7 +135,7 @@ gent create "Fix login bug" --provider gemini # Use specific AI provider
|
|
|
133
135
|
|
|
134
136
|
Options:
|
|
135
137
|
- `-y, --yes` - Skip confirmation and create issue immediately
|
|
136
|
-
- `-p, --provider <provider>` - AI provider to use (`claude` or `
|
|
138
|
+
- `-p, --provider <provider>` - AI provider to use (`claude`, `gemini`, or `codex`)
|
|
137
139
|
|
|
138
140
|
### `gent list`
|
|
139
141
|
|
|
@@ -163,7 +165,7 @@ gent run 123 --provider gemini # Use specific AI provider
|
|
|
163
165
|
|
|
164
166
|
Options:
|
|
165
167
|
- `-a, --auto` - Auto-select highest priority ai-ready issue
|
|
166
|
-
- `-p, --provider <provider>` - AI provider to use (`claude` or `
|
|
168
|
+
- `-p, --provider <provider>` - AI provider to use (`claude`, `gemini`, or `codex`)
|
|
167
169
|
|
|
168
170
|
### `gent pr`
|
|
169
171
|
|
|
@@ -177,7 +179,7 @@ gent pr --provider gemini # Use specific AI provider
|
|
|
177
179
|
|
|
178
180
|
Options:
|
|
179
181
|
- `-d, --draft` - Create as draft PR
|
|
180
|
-
- `-p, --provider <provider>` - AI provider to use (`claude` or `
|
|
182
|
+
- `-p, --provider <provider>` - AI provider to use (`claude`, `gemini`, or `codex`)
|
|
181
183
|
|
|
182
184
|
### `gent status`
|
|
183
185
|
|
|
@@ -231,8 +233,15 @@ claude:
|
|
|
231
233
|
permission_mode: "acceptEdits"
|
|
232
234
|
agent_file: "AGENT.md"
|
|
233
235
|
|
|
236
|
+
gemini:
|
|
237
|
+
sandbox_mode: "on"
|
|
238
|
+
agent_file: "AGENT.md"
|
|
239
|
+
|
|
240
|
+
codex:
|
|
241
|
+
agent_file: "AGENT.md"
|
|
242
|
+
|
|
234
243
|
ai:
|
|
235
|
-
provider: "claude" # claude | gemini
|
|
244
|
+
provider: "claude" # claude | gemini | codex
|
|
236
245
|
fallback_provider: "gemini" # optional fallback when rate limited
|
|
237
246
|
auto_fallback: true # automatically switch to fallback on rate limit
|
|
238
247
|
|
|
@@ -371,7 +380,7 @@ The author is derived from:
|
|
|
371
380
|
| Variable | Description |
|
|
372
381
|
|----------|-------------|
|
|
373
382
|
| `GENT_AUTHOR` | Override author initials for branch naming |
|
|
374
|
-
| `GENT_AI_PROVIDER` | Override AI provider (`claude` or `
|
|
383
|
+
| `GENT_AI_PROVIDER` | Override AI provider (`claude`, `gemini`, or `codex`) |
|
|
375
384
|
| `DEBUG` | Enable debug output |
|
|
376
385
|
|
|
377
386
|
## Tips
|
|
@@ -113,6 +113,9 @@ var DEFAULT_CONFIG = {
|
|
|
113
113
|
sandbox_mode: "on",
|
|
114
114
|
agent_file: "AGENT.md"
|
|
115
115
|
},
|
|
116
|
+
codex: {
|
|
117
|
+
agent_file: "AGENT.md"
|
|
118
|
+
},
|
|
116
119
|
ai: {
|
|
117
120
|
provider: "claude",
|
|
118
121
|
auto_fallback: true
|
|
@@ -186,6 +189,10 @@ function mergeConfig(defaults, user) {
|
|
|
186
189
|
...defaults.gemini,
|
|
187
190
|
...user.gemini
|
|
188
191
|
},
|
|
192
|
+
codex: {
|
|
193
|
+
...defaults.codex,
|
|
194
|
+
...user.codex
|
|
195
|
+
},
|
|
189
196
|
ai: {
|
|
190
197
|
...defaults.ai,
|
|
191
198
|
...user.ai,
|
|
@@ -195,7 +202,7 @@ function mergeConfig(defaults, user) {
|
|
|
195
202
|
validation: user.validation ?? defaults.validation
|
|
196
203
|
};
|
|
197
204
|
}
|
|
198
|
-
function generateDefaultConfig() {
|
|
205
|
+
function generateDefaultConfig(provider = "claude") {
|
|
199
206
|
return `# Gent Configuration
|
|
200
207
|
# See https://github.com/rotorsoft/gent for documentation
|
|
201
208
|
version: 1
|
|
@@ -255,9 +262,13 @@ gemini:
|
|
|
255
262
|
sandbox_mode: "on"
|
|
256
263
|
agent_file: "AGENT.md"
|
|
257
264
|
|
|
265
|
+
# Codex settings
|
|
266
|
+
codex:
|
|
267
|
+
agent_file: "AGENT.md"
|
|
268
|
+
|
|
258
269
|
# AI provider settings
|
|
259
270
|
ai:
|
|
260
|
-
provider: "
|
|
271
|
+
provider: "${provider}" # claude | gemini | codex
|
|
261
272
|
# fallback_provider: "gemini" # optional fallback when rate limited
|
|
262
273
|
auto_fallback: true # automatically switch to fallback on rate limit
|
|
263
274
|
|
|
@@ -632,8 +643,23 @@ async function checkGeminiCli() {
|
|
|
632
643
|
return false;
|
|
633
644
|
}
|
|
634
645
|
}
|
|
646
|
+
async function checkCodexCLI() {
|
|
647
|
+
try {
|
|
648
|
+
await execa2("codex", ["--version"]);
|
|
649
|
+
return true;
|
|
650
|
+
} catch {
|
|
651
|
+
return false;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
635
654
|
async function checkAIProvider(provider) {
|
|
636
|
-
|
|
655
|
+
switch (provider) {
|
|
656
|
+
case "claude":
|
|
657
|
+
return checkClaudeCli();
|
|
658
|
+
case "gemini":
|
|
659
|
+
return checkGeminiCli();
|
|
660
|
+
case "codex":
|
|
661
|
+
return checkCodexCLI();
|
|
662
|
+
}
|
|
637
663
|
}
|
|
638
664
|
async function checkGitRepo() {
|
|
639
665
|
try {
|
|
@@ -718,4 +744,4 @@ export {
|
|
|
718
744
|
getCurrentUser,
|
|
719
745
|
setupLabelsCommand
|
|
720
746
|
};
|
|
721
|
-
//# sourceMappingURL=chunk-
|
|
747
|
+
//# sourceMappingURL=chunk-XQJWUAG6.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 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 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 } 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 async function getPrForBranch(): Promise<{\n number: number;\n url: string;\n} | 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 getCurrentUser(): Promise<string> {\n const { stdout } = await execa(\"gh\", [\"api\", \"user\", \"--jq\", \".login\"]);\n return stdout.trim();\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
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
sortByPriority,
|
|
31
31
|
updateIssueLabels,
|
|
32
32
|
withSpinner
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-XQJWUAG6.js";
|
|
34
34
|
|
|
35
35
|
// src/index.ts
|
|
36
36
|
import { Command } from "commander";
|
|
@@ -154,8 +154,17 @@ async function initCommand(options) {
|
|
|
154
154
|
return;
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
|
+
const { provider } = await inquirer.prompt([
|
|
158
|
+
{
|
|
159
|
+
type: "list",
|
|
160
|
+
name: "provider",
|
|
161
|
+
message: "Which AI provider would you like to use by default?",
|
|
162
|
+
choices: ["claude", "gemini", "codex"],
|
|
163
|
+
default: "claude"
|
|
164
|
+
}
|
|
165
|
+
]);
|
|
157
166
|
const configPath = getConfigPath(cwd);
|
|
158
|
-
writeFileSync2(configPath, generateDefaultConfig(), "utf-8");
|
|
167
|
+
writeFileSync2(configPath, generateDefaultConfig(provider), "utf-8");
|
|
159
168
|
logger.success(`Created ${colors.file(".gent.yml")}`);
|
|
160
169
|
const agentPath = join2(cwd, "AGENT.md");
|
|
161
170
|
if (!existsSync2(agentPath) || options.force) {
|
|
@@ -182,7 +191,7 @@ async function initCommand(options) {
|
|
|
182
191
|
}
|
|
183
192
|
]);
|
|
184
193
|
if (setupLabels) {
|
|
185
|
-
const { setupLabelsCommand: setupLabelsCommand2 } = await import("./setup-labels-
|
|
194
|
+
const { setupLabelsCommand: setupLabelsCommand2 } = await import("./setup-labels-WXNPB6OD.js");
|
|
186
195
|
await setupLabelsCommand2();
|
|
187
196
|
}
|
|
188
197
|
}
|
|
@@ -194,17 +203,27 @@ import chalk from "chalk";
|
|
|
194
203
|
// src/lib/ai-provider.ts
|
|
195
204
|
import { spawn } from "child_process";
|
|
196
205
|
import { execa } from "execa";
|
|
206
|
+
async function invokeInternal(provider, options) {
|
|
207
|
+
switch (provider) {
|
|
208
|
+
case "claude":
|
|
209
|
+
return invokeClaudeInternal(options);
|
|
210
|
+
case "gemini":
|
|
211
|
+
return invokeGeminiInternal(options);
|
|
212
|
+
case "codex":
|
|
213
|
+
return invokeCodexInternal(options);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
197
216
|
async function invokeAI(options, config, providerOverride) {
|
|
198
217
|
const provider = providerOverride ?? config.ai.provider;
|
|
199
218
|
try {
|
|
200
|
-
const output =
|
|
219
|
+
const output = await invokeInternal(provider, options);
|
|
201
220
|
return { output, provider };
|
|
202
221
|
} catch (error) {
|
|
203
222
|
if (isRateLimitError(error, provider)) {
|
|
204
223
|
if (config.ai.auto_fallback && config.ai.fallback_provider && !providerOverride) {
|
|
205
224
|
const fallback = config.ai.fallback_provider;
|
|
206
225
|
logger.warning(`Rate limit reached on ${getProviderDisplayName(provider)}, switching to ${getProviderDisplayName(fallback)}...`);
|
|
207
|
-
const output =
|
|
226
|
+
const output = await invokeInternal(fallback, options);
|
|
208
227
|
return { output, provider: fallback };
|
|
209
228
|
}
|
|
210
229
|
const err = error;
|
|
@@ -217,28 +236,52 @@ async function invokeAI(options, config, providerOverride) {
|
|
|
217
236
|
}
|
|
218
237
|
async function invokeAIInteractive(prompt, config, providerOverride) {
|
|
219
238
|
const provider = providerOverride ?? config.ai.provider;
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
239
|
+
switch (provider) {
|
|
240
|
+
case "claude": {
|
|
241
|
+
const args = ["--permission-mode", config.claude.permission_mode, prompt];
|
|
242
|
+
return {
|
|
243
|
+
result: execa("claude", args, { stdio: "inherit" }),
|
|
244
|
+
provider
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
case "gemini": {
|
|
248
|
+
return {
|
|
249
|
+
result: execa("gemini", ["-i", prompt], { stdio: "inherit" }),
|
|
250
|
+
provider
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
case "codex": {
|
|
254
|
+
const args = prompt ? [prompt] : [];
|
|
255
|
+
return {
|
|
256
|
+
result: execa("codex", args, { stdio: "inherit" }),
|
|
257
|
+
provider
|
|
258
|
+
};
|
|
259
|
+
}
|
|
231
260
|
}
|
|
232
261
|
}
|
|
233
262
|
function getProviderDisplayName(provider) {
|
|
234
|
-
|
|
263
|
+
switch (provider) {
|
|
264
|
+
case "claude":
|
|
265
|
+
return "Claude";
|
|
266
|
+
case "gemini":
|
|
267
|
+
return "Gemini";
|
|
268
|
+
case "codex":
|
|
269
|
+
return "Codex";
|
|
270
|
+
}
|
|
235
271
|
}
|
|
236
272
|
function getProviderEmail(provider) {
|
|
237
|
-
|
|
273
|
+
switch (provider) {
|
|
274
|
+
case "claude":
|
|
275
|
+
return "noreply@anthropic.com";
|
|
276
|
+
case "gemini":
|
|
277
|
+
return "noreply@google.com";
|
|
278
|
+
case "codex":
|
|
279
|
+
return "noreply@openai.com";
|
|
280
|
+
}
|
|
238
281
|
}
|
|
239
282
|
function isRateLimitError(error, provider) {
|
|
240
283
|
if (!error || typeof error !== "object") return false;
|
|
241
|
-
if (provider === "claude" && "exitCode" in error && error.exitCode === 2) {
|
|
284
|
+
if ((provider === "claude" || provider === "codex") && "exitCode" in error && error.exitCode === 2) {
|
|
242
285
|
return true;
|
|
243
286
|
}
|
|
244
287
|
if ("message" in error && typeof error.message === "string") {
|
|
@@ -330,6 +373,44 @@ async function invokeGeminiInternal(options) {
|
|
|
330
373
|
return stdout;
|
|
331
374
|
}
|
|
332
375
|
}
|
|
376
|
+
async function invokeCodexInternal(options) {
|
|
377
|
+
const args = ["exec", options.prompt];
|
|
378
|
+
if (options.printOutput) {
|
|
379
|
+
const subprocess = execa("codex", args, {
|
|
380
|
+
stdio: "inherit"
|
|
381
|
+
});
|
|
382
|
+
await subprocess;
|
|
383
|
+
return "";
|
|
384
|
+
} else if (options.streamOutput) {
|
|
385
|
+
return new Promise((resolve, reject) => {
|
|
386
|
+
const child = spawn("codex", args, {
|
|
387
|
+
stdio: ["inherit", "pipe", "pipe"]
|
|
388
|
+
});
|
|
389
|
+
let output = "";
|
|
390
|
+
child.stdout.on("data", (chunk) => {
|
|
391
|
+
const text = chunk.toString();
|
|
392
|
+
output += text;
|
|
393
|
+
process.stdout.write(text);
|
|
394
|
+
});
|
|
395
|
+
child.stderr.on("data", (chunk) => {
|
|
396
|
+
process.stderr.write(chunk);
|
|
397
|
+
});
|
|
398
|
+
child.on("close", (code) => {
|
|
399
|
+
if (code === 0) {
|
|
400
|
+
resolve(output);
|
|
401
|
+
} else {
|
|
402
|
+
const error = new Error(`Codex exited with code ${code}`);
|
|
403
|
+
error.exitCode = code ?? 1;
|
|
404
|
+
reject(error);
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
child.on("error", reject);
|
|
408
|
+
});
|
|
409
|
+
} else {
|
|
410
|
+
const { stdout } = await execa("codex", args);
|
|
411
|
+
return stdout;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
333
414
|
|
|
334
415
|
// src/lib/prompts.ts
|
|
335
416
|
function buildTicketPrompt(description, agentInstructions, additionalHints = null) {
|
|
@@ -1361,8 +1442,8 @@ import { homedir } from "os";
|
|
|
1361
1442
|
// package.json
|
|
1362
1443
|
var package_default = {
|
|
1363
1444
|
name: "@rotorsoft/gent",
|
|
1364
|
-
version: "1.
|
|
1365
|
-
description: "AI-powered GitHub workflow CLI - leverage AI (Claude or
|
|
1445
|
+
version: "1.8.0",
|
|
1446
|
+
description: "AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs",
|
|
1366
1447
|
keywords: [
|
|
1367
1448
|
"cli",
|
|
1368
1449
|
"ai",
|
|
@@ -1703,7 +1784,7 @@ function startVersionCheck() {
|
|
|
1703
1784
|
});
|
|
1704
1785
|
}
|
|
1705
1786
|
var program = new Command();
|
|
1706
|
-
program.name("gent").description("AI-powered GitHub workflow CLI - leverage AI (Claude or
|
|
1787
|
+
program.name("gent").description("AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs").version(version).option("--skip-update-check", "Skip checking for CLI updates").hook("preAction", (thisCommand) => {
|
|
1707
1788
|
if (!thisCommand.opts().skipUpdateCheck) {
|
|
1708
1789
|
startVersionCheck();
|
|
1709
1790
|
}
|
|
@@ -1714,7 +1795,7 @@ program.command("init").description("Initialize gent workflow in current reposit
|
|
|
1714
1795
|
program.command("setup-labels").description("Setup GitHub labels for AI workflow").action(async () => {
|
|
1715
1796
|
await setupLabelsCommand();
|
|
1716
1797
|
});
|
|
1717
|
-
program.command("create <description>").description("Create an AI-enhanced GitHub issue").option("-y, --yes", "Skip confirmation and create issue immediately").option("-p, --provider <provider>", "AI provider to use (claude or
|
|
1798
|
+
program.command("create <description>").description("Create an AI-enhanced GitHub issue").option("-y, --yes", "Skip confirmation and create issue immediately").option("-p, --provider <provider>", "AI provider to use (claude, gemini, or codex)").option("-t, --title <title>", "Override the generated issue title").action(async (description, options) => {
|
|
1718
1799
|
await createCommand(description, { yes: options.yes, provider: options.provider, title: options.title });
|
|
1719
1800
|
});
|
|
1720
1801
|
program.command("list").description("List GitHub issues by label/status").option("-l, --label <label>", "Filter by label").option("-s, --status <status>", "Filter by workflow status (ready, in-progress, completed, blocked, all)").option("-n, --limit <number>", "Maximum number of issues to show", "20").action(async (options) => {
|
|
@@ -1724,10 +1805,10 @@ program.command("list").description("List GitHub issues by label/status").option
|
|
|
1724
1805
|
limit: parseInt(options.limit, 10)
|
|
1725
1806
|
});
|
|
1726
1807
|
});
|
|
1727
|
-
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 or
|
|
1808
|
+
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) => {
|
|
1728
1809
|
await runCommand(issueNumber, { auto: options.auto, provider: options.provider });
|
|
1729
1810
|
});
|
|
1730
|
-
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 or
|
|
1811
|
+
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) => {
|
|
1731
1812
|
await prCommand({ draft: options.draft, provider: options.provider });
|
|
1732
1813
|
});
|
|
1733
1814
|
program.command("status").description("Show current workflow status").action(async () => {
|
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/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 { 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 or Gemini) 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 or gemini)\")\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 or gemini)\")\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 or gemini)\")\n .action(async (options) => {\n await prCommand({ draft: options.draft, 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();","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 // Create .gent.yml\n const configPath = getConfigPath(cwd);\n writeFileSync(configPath, generateDefaultConfig(), \"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/**\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 = provider === \"claude\"\n ? await invokeClaudeInternal(options)\n : await invokeGeminiInternal(options);\n\n return { output, provider };\n } catch (error) {\n // Check for rate limiting\n if (isRateLimitError(error, provider)) {\n // Try fallback if configured\n if (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 = fallback === \"claude\"\n ? await invokeClaudeInternal(options)\n : await invokeGeminiInternal(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 if (provider === \"claude\") {\n const args = [\"--permission-mode\", config.claude.permission_mode, prompt];\n return {\n result: execa(\"claude\", args, { stdio: \"inherit\" }),\n provider,\n };\n } else {\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}\n\n/**\n * Get display name for provider\n */\nexport function getProviderDisplayName(provider: AIProvider): string {\n return provider === \"claude\" ? \"Claude\" : \"Gemini\";\n}\n\n/**\n * Get email for provider co-author credit\n */\nexport function getProviderEmail(provider: AIProvider): string {\n return provider === \"claude\"\n ? \"noreply@anthropic.com\"\n : \"noreply@google.com\";\n}\n\n/**\n * Get colored provider name for display\n */\nexport function getProviderDisplay(provider: AIProvider): string {\n const name = getProviderDisplayName(provider);\n return provider === \"claude\"\n ? colors.command(name)\n : colors.label(name);\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 CLI uses exit code 2 for rate limiting\n if (provider === \"claude\" && \"exitCode\" in error && error.exitCode === 2) {\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","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): 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\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","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 { 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.7.1\",\n \"description\": \"AI-powered GitHub workflow CLI - leverage AI (Claude or Gemini) 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, getPrForBranch } from \"../lib/github.js\";\nimport { getCurrentBranch, isOnMainBranch, hasUncommittedChanges, getUnpushedCommits, getCommitsSinceBase, getDefaultBranch } 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, checkForUpdates } from \"../lib/version.js\";\n\nexport async function statusCommand(): Promise<void> {\n const version = getVersion();\n logger.bold(`Gent Workflow Status ${colors.label(`v${version}`)}`);\n\n // Check for updates (non-blocking, with short timeout for status command)\n const versionCheck = await checkForUpdates();\n if (versionCheck.updateAvailable && versionCheck.latestVersion) {\n logger.warning(` Update available: ${version} → ${versionCheck.latestVersion}`);\n logger.dim(` Run: npm install -g @rotorsoft/gent`);\n }\n\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\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 const pr = await getPrForBranch();\n if (pr) {\n logger.success(` PR #${pr.number} exists`);\n logger.info(` ${colors.url(pr.url)}`);\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 {\n const pr = await getPrForBranch();\n if (!pr) {\n logger.list([\n `${colors.command(\"gent pr\")} - Create a pull request`,\n `${colors.command(\"git push\")} - Push your 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}\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;AAGA,QAAM,aAAa,cAAc,GAAG;AACpC,EAAAC,eAAc,YAAY,sBAAsB,GAAG,OAAO;AAC1D,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;;;AEvIA,OAAOC,eAAc;AACrB,OAAO,WAAW;;;ACDlB,SAAS,aAAa;AACtB,SAAS,aAAiC;AAqB1C,eAAsB,SACpB,SACA,QACA,kBAC2B;AAC3B,QAAM,WAAW,oBAAoB,OAAO,GAAG;AAE/C,MAAI;AACF,UAAM,SAAS,aAAa,WACxB,MAAM,qBAAqB,OAAO,IAClC,MAAM,qBAAqB,OAAO;AAEtC,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,aAAa,WACxB,MAAM,qBAAqB,OAAO,IAClC,MAAM,qBAAqB,OAAO;AAEtC,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,MAAI,aAAa,UAAU;AACzB,UAAM,OAAO,CAAC,qBAAqB,OAAO,OAAO,iBAAiB,MAAM;AACxE,WAAO;AAAA,MACL,QAAQ,MAAM,UAAU,MAAM,EAAE,OAAO,UAAU,CAAC;AAAA,MAClD;AAAA,IACF;AAAA,EACF,OAAO;AAGL,WAAO;AAAA,MACL,QAAQ,MAAM,UAAU,CAAC,MAAM,MAAM,GAAG,EAAE,OAAO,UAAU,CAAC;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,uBAAuB,UAA8B;AACnE,SAAO,aAAa,WAAW,WAAW;AAC5C;AAKO,SAAS,iBAAiB,UAA8B;AAC7D,SAAO,aAAa,WAChB,0BACA;AACN;AAeA,SAAS,iBAAiB,OAAgB,UAA+B;AACvE,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAGhD,MAAI,aAAa,YAAY,cAAc,SAAS,MAAM,aAAa,GAAG;AACxE,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;;;AChPO,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,QACQ;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOrE,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;;;AFhLA,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;;;ACpKA,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;AAkBrB,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;AAGf,QAAM,SAAS,cAAc,OAAO,SAAS,WAAW;AAExD,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;;;AC7MA,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;;;AEjJA,eAAsB,gBAA+B;AACnD,QAAMC,WAAU,WAAW;AAC3B,SAAO,KAAK,wBAAwB,OAAO,MAAM,IAAIA,QAAO,EAAE,CAAC,EAAE;AAGjE,QAAM,eAAe,MAAM,gBAAgB;AAC3C,MAAI,aAAa,mBAAmB,aAAa,eAAe;AAC9D,WAAO,QAAQ,uBAAuBA,QAAO,WAAM,aAAa,aAAa,EAAE;AAC/E,WAAO,IAAI,uCAAuC;AAAA,EACpD;AAEA,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,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,UAAM,KAAK,MAAM,eAAe;AAChC,QAAI,IAAI;AACN,aAAO,QAAQ,SAAS,GAAG,MAAM,SAAS;AAC1C,aAAO,KAAK,KAAK,OAAO,IAAI,GAAG,GAAG,CAAC,EAAE;AAAA,IACvC,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,OAAO;AACL,UAAM,KAAK,MAAM,eAAe;AAChC,QAAI,CAAC,IAAI;AACP,aAAO,KAAK;AAAA,QACV,GAAG,OAAO,QAAQ,SAAS,CAAC;AAAA,QAC5B,GAAG,OAAO,QAAQ,UAAU,CAAC;AAAA,MAC/B,CAAC;AAAA,IACH,OAAO;AACL,aAAO,KAAK;AAAA,QACV;AAAA,QACA,GAAG,OAAO,QAAQ,mBAAmB,CAAC;AAAA,MACxC,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;AbvLA,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,uHAAuH,EACnI,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,uCAAuC,EAC3E,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,uCAAuC,EAC3E,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,uCAAuC,EAC3E,OAAO,OAAO,YAAY;AACzB,QAAM,UAAU,EAAE,OAAO,QAAQ,OAAO,UAAU,QAAQ,SAAS,CAAC;AACtE,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","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/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 { 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(\"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): 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\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","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 { 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.8.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, getPrForBranch } from \"../lib/github.js\";\nimport { getCurrentBranch, isOnMainBranch, hasUncommittedChanges, getUnpushedCommits, getCommitsSinceBase, getDefaultBranch } 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, checkForUpdates } from \"../lib/version.js\";\n\nexport async function statusCommand(): Promise<void> {\n const version = getVersion();\n logger.bold(`Gent Workflow Status ${colors.label(`v${version}`)}`);\n\n // Check for updates (non-blocking, with short timeout for status command)\n const versionCheck = await checkForUpdates();\n if (versionCheck.updateAvailable && versionCheck.latestVersion) {\n logger.warning(` Update available: ${version} → ${versionCheck.latestVersion}`);\n logger.dim(` Run: npm install -g @rotorsoft/gent`);\n }\n\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\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 const pr = await getPrForBranch();\n if (pr) {\n logger.success(` PR #${pr.number} exists`);\n logger.info(` ${colors.url(pr.url)}`);\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 {\n const pr = await getPrForBranch();\n if (!pr) {\n logger.list([\n `${colors.command(\"gent pr\")} - Create a pull request`,\n `${colors.command(\"git push\")} - Push your 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}\n"],"mappings":"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","names":["writeFileSync","existsSync","join","writeFileSync","join","existsSync","setupLabelsCommand","inquirer","inquirer","chalk","chalk","inquirer","execa","execa","inquirer","inquirer","inquirer","readFileSync","writeFileSync","existsSync","mkdirSync","join","join","existsSync","readFileSync","mkdirSync","writeFileSync","version"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rotorsoft/gent",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "AI-powered GitHub workflow CLI - leverage AI (Claude or
|
|
3
|
+
"version": "1.8.0",
|
|
4
|
+
"description": "AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
7
7
|
"ai",
|
|
@@ -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 } 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 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 \"claude\" | \"gemini\" | 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 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(): 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# AI provider settings\nai:\n provider: \"claude\" # claude | gemini\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\";\n\nexport interface GentConfig {\n version: number;\n github: GitHubConfig;\n branch: BranchConfig;\n progress: ProgressConfig;\n claude: ClaudeConfig;\n gemini: GeminiConfig;\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 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 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 } 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 async function getPrForBranch(): Promise<{\n number: number;\n url: string;\n} | 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 getCurrentUser(): Promise<string> {\n const { stdout } = await execa(\"gh\", [\"api\", \"user\", \"--jq\", \".login\"]);\n return stdout.trim();\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 checkAIProvider(provider: AIProvider): Promise<boolean> {\n return provider === \"claude\" ? checkClaudeCli() : checkGeminiCli();\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 // Add AI provider check based on config\n if (config) {\n const provider = config.ai.provider;\n const providerName = provider === \"claude\" ? \"claude CLI\" : \"gemini CLI\";\n checks.push({\n name: providerName,\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 const fallbackName = fallback === \"claude\" ? \"claude CLI (fallback)\" : \"gemini CLI (fallback)\";\n checks.push({\n name: fallbackName,\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
|