@iloom/cli 0.1.14
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/LICENSE +33 -0
- package/README.md +711 -0
- package/dist/ClaudeContextManager-XOSXQ67R.js +13 -0
- package/dist/ClaudeContextManager-XOSXQ67R.js.map +1 -0
- package/dist/ClaudeService-YSZ6EXWP.js +12 -0
- package/dist/ClaudeService-YSZ6EXWP.js.map +1 -0
- package/dist/GitHubService-F7Z3XJOS.js +11 -0
- package/dist/GitHubService-F7Z3XJOS.js.map +1 -0
- package/dist/LoomLauncher-MODG2SEM.js +263 -0
- package/dist/LoomLauncher-MODG2SEM.js.map +1 -0
- package/dist/NeonProvider-PAGPUH7F.js +12 -0
- package/dist/NeonProvider-PAGPUH7F.js.map +1 -0
- package/dist/PromptTemplateManager-7FINLRDE.js +9 -0
- package/dist/PromptTemplateManager-7FINLRDE.js.map +1 -0
- package/dist/SettingsManager-VAZF26S2.js +19 -0
- package/dist/SettingsManager-VAZF26S2.js.map +1 -0
- package/dist/SettingsMigrationManager-MTQIMI54.js +146 -0
- package/dist/SettingsMigrationManager-MTQIMI54.js.map +1 -0
- package/dist/add-issue-22JBNOML.js +54 -0
- package/dist/add-issue-22JBNOML.js.map +1 -0
- package/dist/agents/iloom-issue-analyze-and-plan.md +580 -0
- package/dist/agents/iloom-issue-analyzer.md +290 -0
- package/dist/agents/iloom-issue-complexity-evaluator.md +224 -0
- package/dist/agents/iloom-issue-enhancer.md +266 -0
- package/dist/agents/iloom-issue-implementer.md +262 -0
- package/dist/agents/iloom-issue-planner.md +358 -0
- package/dist/agents/iloom-issue-reviewer.md +63 -0
- package/dist/chunk-2ZPFJQ3B.js +63 -0
- package/dist/chunk-2ZPFJQ3B.js.map +1 -0
- package/dist/chunk-37DYYFVK.js +29 -0
- package/dist/chunk-37DYYFVK.js.map +1 -0
- package/dist/chunk-BLCTGFZN.js +121 -0
- package/dist/chunk-BLCTGFZN.js.map +1 -0
- package/dist/chunk-CP2NU2JC.js +545 -0
- package/dist/chunk-CP2NU2JC.js.map +1 -0
- package/dist/chunk-CWR2SANQ.js +39 -0
- package/dist/chunk-CWR2SANQ.js.map +1 -0
- package/dist/chunk-F3XBU2R7.js +110 -0
- package/dist/chunk-F3XBU2R7.js.map +1 -0
- package/dist/chunk-GEHQXLEI.js +130 -0
- package/dist/chunk-GEHQXLEI.js.map +1 -0
- package/dist/chunk-GYCR2LOU.js +143 -0
- package/dist/chunk-GYCR2LOU.js.map +1 -0
- package/dist/chunk-GZP4UGGM.js +48 -0
- package/dist/chunk-GZP4UGGM.js.map +1 -0
- package/dist/chunk-H4E4THUZ.js +55 -0
- package/dist/chunk-H4E4THUZ.js.map +1 -0
- package/dist/chunk-HPJJSYNS.js +644 -0
- package/dist/chunk-HPJJSYNS.js.map +1 -0
- package/dist/chunk-JBH2ZYYZ.js +220 -0
- package/dist/chunk-JBH2ZYYZ.js.map +1 -0
- package/dist/chunk-JNKJ7NJV.js +78 -0
- package/dist/chunk-JNKJ7NJV.js.map +1 -0
- package/dist/chunk-JQ7VOSTC.js +437 -0
- package/dist/chunk-JQ7VOSTC.js.map +1 -0
- package/dist/chunk-KQDEK2ZW.js +199 -0
- package/dist/chunk-KQDEK2ZW.js.map +1 -0
- package/dist/chunk-O2QWO64Z.js +179 -0
- package/dist/chunk-O2QWO64Z.js.map +1 -0
- package/dist/chunk-OC4H6HJD.js +248 -0
- package/dist/chunk-OC4H6HJD.js.map +1 -0
- package/dist/chunk-PR7FKQBG.js +120 -0
- package/dist/chunk-PR7FKQBG.js.map +1 -0
- package/dist/chunk-PXZBAC2M.js +250 -0
- package/dist/chunk-PXZBAC2M.js.map +1 -0
- package/dist/chunk-QEPVTTHD.js +383 -0
- package/dist/chunk-QEPVTTHD.js.map +1 -0
- package/dist/chunk-RSRO7564.js +203 -0
- package/dist/chunk-RSRO7564.js.map +1 -0
- package/dist/chunk-SJUQ2NDR.js +146 -0
- package/dist/chunk-SJUQ2NDR.js.map +1 -0
- package/dist/chunk-SPYPLHMK.js +177 -0
- package/dist/chunk-SPYPLHMK.js.map +1 -0
- package/dist/chunk-SSCQCCJ7.js +75 -0
- package/dist/chunk-SSCQCCJ7.js.map +1 -0
- package/dist/chunk-SSR5AVRJ.js +41 -0
- package/dist/chunk-SSR5AVRJ.js.map +1 -0
- package/dist/chunk-T7QPXANZ.js +315 -0
- package/dist/chunk-T7QPXANZ.js.map +1 -0
- package/dist/chunk-U3WU5OWO.js +203 -0
- package/dist/chunk-U3WU5OWO.js.map +1 -0
- package/dist/chunk-W3DQTW63.js +124 -0
- package/dist/chunk-W3DQTW63.js.map +1 -0
- package/dist/chunk-WKEWRSDB.js +151 -0
- package/dist/chunk-WKEWRSDB.js.map +1 -0
- package/dist/chunk-Y7SAGNUT.js +66 -0
- package/dist/chunk-Y7SAGNUT.js.map +1 -0
- package/dist/chunk-YETJNRQM.js +39 -0
- package/dist/chunk-YETJNRQM.js.map +1 -0
- package/dist/chunk-YYSKGAZT.js +384 -0
- package/dist/chunk-YYSKGAZT.js.map +1 -0
- package/dist/chunk-ZZZWQGTS.js +169 -0
- package/dist/chunk-ZZZWQGTS.js.map +1 -0
- package/dist/claude-7LUVDZZ4.js +17 -0
- package/dist/claude-7LUVDZZ4.js.map +1 -0
- package/dist/cleanup-3LUWPSM7.js +412 -0
- package/dist/cleanup-3LUWPSM7.js.map +1 -0
- package/dist/cli-overrides-XFZWY7CM.js +16 -0
- package/dist/cli-overrides-XFZWY7CM.js.map +1 -0
- package/dist/cli.js +603 -0
- package/dist/cli.js.map +1 -0
- package/dist/color-ZVALX37U.js +21 -0
- package/dist/color-ZVALX37U.js.map +1 -0
- package/dist/enhance-XJIQHVPD.js +166 -0
- package/dist/enhance-XJIQHVPD.js.map +1 -0
- package/dist/env-MDFL4ZXL.js +23 -0
- package/dist/env-MDFL4ZXL.js.map +1 -0
- package/dist/feedback-23CLXKFT.js +158 -0
- package/dist/feedback-23CLXKFT.js.map +1 -0
- package/dist/finish-CY4CIH6O.js +1608 -0
- package/dist/finish-CY4CIH6O.js.map +1 -0
- package/dist/git-LVRZ57GJ.js +43 -0
- package/dist/git-LVRZ57GJ.js.map +1 -0
- package/dist/ignite-WXEF2ID5.js +359 -0
- package/dist/ignite-WXEF2ID5.js.map +1 -0
- package/dist/index.d.ts +1341 -0
- package/dist/index.js +3058 -0
- package/dist/index.js.map +1 -0
- package/dist/init-RHACUR4E.js +123 -0
- package/dist/init-RHACUR4E.js.map +1 -0
- package/dist/installation-detector-VARGFFRZ.js +11 -0
- package/dist/installation-detector-VARGFFRZ.js.map +1 -0
- package/dist/logger-MKYH4UDV.js +12 -0
- package/dist/logger-MKYH4UDV.js.map +1 -0
- package/dist/mcp/chunk-6SDFJ42P.js +62 -0
- package/dist/mcp/chunk-6SDFJ42P.js.map +1 -0
- package/dist/mcp/claude-YHHHLSXH.js +249 -0
- package/dist/mcp/claude-YHHHLSXH.js.map +1 -0
- package/dist/mcp/color-QS5BFCNN.js +168 -0
- package/dist/mcp/color-QS5BFCNN.js.map +1 -0
- package/dist/mcp/github-comment-server.js +165 -0
- package/dist/mcp/github-comment-server.js.map +1 -0
- package/dist/mcp/terminal-SDCMDVD7.js +202 -0
- package/dist/mcp/terminal-SDCMDVD7.js.map +1 -0
- package/dist/open-X6BTENPV.js +278 -0
- package/dist/open-X6BTENPV.js.map +1 -0
- package/dist/prompt-ANTQWHUF.js +13 -0
- package/dist/prompt-ANTQWHUF.js.map +1 -0
- package/dist/prompts/issue-prompt.txt +230 -0
- package/dist/prompts/pr-prompt.txt +35 -0
- package/dist/prompts/regular-prompt.txt +14 -0
- package/dist/run-2JCPQAX3.js +278 -0
- package/dist/run-2JCPQAX3.js.map +1 -0
- package/dist/schema/settings.schema.json +221 -0
- package/dist/start-LWVRBJ6S.js +982 -0
- package/dist/start-LWVRBJ6S.js.map +1 -0
- package/dist/terminal-3D6TUAKJ.js +16 -0
- package/dist/terminal-3D6TUAKJ.js.map +1 -0
- package/dist/test-git-XPF4SZXJ.js +52 -0
- package/dist/test-git-XPF4SZXJ.js.map +1 -0
- package/dist/test-prefix-XGFXFAYN.js +68 -0
- package/dist/test-prefix-XGFXFAYN.js.map +1 -0
- package/dist/test-tabs-JRKY3QMM.js +69 -0
- package/dist/test-tabs-JRKY3QMM.js.map +1 -0
- package/dist/test-webserver-M2I3EV4J.js +62 -0
- package/dist/test-webserver-M2I3EV4J.js.map +1 -0
- package/dist/update-3ZT2XX2G.js +79 -0
- package/dist/update-3ZT2XX2G.js.map +1 -0
- package/dist/update-notifier-QSSEB5KC.js +11 -0
- package/dist/update-notifier-QSSEB5KC.js.map +1 -0
- package/package.json +113 -0
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/utils/package-info.ts"],"sourcesContent":["import { program, Command, Option } from 'commander'\nimport { logger } from './utils/logger.js'\nimport { GitWorktreeManager } from './lib/GitWorktreeManager.js'\nimport { ShellCompletion } from './lib/ShellCompletion.js'\nimport type { StartOptions, CleanupOptions, FinishOptions } from './types/index.js'\nimport { getPackageInfo } from './utils/package-info.js'\nimport { fileURLToPath } from 'url'\n\n// Get package.json for version\nconst __filename = fileURLToPath(import.meta.url)\nconst packageJson = getPackageInfo(__filename)\n\nprogram\n .name('iloom')\n .description(packageJson.description)\n .version(packageJson.version)\n .option('--debug', 'Enable debug output (default: based on ILOOM_DEBUG env var)')\n .option('--completion', 'Output shell completion script for current shell')\n .option('--set <key=value>', 'Override any setting using dot notation (repeatable, e.g., --set workflows.issue.startIde=false)')\n .allowUnknownOption() // Allow --set to be used multiple times\n .hook('preAction', async (thisCommand) => {\n // Set debug mode based on flag or environment variable\n const options = thisCommand.opts()\n // Default to environment variable value, then false if not set\n const envDebug = process.env.ILOOM_DEBUG === 'true'\n const debugEnabled = options.debug !== undefined ? options.debug : envDebug\n logger.setDebug(debugEnabled)\n\n // Handle --completion flag\n if (options.completion) {\n const shellCompletion = new ShellCompletion()\n shellCompletion.printCompletionScript()\n process.exit(0)\n }\n\n // Check for updates before command execution for global installations\n try {\n const { checkAndNotifyUpdate } = await import('./utils/update-notifier.js')\n const { detectInstallationMethod } = await import('./utils/installation-detector.js')\n\n // Detect installation method\n const installMethod = detectInstallationMethod(__filename)\n\n // Check and notify (non-blocking, all errors handled internally)\n await checkAndNotifyUpdate(packageJson.version, packageJson.name, installMethod)\n } catch {\n // Silently fail - update check should never break user experience\n }\n\n // Migrate legacy .hatchbox settings to .iloom (BEFORE settings validation)\n try {\n const { SettingsMigrationManager } = await import('./lib/SettingsMigrationManager.js')\n const migrationManager = new SettingsMigrationManager()\n await migrationManager.migrateSettingsIfNeeded()\n } catch (error) {\n // Log warning but don't fail - migration is best-effort\n logger.debug(`Settings migration failed: ${error instanceof Error ? error.message : 'Unknown'}`)\n }\n\n // Validate settings for all commands\n await validateSettingsForCommand()\n })\n\n// Helper function to validate settings at startup\nasync function validateSettingsForCommand(): Promise<void> {\n try {\n const { SettingsManager } = await import('./lib/SettingsManager.js')\n const settingsManager = new SettingsManager()\n\n // Attempt to load settings - this will throw on validation errors\n // Missing file is OK (returns {})\n await settingsManager.loadSettings()\n } catch (error) {\n logger.error(`Configuration error: ${error instanceof Error ? error.message : 'Unknown error'}`)\n logger.info('Please fix your .iloom/settings.json file and try again.')\n process.exit(1)\n }\n}\n\n// Initialize shell completion (must be after program setup, before parseAsync)\nconst shellCompletion = new ShellCompletion()\nshellCompletion.init()\n\nprogram\n .command('start')\n .alias('create')\n .alias('up')\n .description('Create isolated workspace for an issue/PR')\n .argument('[identifier]', 'Issue number, PR number, or branch name (optional - will prompt if not provided)')\n .option('--claude', 'Enable Claude integration (default: true)')\n .option('--no-claude', 'Disable Claude integration')\n .option('--code', 'Enable VSCode (default: true)')\n .option('--no-code', 'Disable VSCode')\n .option('--dev-server', 'Enable dev server in terminal (default: true)')\n .option('--no-dev-server', 'Disable dev server')\n .option('--terminal', 'Enable terminal without dev server (default: false)')\n .option('--no-terminal', 'Disable terminal')\n .addOption(\n new Option('--one-shot <mode>', 'One-shot automation mode')\n .choices(['default', 'noReview', 'bypassPermissions'])\n .default('default')\n )\n .action(async (identifier: string | undefined, options: StartOptions) => {\n try {\n let finalIdentifier = identifier\n\n // Interactive prompting when no identifier provided\n if (!finalIdentifier) {\n const { promptInput } = await import('./utils/prompt.js')\n finalIdentifier = await promptInput('Enter issue number, PR number (pr/123), or branch name')\n\n // Validate non-empty after prompting\n if (!finalIdentifier?.trim()) {\n logger.error('Identifier is required')\n process.exit(1)\n }\n }\n\n const { StartCommand } = await import('./commands/start.js')\n const command = new StartCommand()\n await command.execute({ identifier: finalIdentifier, options })\n } catch (error) {\n logger.error(`Failed to start workspace: ${error instanceof Error ? error.message : 'Unknown error'}`)\n process.exit(1)\n }\n })\n\nprogram\n .command('add-issue')\n .alias('a')\n .description('Create and enhance GitHub issue without starting workspace')\n .argument('<description>', 'Natural language description of the issue (>50 chars, >2 spaces)')\n .action(async (description: string) => {\n try {\n const { AddIssueCommand } = await import('./commands/add-issue.js')\n const command = new AddIssueCommand()\n const issueNumber = await command.execute({\n description,\n options: {}\n })\n logger.success(`Issue #${issueNumber} created successfully`)\n process.exit(0)\n } catch (error) {\n logger.error(`Failed to create issue: ${error instanceof Error ? error.message : 'Unknown error'}`)\n process.exit(1)\n }\n })\n\nprogram\n .command('feedback')\n .alias('f')\n .description('Submit feedback/bug report to iloom-cli repository')\n .argument('<description>', 'Natural language description of feedback (>50 chars, >2 spaces)')\n .action(async (description: string) => {\n try {\n const { FeedbackCommand } = await import('./commands/feedback.js')\n const command = new FeedbackCommand()\n const issueNumber = await command.execute({\n description,\n options: {}\n })\n logger.success(`Feedback submitted as issue #${issueNumber} in iloom-cli repository`)\n process.exit(0)\n } catch (error) {\n logger.error(`Failed to submit feedback: ${error instanceof Error ? error.message : 'Unknown error'}`)\n process.exit(1)\n }\n })\n\nprogram\n .command('enhance')\n .description('Apply enhancement agent to existing GitHub issue')\n .argument('<issue-number>', 'GitHub issue number to enhance', parseInt)\n .option('--no-browser', 'Skip browser opening prompt')\n .option('--author <username>', 'GitHub username to tag in questions (for CI usage)')\n .action(async (issueNumber: number, options: { browser?: boolean; author?: string }) => {\n try {\n const { EnhanceCommand } = await import('./commands/enhance.js')\n const command = new EnhanceCommand()\n await command.execute({\n issueNumber,\n options: {\n noBrowser: options.browser === false,\n ...(options.author && { author: options.author })\n }\n })\n logger.success(`Enhancement process completed for issue #${issueNumber}`)\n process.exit(0)\n } catch (error) {\n logger.error(`Failed to enhance issue: ${error instanceof Error ? error.message : 'Unknown error'}`)\n process.exit(1)\n }\n })\n\nprogram\n .command('finish')\n .alias('dn')\n .description('Merge work and cleanup workspace')\n .argument('[identifier]', 'Issue number, PR number, or branch name (auto-detected if omitted)')\n .option('-f, --force', 'Skip confirmation prompts')\n .option('-n, --dry-run', 'Preview actions without executing')\n .option('--pr <number>', 'Treat input as PR number', parseFloat)\n .option('--skip-build', 'Skip post-merge build verification')\n .action(async (identifier: string | undefined, options: FinishOptions) => {\n try {\n const { FinishCommand } = await import('./commands/finish.js')\n const command = new FinishCommand()\n await command.execute({ identifier, options })\n } catch (error) {\n logger.error(`Failed to finish workspace: ${error instanceof Error ? error.message : 'Unknown error'}`)\n process.exit(1)\n }\n })\n\nprogram\n .command('spin')\n .alias('ignite')\n .description('Launch Claude with auto-detected workspace context')\n .addOption(\n new Option('--one-shot <mode>', 'One-shot automation mode')\n .choices(['default', 'noReview', 'bypassPermissions'])\n .default('default')\n )\n .action(async (options: { oneShot?: import('./types/index.js').OneShotMode }) => {\n try {\n const { IgniteCommand } = await import('./commands/ignite.js')\n const command = new IgniteCommand()\n await command.execute(options.oneShot ?? 'default')\n } catch (error) {\n logger.error(`Failed to spin up loom: ${error instanceof Error ? error.message : 'Unknown error'}`)\n process.exit(1)\n }\n })\n\nprogram\n .command('open')\n .description('Open workspace in browser or run CLI tool')\n .argument('[identifier]', 'Issue number, PR number, or branch name (auto-detected if omitted)')\n .allowUnknownOption()\n .action(async (identifier?: string, _options?: Record<string, unknown>, command?: Command) => {\n try {\n // Extract additional arguments - everything after identifier\n const args = command?.args ? command.args.slice(identifier ? 1 : 0) : []\n\n const { OpenCommand } = await import('./commands/open.js')\n const cmd = new OpenCommand()\n const input = identifier ? { identifier, args } : { args }\n await cmd.execute(input)\n } catch (error) {\n logger.error(`Failed to open: ${error instanceof Error ? error.message : 'Unknown error'}`)\n process.exit(1)\n }\n })\n\nprogram\n .command('run')\n .description('Run CLI tool or open workspace in browser')\n .argument('[identifier]', 'Issue number, PR number, or branch name (auto-detected if omitted)')\n .allowUnknownOption()\n .action(async (identifier?: string, _options?: Record<string, unknown>, command?: Command) => {\n try {\n // Extract additional arguments - everything after identifier\n const args = command?.args ? command.args.slice(identifier ? 1 : 0) : []\n\n const { RunCommand } = await import('./commands/run.js')\n const cmd = new RunCommand()\n const input = identifier ? { identifier, args } : { args }\n await cmd.execute(input)\n } catch (error) {\n logger.error(`Failed to run: ${error instanceof Error ? error.message : 'Unknown error'}`)\n process.exit(1)\n }\n })\n\nprogram\n .command('cleanup')\n .description('Remove workspaces')\n .argument('[identifier]', 'Branch name or issue number to cleanup (auto-detected)')\n .option('-l, --list', 'List all worktrees')\n .option('-a, --all', 'Remove all worktrees (interactive confirmation)')\n .option('-i, --issue <number>', 'Cleanup by issue number', parseInt)\n .option('-f, --force', 'Skip confirmations and force removal')\n .option('--dry-run', 'Show what would be done without doing it')\n .action(async (identifier?: string, options?: CleanupOptions) => {\n try {\n const { CleanupCommand } = await import('./commands/cleanup.js')\n const command = new CleanupCommand()\n const input: { identifier?: string; options: CleanupOptions } = {\n options: options ?? {}\n }\n if (identifier) {\n input.identifier = identifier\n }\n await command.execute(input)\n } catch (error) {\n logger.error(`Failed to cleanup worktrees: ${error instanceof Error ? error.message : 'Unknown error'}`)\n process.exit(1)\n }\n })\n\nprogram\n .command('list')\n .description('Show active workspaces')\n .option('--json', 'Output as JSON')\n .action(async (options: { json?: boolean }) => {\n try {\n const manager = new GitWorktreeManager()\n const worktrees = await manager.listWorktrees({ porcelain: true })\n\n if (options.json) {\n console.log(JSON.stringify(worktrees, null, 2))\n return\n }\n\n if (worktrees.length === 0) {\n logger.info('No worktrees found')\n return\n }\n\n logger.info('Active workspaces:')\n for (const worktree of worktrees) {\n const formatted = manager.formatWorktree(worktree)\n logger.info(` ${formatted.title}`)\n logger.info(` Path: ${formatted.path}`)\n logger.info(` Commit: ${formatted.commit}`)\n }\n } catch (error) {\n logger.error(`Failed to list worktrees: ${error instanceof Error ? error.message : 'Unknown error'}`)\n process.exit(1)\n }\n })\n\n\nprogram\n .command('init')\n .description('Initialize iloom configuration and setup shell autocomplete')\n .action(async () => {\n try {\n const { InitCommand } = await import('./commands/init.js')\n const command = new InitCommand()\n await command.execute()\n } catch (error) {\n logger.error(`Failed to initialize: ${error instanceof Error ? error.message : 'Unknown error'}`)\n process.exit(1)\n }\n })\n\nprogram\n .command('update')\n .description('Update iloom-cli to the latest version')\n .option('--dry-run', 'Show what would be done without actually updating')\n .action(async (options: { dryRun?: boolean }) => {\n try {\n const { UpdateCommand } = await import('./commands/update.js')\n const command = new UpdateCommand()\n await command.execute(options)\n } catch (error) {\n logger.error(`Failed to update: ${error instanceof Error ? error.message : 'Unknown error'}`)\n process.exit(1)\n }\n })\n\n// Test command for GitHub integration\nprogram\n .command('test-github')\n .description('Test GitHub integration (Issue #3)')\n .argument('<identifier>', 'Issue number or PR number')\n .option('--no-claude', 'Skip Claude for branch name generation')\n .action(async (identifier: string, options: { claude?: boolean }) => {\n try {\n const { GitHubService } = await import('./lib/GitHubService.js')\n\n logger.info('Testing GitHub Integration\\n')\n\n const service = new GitHubService(options.claude !== undefined ? { useClaude: options.claude } : {})\n\n // Test 1: Input detection\n logger.info('Detecting input type...')\n const detection = await service.detectInputType(identifier)\n logger.info(` Type: ${detection.type}`)\n logger.info(` Number: ${detection.number}`) \n\n if (detection.type === 'unknown') {\n logger.error('Could not detect if input is an issue or PR')\n process.exit(1)\n }\n\n // Test 2: Fetch the issue/PR\n logger.info('Fetching from GitHub...')\n if (detection.type === 'issue') {\n if (!detection.number) {\n throw new Error('Issue number not detected')\n }\n const issue = await service.fetchIssue(detection.number)\n logger.success(` Issue #${issue.number}: ${issue.title}`)\n logger.info(` State: ${issue.state}`)\n logger.info(` Labels: ${issue.labels.join(', ') || 'none'}`)\n logger.info(` URL: ${issue.url}`)\n\n // Test 3: Generate branch name\n \n logger.info('Generating branch name...')\n const branchName = await service.generateBranchName({\n issueNumber: issue.number,\n title: issue.title\n })\n logger.success(` Branch: ${branchName}`)\n\n // Test 4: Extract context\n \n logger.info('Extracting context for Claude...')\n const context = service.extractContext(issue)\n logger.info(` ${context.split('\\n').join('\\n ')}`)\n\n } else {\n if (!detection.number) {\n throw new Error('PR number not detected')\n }\n const pr = await service.fetchPR(detection.number)\n logger.success(` PR #${pr.number}: ${pr.title}`)\n logger.info(` State: ${pr.state}`)\n logger.info(` Branch: ${pr.branch}`)\n logger.info(` Base: ${pr.baseBranch}`)\n logger.info(` URL: ${pr.url}`)\n\n // Test 3: Extract context\n \n logger.info('Extracting context for Claude...')\n const context = service.extractContext(pr)\n logger.info(` ${context.split('\\n').join('\\n ')}`)\n }\n\n \n logger.success('All GitHub integration tests passed!')\n\n } catch (error) {\n logger.error(`Test failed: ${error instanceof Error ? error.message : 'Unknown error'}`)\n if (error instanceof Error && error.stack) {\n logger.debug(error.stack)\n }\n process.exit(1)\n }\n })\n\n// Test command for Claude integration\nprogram\n .command('test-claude')\n .description('Test Claude integration (Issue #10)')\n .option('--detect', 'Test Claude CLI detection')\n .option('--version', 'Get Claude CLI version')\n .option('--branch <title>', 'Test branch name generation with given title')\n .option('--issue <number>', 'Issue number for branch generation', '123')\n .option('--launch <prompt>', 'Launch Claude with a prompt (headless)')\n .option('--interactive', 'Launch Claude interactively (requires --launch)')\n .option('--template <name>', 'Test template loading')\n .action(async (options: {\n detect?: boolean\n version?: boolean\n branch?: string\n issue?: string\n launch?: string\n interactive?: boolean\n template?: 'issue' | 'pr' | 'regular'\n }) => {\n try {\n const { detectClaudeCli, getClaudeVersion, generateBranchName, launchClaude } = await import('./utils/claude.js')\n const { PromptTemplateManager } = await import('./lib/PromptTemplateManager.js')\n const { ClaudeService } = await import('./lib/ClaudeService.js')\n const { ClaudeContextManager } = await import('./lib/ClaudeContextManager.js')\n\n logger.info('Testing Claude Integration\\n')\n\n // Test 1: Detection\n if (options.detect) {\n logger.info('Detecting Claude CLI...')\n const isAvailable = await detectClaudeCli()\n if (isAvailable) {\n logger.success(' Claude CLI is available')\n } else {\n logger.error(' Claude CLI not found')\n }\n }\n\n // Test 2: Version\n if (options.version) {\n logger.info('Getting Claude version...')\n const version = await getClaudeVersion()\n if (version) {\n logger.success(` Version: ${version}`)\n } else {\n logger.error(' Could not get version')\n }\n }\n\n // Test 3: Branch name generation\n if (options.branch) {\n logger.info('Generating branch name...')\n const issueNumber = parseInt(options.issue ?? '123')\n logger.info(` Issue #${issueNumber}: ${options.branch}`)\n const branchName = await generateBranchName(options.branch, issueNumber)\n logger.success(` Generated: ${branchName}`)\n }\n\n // Test 4: Launch Claude\n if (options.launch) {\n logger.info('Launching Claude...')\n logger.info(` Prompt: \"${options.launch}\"`)\n logger.info(` Mode: ${options.interactive ? 'Interactive' : 'Headless'}`)\n\n if (options.interactive) {\n logger.info(' Launching Claude in new terminal...')\n await launchClaude(options.launch, { headless: false })\n logger.info(' (Claude should open in a separate process)')\n } else {\n logger.info(' Waiting for response...')\n const result = await launchClaude(options.launch, { headless: true })\n if (result) {\n logger.success(' Response:')\n logger.info(` ${result.split('\\n').join('\\n ')}`)\n }\n }\n }\n\n // Test 5: Template loading\n if (options.template) {\n logger.info('Loading template...')\n logger.info(` Template: ${options.template}`)\n const manager = new PromptTemplateManager()\n try {\n const content = await manager.loadTemplate(options.template)\n logger.success(' Template loaded successfully')\n logger.info(' First 200 chars:')\n logger.info(` ${content.substring(0, 200).split('\\n').join('\\n ')}...`)\n } catch (error) {\n logger.error(` Failed: ${error instanceof Error ? error.message : 'Unknown error'}`)\n }\n }\n\n // Run all tests in sequence when no specific options provided\n if (!options.detect && !options.version && !options.branch && !options.launch && !options.template) {\n logger.info('Running full Claude integration test suite...\\n')\n\n // Test 1: Detection\n logger.info('1. Testing Claude CLI detection...')\n const isAvailable = await detectClaudeCli()\n if (isAvailable) {\n logger.success(' Claude CLI is available')\n } else {\n logger.error(' Claude CLI not found')\n logger.info('\\nSkipping remaining tests since Claude CLI is not available')\n return\n }\n\n // Test 2: Version\n logger.info('\\n2. Getting Claude version...')\n const version = await getClaudeVersion()\n if (version) {\n logger.success(` Version: ${version}`)\n } else {\n logger.error(' Could not get version')\n }\n\n // Test 3: Branch name generation\n logger.info('\\n3. Testing branch name generation...')\n const testIssueNumber = 123\n const testTitle = 'Add user authentication feature'\n logger.info(` Issue #${testIssueNumber}: ${testTitle}`)\n const branchName = await generateBranchName(testTitle, testIssueNumber)\n logger.success(` Generated: ${branchName}`)\n\n // Test 4: Service initialization\n logger.info('\\n4. Testing ClaudeService initialization...')\n new ClaudeService() // Just verify it can be instantiated\n logger.success(' Service initialized')\n\n // Test 5: Context manager\n logger.info('\\n5. Testing ClaudeContextManager...')\n const contextManager = new ClaudeContextManager()\n await contextManager.prepareContext({\n type: 'issue',\n identifier: 123,\n title: 'Test issue',\n workspacePath: process.cwd(),\n port: 3123\n })\n logger.success(' Context prepared')\n\n // Test 6: Template loading\n logger.info('\\n6. Testing template loading...')\n const templateManager = new PromptTemplateManager()\n const templates: Array<'issue' | 'pr' | 'regular'> = ['issue', 'pr', 'regular']\n let templateCount = 0\n for (const template of templates) {\n try {\n await templateManager.loadTemplate(template)\n logger.success(` ${template} template loaded`)\n templateCount++\n } catch {\n logger.warn(` ${template} template not found`)\n }\n }\n logger.info(` Loaded ${templateCount}/${templates.length} templates`)\n\n // Test 7: Launch Claude headless (quick test)\n logger.info('\\n7. Testing Claude launch (headless)...')\n logger.info(' Sending test prompt: \"Say hello\"')\n try {\n const result = await launchClaude('Say hello', { headless: true })\n if (result) {\n logger.success(' Claude responded successfully')\n logger.info(` Response preview: ${result.substring(0, 100)}...`)\n } else {\n logger.warn(' No response received')\n }\n } catch (error) {\n logger.error(` Launch failed: ${error instanceof Error ? error.message : 'Unknown error'}`)\n }\n\n logger.info('\\n' + '='.repeat(50))\n logger.success('All Claude integration tests complete!')\n logger.info('Summary: All core Claude features are working correctly')\n }\n\n } catch (error) {\n logger.error(`Test failed: ${error instanceof Error ? error.message : 'Unknown error'}`)\n if (error instanceof Error && error.stack) {\n logger.debug(error.stack)\n }\n process.exit(1)\n }\n })\n\n// Test command for webserver detection\nprogram\n .command('test-webserver')\n .description('Test if a web server is running on a workspace port')\n .argument('<issue-number>', 'Issue number (port will be calculated as 3000 + issue number)', parseInt)\n .option('--kill', 'Kill the web server if detected')\n .action(async (issueNumber: number, options: { kill?: boolean }) => {\n try {\n const { TestWebserverCommand } = await import('./commands/test-webserver.js')\n const command = new TestWebserverCommand()\n await command.execute({ issueNumber, options })\n } catch (error) {\n logger.error(`Test webserver failed: ${error instanceof Error ? error.message : 'Unknown error'}`)\n if (error instanceof Error && error.stack) {\n logger.debug(error.stack)\n }\n process.exit(1)\n }\n })\n\n// Test command for Git integration\nprogram\n .command('test-git')\n .description('Test Git integration - findMainWorktreePath() function (reads .iloom/settings.json)')\n .action(async () => {\n try {\n const { TestGitCommand } = await import('./commands/test-git.js')\n const command = new TestGitCommand()\n await command.execute()\n } catch (error) {\n logger.error(`Test git failed: ${error instanceof Error ? error.message : 'Unknown error'}`)\n if (error instanceof Error && error.stack) {\n logger.debug(error.stack)\n }\n process.exit(1)\n }\n })\n\n// Test command for iTerm2 dual tab functionality\nprogram\n .command('test-tabs')\n .description('Test iTerm2 dual tab functionality - opens two tabs with test commands')\n .action(async () => {\n try {\n const { TestTabsCommand } = await import('./commands/test-tabs.js')\n const command = new TestTabsCommand()\n await command.execute()\n } catch (error) {\n logger.error(`Test tabs failed: ${error instanceof Error ? error.message : 'Unknown error'}`)\n if (error instanceof Error && error.stack) {\n logger.debug(error.stack)\n }\n process.exit(1)\n }\n })\n\n// Test command for worktree prefix configuration\nprogram\n .command('test-prefix')\n .description('Test worktree prefix configuration - preview worktree paths (reads .iloom/settings.json)')\n .action(async () => {\n try {\n const { TestPrefixCommand } = await import('./commands/test-prefix.js')\n const command = new TestPrefixCommand()\n await command.execute()\n } catch (error) {\n logger.error(`Test prefix failed: ${error instanceof Error ? error.message : 'Unknown error'}`)\n if (error instanceof Error && error.stack) {\n logger.debug(error.stack)\n }\n process.exit(1)\n }\n })\n\n// Test command for Neon integration\nprogram\n .command('test-neon')\n .description('Test Neon integration and debug configuration')\n .action(async () => {\n try {\n const { NeonProvider } = await import('./lib/providers/NeonProvider.js')\n const { loadEnvIntoProcess } = await import('./utils/env.js')\n\n logger.info('Testing Neon Integration\\n')\n\n // Load environment variables\n logger.info('0. Loading environment variables...')\n const envResult = loadEnvIntoProcess()\n if (envResult.error) {\n logger.warn(` Warning: ${envResult.error.message}`)\n }\n if (envResult.parsed) {\n logger.success(` Loaded ${Object.keys(envResult.parsed).length} environment variables`)\n } else {\n logger.info(' No .env files found or parsed')\n }\n\n // Test 1: Environment variables\n logger.info('\\n1. Environment Variables:')\n logger.info(` NEON_PROJECT_ID: ${process.env.NEON_PROJECT_ID ?? '(not set)'}`)\n logger.info(` NEON_PARENT_BRANCH: ${process.env.NEON_PARENT_BRANCH ?? '(not set)'}`)\n\n // Test 2: Create provider and test initialization\n logger.info('\\n2. Creating NeonProvider...')\n try {\n const neonProvider = new NeonProvider({\n projectId: process.env.NEON_PROJECT_ID ?? '',\n parentBranch: process.env.NEON_PARENT_BRANCH ?? '',\n })\n logger.success(' NeonProvider created successfully')\n\n // Test 3: CLI availability\n logger.info('\\n3. Testing Neon CLI availability...')\n const isAvailable = await neonProvider.isCliAvailable()\n if (isAvailable) {\n logger.success(' Neon CLI is available')\n } else {\n logger.error(' Neon CLI not found')\n logger.info(' Install with: npm install -g @neon/cli')\n return\n }\n\n // Test 4: Authentication\n logger.info('\\n4. Testing Neon CLI authentication...')\n const isAuthenticated = await neonProvider.isAuthenticated()\n if (isAuthenticated) {\n logger.success(' Neon CLI is authenticated')\n } else {\n logger.error(' Neon CLI not authenticated')\n logger.info(' Run: neon auth')\n return\n }\n\n // Test 5: List branches (if config is valid)\n if (process.env.NEON_PROJECT_ID) {\n logger.info('\\n5. Testing branch listing...')\n try {\n const branches = await neonProvider.listBranches()\n logger.success(` Found ${branches.length} branches:`)\n for (const branch of branches.slice(0, 5)) { // Show first 5\n logger.info(` - ${branch}`)\n }\n if (branches.length > 5) {\n logger.info(` ... and ${branches.length - 5} more`)\n }\n } catch (error) {\n logger.error(` Failed to list branches: ${error instanceof Error ? error.message : 'Unknown error'}`)\n }\n } else {\n logger.warn('\\n5. Skipping branch listing (NEON_PROJECT_ID not set)')\n }\n\n } catch (error) {\n logger.error(` Failed to create NeonProvider: ${error instanceof Error ? error.message : 'Unknown error'}`)\n if (error instanceof Error && error.message.includes('NEON_PROJECT_ID')) {\n logger.info('\\n This is expected if NEON_PROJECT_ID is not set.')\n logger.info(' Set NEON_PROJECT_ID and NEON_PARENT_BRANCH environment variables to test fully.')\n }\n }\n\n logger.info('\\n' + '='.repeat(50))\n logger.success('Neon integration test complete!')\n\n } catch (error) {\n logger.error(`Test failed: ${error instanceof Error ? error.message : 'Unknown error'}`)\n if (error instanceof Error && error.stack) {\n logger.debug(error.stack)\n }\n process.exit(1)\n }\n })\n\n// Add custom help command in order to get preAction to run (update check handled by preAction hook)\nprogram\n .command('help')\n .description('Display help information')\n .argument('[command]', 'Show help for specific command')\n .action(async (command?: string) => {\n // Show help (update check already ran in preAction)\n if (command) {\n // Show help for specific command\n const subCommand = program.commands.find(cmd => cmd.name() === command)\n if (subCommand) {\n subCommand.outputHelp()\n } else {\n logger.error(`Unknown command: ${command}`)\n program.outputHelp()\n }\n } else {\n program.outputHelp()\n }\n\n process.exit(0)\n })\n\n// Parse CLI arguments\ntry {\n await program.parseAsync()\n} catch (error) {\n if (error instanceof Error) {\n logger.error(`Error: ${error.message}`)\n process.exit(1)\n }\n}\n","import { readFileSync } from 'fs'\nimport { fileURLToPath } from 'url'\nimport { dirname, join } from 'path'\n\n/**\n * Package information from package.json\n */\nexport interface PackageInfo {\n name: string\n version: string\n description: string\n [key: string]: unknown\n}\n\n/**\n * Get package.json information\n *\n * @param scriptPath - Optional path to use for finding package.json (defaults to current file location)\n * @returns Parsed package.json contents\n * @throws Error if package.json cannot be read or parsed\n */\nexport function getPackageInfo(scriptPath?: string): PackageInfo {\n try {\n // Determine the base path to use\n let basePath: string\n if (scriptPath) {\n basePath = scriptPath\n } else {\n // Use import.meta.url to get the current file path\n const __filename = fileURLToPath(import.meta.url)\n basePath = __filename\n }\n\n // Navigate from current file to package.json\n // The compiled CLI runs from dist/cli.js, so we need dist/../package.json (one level up)\n const __dirname = dirname(basePath)\n const packageJsonPath = join(__dirname, '..', 'package.json')\n\n // Read and parse package.json\n const packageJsonContent = readFileSync(packageJsonPath, 'utf8')\n const packageJson = JSON.parse(packageJsonContent) as PackageInfo\n\n return packageJson\n } catch (error) {\n throw new Error(\n `Failed to read package.json: ${error instanceof Error ? error.message : 'Unknown error'}`\n )\n }\n}\n"],"mappings":"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","names":["__filename","packageJson","fileURLToPath","shellCompletion"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
calculateForegroundColor,
|
|
4
|
+
generateColorFromBranchName,
|
|
5
|
+
getColorPalette,
|
|
6
|
+
hexToRgb,
|
|
7
|
+
lightenColor,
|
|
8
|
+
rgbToHex,
|
|
9
|
+
saturateColor
|
|
10
|
+
} from "./chunk-ZZZWQGTS.js";
|
|
11
|
+
import "./chunk-GEHQXLEI.js";
|
|
12
|
+
export {
|
|
13
|
+
calculateForegroundColor,
|
|
14
|
+
generateColorFromBranchName,
|
|
15
|
+
getColorPalette,
|
|
16
|
+
hexToRgb,
|
|
17
|
+
lightenColor,
|
|
18
|
+
rgbToHex,
|
|
19
|
+
saturateColor
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=color-ZVALX37U.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
generateGitHubCommentMcpConfig
|
|
4
|
+
} from "./chunk-SSR5AVRJ.js";
|
|
5
|
+
import {
|
|
6
|
+
AgentManager
|
|
7
|
+
} from "./chunk-OC4H6HJD.js";
|
|
8
|
+
import {
|
|
9
|
+
openBrowser
|
|
10
|
+
} from "./chunk-YETJNRQM.js";
|
|
11
|
+
import {
|
|
12
|
+
GitHubService
|
|
13
|
+
} from "./chunk-T7QPXANZ.js";
|
|
14
|
+
import "./chunk-KQDEK2ZW.js";
|
|
15
|
+
import {
|
|
16
|
+
launchClaude
|
|
17
|
+
} from "./chunk-PXZBAC2M.js";
|
|
18
|
+
import {
|
|
19
|
+
SettingsManager
|
|
20
|
+
} from "./chunk-JBH2ZYYZ.js";
|
|
21
|
+
import {
|
|
22
|
+
waitForKeypress
|
|
23
|
+
} from "./chunk-JNKJ7NJV.js";
|
|
24
|
+
import {
|
|
25
|
+
logger
|
|
26
|
+
} from "./chunk-GEHQXLEI.js";
|
|
27
|
+
|
|
28
|
+
// src/commands/enhance.ts
|
|
29
|
+
var EnhanceCommand = class {
|
|
30
|
+
constructor(gitHubService, agentManager, settingsManager) {
|
|
31
|
+
this.gitHubService = gitHubService ?? new GitHubService();
|
|
32
|
+
this.agentManager = agentManager ?? new AgentManager();
|
|
33
|
+
this.settingsManager = settingsManager ?? new SettingsManager();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Execute the enhance command workflow:
|
|
37
|
+
* 1. Validate issue number
|
|
38
|
+
* 2. Fetch issue to verify it exists
|
|
39
|
+
* 3. Load agent configurations
|
|
40
|
+
* 4. Invoke Claude CLI with enhancer agent
|
|
41
|
+
* 5. Parse response to determine outcome
|
|
42
|
+
* 6. Handle browser interaction based on outcome
|
|
43
|
+
*/
|
|
44
|
+
async execute(input) {
|
|
45
|
+
const { issueNumber, options } = input;
|
|
46
|
+
const { author } = options;
|
|
47
|
+
this.validateIssueNumber(issueNumber);
|
|
48
|
+
logger.info(`Fetching issue #${issueNumber}...`);
|
|
49
|
+
const issue = await this.gitHubService.fetchIssue(issueNumber);
|
|
50
|
+
logger.debug("Issue fetched successfully", { number: issue.number, title: issue.title });
|
|
51
|
+
logger.debug("Loading agent configurations...");
|
|
52
|
+
const settings = await this.settingsManager.loadSettings();
|
|
53
|
+
const loadedAgents = await this.agentManager.loadAgents(settings);
|
|
54
|
+
const agents = this.agentManager.formatForCli(loadedAgents);
|
|
55
|
+
let mcpConfig;
|
|
56
|
+
let allowedTools;
|
|
57
|
+
let disallowedTools;
|
|
58
|
+
try {
|
|
59
|
+
mcpConfig = await generateGitHubCommentMcpConfig("issue");
|
|
60
|
+
logger.debug("Generated MCP configuration for GitHub comment broker");
|
|
61
|
+
allowedTools = [
|
|
62
|
+
"mcp__github_comment__create_comment",
|
|
63
|
+
"mcp__github_comment__update_comment"
|
|
64
|
+
];
|
|
65
|
+
disallowedTools = ["Bash(gh api:*)"];
|
|
66
|
+
logger.debug("Configured tool filtering for issue workflow", { allowedTools, disallowedTools });
|
|
67
|
+
} catch (error) {
|
|
68
|
+
logger.warn(`Failed to generate MCP config: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
69
|
+
}
|
|
70
|
+
logger.info("Invoking enhancer agent. This may take a moment...");
|
|
71
|
+
const prompt = this.constructPrompt(issueNumber, author);
|
|
72
|
+
const response = await launchClaude(prompt, {
|
|
73
|
+
headless: true,
|
|
74
|
+
model: "sonnet",
|
|
75
|
+
agents,
|
|
76
|
+
...mcpConfig && { mcpConfig },
|
|
77
|
+
...allowedTools && { allowedTools },
|
|
78
|
+
...disallowedTools && { disallowedTools }
|
|
79
|
+
});
|
|
80
|
+
const result = this.parseEnhancerResponse(response);
|
|
81
|
+
if (!result.enhanced) {
|
|
82
|
+
logger.success("Issue already has thorough description. No enhancement needed.");
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
logger.success(`Issue #${issueNumber} enhanced successfully!`);
|
|
86
|
+
logger.info(`Enhanced specification available at: ${result.url}`);
|
|
87
|
+
if (!options.noBrowser && result.url) {
|
|
88
|
+
await this.promptAndOpenBrowser(result.url);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Validate that issue number is a valid positive integer
|
|
93
|
+
*/
|
|
94
|
+
validateIssueNumber(issueNumber) {
|
|
95
|
+
if (issueNumber === void 0 || issueNumber === null) {
|
|
96
|
+
throw new Error("Issue number is required");
|
|
97
|
+
}
|
|
98
|
+
if (typeof issueNumber !== "number" || Number.isNaN(issueNumber) || issueNumber <= 0 || !Number.isInteger(issueNumber)) {
|
|
99
|
+
throw new Error("Issue number must be a valid positive integer");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Construct the prompt for the orchestrating Claude instance.
|
|
104
|
+
* This prompt is very clear about expected output format to ensure reliable parsing.
|
|
105
|
+
*/
|
|
106
|
+
constructPrompt(issueNumber, author) {
|
|
107
|
+
const authorInstruction = author ? `
|
|
108
|
+
IMPORTANT: When you create your analysis comment, tag @${author} in the "Questions for Reporter" section if you have questions.
|
|
109
|
+
` : "";
|
|
110
|
+
return `Execute @agent-iloom-issue-enhancer ${issueNumber}${authorInstruction}
|
|
111
|
+
|
|
112
|
+
## OUTPUT REQUIREMENTS
|
|
113
|
+
* If the issue was not enhanced, return ONLY: "No enhancement needed"
|
|
114
|
+
* If the issue WAS enhanced, return ONLY: <FULL URL OF THE COMMENT INCLUDING COMMENT ID>
|
|
115
|
+
* If you encounter permission/authentication/access errors, return ONLY: "Permission denied: <specific error description>"
|
|
116
|
+
* IMPORTANT: Return ONLY one of the above - DO NOT include commentary such as "I created a comment at <URL>" or "I examined the issue and found no enhancement was necessary"
|
|
117
|
+
* CONTEXT: Your output is going to be parsed programmatically, so adherence to the output requirements is CRITICAL.`;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Parse the response from the enhancer agent.
|
|
121
|
+
* Returns either { enhanced: false } or { enhanced: true, url: "..." }
|
|
122
|
+
* Throws specific errors for permission issues.
|
|
123
|
+
*/
|
|
124
|
+
parseEnhancerResponse(response) {
|
|
125
|
+
if (!response || typeof response !== "string") {
|
|
126
|
+
throw new Error("No response from enhancer agent");
|
|
127
|
+
}
|
|
128
|
+
const trimmed = response.trim();
|
|
129
|
+
logger.debug(`RESPONSE FROM ENHANCER AGENT: '${trimmed}'`);
|
|
130
|
+
if (trimmed.toLowerCase().startsWith("permission denied:")) {
|
|
131
|
+
const errorMessage = trimmed.substring("permission denied:".length).trim();
|
|
132
|
+
throw new Error(`Permission denied: ${errorMessage}`);
|
|
133
|
+
}
|
|
134
|
+
if (trimmed.toLowerCase().includes("no enhancement needed")) {
|
|
135
|
+
return { enhanced: false };
|
|
136
|
+
}
|
|
137
|
+
const urlPattern = /https:\/\/github\.com\/[^/]+\/[^/]+\/issues\/\d+#issuecomment-\d+/;
|
|
138
|
+
const match = trimmed.match(urlPattern);
|
|
139
|
+
if (match) {
|
|
140
|
+
return { enhanced: true, url: match[0] };
|
|
141
|
+
}
|
|
142
|
+
throw new Error(`Unexpected response from enhancer agent: ${trimmed}`);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Prompt user and open browser to view enhanced issue.
|
|
146
|
+
* Matches the pattern from the issue specification.
|
|
147
|
+
*/
|
|
148
|
+
async promptAndOpenBrowser(commentUrl) {
|
|
149
|
+
try {
|
|
150
|
+
const key = await waitForKeypress(
|
|
151
|
+
"Press q to quit or any other key to view the enhanced issue in a web browser..."
|
|
152
|
+
);
|
|
153
|
+
if (key.toLowerCase() === "q") {
|
|
154
|
+
logger.info("Skipping browser opening");
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
await openBrowser(commentUrl);
|
|
158
|
+
} catch (error) {
|
|
159
|
+
logger.warn(`Failed to open browser: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
export {
|
|
164
|
+
EnhanceCommand
|
|
165
|
+
};
|
|
166
|
+
//# sourceMappingURL=enhance-XJIQHVPD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/enhance.ts"],"sourcesContent":["import type { GitHubService } from '../lib/GitHubService.js'\nimport type { AgentManager } from '../lib/AgentManager.js'\nimport type { SettingsManager } from '../lib/SettingsManager.js'\nimport { launchClaude } from '../utils/claude.js'\nimport { openBrowser } from '../utils/browser.js'\nimport { waitForKeypress } from '../utils/prompt.js'\nimport { logger } from '../utils/logger.js'\nimport { generateGitHubCommentMcpConfig } from '../utils/mcp.js'\nimport { GitHubService as DefaultGitHubService } from '../lib/GitHubService.js'\nimport { AgentManager as DefaultAgentManager } from '../lib/AgentManager.js'\nimport { SettingsManager as DefaultSettingsManager } from '../lib/SettingsManager.js'\n\nexport interface EnhanceCommandInput {\n\tissueNumber: number\n\toptions: EnhanceOptions\n}\n\nexport interface EnhanceOptions {\n\tnoBrowser?: boolean // Skip browser opening prompt\n\tauthor?: string // GitHub username of issue author for tagging\n}\n\n/**\n * Command to enhance existing GitHub issues with AI assistance.\n * Applies the issue enhancer agent to an existing issue, respecting idempotency checks.\n */\nexport class EnhanceCommand {\n\tprivate gitHubService: GitHubService\n\tprivate agentManager: AgentManager\n\tprivate settingsManager: SettingsManager\n\n\tconstructor(\n\t\tgitHubService?: GitHubService,\n\t\tagentManager?: AgentManager,\n\t\tsettingsManager?: SettingsManager\n\t) {\n\t\t// Use provided services or create defaults\n\t\tthis.gitHubService = gitHubService ?? new DefaultGitHubService()\n\t\tthis.agentManager = agentManager ?? new DefaultAgentManager()\n\t\tthis.settingsManager = settingsManager ?? new DefaultSettingsManager()\n\t}\n\n\t/**\n\t * Execute the enhance command workflow:\n\t * 1. Validate issue number\n\t * 2. Fetch issue to verify it exists\n\t * 3. Load agent configurations\n\t * 4. Invoke Claude CLI with enhancer agent\n\t * 5. Parse response to determine outcome\n\t * 6. Handle browser interaction based on outcome\n\t */\n\tpublic async execute(input: EnhanceCommandInput): Promise<void> {\n\t\tconst { issueNumber, options } = input\n\t\tconst { author } = options\n\n\t\t// Step 1: Validate issue number\n\t\tthis.validateIssueNumber(issueNumber)\n\n\t\t// Step 2: Fetch issue to verify it exists\n\t\tlogger.info(`Fetching issue #${issueNumber}...`)\n\t\tconst issue = await this.gitHubService.fetchIssue(issueNumber)\n\t\tlogger.debug('Issue fetched successfully', { number: issue.number, title: issue.title })\n\n\t\t// Step 3: Load agent configurations\n\t\tlogger.debug('Loading agent configurations...')\n\t\tconst settings = await this.settingsManager.loadSettings()\n\t\tconst loadedAgents = await this.agentManager.loadAgents(settings)\n\t\tconst agents = this.agentManager.formatForCli(loadedAgents)\n\n\t\t// Step 3.5: Generate MCP config and tool filtering for GitHub comment broker\n\t\tlet mcpConfig: Record<string, unknown>[] | undefined\n\t\tlet allowedTools: string[] | undefined\n\t\tlet disallowedTools: string[] | undefined\n\n\t\ttry {\n\t\t\tmcpConfig = await generateGitHubCommentMcpConfig('issue')\n\t\t\tlogger.debug('Generated MCP configuration for GitHub comment broker')\n\n\t\t\t// Configure tool filtering for issue workflows\n\t\t\tallowedTools = [\n\t\t\t\t'mcp__github_comment__create_comment',\n\t\t\t\t'mcp__github_comment__update_comment',\n\t\t\t]\n\t\t\tdisallowedTools = ['Bash(gh api:*)']\n\n\t\t\tlogger.debug('Configured tool filtering for issue workflow', { allowedTools, disallowedTools })\n\t\t} catch (error) {\n\t\t\t// Log warning but continue without MCP\n\t\t\tlogger.warn(`Failed to generate MCP config: ${error instanceof Error ? error.message : 'Unknown error'}`)\n\t\t}\n\n\t\t// Step 4: Invoke Claude CLI with enhancer agent\n\t\tlogger.info('Invoking enhancer agent. This may take a moment...')\n\t\tconst prompt = this.constructPrompt(issueNumber, author)\n\t\tconst response = await launchClaude(prompt, {\n\t\t\theadless: true,\n\t\t\tmodel: 'sonnet',\n\t\t\tagents,\n\t\t\t...(mcpConfig && { mcpConfig }),\n\t\t\t...(allowedTools && { allowedTools }),\n\t\t\t...(disallowedTools && { disallowedTools }),\n\t\t})\n\n\t\t// Step 5: Parse response to determine outcome\n\t\tconst result = this.parseEnhancerResponse(response)\n\n\t\t// Step 6: Handle browser interaction based on outcome\n\t\tif (!result.enhanced) {\n\t\t\tlogger.success('Issue already has thorough description. No enhancement needed.')\n\t\t\treturn\n\t\t}\n\n\t\tlogger.success(`Issue #${issueNumber} enhanced successfully!`)\n\t\tlogger.info(`Enhanced specification available at: ${result.url}`)\n\n\t\t// Prompt to open browser (unless --no-browser flag is set)\n\t\tif (!options.noBrowser && result.url) {\n\t\t\tawait this.promptAndOpenBrowser(result.url)\n\t\t}\n\t}\n\n\t/**\n\t * Validate that issue number is a valid positive integer\n\t */\n\tprivate validateIssueNumber(issueNumber: number): void {\n\t\tif (issueNumber === undefined || issueNumber === null) {\n\t\t\tthrow new Error('Issue number is required')\n\t\t}\n\n\t\tif (typeof issueNumber !== 'number' || Number.isNaN(issueNumber) || issueNumber <= 0 || !Number.isInteger(issueNumber)) {\n\t\t\tthrow new Error('Issue number must be a valid positive integer')\n\t\t}\n\t}\n\n\t/**\n\t * Construct the prompt for the orchestrating Claude instance.\n\t * This prompt is very clear about expected output format to ensure reliable parsing.\n\t */\n\tprivate constructPrompt(issueNumber: number, author?: string): string {\n\t\tconst authorInstruction = author\n\t\t\t? `\\nIMPORTANT: When you create your analysis comment, tag @${author} in the \"Questions for Reporter\" section if you have questions.\\n`\n\t\t\t: ''\n\n\t\treturn `Execute @agent-iloom-issue-enhancer ${issueNumber}${authorInstruction}\n\n## OUTPUT REQUIREMENTS\n* If the issue was not enhanced, return ONLY: \"No enhancement needed\"\n* If the issue WAS enhanced, return ONLY: <FULL URL OF THE COMMENT INCLUDING COMMENT ID>\n* If you encounter permission/authentication/access errors, return ONLY: \"Permission denied: <specific error description>\"\n* IMPORTANT: Return ONLY one of the above - DO NOT include commentary such as \"I created a comment at <URL>\" or \"I examined the issue and found no enhancement was necessary\"\n* CONTEXT: Your output is going to be parsed programmatically, so adherence to the output requirements is CRITICAL.`\n\t}\n\n\t/**\n\t * Parse the response from the enhancer agent.\n\t * Returns either { enhanced: false } or { enhanced: true, url: \"...\" }\n\t * Throws specific errors for permission issues.\n\t */\n\tprivate parseEnhancerResponse(response: string | void): { enhanced: boolean; url?: string } {\n\t\t// Handle empty or void response\n\t\tif (!response || typeof response !== 'string') {\n\t\t\tthrow new Error('No response from enhancer agent')\n\t\t}\n\n\t\tconst trimmed = response.trim()\n\t\n\t\tlogger.debug(`RESPONSE FROM ENHANCER AGENT: '${trimmed}'`)\n\n\t\t// Check for permission denied errors (case-insensitive)\n\t\tif (trimmed.toLowerCase().startsWith('permission denied:')) {\n\t\t\tconst errorMessage = trimmed.substring('permission denied:'.length).trim()\n\t\t\tthrow new Error(`Permission denied: ${errorMessage}`)\n\t\t}\n\n\t\t// Check for \"No enhancement needed\" (case-insensitive)\n\t\tif (trimmed.toLowerCase().includes('no enhancement needed')) {\n\t\t\treturn { enhanced: false }\n\t\t}\n\n\t\t// Check if response looks like a GitHub comment URL\n\t\tconst urlPattern = /https:\\/\\/github\\.com\\/[^/]+\\/[^/]+\\/issues\\/\\d+#issuecomment-\\d+/\n\t\tconst match = trimmed.match(urlPattern)\n\n\t\tif (match) {\n\t\t\treturn { enhanced: true, url: match[0] }\n\t\t}\n\n\t\t// Unexpected response format\n\t\tthrow new Error(`Unexpected response from enhancer agent: ${trimmed}`)\n\t}\n\n\t/**\n\t * Prompt user and open browser to view enhanced issue.\n\t * Matches the pattern from the issue specification.\n\t */\n\tprivate async promptAndOpenBrowser(commentUrl: string): Promise<void> {\n\t\ttry {\n\t\t\t// Prompt user with custom message\n\t\t\tconst key = await waitForKeypress(\n\t\t\t\t'Press q to quit or any other key to view the enhanced issue in a web browser...'\n\t\t\t)\n\n\t\t\t// Check if user pressed 'q' to quit\n\t\t\tif (key.toLowerCase() === 'q') {\n\t\t\t\tlogger.info('Skipping browser opening')\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Open browser with comment URL\n\t\t\tawait openBrowser(commentUrl)\n\t\t} catch (error) {\n\t\t\t// Browser opening failures should not be fatal\n\t\t\tlogger.warn(`Failed to open browser: ${error instanceof Error ? error.message : 'Unknown error'}`)\n\t\t}\n\t}\n\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
extractPort,
|
|
4
|
+
formatEnvLine,
|
|
5
|
+
isValidEnvKey,
|
|
6
|
+
loadEnvIntoProcess,
|
|
7
|
+
loadWorkspaceEnv,
|
|
8
|
+
normalizeLineEndings,
|
|
9
|
+
parseEnvFile,
|
|
10
|
+
validateEnvVariable
|
|
11
|
+
} from "./chunk-SJUQ2NDR.js";
|
|
12
|
+
import "./chunk-GEHQXLEI.js";
|
|
13
|
+
export {
|
|
14
|
+
extractPort,
|
|
15
|
+
formatEnvLine,
|
|
16
|
+
isValidEnvKey,
|
|
17
|
+
loadEnvIntoProcess,
|
|
18
|
+
loadWorkspaceEnv,
|
|
19
|
+
normalizeLineEndings,
|
|
20
|
+
parseEnvFile,
|
|
21
|
+
validateEnvVariable
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=env-MDFL4ZXL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
IssueEnhancementService
|
|
4
|
+
} from "./chunk-PR7FKQBG.js";
|
|
5
|
+
import {
|
|
6
|
+
AgentManager
|
|
7
|
+
} from "./chunk-OC4H6HJD.js";
|
|
8
|
+
import "./chunk-YETJNRQM.js";
|
|
9
|
+
import {
|
|
10
|
+
ProjectCapabilityDetector
|
|
11
|
+
} from "./chunk-CWR2SANQ.js";
|
|
12
|
+
import "./chunk-2ZPFJQ3B.js";
|
|
13
|
+
import {
|
|
14
|
+
GitHubService
|
|
15
|
+
} from "./chunk-T7QPXANZ.js";
|
|
16
|
+
import "./chunk-KQDEK2ZW.js";
|
|
17
|
+
import {
|
|
18
|
+
getClaudeVersion
|
|
19
|
+
} from "./chunk-PXZBAC2M.js";
|
|
20
|
+
import {
|
|
21
|
+
SettingsManager
|
|
22
|
+
} from "./chunk-JBH2ZYYZ.js";
|
|
23
|
+
import "./chunk-JNKJ7NJV.js";
|
|
24
|
+
import {
|
|
25
|
+
logger
|
|
26
|
+
} from "./chunk-GEHQXLEI.js";
|
|
27
|
+
|
|
28
|
+
// src/utils/diagnostics.ts
|
|
29
|
+
import { readFile } from "fs/promises";
|
|
30
|
+
import { join, dirname } from "path";
|
|
31
|
+
import { fileURLToPath } from "url";
|
|
32
|
+
import { platform, release, arch } from "os";
|
|
33
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
34
|
+
var __dirname = dirname(__filename);
|
|
35
|
+
async function gatherDiagnosticInfo() {
|
|
36
|
+
const detector = new ProjectCapabilityDetector();
|
|
37
|
+
const { capabilities } = await detector.detectCapabilities(process.cwd());
|
|
38
|
+
const claudeVersion = await getClaudeVersion();
|
|
39
|
+
const diagnostics = {
|
|
40
|
+
cliVersion: await getCliVersion(),
|
|
41
|
+
nodeVersion: getNodeVersion(),
|
|
42
|
+
osType: getOsType(),
|
|
43
|
+
osVersion: getOsVersion(),
|
|
44
|
+
architecture: getArchitecture(),
|
|
45
|
+
capabilities,
|
|
46
|
+
claudeVersion
|
|
47
|
+
};
|
|
48
|
+
return diagnostics;
|
|
49
|
+
}
|
|
50
|
+
function formatDiagnosticsAsMarkdown(diagnostics, includeMarker = true) {
|
|
51
|
+
const marker = includeMarker ? `<!-- CLI GENERATED FEEDBACK v${diagnostics.cliVersion} -->
|
|
52
|
+
` : "";
|
|
53
|
+
const capabilitiesDisplay = diagnostics.capabilities.length > 0 ? diagnostics.capabilities.join(", ") : "none";
|
|
54
|
+
const claudeVersionDisplay = diagnostics.claudeVersion ?? "not available";
|
|
55
|
+
return `${marker}
|
|
56
|
+
<details>
|
|
57
|
+
<summary>Diagnostic Information</summary>
|
|
58
|
+
|
|
59
|
+
| Property | Value |
|
|
60
|
+
|----------|-------|
|
|
61
|
+
| CLI Version | ${diagnostics.cliVersion} |
|
|
62
|
+
| Node.js Version | ${diagnostics.nodeVersion} |
|
|
63
|
+
| OS | ${diagnostics.osType} |
|
|
64
|
+
| OS Version | ${diagnostics.osVersion} |
|
|
65
|
+
| Architecture | ${diagnostics.architecture} |
|
|
66
|
+
| Capabilities | ${capabilitiesDisplay} |
|
|
67
|
+
| Claude CLI Version | ${claudeVersionDisplay} |
|
|
68
|
+
|
|
69
|
+
</details>
|
|
70
|
+
`;
|
|
71
|
+
}
|
|
72
|
+
async function getCliVersion() {
|
|
73
|
+
try {
|
|
74
|
+
const packageJsonPath = join(__dirname, "..", "package.json");
|
|
75
|
+
const packageJson = await readFile(packageJsonPath, "utf-8");
|
|
76
|
+
const parsed = JSON.parse(packageJson);
|
|
77
|
+
return parsed.version ?? "unknown";
|
|
78
|
+
} catch (error) {
|
|
79
|
+
logger.debug("Failed to read CLI version from package.json: ", error);
|
|
80
|
+
return "unknown (failed to read package.json)";
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function getNodeVersion() {
|
|
84
|
+
try {
|
|
85
|
+
return process.version ?? "unknown";
|
|
86
|
+
} catch (error) {
|
|
87
|
+
logger.debug("Failed to read Node.js version:", error);
|
|
88
|
+
return "unknown (failed to read Node.js version)";
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function getOsType() {
|
|
92
|
+
try {
|
|
93
|
+
return platform() ?? "unknown";
|
|
94
|
+
} catch (error) {
|
|
95
|
+
logger.debug("Failed to read OS type:", error);
|
|
96
|
+
return "unknown (failed to detect OS)";
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function getOsVersion() {
|
|
100
|
+
try {
|
|
101
|
+
return release() ?? "unknown";
|
|
102
|
+
} catch (error) {
|
|
103
|
+
logger.debug("Failed to read OS version:", error);
|
|
104
|
+
return "unknown (failed to detect OS version)";
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function getArchitecture() {
|
|
108
|
+
try {
|
|
109
|
+
return arch() ?? "unknown";
|
|
110
|
+
} catch (error) {
|
|
111
|
+
logger.debug("Failed to read system architecture:", error);
|
|
112
|
+
return "unknown (failed to detect architecture)";
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/commands/feedback.ts
|
|
117
|
+
var FEEDBACK_REPOSITORY = "iloom-ai/iloom-cli";
|
|
118
|
+
var FeedbackCommand = class {
|
|
119
|
+
constructor(enhancementService) {
|
|
120
|
+
this.enhancementService = enhancementService ?? new IssueEnhancementService(
|
|
121
|
+
new GitHubService(),
|
|
122
|
+
new AgentManager(),
|
|
123
|
+
new SettingsManager()
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Execute the feedback command workflow:
|
|
128
|
+
* 1. Validate description format
|
|
129
|
+
* 2. Gather diagnostic information
|
|
130
|
+
* 3. Create GitHub issue in iloom-ai/iloom-cli with CLI marker and diagnostics
|
|
131
|
+
* 4. Wait for keypress and open browser for review
|
|
132
|
+
* 5. Return issue number
|
|
133
|
+
*/
|
|
134
|
+
async execute(input) {
|
|
135
|
+
const { description } = input;
|
|
136
|
+
if (!description || !this.enhancementService.validateDescription(description)) {
|
|
137
|
+
throw new Error("Description is required and must be more than 30 characters with at least 3 words");
|
|
138
|
+
}
|
|
139
|
+
const diagnostics = await gatherDiagnosticInfo();
|
|
140
|
+
const diagnosticsMarkdown = formatDiagnosticsAsMarkdown(diagnostics);
|
|
141
|
+
const enhancedBody = `${diagnosticsMarkdown}
|
|
142
|
+
|
|
143
|
+
${description}`;
|
|
144
|
+
const result = await this.enhancementService.createEnhancedIssue(
|
|
145
|
+
description,
|
|
146
|
+
enhancedBody,
|
|
147
|
+
FEEDBACK_REPOSITORY,
|
|
148
|
+
void 0
|
|
149
|
+
// No labels needed
|
|
150
|
+
);
|
|
151
|
+
await this.enhancementService.waitForReviewAndOpen(result.number, false, FEEDBACK_REPOSITORY);
|
|
152
|
+
return result.number;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
export {
|
|
156
|
+
FeedbackCommand
|
|
157
|
+
};
|
|
158
|
+
//# sourceMappingURL=feedback-23CLXKFT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/diagnostics.ts","../src/commands/feedback.ts"],"sourcesContent":["import { readFile } from 'fs/promises'\nimport { join, dirname } from 'path'\nimport { fileURLToPath } from 'url'\nimport { platform, release, arch } from 'os'\nimport { logger } from './logger'\nimport { ProjectCapabilityDetector } from '../lib/ProjectCapabilityDetector.js'\nimport type { ProjectCapability } from '../types/loom.js'\nimport { getClaudeVersion } from './claude.js'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\n/**\n * Diagnostic information gathered from the system\n */\nexport interface DiagnosticInfo {\n\tcliVersion: string\n\tnodeVersion: string\n\tosType: string\n\tosVersion: string\n\tarchitecture: string\n\tcapabilities: ProjectCapability[]\n\tclaudeVersion: string | null\n}\n\n/**\n * Gathers diagnostic information about the CLI environment.\n * Fails gracefully with fallback messages if any information cannot be gathered.\n */\nexport async function gatherDiagnosticInfo(): Promise<DiagnosticInfo> {\n\t// Instantiate detector for current directory\n\tconst detector = new ProjectCapabilityDetector()\n\tconst { capabilities } = await detector.detectCapabilities(process.cwd())\n\n\t// Get Claude CLI version (returns null if not available)\n\tconst claudeVersion = await getClaudeVersion()\n\n\tconst diagnostics: DiagnosticInfo = {\n\t\tcliVersion: await getCliVersion(),\n\t\tnodeVersion: getNodeVersion(),\n\t\tosType: getOsType(),\n\t\tosVersion: getOsVersion(),\n\t\tarchitecture: getArchitecture(),\n\t\tcapabilities,\n\t\tclaudeVersion,\n\t}\n\n\treturn diagnostics\n}\n\n/**\n * Formats diagnostic information as markdown for inclusion in GitHub issues\n */\nexport function formatDiagnosticsAsMarkdown(diagnostics: DiagnosticInfo, includeMarker = true): string {\n\tconst marker = includeMarker ? `<!-- CLI GENERATED FEEDBACK v${diagnostics.cliVersion} -->\\n` : ''\n\n\t// Format capabilities as comma-separated string or \"none\"\n\tconst capabilitiesDisplay = diagnostics.capabilities.length > 0\n\t\t? diagnostics.capabilities.join(', ')\n\t\t: 'none'\n\n\t// Format Claude version with fallback for null\n\tconst claudeVersionDisplay = diagnostics.claudeVersion ?? 'not available'\n\n\treturn `${marker}\n<details>\n<summary>Diagnostic Information</summary>\n\n| Property | Value |\n|----------|-------|\n| CLI Version | ${diagnostics.cliVersion} |\n| Node.js Version | ${diagnostics.nodeVersion} |\n| OS | ${diagnostics.osType} |\n| OS Version | ${diagnostics.osVersion} |\n| Architecture | ${diagnostics.architecture} |\n| Capabilities | ${capabilitiesDisplay} |\n| Claude CLI Version | ${claudeVersionDisplay} |\n\n</details>\n`\n}\n\n/**\n * Gets the CLI version from package.json.\n * Falls back to \"unknown\" if package.json cannot be read.\n */\nasync function getCliVersion(): Promise<string> {\n\ttry {\n\t\t// Navigate up from dist/ to root directory (same as cli.ts does)\n\t\tconst packageJsonPath = join(__dirname, '..', 'package.json')\n\t\tconst packageJson = await readFile(packageJsonPath, 'utf-8')\n\t\tconst parsed = JSON.parse(packageJson)\n\t\treturn parsed.version ?? 'unknown'\n\t} catch (error) {\n\t\tlogger.debug('Failed to read CLI version from package.json: ', error)\n\t\treturn 'unknown (failed to read package.json)'\n\t}\n}\n\n/**\n * Gets the Node.js version.\n * Falls back to \"unknown\" if process.version is not available.\n */\nfunction getNodeVersion(): string {\n\ttry {\n\t\treturn process.version ?? 'unknown'\n\t} catch (error) {\n\t\tlogger.debug('Failed to read Node.js version:', error)\n\t\treturn 'unknown (failed to read Node.js version)'\n\t}\n}\n\n/**\n * Gets the operating system type.\n * Falls back to \"unknown\" if os.platform() fails.\n */\nfunction getOsType(): string {\n\ttry {\n\t\treturn platform() ?? 'unknown'\n\t} catch (error) {\n\t\tlogger.debug('Failed to read OS type:', error)\n\t\treturn 'unknown (failed to detect OS)'\n\t}\n}\n\n/**\n * Gets the operating system version.\n * Falls back to \"unknown\" if os.release() fails.\n */\nfunction getOsVersion(): string {\n\ttry {\n\t\treturn release() ?? 'unknown'\n\t} catch (error) {\n\t\tlogger.debug('Failed to read OS version:', error)\n\t\treturn 'unknown (failed to detect OS version)'\n\t}\n}\n\n/**\n * Gets the system architecture.\n * Falls back to \"unknown\" if os.arch() fails.\n */\nfunction getArchitecture(): string {\n\ttry {\n\t\treturn arch() ?? 'unknown'\n\t} catch (error) {\n\t\tlogger.debug('Failed to read system architecture:', error)\n\t\treturn 'unknown (failed to detect architecture)'\n\t}\n}\n","import type { FeedbackOptions } from '../types/index.js'\nimport { IssueEnhancementService } from '../lib/IssueEnhancementService.js'\nimport { GitHubService } from '../lib/GitHubService.js'\nimport { AgentManager } from '../lib/AgentManager.js'\nimport { SettingsManager } from '../lib/SettingsManager.js'\nimport { gatherDiagnosticInfo, formatDiagnosticsAsMarkdown } from '../utils/diagnostics.js'\n\n// Hardcoded target repository for feedback\nconst FEEDBACK_REPOSITORY = 'iloom-ai/iloom-cli'\n\n/**\n * Input structure for FeedbackCommand\n */\nexport interface FeedbackCommandInput {\n\tdescription: string\n\toptions: FeedbackOptions\n}\n\n/**\n * Command to submit feedback/bug reports to the iloom-cli repository.\n * Mirrors add-issue command but targets iloom-ai/iloom-cli repo.\n */\nexport class FeedbackCommand {\n\tprivate enhancementService: IssueEnhancementService\n\n\tconstructor(enhancementService?: IssueEnhancementService) {\n\t\t// Use provided service or create default\n\t\tthis.enhancementService = enhancementService ?? new IssueEnhancementService(\n\t\t\tnew GitHubService(),\n\t\t\tnew AgentManager(),\n\t\t\tnew SettingsManager()\n\t\t)\n\t}\n\n\t/**\n\t * Execute the feedback command workflow:\n\t * 1. Validate description format\n\t * 2. Gather diagnostic information\n\t * 3. Create GitHub issue in iloom-ai/iloom-cli with CLI marker and diagnostics\n\t * 4. Wait for keypress and open browser for review\n\t * 5. Return issue number\n\t */\n\tpublic async execute(input: FeedbackCommandInput): Promise<number> {\n\t\tconst { description } = input\n\n\t\t// Step 1: Validate description format\n\t\tif (!description || !this.enhancementService.validateDescription(description)) {\n\t\t\tthrow new Error('Description is required and must be more than 30 characters with at least 3 words')\n\t\t}\n\n\t\t// Step 2: Gather diagnostic information\n\t\tconst diagnostics = await gatherDiagnosticInfo()\n\t\tconst diagnosticsMarkdown = formatDiagnosticsAsMarkdown(diagnostics)\n\n\t\t// Step 3: Create enhanced issue body with marker and diagnostics\n\t\tconst enhancedBody = `${diagnosticsMarkdown}\n\n${description}`\n\n\t\t// Step 4: Create GitHub issue in iloom-cli repo (no label needed)\n\t\t// The GitHub Action workflow will detect the CLI marker and enhance the issue\n\t\tconst result = await this.enhancementService.createEnhancedIssue(\n\t\t\tdescription,\n\t\t\tenhancedBody,\n\t\t\tFEEDBACK_REPOSITORY,\n\t\t\tundefined // No labels needed\n\t\t)\n\n\t\t// Step 5: Wait for keypress and open issue in browser for review\n\t\tawait this.enhancementService.waitForReviewAndOpen(result.number, false, FEEDBACK_REPOSITORY)\n\n\t\t// Step 6: Return issue number for reference\n\t\treturn result.number\n\t}\n}\n"],"mappings":"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","names":[]}
|