@rotorsoft/gent 1.0.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 +397 -0
- package/dist/chunk-NRTQPDZB.js +667 -0
- package/dist/chunk-NRTQPDZB.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1184 -0
- package/dist/index.js.map +1 -0
- package/dist/setup-labels-2YOKZ2AK.js +8 -0
- package/dist/setup-labels-2YOKZ2AK.js.map +1 -0
- package/package.json +87 -0
- package/templates/.gent.yml +61 -0
- package/templates/AGENT.md +108 -0
- package/templates/issue-template.md +44 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/lib/progress.ts","../src/lib/claude.ts","../src/commands/create.ts","../src/commands/list.ts","../src/commands/run.ts","../src/lib/git.ts","../src/lib/branch.ts","../src/commands/pr.ts","../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\";\n\nconst program = new Command();\n\nprogram\n .name(\"gent\")\n .description(\"AI-powered GitHub workflow CLI - leverage Claude AI to create tickets, implement features, and manage PRs\")\n .version(\"0.1.0\");\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 .action(async (description) => {\n await createCommand(description);\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 Claude to implement a GitHub issue\")\n .option(\"-a, --auto\", \"Auto-select highest priority ai-ready issue\")\n .action(async (issueNumber, options) => {\n await runCommand(issueNumber, { auto: options.auto });\n });\n\nprogram\n .command(\"pr\")\n .description(\"Create an AI-enhanced pull request\")\n .option(\"-d, --draft\", \"Create as draft PR\")\n .action(async (options) => {\n await prCommand({ draft: options.draft });\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 Claude 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:\n\\`\\`\\`\nCo-Authored-By: Claude <noreply@anthropic.com>\n\\`\\`\\`\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 { spawn } from \"child_process\";\nimport { execa, type ResultPromise } from \"execa\";\nimport type { GentConfig } from \"../types/index.js\";\n\nexport interface ClaudeOptions {\n prompt: string;\n permissionMode?: string;\n printOutput?: boolean;\n streamOutput?: boolean;\n}\n\nexport async function invokeClaude(options: ClaudeOptions): 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 reject(new Error(`Claude exited with code ${code}`));\n }\n });\n\n child.on(\"error\", reject);\n });\n } else {\n const { stdout } = await execa(\"claude\", args);\n return stdout;\n }\n}\n\nexport async function invokeClaudeInteractive(\n prompt: string,\n config: GentConfig\n): Promise<ResultPromise> {\n const args = [\"--permission-mode\", config.claude.permission_mode, prompt];\n\n return execa(\"claude\", args, {\n stdio: \"inherit\",\n });\n}\n\nexport function buildTicketPrompt(\n description: string,\n agentInstructions: string | 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` : \"\"}\n\nCreate a detailed GitHub issue following this exact template:\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 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: Claude <noreply@anthropic.com>\n5. **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 return output.replace(/\\n?META:type=\\w+,priority=\\w+,risk=\\w+,area=\\w+\\s*$/, \"\").trim();\n}\n","import { logger, colors } from \"../utils/logger.js\";\nimport { withSpinner } from \"../utils/spinner.js\";\nimport { loadAgentInstructions } from \"../lib/config.js\";\nimport {\n invokeClaude,\n buildTicketPrompt,\n parseTicketMeta,\n extractIssueBody,\n} from \"../lib/claude.js\";\nimport { createIssue } from \"../lib/github.js\";\nimport { buildIssueLabels } from \"../lib/labels.js\";\nimport { checkGhAuth, checkClaudeCli } from \"../utils/validators.js\";\n\nexport async function createCommand(description: string): Promise<void> {\n logger.bold(\"Creating AI-enhanced ticket...\");\n logger.newline();\n\n // Validate prerequisites\n const [ghAuth, claudeOk] = await Promise.all([checkGhAuth(), checkClaudeCli()]);\n\n if (!ghAuth) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n process.exit(1);\n }\n\n if (!claudeOk) {\n logger.error(\"Claude CLI not found. Please install claude CLI first.\");\n process.exit(1);\n }\n\n const agentInstructions = loadAgentInstructions();\n\n // Build prompt and invoke Claude\n const prompt = buildTicketPrompt(description, agentInstructions);\n\n let claudeOutput: string;\n try {\n logger.info(\"Generating ticket with Claude...\");\n logger.newline();\n claudeOutput = await invokeClaude({ prompt, streamOutput: true });\n logger.newline();\n } catch (error) {\n logger.error(`Claude invocation failed: ${error}`);\n return;\n }\n\n // Parse metadata\n const meta = parseTicketMeta(claudeOutput);\n if (!meta) {\n logger.warning(\"Could not parse metadata from Claude output. Using defaults.\");\n }\n\n const finalMeta = meta || {\n type: \"feature\",\n priority: \"medium\",\n risk: \"low\",\n area: \"shared\",\n };\n\n // Extract issue body (without META line)\n const issueBody = extractIssueBody(claudeOutput);\n\n // Generate title from description\n const title =\n description.length > 60 ? description.slice(0, 57) + \"...\" : description;\n\n // Build labels\n const labels = buildIssueLabels(finalMeta);\n\n // Create issue\n let issueNumber: number;\n try {\n issueNumber = await withSpinner(\"Creating GitHub issue...\", async () => {\n return createIssue({\n title,\n body: issueBody,\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(\"Issue Created\", `Issue: ${colors.issue(`#${issueNumber}`)}\nType: ${colors.label(`type:${finalMeta.type}`)}\nPriority: ${colors.label(`priority:${finalMeta.priority}`)}\nRisk: ${colors.label(`risk:${finalMeta.risk}`)}\nArea: ${colors.label(`area:${finalMeta.area}`)}\n\nNext steps:\n1. Review the issue on GitHub\n2. Run ${colors.command(`gent run ${issueNumber}`)} to implement`);\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 { invokeClaudeInteractive, buildImplementationPrompt } from \"../lib/claude.js\";\nimport { getCurrentBranch, isOnMainBranch, createBranch, branchExists, checkoutBranch, hasUncommittedChanges } 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, checkClaudeCli, isValidIssueNumber } from \"../utils/validators.js\";\nimport type { GitHubIssue } from \"../types/index.js\";\n\nexport interface RunOptions {\n auto?: boolean;\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 // Validate prerequisites\n const [ghAuth, claudeOk] = await Promise.all([checkGhAuth(), checkClaudeCli()]);\n\n if (!ghAuth) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n process.exit(1);\n }\n\n if (!claudeOk) {\n logger.error(\"Claude CLI not found. Please install claude 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 config = loadConfig();\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 Claude 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 Claude implementation session...\");\n logger.dim(\"Claude will implement the feature and create a commit.\");\n logger.dim(\"Review the changes before pushing.\");\n logger.newline();\n\n // Invoke Claude interactively\n try {\n await invokeClaudeInteractive(prompt, config);\n } catch (error) {\n logger.error(`Claude session failed: ${error}`);\n // Don't exit - allow user to see what happened\n }\n\n // Post-completion\n logger.newline();\n logger.success(\"Claude session completed.\");\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}\\`.\\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\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","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 { getIssue, createPullRequest, getPrForBranch, assignIssue, getCurrentUser } from \"../lib/github.js\";\nimport { invokeClaude, buildPrPrompt } from \"../lib/claude.js\";\nimport { getCurrentBranch, isOnMainBranch, getDefaultBranch, getCommitsSinceBase, getDiffSummary, getUnpushedCommits, pushBranch } from \"../lib/git.js\";\nimport { extractIssueNumber } from \"../lib/branch.js\";\nimport { checkGhAuth, checkClaudeCli } from \"../utils/validators.js\";\nimport type { GitHubIssue } from \"../types/index.js\";\n\nexport interface PrOptions {\n draft?: boolean;\n}\n\nexport async function prCommand(options: PrOptions): Promise<void> {\n logger.bold(\"Creating AI-enhanced pull request...\");\n logger.newline();\n\n // Validate prerequisites\n const [ghAuth, claudeOk] = await Promise.all([checkGhAuth(), checkClaudeCli()]);\n\n if (!ghAuth) {\n logger.error(\"Not authenticated with GitHub. Run 'gh auth login' first.\");\n process.exit(1);\n }\n\n if (!claudeOk) {\n logger.error(\"Claude CLI not found. Please install claude 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 Claude\n const prompt = buildPrPrompt(issue, commits, diffSummary);\n\n let prBody: string;\n try {\n logger.info(\"Generating PR description with Claude...\");\n logger.newline();\n prBody = await invokeClaude({ prompt, streamOutput: true });\n logger.newline();\n } catch (error) {\n logger.warning(`Claude invocation failed: ${error}`);\n // Fall back to basic description\n prBody = generateFallbackBody(issue, commits);\n }\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\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 { 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, checkGitRepo } from \"../utils/validators.js\";\n\nexport async function statusCommand(): Promise<void> {\n logger.bold(\"Gent Workflow Status\");\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 // 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 const claudeOk = await checkClaudeCli();\n if (claudeOk) {\n logger.success(\" Claude CLI available\");\n } else {\n logger.error(\" Claude CLI not found\");\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","execa","execa","inquirer","inquirer","inquirer"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rotorsoft/gent",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "AI-powered GitHub workflow CLI - leverage Claude AI to create tickets, implement features, and manage PRs",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"cli",
|
|
7
|
+
"ai",
|
|
8
|
+
"claude",
|
|
9
|
+
"github",
|
|
10
|
+
"workflow",
|
|
11
|
+
"automation",
|
|
12
|
+
"developer-tools"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://github.com/rotorsoft/gent#readme",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/rotorsoft/gent/issues"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/rotorsoft/gent.git"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"author": "Rotorsoft",
|
|
24
|
+
"type": "module",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"import": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"main": "./dist/index.js",
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"bin": {
|
|
34
|
+
"gent": "./dist/index.js"
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"templates"
|
|
39
|
+
],
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsup",
|
|
42
|
+
"dev": "tsx src/index.ts",
|
|
43
|
+
"watch": "tsup --watch",
|
|
44
|
+
"test": "vitest run",
|
|
45
|
+
"test:watch": "vitest",
|
|
46
|
+
"test:coverage": "vitest run --coverage",
|
|
47
|
+
"lint": "eslint src/",
|
|
48
|
+
"lint:fix": "eslint src/ --fix",
|
|
49
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
50
|
+
"format:check": "prettier --check \"src/**/*.ts\"",
|
|
51
|
+
"typecheck": "tsc --noEmit",
|
|
52
|
+
"prepublishOnly": "npm run build",
|
|
53
|
+
"prepare": "npm run build"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"chalk": "^5.3.0",
|
|
57
|
+
"commander": "^12.1.0",
|
|
58
|
+
"execa": "^9.5.2",
|
|
59
|
+
"inquirer": "^12.2.0",
|
|
60
|
+
"ora": "^8.1.1",
|
|
61
|
+
"yaml": "^2.6.1"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@eslint/js": "^9.17.0",
|
|
65
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
66
|
+
"@semantic-release/git": "^10.0.1",
|
|
67
|
+
"@types/inquirer": "^9.0.7",
|
|
68
|
+
"@types/node": "^22.10.5",
|
|
69
|
+
"@typescript-eslint/eslint-plugin": "^8.19.1",
|
|
70
|
+
"@typescript-eslint/parser": "^8.19.1",
|
|
71
|
+
"@vitest/coverage-v8": "^2.1.8",
|
|
72
|
+
"eslint": "^9.17.0",
|
|
73
|
+
"eslint-config-prettier": "^9.1.0",
|
|
74
|
+
"prettier": "^3.4.2",
|
|
75
|
+
"semantic-release": "^24.2.1",
|
|
76
|
+
"tsup": "^8.3.5",
|
|
77
|
+
"tsx": "^4.21.0",
|
|
78
|
+
"typescript": "^5.7.3",
|
|
79
|
+
"vitest": "^2.1.8"
|
|
80
|
+
},
|
|
81
|
+
"engines": {
|
|
82
|
+
"node": ">=20.0.0"
|
|
83
|
+
},
|
|
84
|
+
"publishConfig": {
|
|
85
|
+
"access": "public"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Gent Configuration
|
|
2
|
+
# See https://github.com/rotorsoft/gent for documentation
|
|
3
|
+
version: 1
|
|
4
|
+
|
|
5
|
+
# GitHub settings
|
|
6
|
+
github:
|
|
7
|
+
labels:
|
|
8
|
+
workflow:
|
|
9
|
+
ready: "ai-ready"
|
|
10
|
+
in_progress: "ai-in-progress"
|
|
11
|
+
completed: "ai-completed"
|
|
12
|
+
blocked: "ai-blocked"
|
|
13
|
+
types:
|
|
14
|
+
- feature
|
|
15
|
+
- fix
|
|
16
|
+
- refactor
|
|
17
|
+
- chore
|
|
18
|
+
- docs
|
|
19
|
+
- test
|
|
20
|
+
priorities:
|
|
21
|
+
- critical
|
|
22
|
+
- high
|
|
23
|
+
- medium
|
|
24
|
+
- low
|
|
25
|
+
risks:
|
|
26
|
+
- low
|
|
27
|
+
- medium
|
|
28
|
+
- high
|
|
29
|
+
areas:
|
|
30
|
+
- ui
|
|
31
|
+
- api
|
|
32
|
+
- database
|
|
33
|
+
- workers
|
|
34
|
+
- shared
|
|
35
|
+
- testing
|
|
36
|
+
- infra
|
|
37
|
+
|
|
38
|
+
# Branch naming convention
|
|
39
|
+
# Available placeholders: {author}, {type}, {issue}, {slug}
|
|
40
|
+
branch:
|
|
41
|
+
pattern: "{author}/{type}-{issue}-{slug}"
|
|
42
|
+
author_source: "git" # git | env | prompt
|
|
43
|
+
author_env_var: "GENT_AUTHOR"
|
|
44
|
+
|
|
45
|
+
# Progress tracking
|
|
46
|
+
progress:
|
|
47
|
+
file: "progress.txt"
|
|
48
|
+
archive_threshold: 500 # lines before archiving
|
|
49
|
+
archive_dir: ".gent/archive"
|
|
50
|
+
|
|
51
|
+
# Claude settings
|
|
52
|
+
claude:
|
|
53
|
+
permission_mode: "acceptEdits"
|
|
54
|
+
agent_file: "AGENT.md"
|
|
55
|
+
|
|
56
|
+
# Validation commands (run before commit)
|
|
57
|
+
# These commands must pass for the implementation to be considered complete
|
|
58
|
+
validation:
|
|
59
|
+
- "npm run typecheck"
|
|
60
|
+
- "npm run lint"
|
|
61
|
+
- "npm run test"
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# AI Agent Instructions
|
|
2
|
+
|
|
3
|
+
This file contains instructions for Claude when working on this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
[Describe your project, its purpose, and key technologies used]
|
|
8
|
+
|
|
9
|
+
Example:
|
|
10
|
+
- **Name**: My Awesome Project
|
|
11
|
+
- **Purpose**: A web application for managing tasks
|
|
12
|
+
- **Stack**: TypeScript, React, Node.js, PostgreSQL
|
|
13
|
+
- **Architecture**: Monorepo with packages for frontend, backend, and shared code
|
|
14
|
+
|
|
15
|
+
## Code Patterns
|
|
16
|
+
|
|
17
|
+
### Architecture
|
|
18
|
+
[Document your architecture - e.g., MVC, Clean Architecture, etc.]
|
|
19
|
+
|
|
20
|
+
Example:
|
|
21
|
+
- Follow clean architecture principles
|
|
22
|
+
- Business logic in `src/domain/`
|
|
23
|
+
- Data access in `src/repositories/`
|
|
24
|
+
- API routes in `src/routes/`
|
|
25
|
+
|
|
26
|
+
### Naming Conventions
|
|
27
|
+
[Document naming conventions for files, functions, variables, etc.]
|
|
28
|
+
|
|
29
|
+
Example:
|
|
30
|
+
- Files: `kebab-case.ts`
|
|
31
|
+
- Classes: `PascalCase`
|
|
32
|
+
- Functions/Variables: `camelCase`
|
|
33
|
+
- Constants: `SCREAMING_SNAKE_CASE`
|
|
34
|
+
|
|
35
|
+
### Component Structure
|
|
36
|
+
[If applicable, describe component/module structure]
|
|
37
|
+
|
|
38
|
+
Example:
|
|
39
|
+
```
|
|
40
|
+
src/components/
|
|
41
|
+
├── Button/
|
|
42
|
+
│ ├── Button.tsx
|
|
43
|
+
│ ├── Button.test.tsx
|
|
44
|
+
│ ├── Button.styles.ts
|
|
45
|
+
│ └── index.ts
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Testing Requirements
|
|
49
|
+
|
|
50
|
+
### Unit Tests
|
|
51
|
+
- All new functions should have corresponding unit tests
|
|
52
|
+
- Use the project's testing framework for unit tests
|
|
53
|
+
- Aim for high coverage on new code
|
|
54
|
+
|
|
55
|
+
### Integration Tests
|
|
56
|
+
[Document when and how to write integration tests]
|
|
57
|
+
|
|
58
|
+
### Running Tests
|
|
59
|
+
```bash
|
|
60
|
+
npm test # Run all tests
|
|
61
|
+
npm run test:unit # Run unit tests only
|
|
62
|
+
npm run test:e2e # Run e2e tests
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Commit Conventions
|
|
66
|
+
|
|
67
|
+
Follow conventional commits format:
|
|
68
|
+
- `feat:` New feature
|
|
69
|
+
- `fix:` Bug fix
|
|
70
|
+
- `refactor:` Code improvement without behavior change
|
|
71
|
+
- `test:` Testing additions
|
|
72
|
+
- `chore:` Maintenance/dependencies
|
|
73
|
+
- `docs:` Documentation
|
|
74
|
+
|
|
75
|
+
All AI commits should include:
|
|
76
|
+
```
|
|
77
|
+
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Important Files
|
|
81
|
+
|
|
82
|
+
[List key files the AI should understand before making changes]
|
|
83
|
+
|
|
84
|
+
- `src/index.ts` - Main entry point
|
|
85
|
+
- `src/config/` - Configuration files
|
|
86
|
+
- `package.json` - Dependencies and scripts
|
|
87
|
+
|
|
88
|
+
## Constraints
|
|
89
|
+
|
|
90
|
+
[List any constraints or limitations]
|
|
91
|
+
|
|
92
|
+
- Do not modify files in `/vendor` or `/dist`
|
|
93
|
+
- Always use async/await over callbacks
|
|
94
|
+
- Do not add new dependencies without discussion
|
|
95
|
+
- Keep bundle size under X MB
|
|
96
|
+
|
|
97
|
+
## Validation Commands
|
|
98
|
+
|
|
99
|
+
Before committing, ensure these pass:
|
|
100
|
+
```bash
|
|
101
|
+
npm run typecheck # Type checking
|
|
102
|
+
npm run lint # Linting
|
|
103
|
+
npm test # Tests
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Additional Notes
|
|
107
|
+
|
|
108
|
+
[Any other project-specific information]
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
## Description
|
|
2
|
+
|
|
3
|
+
[Clear user-facing description of what needs to be done]
|
|
4
|
+
|
|
5
|
+
## Technical Context
|
|
6
|
+
|
|
7
|
+
**Type:** feature | fix | refactor | chore | docs | test
|
|
8
|
+
**Category:** ui | api | database | workers | shared | testing | infra
|
|
9
|
+
**Priority:** critical | high | medium | low
|
|
10
|
+
**Risk:** low | medium | high
|
|
11
|
+
**Packages:** [List affected packages if monorepo]
|
|
12
|
+
|
|
13
|
+
### Architecture Notes
|
|
14
|
+
|
|
15
|
+
- [Relevant patterns to follow]
|
|
16
|
+
- [Related systems affected]
|
|
17
|
+
- [Constraints or invariants]
|
|
18
|
+
|
|
19
|
+
## Implementation Steps
|
|
20
|
+
|
|
21
|
+
- [ ] Step 1: Specific technical task
|
|
22
|
+
- [ ] Step 2: Specific technical task
|
|
23
|
+
- [ ] Step 3: Specific technical task
|
|
24
|
+
|
|
25
|
+
## Testing Requirements
|
|
26
|
+
|
|
27
|
+
- **Unit tests:** [What to test]
|
|
28
|
+
- **Integration tests:** [What to test if applicable]
|
|
29
|
+
- **Manual verification:** [What to check]
|
|
30
|
+
|
|
31
|
+
## Dependencies
|
|
32
|
+
|
|
33
|
+
Blocked by: #[issue-number]
|
|
34
|
+
Blocks: #[issue-number]
|
|
35
|
+
|
|
36
|
+
## Acceptance Criteria
|
|
37
|
+
|
|
38
|
+
- [ ] Criterion 1
|
|
39
|
+
- [ ] Criterion 2
|
|
40
|
+
- [ ] Criterion 3
|
|
41
|
+
|
|
42
|
+
## Labels
|
|
43
|
+
|
|
44
|
+
ai-ready, type:feature, priority:medium, risk:low, area:shared
|