@braingrid/cli 0.2.5 → 0.2.7
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/CHANGELOG.md +56 -0
- package/dist/{chunk-KNVWIF3L.js → chunk-RAV3B4UY.js} +59 -7
- package/dist/chunk-RAV3B4UY.js.map +1 -0
- package/dist/cli.js +820 -744
- package/dist/cli.js.map +1 -1
- package/dist/{gh-installer-B65ZOOC4.js → gh-installer-LNR25TO7.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-KNVWIF3L.js.map +0 -1
- /package/dist/{gh-installer-B65ZOOC4.js.map → gh-installer-LNR25TO7.js.map} +0 -0
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/handlers/project.handlers.ts","../src/utils/axios-with-auth.ts","../src/utils/logger.ts","../src/services/project-service.ts","../src/services/auth.ts","../src/utils/axios-retry.ts","../src/services/oauth2-auth.ts","../src/build-config.ts","../src/utils/config.ts","../src/utils/jwt.ts","../src/services/credential-store.ts","../src/utils/error-formatter.ts","../src/utils/error-handler.ts","../src/utils/id-normalization.ts","../src/utils/projects.ts","../src/utils/workspace-manager.ts","../src/utils/local-store.ts","../src/types/local-project.ts","../src/utils/git.ts","../src/utils/requirements.ts","../src/utils/spinner.ts","../src/services/internal/repository-service.ts","../src/utils/repository-access.ts","../src/utils/formatting.ts","../src/utils/tasks.ts","../src/handlers/requirement.handlers.ts","../src/services/requirement-service.ts","../src/handlers/task.handlers.ts","../src/services/task-service.ts","../src/handlers/auth.handlers.ts","../src/handlers/status.handlers.ts","../src/handlers/init.handlers.ts","../src/services/internal/github-service.ts","../src/utils/git-installer.ts","../src/utils/github-repo.ts","../src/handlers/update.handlers.ts","../src/utils/package-manager.ts","../src/handlers/setup.handlers.ts","../src/utils/command-execution.ts","../src/services/setup-service.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { createRequire } from 'module';\nimport * as handlers from './handlers/index.js';\n\nconst require = createRequire(import.meta.url);\nconst packageJson = require('../package.json');\n\nconst program = new Command();\n\nprogram\n\t.name('braingrid')\n\t.description('BrainGrid CLI - Manage projects, requirements, and tasks')\n\t.version(packageJson.version, '-v, --version', 'output the current version')\n\t.showHelpAfterError('(use --help for usage)');\n\n// ============================================\n// AUTH COMMANDS\n// ============================================\nprogram\n\t.command('login')\n\t.description('Authenticate with BrainGrid')\n\t.action(async () => {\n\t\tconst result = await handlers.handleLogin();\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('logout')\n\t.description('Sign out from BrainGrid')\n\t.action(async () => {\n\t\tconst result = await handlers.handleLogout();\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('whoami')\n\t.description('Show current user information')\n\t.action(async () => {\n\t\tconst result = await handlers.handleWhoami();\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('status')\n\t.description('Show CLI status (authentication, git, config)')\n\t.action(async () => {\n\t\tconst result = await handlers.handleStatus();\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('init')\n\t.description('Initialize BrainGrid project in current repository')\n\t.option('--project <id>', 'project ID to initialize with (auto-detects if not provided)')\n\t.option('--force', 'skip confirmation and force reinitialization if already initialized')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleInit(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('update')\n\t.description('Update BrainGrid CLI to the latest version')\n\t.option('--check', 'check for updates without installing')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleUpdate(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('specify')\n\t.description('Create AI-refined requirement from prompt')\n\t.option(\n\t\t'-p, --project <id>',\n\t\t'project ID (auto-detects from .braingrid/project.json if not provided)'\n\t)\n\t.requiredOption('--prompt <prompt>', 'requirement description (10-5000 characters)')\n\t.option('--format <format>', 'output format (table, json, xml, markdown)', 'table')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleRequirementSpecify(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\n// ============================================\n// SETUP COMMANDS\n// ============================================\nconst createSetupAction = (\n\thandler: (opts: { force?: boolean; dryRun?: boolean }) => Promise<handlers.HandlerResult>\n) => {\n\treturn async (opts: { force?: boolean; dryRun?: boolean }) => {\n\t\tconst result = await handler(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t};\n};\n\nconst setup = program\n\t.command('setup')\n\t.description('Setup BrainGrid integrations for AI coding tools');\n\nsetup\n\t.command('claude-code')\n\t.description('Install Claude Code integration')\n\t.option('--force', 'overwrite existing files without prompting')\n\t.option('--dry-run', 'show what would be done without making changes')\n\t.action(createSetupAction(handlers.handleSetupClaudeCode));\n\nsetup\n\t.command('cursor')\n\t.description('Install Cursor integration')\n\t.option('--force', 'overwrite existing files without prompting')\n\t.option('--dry-run', 'show what would be done without making changes')\n\t.action(createSetupAction(handlers.handleSetupCursor));\n\n// ============================================\n// PROJECT RESOURCE COMMANDS\n// ============================================\nconst project = program.command('project').description('Manage projects');\n\nproject\n\t.command('list')\n\t.description('List all projects')\n\t.option('--format <format>', 'output format (table, json, xml, markdown)', 'table')\n\t.option('--page <page>', 'page number for pagination', '1')\n\t.option('--limit <limit>', 'number of projects per page', '20')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleProjectList(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nproject\n\t.command('show [id]')\n\t.description('Show current or specified project (or use --repository to list by repo)')\n\t.option(\n\t\t'--repository, --repo <owner/name>',\n\t\t'list projects for repository (e.g., microsoft/vscode)'\n\t)\n\t.option('--format <format>', 'output format (table, json, xml, markdown)', 'table')\n\t.option('--page <page>', 'page number for pagination', '1')\n\t.option('--limit <limit>', 'number of projects per page', '20')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleProjectShow({ id, ...opts });\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nproject\n\t.command('create')\n\t.description('Create a new project')\n\t.requiredOption('--name <name>', 'project name')\n\t.option('--description <description>', 'project description')\n\t.option('--repository-id <uuid>', 'repository UUID to link to project')\n\t.option('--repository <owner/name>', 'repository in owner/name format (e.g., microsoft/vscode)')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleProjectCreate(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nproject\n\t.command('update <id>')\n\t.description('Update project information')\n\t.option('--name <name>', 'new project name')\n\t.option('--description <description>', 'new project description')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleProjectUpdate(id, opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nproject\n\t.command('delete <id>')\n\t.description('Delete a project')\n\t.option('--force', 'force deletion without confirmation')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleProjectDelete(id, opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\n// ============================================\n// REQUIREMENT RESOURCE COMMANDS\n// ============================================\nconst requirement = program.command('requirement').description('Manage requirements');\n\nrequirement\n\t.command('list')\n\t.description('List requirements for a project')\n\t.option(\n\t\t'-p, --project <id>',\n\t\t'project ID (auto-detects from .braingrid/project.json if not provided)'\n\t)\n\t.option(\n\t\t'--status <status>',\n\t\t'filter by status (IDEA, PLANNED, IN_PROGRESS, REVIEW, COMPLETED, CANCELLED)'\n\t)\n\t.option('--format <format>', 'output format (table, json, xml, markdown)', 'table')\n\t.option('--page <page>', 'page number for pagination', '1')\n\t.option('--limit <limit>', 'number of requirements per page', '20')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleRequirementList(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nrequirement\n\t.command('show [id]')\n\t.description('Show requirement details (auto-detects ID from git branch if not provided)')\n\t.option(\n\t\t'-p, --project <id>',\n\t\t'project ID (auto-detects from .braingrid/project.json if not provided)'\n\t)\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleRequirementShow({ ...opts, id });\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nrequirement\n\t.command('create')\n\t.description('Create a new requirement')\n\t.option(\n\t\t'-p, --project <id>',\n\t\t'project ID (auto-detects from .braingrid/project.json if not provided)'\n\t)\n\t.requiredOption('-n, --name <name>', 'requirement name')\n\t.option('-c, --content <content>', 'requirement content/description')\n\t.option('-a, --assigned-to <uuid>', 'user UUID to assign the requirement to')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleRequirementCreate(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nrequirement\n\t.command('update [id]')\n\t.description('Update requirement information (auto-detects ID from git branch if not provided)')\n\t.option('-p, --project <id>', 'project ID (auto-detects from workspace if not specified)')\n\t.option(\n\t\t'--status <status>',\n\t\t'new status (IDEA, PLANNED, IN_PROGRESS, REVIEW, COMPLETED, CANCELLED)'\n\t)\n\t.option('--name <name>', 'new requirement name')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleRequirementUpdate({ ...opts, id });\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nrequirement\n\t.command('delete [id]')\n\t.description('Delete a requirement (auto-detects ID from git branch if not provided)')\n\t.option('-p, --project <id>', 'project ID (auto-detects from workspace if not specified)')\n\t.option('--force', 'force deletion without confirmation')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleRequirementDelete({ ...opts, id });\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nrequirement\n\t.command('breakdown [id]')\n\t.description(\n\t\t'Break down a requirement into actionable tasks using AI (auto-detects ID from git branch if not provided)'\n\t)\n\t.option(\n\t\t'-p, --project <id>',\n\t\t'project ID (auto-detects from .braingrid/project.json if not provided)'\n\t)\n\t.option('--format <format>', 'output format (table, json, xml, markdown)', 'markdown')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleRequirementBreakdown({ ...opts, id });\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nrequirement\n\t.command('build [id]')\n\t.description(\n\t\t'Build requirement with all tasks in specified format (auto-detects ID from git branch if not provided)'\n\t)\n\t.option(\n\t\t'-p, --project <id>',\n\t\t'project ID (auto-detects from .braingrid/project.json if not provided)'\n\t)\n\t.option('--format <format>', 'output format (markdown, json, xml)', 'markdown')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleRequirementBuild({ ...opts, id });\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\n// ============================================\n// TASK RESOURCE COMMANDS\n// ============================================\nconst task = program.command('task').description('Manage tasks');\n\ntask\n\t.command('list')\n\t.description('List tasks for a requirement')\n\t.option('-r, --requirement <id>', 'requirement ID (REQ-456, auto-detects project if initialized)')\n\t.option('-p, --project <id>', 'project ID (PROJ-123, optional if project is initialized)')\n\t.option('--format <format>', 'output format (table, json, xml, markdown)', 'markdown')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleTaskList(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\ntask\n\t.command('summary')\n\t.description('Show task summary table (quick overview without content)')\n\t.option('-r, --requirement <id>', 'requirement ID (REQ-456, auto-detects project if initialized)')\n\t.option('-p, --project <id>', 'project ID (PROJ-123, optional if project is initialized)')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleTaskSummary(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\ntask\n\t.command('show <id>')\n\t.description('Show task details')\n\t.option('-r, --requirement <id>', 'requirement ID (REQ-456, auto-detects project if initialized)')\n\t.option('-p, --project <id>', 'project ID (PROJ-123, optional if project is initialized)')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleTaskShow(id, opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\ntask\n\t.command('create')\n\t.description('Create a new task')\n\t.option('-r, --requirement <id>', 'requirement ID (REQ-456, auto-detects project if initialized)')\n\t.option('-p, --project <id>', 'project ID (PROJ-123, optional if project is initialized)')\n\t.requiredOption('--title <title>', 'task title')\n\t.option('--content <content>', 'task content/description')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleTaskCreate(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\ntask\n\t.command('update <id>')\n\t.description('Update task information')\n\t.option('-r, --requirement <id>', 'requirement ID (REQ-456, auto-detects project if initialized)')\n\t.option('-p, --project <id>', 'project ID (PROJ-123, optional if project is initialized)')\n\t.option('--status <status>', 'new status (PLANNED, IN_PROGRESS, COMPLETED, CANCELLED)')\n\t.option('--title <title>', 'new task title')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleTaskUpdate(id, opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\ntask\n\t.command('delete <id>')\n\t.description('Delete a task')\n\t.option('-r, --requirement <id>', 'requirement ID (REQ-456, auto-detects project if initialized)')\n\t.option('-p, --project <id>', 'project ID (PROJ-123, optional if project is initialized)')\n\t.option('--force', 'force deletion without confirmation')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleTaskDelete(id, opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram.parse();\n","/**\n * Project Resource Handlers\n *\n * Handles all project-related commands:\n * - list: List all projects\n * - show: Show current project, specific project by ID, or projects for a repository\n * - create: Create a new project\n * - update: Update project information\n * - delete: Delete a project\n */\n\nimport chalk from 'chalk';\nimport { ProjectService } from '../services/project-service.js';\nimport { BraingridAuth } from '../services/auth.js';\nimport { getConfig } from '../utils/config.js';\nimport { formatError, getResourceContext } from '../utils/error-formatter.js';\nimport { parseProjectId } from '../utils/projects.js';\nimport { workspaceManager } from '../utils/workspace-manager.js';\nimport { showSpinner } from '../utils/spinner.js';\nimport { RepositoryService } from '../services/internal/repository-service.js';\nimport { getRepositoryId } from '../utils/repository-access.js';\nimport {\n\tformatProjectListMarkdown,\n\tformatProjectListXml,\n\tformatProjectShowMarkdown,\n\tformatProjectShowXml,\n} from '../utils/formatting.js';\nimport type { HandlerResult } from './types.js';\nimport type { ListProjectsResponse, ListProjectsWithRepositoryResponse } from '../types/project.js';\n\n/**\n * Format pagination or total count display for project list responses\n */\nfunction formatProjectListPagination(\n\tresponse: ListProjectsResponse | ListProjectsWithRepositoryResponse\n): string {\n\tif ('pagination' in response) {\n\t\tconst totalPages = Math.ceil(response.pagination.total / response.pagination.limit);\n\t\treturn `Page ${response.pagination.page} of ${totalPages} (${response.pagination.total} total)`;\n\t}\n\treturn `Total: ${response.total_count || response.projects.length}`;\n}\n\nfunction getServices(): { projectService: ProjectService; auth: BraingridAuth } {\n\tconst config = getConfig();\n\tconst auth = new BraingridAuth(config.apiUrl);\n\tconst projectService = new ProjectService(config.apiUrl, auth);\n\treturn { projectService, auth };\n}\n\nexport async function handleProjectList(opts: {\n\tformat?: string;\n\tpage?: string;\n\tlimit?: string;\n}): Promise<HandlerResult> {\n\ttry {\n\t\tconst { projectService, auth } = getServices();\n\n\t\t// Check authentication\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Validate format option\n\t\tconst format = opts.format || 'table';\n\t\tif (!['table', 'json', 'xml', 'markdown'].includes(format)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t`❌ Invalid format: ${format}. Supported formats: table, json, xml, markdown`\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\tconst stop = showSpinner('Loading projects', chalk.gray);\n\t\ttry {\n\t\t\tconst response = await projectService.listProjects({\n\t\t\t\tpage: opts.page ? parseInt(opts.page, 10) : 1,\n\t\t\t\tlimit: opts.limit ? parseInt(opts.limit, 10) : 20,\n\t\t\t});\n\t\t\tstop();\n\n\t\t\t// Format output based on requested format\n\t\t\tlet output: string;\n\t\t\tswitch (format) {\n\t\t\t\tcase 'json': {\n\t\t\t\t\toutput = JSON.stringify(response, null, 2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'xml': {\n\t\t\t\t\tconst pagination = 'pagination' in response ? response.pagination : undefined;\n\t\t\t\t\toutput = formatProjectListXml(response.projects, pagination);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'markdown': {\n\t\t\t\t\tconst pagination = 'pagination' in response ? response.pagination : undefined;\n\t\t\t\t\toutput = formatProjectListMarkdown(response.projects, pagination);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'table':\n\t\t\t\tdefault: {\n\t\t\t\t\t// Table format\n\t\t\t\t\tif (response.projects.length === 0) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\tmessage: chalk.yellow('No projects found.'),\n\t\t\t\t\t\t\tdata: response,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\toutput = chalk.bold('📋 Projects\\n\\n');\n\t\t\t\t\toutput +=\n\t\t\t\t\t\t'ID Short ID Name Created\\n';\n\t\t\t\t\toutput += '─'.repeat(100) + '\\n';\n\n\t\t\t\t\tfor (const project of response.projects) {\n\t\t\t\t\t\tconst id = project.id.padEnd(36);\n\t\t\t\t\t\tconst shortId = project.short_id.padEnd(11);\n\t\t\t\t\t\tconst name = project.name.substring(0, 28).padEnd(28);\n\t\t\t\t\t\tconst created = new Date(project.created_at).toLocaleDateString();\n\t\t\t\t\t\toutput += `${id} ${shortId} ${name} ${created}\\n`;\n\t\t\t\t\t}\n\n\t\t\t\t\toutput += '\\n';\n\t\t\t\t\toutput += formatProjectListPagination(response);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: output,\n\t\t\t\tdata: response,\n\t\t\t};\n\t\t} finally {\n\t\t\tstop();\n\t\t}\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'listing projects'),\n\t\t};\n\t}\n}\n\nexport async function handleProjectShow(opts: {\n\tid?: string;\n\trepo?: string;\n\trepository?: string;\n\tformat?: string;\n\tpage?: string;\n\tlimit?: string;\n}): Promise<HandlerResult> {\n\ttry {\n\t\tconst { projectService, auth } = getServices();\n\n\t\t// Check authentication\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Validate format option\n\t\tconst format = opts.format || 'table';\n\t\tif (!['table', 'json', 'xml', 'markdown'].includes(format)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t`❌ Invalid format: ${format}. Supported formats: table, json, xml, markdown`\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Case 1: Specific project ID provided - show that project\n\t\tif (opts.id) {\n\t\t\tconst normalizedId = parseProjectId(opts.id);\n\t\t\tconst stop = showSpinner('Loading project', chalk.gray);\n\t\t\ttry {\n\t\t\t\tconst project = await projectService.getProject(normalizedId);\n\t\t\t\tstop();\n\n\t\t\t\tlet output: string;\n\t\t\t\tswitch (format) {\n\t\t\t\t\tcase 'json': {\n\t\t\t\t\t\toutput = JSON.stringify(project, null, 2);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'xml': {\n\t\t\t\t\t\toutput = formatProjectShowXml(project);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'markdown': {\n\t\t\t\t\t\toutput = formatProjectShowMarkdown(project);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'table':\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\toutput = chalk.bold(`\\n📁 Project: ${project.name}\\n\\n`);\n\t\t\t\t\t\toutput += `${chalk.bold('ID:')} ${project.id}\\n`;\n\t\t\t\t\t\toutput += `${chalk.bold('Short ID:')} ${project.short_id}\\n`;\n\t\t\t\t\t\toutput += `${chalk.bold('Name:')} ${project.name}\\n`;\n\t\t\t\t\t\tif (project.description) {\n\t\t\t\t\t\t\toutput += `${chalk.bold('Description:')} ${project.description}\\n`;\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutput += `${chalk.bold('Created:')} ${new Date(project.created_at).toLocaleString()}\\n`;\n\t\t\t\t\t\toutput += `${chalk.bold('Updated:')} ${new Date(project.updated_at).toLocaleString()}\\n`;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tmessage: output,\n\t\t\t\t\tdata: project,\n\t\t\t\t};\n\t\t\t} finally {\n\t\t\t\tstop();\n\t\t\t}\n\t\t}\n\n\t\t// Case 2: Repository flag provided - list all projects for that repository\n\t\tconst repoInput = opts.repository || opts.repo;\n\t\tif (repoInput) {\n\t\t\tconst parts = repoInput.split('/');\n\t\t\tif (parts.length !== 2) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t\t'❌ Invalid repository format. Use: --repository owner/name (e.g., --repository microsoft/vscode)'\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst [repositoryOwner, repositoryName] = parts;\n\n\t\t\tconst stop = showSpinner('Loading projects', chalk.gray);\n\t\t\ttry {\n\t\t\t\tconst response = await projectService.listProjects({\n\t\t\t\t\trepository_owner: repositoryOwner,\n\t\t\t\t\trepository_name: repositoryName,\n\t\t\t\t\tpage: opts.page ? parseInt(opts.page, 10) : 1,\n\t\t\t\t\tlimit: opts.limit ? parseInt(opts.limit, 10) : 20,\n\t\t\t\t});\n\t\t\t\tstop();\n\n\t\t\t\t// Format output based on requested format\n\t\t\t\tlet output: string;\n\t\t\t\tswitch (format) {\n\t\t\t\t\tcase 'json': {\n\t\t\t\t\t\toutput = JSON.stringify(response, null, 2);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'xml': {\n\t\t\t\t\t\tconst pagination = 'pagination' in response ? response.pagination : undefined;\n\t\t\t\t\t\toutput = formatProjectListXml(response.projects, pagination);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'markdown': {\n\t\t\t\t\t\tconst pagination = 'pagination' in response ? response.pagination : undefined;\n\t\t\t\t\t\toutput = formatProjectListMarkdown(response.projects, pagination);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'table':\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\t// Table format\n\t\t\t\t\t\tconst repoDisplay = chalk.cyan(`${repositoryOwner}/${repositoryName}`);\n\n\t\t\t\t\t\tif (response.projects.length === 0) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\t\tmessage: chalk.yellow(`No projects found for repository ${repoDisplay}`),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\toutput = chalk.bold(`📋 Projects for ${repoDisplay}\\n\\n`);\n\t\t\t\t\t\toutput +=\n\t\t\t\t\t\t\t'ID Short ID Name Created\\n';\n\t\t\t\t\t\toutput += '─'.repeat(100) + '\\n';\n\n\t\t\t\t\t\tfor (const project of response.projects) {\n\t\t\t\t\t\t\tconst id = project.id.padEnd(36);\n\t\t\t\t\t\t\tconst shortId = project.short_id.padEnd(11);\n\t\t\t\t\t\t\tconst name = project.name.substring(0, 28).padEnd(28);\n\t\t\t\t\t\t\tconst created = new Date(project.created_at).toLocaleDateString();\n\t\t\t\t\t\t\toutput += `${id} ${shortId} ${name} ${created}\\n`;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\toutput += '\\n';\n\t\t\t\t\t\toutput += formatProjectListPagination(response);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tmessage: output,\n\t\t\t\t\tdata: response,\n\t\t\t\t};\n\t\t\t} finally {\n\t\t\t\tstop();\n\t\t\t}\n\t\t}\n\n\t\t// Case 3: No arguments - show initialized project from workspace\n\t\tconst workspace = await workspaceManager.getProject();\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\n\t\tconst stop = showSpinner('Loading project', chalk.gray);\n\t\ttry {\n\t\t\tconst project = await projectService.getProject(workspace.projectId);\n\t\t\tstop();\n\n\t\t\tlet output: string;\n\t\t\tswitch (format) {\n\t\t\t\tcase 'json': {\n\t\t\t\t\toutput = JSON.stringify(project, null, 2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'xml': {\n\t\t\t\t\toutput = formatProjectShowXml(project);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'markdown': {\n\t\t\t\t\toutput = formatProjectShowMarkdown(project);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'table':\n\t\t\t\tdefault: {\n\t\t\t\t\toutput = chalk.bold(`\\n📁 Project: ${project.name}\\n\\n`);\n\t\t\t\t\toutput += `${chalk.bold('ID:')} ${project.id}\\n`;\n\t\t\t\t\toutput += `${chalk.bold('Short ID:')} ${project.short_id}\\n`;\n\t\t\t\t\toutput += `${chalk.bold('Name:')} ${project.name}\\n`;\n\t\t\t\t\tif (project.description) {\n\t\t\t\t\t\toutput += `${chalk.bold('Description:')} ${project.description}\\n`;\n\t\t\t\t\t}\n\t\t\t\t\toutput += `${chalk.bold('Created:')} ${new Date(project.created_at).toLocaleString()}\\n`;\n\t\t\t\t\toutput += `${chalk.bold('Updated:')} ${new Date(project.updated_at).toLocaleString()}\\n`;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: output,\n\t\t\t\tdata: project,\n\t\t\t};\n\t\t} finally {\n\t\t\tstop();\n\t\t}\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'showing project'),\n\t\t};\n\t}\n}\n\nexport async function handleProjectCreate(opts: {\n\tname: string;\n\tdescription?: string;\n\trepositoryId?: string;\n\trepository?: string;\n}): Promise<HandlerResult> {\n\ttry {\n\t\tconst { projectService, auth } = getServices();\n\t\tconst config = getConfig();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Resolve repository ID from either --repository-id or --repository\n\t\tlet repositoryId: string | undefined;\n\n\t\t// Option 1: Direct UUID (highest priority)\n\t\tif (opts.repositoryId) {\n\t\t\trepositoryId = opts.repositoryId;\n\t\t}\n\t\t// Option 2: Lookup by owner/name\n\t\telse if (opts.repository) {\n\t\t\tconst parts = opts.repository.split('/');\n\t\t\tif (parts.length !== 2) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t\t'❌ Invalid repository format. Use: --repository owner/name (e.g., microsoft/vscode)'\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst [owner, name] = parts;\n\t\t\tconst repositoryService = new RepositoryService(config.apiUrl, auth);\n\n\t\t\tconst stop = showSpinner(`Looking up repository ${opts.repository}`, chalk.gray);\n\t\t\ttry {\n\t\t\t\tconst repoId = await getRepositoryId(repositoryService, owner, name);\n\t\t\t\tstop();\n\n\t\t\t\tif (!repoId) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t\t\t`❌ Repository '${opts.repository}' not found. Please check the name or ensure you have access.`\n\t\t\t\t\t\t),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\trepositoryId = repoId;\n\t\t\t} finally {\n\t\t\t\tstop();\n\t\t\t}\n\t\t}\n\n\t\tconst stop = showSpinner('Creating project', chalk.gray);\n\t\ttry {\n\t\t\tconst project = await projectService.createProject({\n\t\t\t\tname: opts.name,\n\t\t\t\tdescription: opts.description,\n\t\t\t\trepository_id: repositoryId,\n\t\t\t});\n\t\t\tstop();\n\n\t\t\tlet message = chalk.green(`✅ Created project ${project.short_id}: ${project.name}`);\n\t\t\tif (opts.repository && repositoryId) {\n\t\t\t\tmessage += chalk.gray(` (linked to ${opts.repository})`);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage,\n\t\t\t\tdata: project,\n\t\t\t};\n\t\t} finally {\n\t\t\tstop();\n\t\t}\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'creating project'),\n\t\t};\n\t}\n}\n\nexport async function handleProjectUpdate(\n\tid: string,\n\topts: {\n\t\tname?: string;\n\t\tdescription?: string;\n\t}\n): Promise<HandlerResult> {\n\ttry {\n\t\tconst { projectService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.name && !opts.description) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t'❌ Please provide at least one field to update (--name or --description)'\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Normalize the project ID\n\t\tconst normalizedId = parseProjectId(id);\n\t\tconst stop = showSpinner('Updating project', chalk.gray);\n\t\ttry {\n\t\t\tconst project = await projectService.updateProject(normalizedId, {\n\t\t\t\tname: opts.name,\n\t\t\t\tdescription: opts.description,\n\t\t\t});\n\t\t\tstop();\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: chalk.green(`✅ Updated project ${project.short_id}: ${project.name}`),\n\t\t\t\tdata: project,\n\t\t\t};\n\t\t} finally {\n\t\t\tstop();\n\t\t}\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('project', id)),\n\t\t};\n\t}\n}\n\nexport async function handleProjectDelete(\n\tid: string,\n\topts: { force?: boolean }\n): Promise<HandlerResult> {\n\ttry {\n\t\tconst { projectService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.force) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.yellow(\n\t\t\t\t\t'⚠️ Deleting a project is permanent. Use --force to confirm deletion.'\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Normalize the project ID\n\t\tconst normalizedId = parseProjectId(id);\n\t\tconst stop = showSpinner('Deleting project', chalk.gray);\n\t\ttry {\n\t\t\tawait projectService.deleteProject(normalizedId);\n\t\t\tstop();\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: chalk.green(`✅ Deleted project ${id}`),\n\t\t\t};\n\t\t} finally {\n\t\t\tstop();\n\t\t}\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('project', id)),\n\t\t};\n\t}\n}\n","/**\n * Axios instance with authentication and automatic token refresh\n */\n\nimport axios, { AxiosInstance, AxiosError, InternalAxiosRequestConfig } from 'axios';\nimport { BraingridAuth } from '../services/auth.js';\nimport { getLogger } from './logger.js';\n\nconst logger = getLogger();\n\n/**\n * Check if a response is a redirect to an auth endpoint\n */\nfunction isAuthRedirect(error: AxiosError): boolean {\n\tconst status = error.response?.status;\n\tif (!status || (status !== 302 && status !== 307 && status !== 303)) {\n\t\treturn false;\n\t}\n\n\tconst location = error.response?.headers?.location as string | undefined;\n\tif (!location) {\n\t\treturn false;\n\t}\n\n\t// Check if redirecting to auth endpoints (WorkOS, AuthKit, etc.)\n\tconst authPatterns = [\n\t\t'/auth/',\n\t\t'/oauth2/',\n\t\t'workos.com',\n\t\t'authkit.app',\n\t\t'/user_management/authorize',\n\t];\n\n\treturn authPatterns.some(pattern => location.toLowerCase().includes(pattern));\n}\n\n/**\n * Create an axios instance with automatic token refresh on 401 errors and auth redirects\n */\nexport function createAuthenticatedAxios(auth: BraingridAuth): AxiosInstance {\n\tconst instance = axios.create({\n\t\tmaxRedirects: 0, // Don't follow redirects - treat them as errors\n\t\tvalidateStatus: status => status >= 200 && status < 300, // Only accept 2xx as success\n\t});\n\n\t// Request interceptor to add auth headers\n\tinstance.interceptors.request.use(\n\t\tasync config => {\n\t\t\tconst session = await auth.getStoredSession();\n\t\t\tif (session) {\n\t\t\t\tconfig.headers.Authorization = `Bearer ${session.sealed_session}`;\n\t\t\t}\n\t\t\treturn config;\n\t\t},\n\t\terror => Promise.reject(error)\n\t);\n\n\t// Response interceptor to handle 401 errors, auth redirects, and refresh token\n\tinstance.interceptors.response.use(\n\t\tresponse => {\n\t\t\t// Log successful API calls for debugging/testing\n\t\t\tconst method = response.config.method?.toUpperCase() || 'UNKNOWN';\n\t\t\tconst url = response.config.url || 'unknown';\n\t\t\tconst status = response.status;\n\n\t\t\tlogger.debug(`[API] ${method} ${url} -> ${status}`);\n\n\t\t\treturn response;\n\t\t},\n\t\tasync (error: AxiosError) => {\n\t\t\tconst originalRequest = error.config as InternalAxiosRequestConfig & { _retry?: boolean };\n\n\t\t\t// Log API error details for debugging/testing\n\t\t\tconst method = error.config?.method?.toUpperCase() || 'UNKNOWN';\n\t\t\tconst url = error.config?.url || 'unknown';\n\t\t\tconst status = error.response?.status || 'NO_RESPONSE';\n\n\t\t\t// Extract request params (query params or request body)\n\t\t\tlet params = '';\n\t\t\tif (error.config?.params) {\n\t\t\t\tparams = JSON.stringify(error.config.params);\n\t\t\t} else if (error.config?.data) {\n\t\t\t\ttry {\n\t\t\t\t\tconst data =\n\t\t\t\t\t\ttypeof error.config.data === 'string'\n\t\t\t\t\t\t\t? JSON.parse(error.config.data)\n\t\t\t\t\t\t\t: error.config.data;\n\t\t\t\t\t// Truncate long prompts for readability\n\t\t\t\t\tif (data.prompt && data.prompt.length > 100) {\n\t\t\t\t\t\tdata.prompt = data.prompt.substring(0, 100) + '...';\n\t\t\t\t\t}\n\t\t\t\t\tparams = JSON.stringify(data);\n\t\t\t\t} catch {\n\t\t\t\t\tparams = String(error.config.data).substring(0, 200);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlogger.debug(`[API] ${method} ${url} -> ${status}`, { params });\n\n\t\t\t// Check if this is an auth failure (401 or redirect to auth)\n\t\t\tconst is401 = error.response?.status === 401;\n\t\t\tconst isRedirectToAuth = isAuthRedirect(error);\n\n\t\t\t// If auth failure and we haven't retried yet, attempt token refresh\n\t\t\tif ((is401 || isRedirectToAuth) && !originalRequest._retry) {\n\t\t\t\toriginalRequest._retry = true;\n\n\t\t\t\tif (isRedirectToAuth) {\n\t\t\t\t\tlogger.debug('[AUTH] Received redirect to auth endpoint - token likely expired');\n\t\t\t\t} else {\n\t\t\t\t\tlogger.debug('[AUTH] Received 401 error - attempting token refresh');\n\t\t\t\t}\n\n\t\t\t\t// Attempt to refresh the token\n\t\t\t\tconst refreshed = await auth.refreshSession();\n\n\t\t\t\tif (refreshed) {\n\t\t\t\t\tlogger.debug('[AUTH] Token refreshed - retrying request');\n\n\t\t\t\t\t// Get the new session and update the request headers\n\t\t\t\t\tconst session = await auth.getStoredSession();\n\t\t\t\t\tif (session && originalRequest.headers) {\n\t\t\t\t\t\toriginalRequest.headers.Authorization = `Bearer ${session.sealed_session}`;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Retry the original request with the new token\n\t\t\t\t\treturn instance(originalRequest);\n\t\t\t\t} else {\n\t\t\t\t\tlogger.warn('[AUTH] Token refresh failed - clearing session');\n\t\t\t\t\t// Refresh failed, clear the session\n\t\t\t\t\tawait auth.clearSession();\n\n\t\t\t\t\t// Return a more user-friendly error\n\t\t\t\t\tconst authError = new Error(\n\t\t\t\t\t\t'Authentication expired. Please run \"braingrid login\" to re-authenticate.'\n\t\t\t\t\t);\n\t\t\t\t\treturn Promise.reject(authError);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// For all other errors or if retry already happened, just reject\n\t\t\treturn Promise.reject(error);\n\t\t}\n\t);\n\n\treturn instance;\n}\n","import fs from 'fs';\nimport path from 'path';\nimport os from 'os';\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\nexport type MessageType = 'user' | 'system' | 'error' | 'info' | 'debug';\n\ninterface LogEntry {\n\ttimestamp: Date;\n\tlevel: LogLevel;\n\ttype: MessageType;\n\tmessage: string;\n\tcontext?: Record<string, unknown>;\n}\n\ninterface LoggerConfig {\n\tlogToFile: boolean;\n\tlogLevel: LogLevel;\n\tlogFilePath?: string;\n\tmaxFileSize: number;\n\tmaxFiles: number;\n\tconsoleOutput: boolean; // Whether to print debug logs to console\n}\n\nclass Logger {\n\tprivate config: LoggerConfig;\n\tprivate logFilePath: string;\n\n\tconstructor(config: Partial<LoggerConfig> = {}) {\n\t\tconst isDebugMode = process.env.DEBUG === 'true';\n\t\tthis.config = {\n\t\t\tlogToFile: false,\n\t\t\tlogLevel: isDebugMode ? 'debug' : 'info', // Set log level to debug when DEBUG=true\n\t\t\tmaxFileSize: 10 * 1024 * 1024, // 10MB\n\t\t\tmaxFiles: 5,\n\t\t\tconsoleOutput: isDebugMode, // Enable console output when DEBUG=true\n\t\t\t...config,\n\t\t};\n\n\t\tthis.logFilePath =\n\t\t\tthis.config.logFilePath || path.join(os.homedir(), '.braingrid', 'logs', 'braingrid-cli.log');\n\n\t\tif (this.config.logToFile) {\n\t\t\tthis.ensureLogDirectory();\n\t\t}\n\t}\n\n\tprivate ensureLogDirectory(): void {\n\t\tconst logDir = path.dirname(this.logFilePath);\n\t\tif (!fs.existsSync(logDir)) {\n\t\t\tfs.mkdirSync(logDir, { recursive: true });\n\t\t}\n\t}\n\n\tprivate shouldLog(level: LogLevel): boolean {\n\t\tconst levels: LogLevel[] = ['debug', 'info', 'warn', 'error'];\n\t\treturn levels.indexOf(level) >= levels.indexOf(this.config.logLevel);\n\t}\n\n\tprivate formatLogEntry(entry: LogEntry): string {\n\t\tconst timestamp = entry.timestamp.toISOString();\n\t\tconst level = entry.level.toUpperCase().padEnd(5);\n\t\tconst type = entry.type.toUpperCase().padEnd(7);\n\t\tconst contextStr = entry.context ? ` | ${JSON.stringify(entry.context)}` : '';\n\t\treturn `[${timestamp}] ${level} [${type}] ${entry.message}${contextStr}`;\n\t}\n\n\tprivate writeToFile(entry: LogEntry): void {\n\t\tif (!this.config.logToFile) return;\n\n\t\ttry {\n\t\t\tconst logLine = this.formatLogEntry(entry) + '\\n';\n\n\t\t\t// Check file size and rotate if necessary\n\t\t\tif (fs.existsSync(this.logFilePath)) {\n\t\t\t\tconst stats = fs.statSync(this.logFilePath);\n\t\t\t\tif (stats.size > this.config.maxFileSize) {\n\t\t\t\t\tthis.rotateLogFile();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfs.appendFileSync(this.logFilePath, logLine);\n\t\t} catch (error) {\n\t\t\tconsole.error('Failed to write to log file:', error);\n\t\t}\n\t}\n\n\tprivate rotateLogFile(): void {\n\t\ttry {\n\t\t\t// Rotate log files\n\t\t\tfor (let i = this.config.maxFiles - 1; i >= 1; i--) {\n\t\t\t\tconst oldFile = `${this.logFilePath}.${i}`;\n\t\t\t\tconst newFile = `${this.logFilePath}.${i + 1}`;\n\n\t\t\t\tif (fs.existsSync(oldFile)) {\n\t\t\t\t\tif (i === this.config.maxFiles - 1) {\n\t\t\t\t\t\tfs.unlinkSync(oldFile); // Delete oldest file\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfs.renameSync(oldFile, newFile);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Move current log to .1\n\t\t\tif (fs.existsSync(this.logFilePath)) {\n\t\t\t\tfs.renameSync(this.logFilePath, `${this.logFilePath}.1`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error('Failed to rotate log file:', error);\n\t\t}\n\t}\n\n\tprivate log(\n\t\tlevel: LogLevel,\n\t\ttype: MessageType,\n\t\tmessage: string,\n\t\tcontext?: Record<string, unknown>\n\t): void {\n\t\tif (!this.shouldLog(level)) return;\n\n\t\tconst entry: LogEntry = {\n\t\t\ttimestamp: new Date(),\n\t\t\tlevel,\n\t\t\ttype,\n\t\t\tmessage,\n\t\t\tcontext,\n\t\t};\n\n\t\t// Write to file if enabled\n\t\tthis.writeToFile(entry);\n\n\t\t// Write to console if enabled and it's a debug message\n\t\tif (this.config.consoleOutput && level === 'debug') {\n\t\t\tconst contextStr = context ? ` ${JSON.stringify(context)}` : '';\n\t\t\t// Write to stderr so it doesn't interfere with CLI output\n\t\t\tconsole.error(`${message}${contextStr}`);\n\t\t}\n\t}\n\n\tdebug(message: string, context?: Record<string, unknown>): void {\n\t\tthis.log('debug', 'debug', message, context);\n\t}\n\n\tinfo(message: string, context?: Record<string, unknown>): void {\n\t\tthis.log('info', 'info', message, context);\n\t}\n\n\twarn(message: string, context?: Record<string, unknown>): void {\n\t\tthis.log('warn', 'info', message, context);\n\t}\n\n\terror(message: string, context?: Record<string, unknown>): void {\n\t\tthis.log('error', 'error', message, context);\n\t}\n\n\tuserMessage(message: string, context?: Record<string, unknown>): void {\n\t\tthis.log('info', 'user', message, context);\n\t}\n\n\tsystemMessage(message: string, context?: Record<string, unknown>): void {\n\t\tthis.log('info', 'system', message, context);\n\t}\n\n\t// Log streaming output with full content\n\tstreamOutput(message: string, isError = false): void {\n\t\tthis.log(isError ? 'error' : 'info', isError ? 'error' : 'system', message);\n\t}\n\n\t// Update configuration\n\tupdateConfig(newConfig: Partial<LoggerConfig>): void {\n\t\tconst wasLoggingToFile = this.config.logToFile;\n\t\tthis.config = { ...this.config, ...newConfig };\n\n\t\tif (this.config.logToFile && !wasLoggingToFile) {\n\t\t\tthis.ensureLogDirectory();\n\t\t\tthis.info('File logging enabled', { logFilePath: this.logFilePath });\n\t\t} else if (!this.config.logToFile && wasLoggingToFile) {\n\t\t\tthis.info('File logging disabled');\n\t\t}\n\t}\n\n\t// Get current log file path\n\tgetLogFilePath(): string {\n\t\treturn this.logFilePath;\n\t}\n\n\t// Get log file size in MB\n\tgetLogFileSize(): number {\n\t\ttry {\n\t\t\tif (fs.existsSync(this.logFilePath)) {\n\t\t\t\tconst stats = fs.statSync(this.logFilePath);\n\t\t\t\treturn stats.size / (1024 * 1024);\n\t\t\t}\n\t\t\treturn 0;\n\t\t} catch {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t// Clear log file\n\tclearLogFile(): void {\n\t\ttry {\n\t\t\tif (fs.existsSync(this.logFilePath)) {\n\t\t\t\tfs.unlinkSync(this.logFilePath);\n\t\t\t\tthis.info('Log file cleared');\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error('Failed to clear log file:', error);\n\t\t}\n\t}\n}\n\n// Create singleton logger instance\nlet loggerInstance: Logger | null = null;\n\nexport function getLogger(config?: Partial<LoggerConfig>): Logger {\n\tif (!loggerInstance) {\n\t\tloggerInstance = new Logger(config);\n\t}\n\treturn loggerInstance;\n}\n\nexport function initializeLogger(config: Partial<LoggerConfig>): Logger {\n\tloggerInstance = new Logger(config);\n\treturn loggerInstance;\n}\n\nexport { Logger };\n","/**\n * Project Service\n * Handles all API interactions for projects\n */\n\nimport { AxiosInstance } from 'axios';\nimport { BraingridAuth } from './auth.js';\nimport { createAuthenticatedAxios } from '../utils/axios-with-auth.js';\nimport {\n\tProject,\n\tCreateProjectRequest,\n\tUpdateProjectRequest,\n\tListProjectsResponse,\n\tListProjectsWithRepositoryResponse,\n} from '../types/project.js';\n\nexport class ProjectService {\n\tprivate baseUrl: string;\n\tprivate auth: BraingridAuth;\n\tprivate axios: AxiosInstance;\n\n\tconstructor(baseUrl: string, auth: BraingridAuth) {\n\t\tthis.baseUrl = baseUrl;\n\t\tthis.auth = auth;\n\t\tthis.axios = createAuthenticatedAxios(auth);\n\t}\n\n\tprivate getHeaders(): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t};\n\t}\n\n\tasync listProjects(params: {\n\t\tpage?: number;\n\t\tlimit?: number;\n\t\trepository_owner?: string;\n\t\trepository_name?: string;\n\t}): Promise<ListProjectsResponse | ListProjectsWithRepositoryResponse> {\n\t\tconst queryParams = new URLSearchParams();\n\t\tif (params.page) queryParams.append('page', params.page.toString());\n\t\tif (params.limit) queryParams.append('limit', params.limit.toString());\n\t\tif (params.repository_owner) queryParams.append('repository_owner', params.repository_owner);\n\t\tif (params.repository_name) queryParams.append('repository_name', params.repository_name);\n\n\t\tconst url = `${this.baseUrl}/api/v1/projects?${queryParams.toString()}`;\n\t\tconst headers = this.getHeaders();\n\n\t\t// API returns different response structures based on query parameters:\n\t\t// - ListProjectsResponse (with pagination) for regular lists\n\t\t// - ListProjectsWithRepositoryResponse (with total_count) for repository filters\n\t\t// Handlers are equipped to handle both types via union type\n\t\tconst response = await this.axios.get<\n\t\t\tListProjectsResponse | ListProjectsWithRepositoryResponse\n\t\t>(url, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync getProject(projectId: string): Promise<Project> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<Project>(url, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync createProject(data: CreateProjectRequest): Promise<Project> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.post<Project>(url, data, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync updateProject(projectId: string, data: UpdateProjectRequest): Promise<Project> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.patch<Project>(url, data, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync deleteProject(projectId: string): Promise<void> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tawait this.axios.delete(url, { headers });\n\t}\n}\n","import axios from 'axios';\nimport { User, BraingridSession, GitUser } from '../types/auth.js';\nimport { axiosWithRetry } from '../utils/axios-retry.js';\nimport { OAuth2Handler } from './oauth2-auth.js';\nimport { getConfig } from '../utils/config.js';\nimport { decodeJWT, isJWTExpired, extractUserFromJWT } from '../utils/jwt.js';\nimport { getLogger } from '../utils/logger.js';\nimport { credentialStore } from './credential-store.js';\n\nconst KEYCHAIN_SERVICE = 'braingrid-cli';\nconst KEYCHAIN_ACCOUNT = 'session';\nconst GITHUB_KEYCHAIN_ACCOUNT = 'github-token';\n\nexport class BraingridAuth {\n\tprivate baseUrl: string;\n\tprivate lastValidationTime: number = 0;\n\tprivate lastValidationResult: boolean = false;\n\tprivate loginTime: number = 0;\n\tprivate readonly VALIDATION_CACHE_MS = 60 * 60 * 1000; // Cache validation for 1 hour\n\tprivate readonly POST_LOGIN_GRACE_MS = 24 * 60 * 60 * 1000; // 24 hours grace period after login\n\tprivate oauthHandler: OAuth2Handler | null = null;\n\tprivate refreshTokenValue?: string; // Store refresh token separately\n\tprivate logger = getLogger();\n\n\tconstructor(baseUrl?: string) {\n\t\tconst config = getConfig();\n\t\tthis.baseUrl = baseUrl || config.apiUrl || 'https://app.braingrid.ai';\n\t}\n\n\tasync isAuthenticated(forceValidation: boolean = false): Promise<boolean> {\n\t\ttry {\n\t\t\tconst session = await this.getStoredSession();\n\t\t\tif (!session) {\n\t\t\t\tthis.logger.debug('[AUTH] No stored session found');\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Debug: Log session dates\n\t\t\tthis.logger.debug('[AUTH] Session dates:', {\n\t\t\t\tcreated_at: session.created_at,\n\t\t\t\tupdated_at: session.updated_at,\n\t\t\t\tlogin_time: session.login_time,\n\t\t\t\tnow: new Date(),\n\t\t\t});\n\n\t\t\t// Check if session is expired (JWT tokens expire in 1 hour)\n\t\t\tif (this.isSessionExpired(session)) {\n\t\t\t\tthis.logger.debug(\n\t\t\t\t\t'[AUTH] Session expired (JWT token expired) - attempting automatic refresh'\n\t\t\t\t);\n\n\t\t\t\t// Attempt to refresh the session using refresh token\n\t\t\t\tconst refreshed = await this.refreshSession();\n\t\t\t\tif (refreshed) {\n\t\t\t\t\tthis.logger.debug('[AUTH] Session refreshed successfully');\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tthis.logger.debug('[AUTH] Session refresh failed - authentication required');\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst now = Date.now();\n\n\t\t\t// If forced validation is requested, skip all caching and validate with server\n\t\t\tif (forceValidation) {\n\t\t\t\tthis.logger.debug('[AUTH] Force validation requested - calling server');\n\t\t\t\tconst validationResult = await this.validateSessionWithServer(session);\n\t\t\t\tthis.lastValidationTime = now;\n\t\t\t\tthis.lastValidationResult = validationResult.isValid;\n\n\t\t\t\tthis.logger.debug(\n\t\t\t\t\t`[AUTH] Server validation result: isValid=${validationResult.isValid}, shouldClearSession=${validationResult.shouldClearSession}`\n\t\t\t\t);\n\n\t\t\t\tif (!validationResult.isValid && validationResult.shouldClearSession) {\n\t\t\t\t\tthis.logger.debug('[AUTH] Clearing session due to validation failure');\n\t\t\t\t\tawait this.clearSession();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn validationResult.isValid;\n\t\t\t}\n\n\t\t\t// Grace period: If we're within 1 hour of login, skip server validation\n\t\t\t// Reduced from 24 hours to 1 hour to catch auth issues faster\n\t\t\tlet effectiveLoginTime = this.loginTime;\n\t\t\tif (effectiveLoginTime === 0) {\n\t\t\t\t// Restore login time from session if not set (CLI restart scenario)\n\t\t\t\tif (session.login_time) {\n\t\t\t\t\teffectiveLoginTime = session.login_time.getTime();\n\t\t\t\t\tthis.loginTime = effectiveLoginTime;\n\t\t\t\t} else {\n\t\t\t\t\t// Fallback to updated_at if login_time is not available (old sessions)\n\t\t\t\t\teffectiveLoginTime = session.updated_at.getTime();\n\t\t\t\t\tthis.loginTime = effectiveLoginTime;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst timeSinceLogin = now - effectiveLoginTime;\n\t\t\tconst graceMs = 60 * 60 * 1000; // 1 hour instead of 24 hours\n\t\t\tthis.logger.debug(\n\t\t\t\t`[AUTH] Time since login: ${timeSinceLogin}ms (${Math.round(timeSinceLogin / 1000)}s), grace period: ${graceMs}ms`\n\t\t\t);\n\t\t\tthis.logger.debug(\n\t\t\t\t`[AUTH] Login time: ${new Date(effectiveLoginTime)}, Now: ${new Date(now)}`\n\t\t\t);\n\t\t\tif (timeSinceLogin < graceMs) {\n\t\t\t\t// Within 1-hour grace period after login - skip server validation\n\t\t\t\tthis.logger.debug('[AUTH] Within grace period - skipping server validation');\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// Use cached validation result if recent enough (15 minutes instead of 1 hour)\n\t\t\tconst cacheMs = 15 * 60 * 1000; // 15 minutes\n\t\t\tif (now - this.lastValidationTime < cacheMs && this.lastValidationResult) {\n\t\t\t\t// Only trust positive cached results, always revalidate failures\n\t\t\t\treturn this.lastValidationResult;\n\t\t\t}\n\n\t\t\t// Validate with server\n\t\t\tconst validationResult = await this.validateSessionWithServer(session);\n\t\t\tthis.lastValidationTime = now;\n\t\t\tthis.lastValidationResult = validationResult.isValid;\n\n\t\t\t// Update user data if validation returned fresh user info\n\t\t\tif (validationResult.user && session.user) {\n\t\t\t\tsession.user = validationResult.user;\n\t\t\t}\n\n\t\t\t// Only clear session for definitive authentication failures, not temporary issues\n\t\t\tif (!validationResult.isValid) {\n\t\t\t\tif (validationResult.shouldClearSession) {\n\t\t\t\t\t// Clear session only for permanent auth failures (401, 403, invalid token)\n\t\t\t\t\tawait this.clearSession();\n\t\t\t\t\treturn false;\n\t\t\t\t} else {\n\t\t\t\t\t// For temporary issues (network errors, 500s, redirects), don't clear session\n\t\t\t\t\t// Fall back to local session check to be more forgiving\n\t\t\t\t\treturn !this.isSessionExpired(session);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} catch {\n\t\t\t// On any error, check if we have a local session that isn't expired\n\t\t\ttry {\n\t\t\t\tconst session = await this.getStoredSession();\n\t\t\t\treturn session !== null && !this.isSessionExpired(session);\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync getCurrentUser(): Promise<User | null> {\n\t\ttry {\n\t\t\tconst session = await this.getStoredSession();\n\t\t\tif (!session) return null;\n\n\t\t\t// First try to get user from stored session\n\t\t\tif (session.user && session.user.id && session.user.email) {\n\t\t\t\treturn session.user;\n\t\t\t}\n\n\t\t\t// If user info is missing or incomplete, decode from JWT\n\t\t\tconst jwtPayload = decodeJWT(session.sealed_session);\n\t\t\tif (!jwtPayload) {\n\t\t\t\t// If we can't decode the JWT, return what we have\n\t\t\t\treturn session.user || null;\n\t\t\t}\n\n\t\t\t// Extract user info from JWT\n\t\t\tconst userInfo = extractUserFromJWT(jwtPayload);\n\n\t\t\t// Create a User object from JWT data\n\t\t\tconst user: User = {\n\t\t\t\tobject: 'user',\n\t\t\t\tid: userInfo.id,\n\t\t\t\temail: userInfo.email,\n\t\t\t\temailVerified: true, // Assume verified if they have a valid JWT\n\t\t\t\tfirstName: userInfo.firstName,\n\t\t\t\tlastName: userInfo.lastName,\n\t\t\t\tprofilePictureUrl: '', // Not available in JWT\n\t\t\t\tcreatedAt: new Date(jwtPayload.iat ? jwtPayload.iat * 1000 : Date.now()).toISOString(),\n\t\t\t\tupdatedAt: new Date().toISOString(),\n\t\t\t\tlastSignInAt: new Date().toISOString(),\n\t\t\t\texternalId: null,\n\t\t\t\tmetadata: jwtPayload.metadata || {},\n\t\t\t};\n\n\t\t\t// Update the stored session with user info from JWT\n\t\t\tsession.user = user;\n\t\t\tawait this.storeSession(session);\n\n\t\t\treturn user;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync hasStoredSession(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst session = await this.getStoredSession();\n\t\t\treturn session !== null && !this.isSessionExpired(session);\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync getStoredSession(): Promise<BraingridSession | null> {\n\t\ttry {\n\t\t\tconst sessionData = await credentialStore.getPassword(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT);\n\t\t\tif (!sessionData) return null;\n\n\t\t\tconst session = JSON.parse(sessionData) as BraingridSession;\n\t\t\treturn {\n\t\t\t\t...session,\n\t\t\t\tcreated_at: new Date(session.created_at),\n\t\t\t\tupdated_at: new Date(session.updated_at),\n\t\t\t\tlogin_time: session.login_time ? new Date(session.login_time) : undefined,\n\t\t\t};\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync storeSession(session: BraingridSession): Promise<void> {\n\t\tconst now = new Date();\n\t\t// Add login time to session data for persistence across CLI instances\n\t\tconst sessionWithLoginTime = {\n\t\t\t...session,\n\t\t\tlogin_time: now,\n\t\t};\n\t\tconst sessionData = JSON.stringify(sessionWithLoginTime);\n\t\tawait credentialStore.setPassword(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, sessionData);\n\t\t// Mark session as valid when we store it and record login time\n\t\tconst nowMs = now.getTime();\n\t\tthis.lastValidationTime = nowMs;\n\t\tthis.lastValidationResult = true;\n\t\tthis.loginTime = nowMs;\n\t}\n\n\tasync clearSession(): Promise<void> {\n\t\tawait credentialStore.deletePassword(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT);\n\t\t// Also clear refresh token\n\t\tawait credentialStore.deletePassword(KEYCHAIN_SERVICE, 'refresh-token');\n\t\tthis.refreshTokenValue = undefined;\n\t\t// Clear the validation cache when session is cleared\n\t\tthis.lastValidationTime = 0;\n\t\tthis.lastValidationResult = false;\n\t}\n\n\tasync handleAuthenticationError(): Promise<void> {\n\t\t// Clear validation cache but don't automatically clear session\n\t\t// Let the user explicitly re-authenticate if needed\n\t\tthis.lastValidationTime = 0;\n\t\tthis.lastValidationResult = false;\n\t}\n\n\t/**\n\t * Start login flow for RPC mode - returns auth URL without opening browser\n\t */\n\tasync startLoginForRpc(): Promise<{ authUrl: string; redirectUri: string }> {\n\t\ttry {\n\t\t\t// Use OAuth2 Authorization Code Flow with PKCE for authentication\n\t\t\tthis.oauthHandler = new OAuth2Handler();\n\n\t\t\t// Prepare auth URL without opening browser\n\t\t\tconst urlResult = await this.oauthHandler.prepareAuthUrl();\n\n\t\t\treturn {\n\t\t\t\tauthUrl: urlResult.authUrl,\n\t\t\t\tredirectUri: urlResult.redirectUri,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tif (this.oauthHandler) {\n\t\t\t\tthis.oauthHandler.abort();\n\t\t\t\tthis.oauthHandler = null;\n\t\t\t}\n\t\t\tthrow new Error(`Failed to start login: ${error}`);\n\t\t}\n\t}\n\n\t/**\n\t * Complete login flow for RPC mode - waits for browser callback\n\t */\n\tasync completeLoginForRpc(): Promise<{ user: User; success: boolean }> {\n\t\tif (!this.oauthHandler) {\n\t\t\tthrow new Error('Must call startLoginForRpc() first');\n\t\t}\n\n\t\ttry {\n\t\t\t// Wait for OAuth callback and get tokens\n\t\t\tconst authResult = await this.oauthHandler.completeAuth();\n\n\t\t\t// Process tokens and create session (same as regular login)\n\t\t\treturn await this.processAuthResult(authResult);\n\t\t} catch (error) {\n\t\t\tif (this.oauthHandler) {\n\t\t\t\tthis.oauthHandler.abort();\n\t\t\t\tthis.oauthHandler = null;\n\t\t\t}\n\t\t\tthrow new Error(`Login failed: ${error}`);\n\t\t}\n\t}\n\n\t/**\n\t * Process OAuth result and create session\n\t */\n\tprivate async processAuthResult(\n\t\tauthResult: {\n\t\t\taccessToken: string;\n\t\t\trefreshToken?: string;\n\t\t\tidToken?: string;\n\t\t},\n\t\tgitUser?: GitUser\n\t): Promise<{ user: User; success: boolean }> {\n\t\t// Store refresh token separately if available\n\t\tif (authResult.refreshToken) {\n\t\t\tthis.refreshTokenValue = authResult.refreshToken;\n\t\t\t// Store refresh token securely\n\t\t\tawait credentialStore.setPassword(KEYCHAIN_SERVICE, 'refresh-token', authResult.refreshToken);\n\t\t}\n\n\t\t// Use ID token if available, otherwise use access token\n\t\tconst tokenToProcess = authResult.idToken || authResult.accessToken;\n\n\t\t// Extract user info from JWT\n\t\tconst jwtPayload = decodeJWT(tokenToProcess);\n\t\tif (!jwtPayload) {\n\t\t\tthrow new Error('Invalid token received - unable to decode');\n\t\t}\n\n\t\t// Extract user info from JWT\n\t\tconst userInfo = extractUserFromJWT(jwtPayload);\n\n\t\t// Create user object from JWT data\n\t\tconst user: User = {\n\t\t\tobject: 'user',\n\t\t\tid: userInfo.id,\n\t\t\temail: userInfo.email,\n\t\t\temailVerified: true, // Assume verified if they have a valid JWT\n\t\t\tfirstName: userInfo.firstName,\n\t\t\tlastName: userInfo.lastName,\n\t\t\tprofilePictureUrl: '', // Not available in JWT\n\t\t\tcreatedAt: new Date(jwtPayload.iat ? jwtPayload.iat * 1000 : Date.now()).toISOString(),\n\t\t\tupdatedAt: new Date().toISOString(),\n\t\t\tlastSignInAt: new Date().toISOString(),\n\t\t\texternalId: null,\n\t\t\tmetadata: jwtPayload.metadata || {},\n\t\t};\n\n\t\t// Store the session\n\t\tconst session: BraingridSession = {\n\t\t\tuser: user,\n\t\t\tsealed_session: authResult.accessToken, // Store access token as sealed_session\n\t\t\torganization_id: jwtPayload.organization_id || 'default', // Use organization from token or default\n\t\t\tcreated_at: new Date(),\n\t\t\tupdated_at: new Date(),\n\t\t\tlogin_time: new Date(),\n\t\t\tgit_user: gitUser, // Store git user info if provided\n\t\t};\n\n\t\tawait this.storeSession(session);\n\n\t\treturn { user, success: true };\n\t}\n\n\tasync login(\n\t\tonAuthUrl?: (authUrl: string) => void,\n\t\tgitUser?: GitUser\n\t): Promise<{ user: User; success: boolean }> {\n\t\ttry {\n\t\t\t// Use OAuth2 Authorization Code Flow with PKCE for authentication\n\t\t\tthis.oauthHandler = new OAuth2Handler();\n\n\t\t\t// Set callback if provided\n\t\t\tif (onAuthUrl) {\n\t\t\t\tthis.oauthHandler.setAuthUrlCallback(onAuthUrl);\n\t\t\t}\n\n\t\t\tconst authResult = await this.oauthHandler.authenticate();\n\n\t\t\t// Process auth result and create session\n\t\t\treturn await this.processAuthResult(authResult, gitUser);\n\t\t} catch (error) {\n\t\t\tif (this.oauthHandler) {\n\t\t\t\tthis.oauthHandler.abort();\n\t\t\t\tthis.oauthHandler = null;\n\t\t\t}\n\t\t\tthrow new Error(`Login failed: ${error}`);\n\t\t}\n\t}\n\n\tcancelLogin(): void {\n\t\tif (this.oauthHandler) {\n\t\t\tthis.oauthHandler.abort();\n\t\t\tthis.oauthHandler = null;\n\t\t}\n\t}\n\n\tasync logout(): Promise<void> {\n\t\tawait this.clearSession();\n\t}\n\n\tasync refreshSession(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst session = await this.getStoredSession();\n\t\t\tif (!session) {\n\t\t\t\tthis.logger.debug('[AUTH] No session found for refresh');\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Get stored refresh token\n\t\t\tlet refreshToken = this.refreshTokenValue;\n\t\t\tif (!refreshToken) {\n\t\t\t\trefreshToken =\n\t\t\t\t\t(await credentialStore.getPassword(KEYCHAIN_SERVICE, 'refresh-token')) || undefined;\n\t\t\t}\n\n\t\t\tif (!refreshToken) {\n\t\t\t\t// No refresh token available, cannot refresh\n\t\t\t\tthis.logger.debug('[AUTH] No refresh token available');\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis.logger.debug('[AUTH] Attempting to refresh access token');\n\n\t\t\t// Use OAuth2 handler to refresh the token\n\t\t\tconst handler = new OAuth2Handler();\n\t\t\tconst authResult = await handler.refreshToken(refreshToken);\n\n\t\t\t// Update stored refresh token if new one provided\n\t\t\tif (authResult.refreshToken && authResult.refreshToken !== refreshToken) {\n\t\t\t\tthis.refreshTokenValue = authResult.refreshToken;\n\t\t\t\tawait credentialStore.setPassword(\n\t\t\t\t\tKEYCHAIN_SERVICE,\n\t\t\t\t\t'refresh-token',\n\t\t\t\t\tauthResult.refreshToken\n\t\t\t\t);\n\t\t\t\tthis.logger.debug('[AUTH] Refresh token rotated');\n\t\t\t}\n\n\t\t\t// Update session with new access token\n\t\t\tsession.sealed_session = authResult.accessToken;\n\t\t\tsession.updated_at = new Date();\n\t\t\tawait this.storeSession(session);\n\n\t\t\tthis.logger.debug('[AUTH] Access token refreshed successfully');\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\tthis.logger.warn(`[AUTH] Token refresh failed: ${errorMsg}`);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate async validateSessionWithServer(\n\t\tsession: BraingridSession\n\t): Promise<{ isValid: boolean; shouldClearSession: boolean; user?: User }> {\n\t\ttry {\n\t\t\tthis.logger.debug(\n\t\t\t\t`[AUTH] Making API call to ${this.baseUrl}/api/v1/auth/validate for session validation`\n\t\t\t);\n\t\t\t// Use the new v1 auth validate endpoint\n\t\t\tconst response = await axiosWithRetry(\n\t\t\t\t{\n\t\t\t\t\turl: `${this.baseUrl}/api/v1/auth/validate`,\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\tAuthorization: `Bearer ${session.sealed_session}`,\n\t\t\t\t\t},\n\t\t\t\t\tmaxRedirects: 0, // Don't follow redirects\n\t\t\t\t\tvalidateStatus: status => status < 500, // Accept all status codes < 500\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tmaxRetries: 2,\n\t\t\t\t\tinitialDelay: 500,\n\t\t\t\t\tonRetry: (attempt, delay) => {\n\t\t\t\t\t\tconsole.warn(`Retrying session validation (attempt ${attempt}) after ${delay}ms`);\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tthis.logger.debug(\n\t\t\t\t`[AUTH] API response: status=${response.status}, contentType=${response.headers['content-type']}`\n\t\t\t);\n\n\t\t\t// Debug response data\n\t\t\tif (response.headers['content-type']?.includes('application/json')) {\n\t\t\t\tthis.logger.debug('[AUTH] API response data:', {\n\t\t\t\t\tdata: JSON.stringify(response.data).substring(0, 200),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Handle redirects (302, 307) - likely temporary, don't clear session\n\t\t\tif (response.status === 302 || response.status === 307) {\n\t\t\t\tthis.logger.warn(\n\t\t\t\t\t`Session validation received ${response.status} redirect - treating as temporary issue`\n\t\t\t\t);\n\t\t\t\treturn { isValid: false, shouldClearSession: false };\n\t\t\t}\n\n\t\t\tif (response.status === 200) {\n\t\t\t\t// Parse the validation response\n\t\t\t\tconst validationData = response.data as {\n\t\t\t\t\tvalid: boolean;\n\t\t\t\t\texp?: number;\n\t\t\t\t\tuser?: {\n\t\t\t\t\t\tid: string;\n\t\t\t\t\t\temail: string;\n\t\t\t\t\t\tusername?: string;\n\t\t\t\t\t\tfirstName?: string;\n\t\t\t\t\t\tlastName?: string;\n\t\t\t\t\t\tavatar?: string;\n\t\t\t\t\t};\n\t\t\t\t\torganization?: {\n\t\t\t\t\t\tid: string;\n\t\t\t\t\t\tname: string;\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\tif (validationData.valid === true && validationData.user) {\n\t\t\t\t\t// Extract user information from the validation response\n\t\t\t\t\tconst user: User = {\n\t\t\t\t\t\tobject: 'user',\n\t\t\t\t\t\tid: validationData.user.id,\n\t\t\t\t\t\temail: validationData.user.email,\n\t\t\t\t\t\temailVerified: true, // Assume verified if they have a valid token\n\t\t\t\t\t\tfirstName: validationData.user.firstName || '',\n\t\t\t\t\t\tlastName: validationData.user.lastName || '',\n\t\t\t\t\t\tprofilePictureUrl: validationData.user.avatar || '',\n\t\t\t\t\t\tcreatedAt: session.user?.createdAt || new Date().toISOString(),\n\t\t\t\t\t\tupdatedAt: new Date().toISOString(),\n\t\t\t\t\t\tlastSignInAt: new Date().toISOString(),\n\t\t\t\t\t\texternalId: null,\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\tusername: validationData.user.username,\n\t\t\t\t\t\t\torganizationId: validationData.organization?.id,\n\t\t\t\t\t\t\torganizationName: validationData.organization?.name,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\n\t\t\t\t\t// Update the stored session with fresh user info\n\t\t\t\t\tif (\n\t\t\t\t\t\tsession.user?.id !== user.id ||\n\t\t\t\t\t\tsession.user?.email !== user.email ||\n\t\t\t\t\t\tsession.user?.firstName !== user.firstName ||\n\t\t\t\t\t\tsession.user?.lastName !== user.lastName\n\t\t\t\t\t) {\n\t\t\t\t\t\tsession.user = user;\n\t\t\t\t\t\tsession.organization_id = validationData.organization?.id || session.organization_id;\n\t\t\t\t\t\tawait this.storeSession(session);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn { isValid: true, shouldClearSession: false, user };\n\t\t\t\t} else if (validationData.valid === false) {\n\t\t\t\t\t// Token is explicitly invalid\n\t\t\t\t\tthis.logger.warn('Token validation failed: token is invalid');\n\t\t\t\t\treturn { isValid: false, shouldClearSession: true };\n\t\t\t\t}\n\n\t\t\t\t// Unexpected response format\n\t\t\t\tthis.logger.warn('Unexpected validation response format');\n\t\t\t\treturn { isValid: false, shouldClearSession: false };\n\t\t\t} else if (response.status === 401 || response.status === 403) {\n\t\t\t\t// Clear session for definitive authentication failures\n\t\t\t\tthis.logger.warn(\n\t\t\t\t\t`Session validation failed: ${response.status} ${response.statusText} - clearing session`\n\t\t\t\t);\n\t\t\t\treturn { isValid: false, shouldClearSession: true };\n\t\t\t} else {\n\t\t\t\t// For other errors (500, 404, etc.), don't clear session - might be temporary\n\t\t\t\tthis.logger.warn(\n\t\t\t\t\t`API error during session validation: ${response.status} - assuming session is valid`\n\t\t\t\t);\n\t\t\t\treturn { isValid: true, shouldClearSession: false }; // Assume session is still valid, server might be having issues\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Network error or API unavailable - don't clear session, might be temporary\n\t\t\tthis.logger.warn('Network error during session validation - assuming session is valid:', {\n\t\t\t\terror,\n\t\t\t});\n\t\t\treturn { isValid: true, shouldClearSession: false };\n\t\t}\n\t}\n\n\tprivate isSessionExpired(session: BraingridSession): boolean {\n\t\t// JWT tokens expire in 1 hour, so we only need to check JWT expiry\n\t\treturn isJWTExpired(session.sealed_session);\n\t}\n\n\tgetUserDisplayName(user: User): string {\n\t\tif (user.firstName && user.lastName) {\n\t\t\treturn `${user.firstName} ${user.lastName}`;\n\t\t}\n\t\tif (user.firstName) {\n\t\t\treturn user.firstName;\n\t\t}\n\t\tif (user.email) {\n\t\t\treturn user.email;\n\t\t}\n\t\treturn 'Unknown User';\n\t}\n\n\tisUserValid(user: User): boolean {\n\t\treturn Boolean(user.id && user.email);\n\t}\n\n\tisSessionValid(session: BraingridSession): boolean {\n\t\treturn this.isUserValid(session.user) && Boolean(session.sealed_session);\n\t}\n\n\t// GitHub token management methods\n\tasync getStoredGitHubToken(): Promise<string | null> {\n\t\ttry {\n\t\t\treturn await credentialStore.getPassword(KEYCHAIN_SERVICE, GITHUB_KEYCHAIN_ACCOUNT);\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync storeGitHubToken(token: string): Promise<void> {\n\t\tif (!token || !token.trim()) {\n\t\t\tthrow new Error('GitHub token cannot be empty');\n\t\t}\n\t\tawait credentialStore.setPassword(KEYCHAIN_SERVICE, GITHUB_KEYCHAIN_ACCOUNT, token.trim());\n\t}\n\n\tasync clearGitHubToken(): Promise<void> {\n\t\tawait credentialStore.deletePassword(KEYCHAIN_SERVICE, GITHUB_KEYCHAIN_ACCOUNT);\n\t}\n\n\tasync validateGitHubToken(\n\t\ttoken?: string\n\t): Promise<{ valid: boolean; user?: Record<string, unknown>; scopes?: string[] }> {\n\t\ttry {\n\t\t\tconst tokenToValidate = token || (await this.getStoredGitHubToken());\n\t\t\tif (!tokenToValidate) {\n\t\t\t\treturn { valid: false };\n\t\t\t}\n\n\t\t\tconst response = await axios.get('https://api.github.com/user', {\n\t\t\t\theaders: {\n\t\t\t\t\tAccept: 'application/vnd.github+json',\n\t\t\t\t\tAuthorization: `Bearer ${tokenToValidate}`,\n\t\t\t\t\t'X-GitHub-Api-Version': '2022-11-28',\n\t\t\t\t\t'User-Agent': 'Braingrid-CLI',\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (response.status >= 400) {\n\t\t\t\treturn { valid: false };\n\t\t\t}\n\n\t\t\tconst user = response.data;\n\t\t\tconst scopes = response.headers['x-oauth-scopes']?.split(', ') || [];\n\n\t\t\treturn {\n\t\t\t\tvalid: true,\n\t\t\t\tuser,\n\t\t\t\tscopes,\n\t\t\t};\n\t\t} catch {\n\t\t\treturn { valid: false };\n\t\t}\n\t}\n}\n","import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';\n\nexport interface RetryOptions {\n\tmaxRetries?: number;\n\tinitialDelay?: number;\n\tmaxDelay?: number;\n\tbackoffMultiplier?: number;\n\tretryableStatuses?: number[];\n\tonRetry?: (attempt: number, delay: number, error: unknown) => void;\n}\n\nconst DEFAULT_OPTIONS: Required<RetryOptions> = {\n\tmaxRetries: 3,\n\tinitialDelay: 1000, // 1 second\n\tmaxDelay: 30000, // 30 seconds\n\tbackoffMultiplier: 2,\n\tretryableStatuses: [408, 429, 500, 502, 503, 504], // Timeout, Too Many Requests, Server Errors\n\tonRetry: () => {}, // No-op by default\n};\n\nexport async function sleep(ms: number): Promise<void> {\n\treturn new Promise(resolve => setTimeout(resolve, ms));\n}\n\nexport function calculateDelay(\n\tattempt: number,\n\tinitialDelay: number,\n\tmaxDelay: number,\n\tbackoffMultiplier: number\n): number {\n\tconst exponentialDelay = initialDelay * Math.pow(backoffMultiplier, attempt - 1);\n\tconst jitteredDelay = exponentialDelay * (0.5 + Math.random() * 0.5); // Add jitter\n\treturn Math.min(jitteredDelay, maxDelay);\n}\n\nexport function isRetryableError(error: unknown, retryableStatuses: number[]): boolean {\n\t// Type guard to check if error has expected properties\n\tconst hasErrorCode = (err: unknown): err is { code: string } =>\n\t\ttypeof err === 'object' && err !== null && 'code' in err;\n\tconst hasErrorMessage = (err: unknown): err is { message?: string } =>\n\t\ttypeof err === 'object' && err !== null;\n\tconst hasResponseStatus = (err: unknown): err is { response?: { status: number } } =>\n\t\ttypeof err === 'object' && err !== null && 'response' in err;\n\t// Network errors are always retryable\n\tif (hasErrorCode(error)) {\n\t\tif (\n\t\t\terror.code === 'ECONNRESET' ||\n\t\t\terror.code === 'ETIMEDOUT' ||\n\t\t\terror.code === 'ENOTFOUND' ||\n\t\t\terror.code === 'ECONNREFUSED' ||\n\t\t\terror.code === 'ECONNABORTED'\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tif (hasErrorMessage(error) && error.message) {\n\t\tif (error.message.includes('network') || error.message.includes('Network')) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// Check if it's an HTTP error with a retryable status\n\tif (hasResponseStatus(error) && error.response?.status) {\n\t\tif (retryableStatuses.includes(error.response.status)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n// Create axios instance with default config\nexport const axiosInstance: AxiosInstance = axios.create({\n\ttimeout: 120000, // 2 minutes default timeout\n\theaders: {\n\t\t'User-Agent': 'Braingrid-CLI',\n\t},\n\t// Don't throw on any status to handle errors ourselves\n\tvalidateStatus: () => true,\n});\n\nexport async function axiosWithRetry<T = unknown>(\n\tconfig: AxiosRequestConfig,\n\toptions?: RetryOptions\n): Promise<AxiosResponse<T>> {\n\tconst opts = { ...DEFAULT_OPTIONS, ...options };\n\tlet lastError: unknown;\n\n\tfor (let attempt = 1; attempt <= opts.maxRetries + 1; attempt++) {\n\t\ttry {\n\t\t\tconst response = await axiosInstance.request<T>(config);\n\n\t\t\t// Check if the response status is retryable\n\t\t\tif (\n\t\t\t\tresponse.status >= 400 &&\n\t\t\t\topts.retryableStatuses.includes(response.status) &&\n\t\t\t\tattempt <= opts.maxRetries\n\t\t\t) {\n\t\t\t\tconst error: Error & { response?: AxiosResponse<T>; status?: number } = new Error(\n\t\t\t\t\t`HTTP ${response.status}: ${response.statusText}`\n\t\t\t\t);\n\t\t\t\terror.response = response;\n\t\t\t\terror.status = response.status;\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\treturn response;\n\t\t} catch (error: unknown) {\n\t\t\tlastError = error;\n\n\t\t\t// Check if we should retry\n\t\t\tif (attempt <= opts.maxRetries && isRetryableError(error, opts.retryableStatuses)) {\n\t\t\t\tconst delay = calculateDelay(\n\t\t\t\t\tattempt,\n\t\t\t\t\topts.initialDelay,\n\t\t\t\t\topts.maxDelay,\n\t\t\t\t\topts.backoffMultiplier\n\t\t\t\t);\n\t\t\t\topts.onRetry(attempt, delay, error);\n\t\t\t\tawait sleep(delay);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If not retryable or max retries exceeded, throw the error\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// This should never be reached, but just in case\n\tthrow lastError || new Error('Unexpected error in axiosWithRetry');\n}\n\n// Enhanced wrapper for common use cases\nexport class RetryableHttpClient {\n\tprivate defaultOptions: RetryOptions;\n\n\tconstructor(defaultOptions?: RetryOptions) {\n\t\tthis.defaultOptions = defaultOptions || {};\n\t}\n\n\tasync get<T = unknown>(\n\t\turl: string,\n\t\tconfig?: AxiosRequestConfig,\n\t\toptions?: RetryOptions\n\t): Promise<AxiosResponse<T>> {\n\t\treturn axiosWithRetry<T>(\n\t\t\t{ ...config, method: 'GET', url },\n\t\t\t{ ...this.defaultOptions, ...options }\n\t\t);\n\t}\n\n\tasync post<T = unknown>(\n\t\turl: string,\n\t\tdata?: unknown,\n\t\tconfig?: AxiosRequestConfig,\n\t\toptions?: RetryOptions\n\t): Promise<AxiosResponse<T>> {\n\t\treturn axiosWithRetry<T>(\n\t\t\t{\n\t\t\t\t...config,\n\t\t\t\tmethod: 'POST',\n\t\t\t\turl,\n\t\t\t\tdata,\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t...config?.headers,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ ...this.defaultOptions, ...options }\n\t\t);\n\t}\n\n\tasync patch<T = unknown>(\n\t\turl: string,\n\t\tdata?: unknown,\n\t\tconfig?: AxiosRequestConfig,\n\t\toptions?: RetryOptions\n\t): Promise<AxiosResponse<T>> {\n\t\treturn axiosWithRetry<T>(\n\t\t\t{\n\t\t\t\t...config,\n\t\t\t\tmethod: 'PATCH',\n\t\t\t\turl,\n\t\t\t\tdata,\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t...config?.headers,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ ...this.defaultOptions, ...options }\n\t\t);\n\t}\n\n\tasync delete<T = unknown>(\n\t\turl: string,\n\t\tconfig?: AxiosRequestConfig,\n\t\toptions?: RetryOptions\n\t): Promise<AxiosResponse<T>> {\n\t\treturn axiosWithRetry<T>(\n\t\t\t{ ...config, method: 'DELETE', url },\n\t\t\t{ ...this.defaultOptions, ...options }\n\t\t);\n\t}\n}\n","import { createHash, randomBytes } from 'crypto';\nimport { createServer, IncomingMessage, ServerResponse } from 'http';\nimport open from 'open';\nimport axios, { AxiosError } from 'axios';\nimport { getConfig } from '../utils/config.js';\nimport { getLogger } from '../utils/logger.js';\nimport type { OAuth2TokenResponse, OAuth2ErrorResponse } from '../types/auth.js';\n\nconst logger = getLogger();\n\nexport interface OAuth2AuthResult {\n\taccessToken: string;\n\trefreshToken?: string;\n\tidToken?: string;\n\texpiresIn?: number;\n\ttokenType?: string;\n}\n\nexport interface OAuth2AuthUrlResult {\n\tauthUrl: string;\n\tredirectUri: string;\n\tstate: string;\n}\n\ninterface PKCEChallenge {\n\tverifier: string;\n\tchallenge: string;\n\tmethod: 'S256';\n}\n\nexport class OAuth2Handler {\n\tprivate abortController?: AbortController;\n\tprivate onAuthCodeReceived?: (authUrl: string) => void;\n\tprivate server?: ReturnType<typeof createServer>;\n\tprivate authorizationCode?: string;\n\tprivate authError?: string;\n\tprivate state?: string;\n\tprivate pkceVerifier?: string;\n\n\t/**\n\t * Set callback for when auth URL is ready\n\t */\n\tsetAuthUrlCallback(callback: (authUrl: string) => void): void {\n\t\tthis.onAuthCodeReceived = callback;\n\t}\n\n\t/**\n\t * Generate PKCE challenge for OAuth2 flow\n\t */\n\tprivate generatePKCEChallenge(): PKCEChallenge {\n\t\t// Generate a cryptographically secure random verifier (43-128 chars)\n\t\tconst verifier = randomBytes(32).toString('base64url');\n\n\t\t// Create challenge from verifier using SHA256\n\t\tconst challenge = createHash('sha256').update(verifier).digest('base64url');\n\n\t\treturn {\n\t\t\tverifier,\n\t\t\tchallenge,\n\t\t\tmethod: 'S256',\n\t\t};\n\t}\n\n\t/**\n\t * Generate a cryptographically secure state parameter\n\t */\n\tprivate generateState(): string {\n\t\treturn randomBytes(32).toString('base64url');\n\t}\n\n\t/**\n\t * Get the fixed port for the callback server\n\t */\n\tprivate getCallbackPort(): number {\n\t\t// Use fixed port 34536 for OAuth callback\n\t\treturn 34536;\n\t}\n\n\t/**\n\t * Start local HTTP server to handle OAuth callback\n\t */\n\tprivate async startCallbackServer(port: number): Promise<void> {\n\t\treturn new Promise(resolve => {\n\t\t\tthis.server = createServer((req: IncomingMessage, res: ServerResponse) => {\n\t\t\t\tconst url = new URL(req.url || '', `http://127.0.0.1:${port}`);\n\n\t\t\t\t// Handle OAuth callback\n\t\t\t\tif (url.pathname === '/callback') {\n\t\t\t\t\tconst code = url.searchParams.get('code');\n\t\t\t\t\tconst error = url.searchParams.get('error');\n\t\t\t\t\tconst state = url.searchParams.get('state');\n\n\t\t\t\t\t// Validate state parameter\n\t\t\t\t\tif (state !== this.state) {\n\t\t\t\t\t\tres.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });\n\t\t\t\t\t\tres.end(`\n\t\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t\t<h1>Authentication Failed</h1>\n\t\t\t\t\t\t\t\t\t<p>Invalid state parameter. Please try again.</p>\n\t\t\t\t\t\t\t\t\t<script>window.setTimeout(() => window.close(), 3000);</script>\n\t\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t\t</html>\n\t\t\t\t\t\t`);\n\t\t\t\t\t\tthis.authError = 'Invalid state parameter';\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\t// Handle error response\n\t\t\t\t\t\tconst errorDescription = url.searchParams.get('error_description') || 'Unknown error';\n\t\t\t\t\t\tres.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });\n\t\t\t\t\t\tres.end(`\n\t\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t\t<h1>Authentication Failed</h1>\n\t\t\t\t\t\t\t\t\t<p>${errorDescription}</p>\n\t\t\t\t\t\t\t\t\t<script>window.setTimeout(() => window.close(), 3000);</script>\n\t\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t\t</html>\n\t\t\t\t\t\t`);\n\t\t\t\t\t\tthis.authError = errorDescription;\n\t\t\t\t\t} else if (code) {\n\t\t\t\t\t\t// Success! Store the code\n\t\t\t\t\t\tthis.authorizationCode = code;\n\t\t\t\t\t\tres.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\n\t\t\t\t\t\tres.end(`\n\t\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t\t<head>\n\t\t\t\t\t\t\t\t\t<style>\n\t\t\t\t\t\t\t\t\t\tbody { font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }\n\t\t\t\t\t\t\t\t\t\t.container { background: white; padding: 2rem; border-radius: 10px; box-shadow: 0 10px 40px rgba(0,0,0,0.1); text-align: center; }\n\t\t\t\t\t\t\t\t\t\th1 { color: #2d3748; margin-bottom: 1rem; }\n\t\t\t\t\t\t\t\t\t\tp { color: #718096; }\n\t\t\t\t\t\t\t\t\t\t.success-icon { font-size: 3rem; margin-bottom: 1rem; }\n\t\t\t\t\t\t\t\t\t</style>\n\t\t\t\t\t\t\t\t</head>\n\t\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t\t<div class=\"container\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"success-icon\">✅</div>\n\t\t\t\t\t\t\t\t\t\t<h1>Authentication Successful!</h1>\n\t\t\t\t\t\t\t\t\t\t<p>You can now close this window and return to the CLI.</p>\n\t\t\t\t\t\t\t\t\t\t<script>window.setTimeout(() => window.close(), 2000);</script>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t\t</html>\n\t\t\t\t\t\t`);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// No code or error\n\t\t\t\t\t\tres.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });\n\t\t\t\t\t\tres.end(`\n\t\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t\t<h1>Authentication Failed</h1>\n\t\t\t\t\t\t\t\t\t<p>No authorization code received.</p>\n\t\t\t\t\t\t\t\t\t<script>window.setTimeout(() => window.close(), 3000);</script>\n\t\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t\t</html>\n\t\t\t\t\t\t`);\n\t\t\t\t\t\tthis.authError = 'No authorization code received';\n\t\t\t\t\t}\n\n\t\t\t\t\t// Close the server after handling the callback\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tif (this.server) {\n\t\t\t\t\t\t\tthis.server.close();\n\t\t\t\t\t\t\tthis.server = undefined;\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 500);\n\t\t\t\t} else {\n\t\t\t\t\t// Handle other routes (redirect to /callback or show waiting page)\n\t\t\t\t\tres.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\n\t\t\t\t\tres.end(`\n\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t<head>\n\t\t\t\t\t\t\t\t<style>\n\t\t\t\t\t\t\t\t\tbody { font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }\n\t\t\t\t\t\t\t\t\t.container { background: white; padding: 2rem; border-radius: 10px; box-shadow: 0 10px 40px rgba(0,0,0,0.1); text-align: center; }\n\t\t\t\t\t\t\t\t\th1 { color: #2d3748; }\n\t\t\t\t\t\t\t\t\t.spinner { border: 3px solid #f3f4f6; border-top: 3px solid #667eea; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 1rem auto; }\n\t\t\t\t\t\t\t\t\t@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\n\t\t\t\t\t\t\t\t</style>\n\t\t\t\t\t\t\t</head>\n\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t<div class=\"container\">\n\t\t\t\t\t\t\t\t\t<h1>Waiting for authentication...</h1>\n\t\t\t\t\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t\t\t\t\t\t<p>Please complete the authentication in your browser.</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t</html>\n\t\t\t\t\t`);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.server.listen(port, '127.0.0.1', () => {\n\t\t\t\tlogger.debug(`Callback server listening on http://127.0.0.1:${port}`);\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Build the authorization URL with PKCE parameters\n\t */\n\tprivate buildAuthorizationUrl(pkce: PKCEChallenge, redirectUri: string): string {\n\t\tconst config = getConfig();\n\n\t\t// Use WorkOS AuthKit directly like the MCP server does\n\t\tconst authUrl = config.getWorkOSAuthUrl();\n\n\t\t// Generate state for CSRF protection\n\t\tthis.state = this.generateState();\n\n\t\tconst params = new URLSearchParams({\n\t\t\tclient_id: config.oauthClientId || 'braingrid-cli',\n\t\t\tredirect_uri: redirectUri,\n\t\t\tresponse_type: 'code',\n\t\t\tscope: 'openid email profile offline_access',\n\t\t\tstate: this.state,\n\t\t\tcode_challenge: pkce.challenge,\n\t\t\tcode_challenge_method: pkce.method,\n\t\t});\n\n\t\treturn `${authUrl}/oauth2/authorize?${params.toString()}`;\n\t}\n\n\t/**\n\t * Exchange authorization code for tokens\n\t */\n\tprivate async exchangeCodeForTokens(\n\t\tcode: string,\n\t\tverifier: string,\n\t\tredirectUri: string\n\t): Promise<OAuth2TokenResponse> {\n\t\tconst config = getConfig();\n\t\t// Use WorkOS AuthKit token endpoint\n\t\tconst tokenUrl = `${config.getWorkOSAuthUrl()}/oauth2/token`;\n\n\t\tconst params = new URLSearchParams({\n\t\t\tgrant_type: 'authorization_code',\n\t\t\tclient_id: config.oauthClientId || 'braingrid-cli',\n\t\t\tcode: code,\n\t\t\tredirect_uri: redirectUri,\n\t\t\tcode_verifier: verifier,\n\t\t});\n\n\t\tlogger.debug('Exchanging authorization code for tokens', { tokenUrl });\n\n\t\ttry {\n\t\t\tconst response = await axios.post<OAuth2TokenResponse>(tokenUrl, params.toString(), {\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/x-www-form-urlencoded',\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tlogger.debug('Token exchange successful', {\n\t\t\t\thasAccessToken: !!response.data.access_token,\n\t\t\t\thasRefreshToken: !!response.data.refresh_token,\n\t\t\t});\n\n\t\t\treturn response.data;\n\t\t} catch (error) {\n\t\t\tif (error instanceof AxiosError && error.response) {\n\t\t\t\tconst errorData = error.response.data as OAuth2ErrorResponse;\n\t\t\t\tlogger.error('Token exchange failed', {\n\t\t\t\t\tstatus: error.response.status,\n\t\t\t\t\terror: errorData,\n\t\t\t\t});\n\t\t\t\tthrow new Error(`Token exchange failed: ${errorData.error_description || errorData.error}`);\n\t\t\t}\n\t\t\tthrow new Error(\n\t\t\t\t`Token exchange failed: ${error instanceof Error ? error.message : String(error)}`\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Wait for the authorization code from the callback\n\t */\n\tprivate async waitForAuthorizationCode(timeoutMs: number = 300000): Promise<string> {\n\t\t// 5 minutes timeout\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst startTime = Date.now();\n\n\t\t\tconst checkInterval = setInterval(() => {\n\t\t\t\t// Check if we should abort\n\t\t\t\tif (this.abortController?.signal.aborted) {\n\t\t\t\t\tclearInterval(checkInterval);\n\t\t\t\t\treject(new Error('Authentication cancelled'));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Check for error\n\t\t\t\tif (this.authError) {\n\t\t\t\t\tclearInterval(checkInterval);\n\t\t\t\t\treject(new Error(this.authError));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Check for success\n\t\t\t\tif (this.authorizationCode) {\n\t\t\t\t\tclearInterval(checkInterval);\n\t\t\t\t\tresolve(this.authorizationCode);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Check for timeout\n\t\t\t\tif (Date.now() - startTime > timeoutMs) {\n\t\t\t\t\tclearInterval(checkInterval);\n\t\t\t\t\treject(new Error('Authentication timeout - no response received'));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}, 500); // Check every 500ms\n\t\t});\n\t}\n\n\t/**\n\t * Prepare OAuth2 flow and return auth URL (for RPC mode)\n\t * Starts the callback server but doesn't open the browser\n\t */\n\tasync prepareAuthUrl(): Promise<OAuth2AuthUrlResult> {\n\t\tlogger.info('Preparing OAuth2 authentication URL for RPC mode');\n\n\t\t// Create new AbortController for this authentication session\n\t\tthis.abortController = new AbortController();\n\n\t\t// Reset state\n\t\tthis.authorizationCode = undefined;\n\t\tthis.authError = undefined;\n\t\tthis.state = undefined;\n\t\tthis.pkceVerifier = undefined;\n\n\t\t// Step 1: Generate PKCE challenge\n\t\tconst pkce = this.generatePKCEChallenge();\n\t\tthis.pkceVerifier = pkce.verifier; // Store for later use\n\t\tlogger.debug('PKCE challenge generated');\n\n\t\t// Step 2: Use fixed port and start callback server\n\t\tconst port = this.getCallbackPort();\n\t\tconst redirectUri = `http://127.0.0.1:${port}/callback`;\n\t\tlogger.info('Starting callback server', { port, redirectUri });\n\n\t\tawait this.startCallbackServer(port);\n\n\t\t// Step 3: Build authorization URL\n\t\tconst authUrl = this.buildAuthorizationUrl(pkce, redirectUri);\n\t\tlogger.info('Authorization URL ready for RPC client', { authUrl });\n\n\t\tif (!this.state) {\n\t\t\tthrow new Error('State not initialized');\n\t\t}\n\n\t\treturn {\n\t\t\tauthUrl,\n\t\t\tredirectUri,\n\t\t\tstate: this.state,\n\t\t};\n\t}\n\n\t/**\n\t * Complete the OAuth2 flow after browser authentication (for RPC mode)\n\t * Call this after prepareAuthUrl() and the user has authenticated\n\t */\n\tasync completeAuth(timeoutMs: number = 300000): Promise<OAuth2AuthResult> {\n\t\tif (!this.pkceVerifier) {\n\t\t\tthrow new Error('Must call prepareAuthUrl() before completeAuth()');\n\t\t}\n\n\t\ttry {\n\t\t\t// Wait for authorization code from callback\n\t\t\tlogger.info('Waiting for user to complete authentication in browser...');\n\t\t\tconst code = await this.waitForAuthorizationCode(timeoutMs);\n\t\t\tlogger.info('Authorization code received');\n\n\t\t\t// Get redirect URI from server (it's always the same port)\n\t\t\tconst port = this.getCallbackPort();\n\t\t\tconst redirectUri = `http://127.0.0.1:${port}/callback`;\n\n\t\t\t// Exchange code for tokens\n\t\t\tconst tokens = await this.exchangeCodeForTokens(code, this.pkceVerifier, redirectUri);\n\t\t\tlogger.info('Authentication successful');\n\n\t\t\t// Return token info\n\t\t\treturn {\n\t\t\t\taccessToken: tokens.access_token,\n\t\t\t\trefreshToken: tokens.refresh_token,\n\t\t\t\tidToken: tokens.id_token,\n\t\t\t\texpiresIn: tokens.expires_in,\n\t\t\t\ttokenType: tokens.token_type,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthis.abort();\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\t// Clean up server if still running\n\t\t\tif (this.server) {\n\t\t\t\tthis.server.close();\n\t\t\t\tthis.server = undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Initiates the OAuth2 authorization code flow with PKCE\n\t */\n\tasync authenticate(): Promise<OAuth2AuthResult> {\n\t\tlogger.info('Starting OAuth2 authentication flow with PKCE');\n\n\t\t// Create new AbortController for this authentication session\n\t\tthis.abortController = new AbortController();\n\n\t\t// Reset state\n\t\tthis.authorizationCode = undefined;\n\t\tthis.authError = undefined;\n\t\tthis.state = undefined;\n\n\t\ttry {\n\t\t\t// Step 1: Generate PKCE challenge\n\t\t\tconst pkce = this.generatePKCEChallenge();\n\t\t\tlogger.debug('PKCE challenge generated');\n\n\t\t\t// Step 2: Use fixed port and start callback server\n\t\t\tconst port = this.getCallbackPort();\n\t\t\tconst redirectUri = `http://127.0.0.1:${port}/callback`;\n\t\t\tlogger.info('Starting callback server', { port, redirectUri });\n\n\t\t\tawait this.startCallbackServer(port);\n\n\t\t\t// Step 3: Build authorization URL\n\t\t\tconst authUrl = this.buildAuthorizationUrl(pkce, redirectUri);\n\t\t\tlogger.info('Authorization URL ready', { authUrl });\n\n\t\t\t// Notify callback if set\n\t\t\tif (this.onAuthCodeReceived) {\n\t\t\t\tthis.onAuthCodeReceived(authUrl);\n\t\t\t}\n\n\t\t\t// Step 4: Open browser\n\t\t\ttry {\n\t\t\t\tlogger.debug('Opening browser for authentication');\n\t\t\t\tawait open(authUrl);\n\t\t\t\tlogger.info('Browser opened automatically');\n\t\t\t} catch (error) {\n\t\t\t\tlogger.warn('Failed to open browser automatically', { error });\n\t\t\t\tlogger.info(`Please open the following URL manually:\\n${authUrl}`);\n\t\t\t}\n\n\t\t\t// Step 5: Wait for authorization code\n\t\t\tlogger.info('Waiting for user to complete authentication...');\n\t\t\tconst code = await this.waitForAuthorizationCode();\n\t\t\tlogger.info('Authorization code received');\n\n\t\t\t// Step 6: Exchange code for tokens\n\t\t\tconst tokens = await this.exchangeCodeForTokens(code, pkce.verifier, redirectUri);\n\t\t\tlogger.info('Authentication successful');\n\n\t\t\t// Step 7: Return token info\n\t\t\treturn {\n\t\t\t\taccessToken: tokens.access_token,\n\t\t\t\trefreshToken: tokens.refresh_token,\n\t\t\t\tidToken: tokens.id_token,\n\t\t\t\texpiresIn: tokens.expires_in,\n\t\t\t\ttokenType: tokens.token_type,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\t// Abort any ongoing operations\n\t\t\tthis.abort();\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\t// Clean up server if still running\n\t\t\tif (this.server) {\n\t\t\t\tthis.server.close();\n\t\t\t\tthis.server = undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Refresh an access token using a refresh token\n\t */\n\tasync refreshToken(refreshToken: string): Promise<OAuth2AuthResult> {\n\t\tconst config = getConfig();\n\t\t// Use WorkOS AuthKit token endpoint for refresh\n\t\tconst tokenUrl = `${config.getWorkOSAuthUrl()}/oauth2/token`;\n\n\t\tconst params = new URLSearchParams({\n\t\t\tgrant_type: 'refresh_token',\n\t\t\tclient_id: config.oauthClientId || 'braingrid-cli',\n\t\t\trefresh_token: refreshToken,\n\t\t});\n\n\t\tlogger.debug('Refreshing access token');\n\n\t\ttry {\n\t\t\tconst response = await axios.post<OAuth2TokenResponse>(tokenUrl, params.toString(), {\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/x-www-form-urlencoded',\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tlogger.debug('Token refresh successful');\n\n\t\t\treturn {\n\t\t\t\taccessToken: response.data.access_token,\n\t\t\t\trefreshToken: response.data.refresh_token,\n\t\t\t\tidToken: response.data.id_token,\n\t\t\t\texpiresIn: response.data.expires_in,\n\t\t\t\ttokenType: response.data.token_type,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tif (error instanceof AxiosError && error.response) {\n\t\t\t\tconst errorData = error.response.data as OAuth2ErrorResponse;\n\t\t\t\tlogger.error('Token refresh failed', {\n\t\t\t\t\tstatus: error.response.status,\n\t\t\t\t\terror: errorData,\n\t\t\t\t});\n\t\t\t\tthrow new Error(`Token refresh failed: ${errorData.error_description || errorData.error}`);\n\t\t\t}\n\t\t\tthrow new Error(\n\t\t\t\t`Token refresh failed: ${error instanceof Error ? error.message : String(error)}`\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Abort any ongoing authentication\n\t */\n\tabort(): void {\n\t\tif (this.abortController) {\n\t\t\tthis.abortController.abort();\n\t\t\tthis.abortController = undefined;\n\t\t}\n\n\t\tif (this.server) {\n\t\t\tthis.server.close();\n\t\t\tthis.server = undefined;\n\t\t}\n\t}\n}\n","/**\n * Build-time constants injected by tsup during compilation.\n * These values are determined when the package is built, not at runtime.\n */\n\n/**\n * BUILD_ENV determines which configuration to use.\n * - 'production': Uses production URLs (set via BUILD_ENV=production during build)\n * - 'development': Uses development/local URLs (set via BUILD_ENV=development during build)\n *\n * This value is injected at build time by tsup and cannot be changed at runtime.\n */\ndeclare const __BUILD_ENV__: string | undefined;\nexport const BUILD_ENV = (\n\ttypeof __BUILD_ENV__ !== 'undefined'\n\t\t? __BUILD_ENV__\n\t\t: process.env.NODE_ENV === 'test'\n\t\t\t? 'development'\n\t\t\t: 'production'\n) as 'production' | 'development';\n\n/**\n * CLI_VERSION is read from package.json during build and baked into the bundle.\n * Used for update checks and version display.\n *\n * This value is injected at build time by tsup and cannot be changed at runtime.\n */\ndeclare const __CLI_VERSION__: string | undefined;\nexport const CLI_VERSION = typeof __CLI_VERSION__ !== 'undefined' ? __CLI_VERSION__ : '0.0.0-test';\n\n/**\n * Production configuration\n * Used when BUILD_ENV === 'production' (npm published package)\n */\nexport const PRODUCTION_CONFIG = {\n\tapiUrl: 'https://app.braingrid.ai',\n\tworkosAuthUrl: 'https://sensitive-harvest-60.authkit.app',\n\tworkosClientId: 'client_01K6H010C9K69HSDPM9CQM85S7',\n} as const;\n\n/**\n * Development configuration\n * Used when BUILD_ENV === 'development' (local development)\n */\nexport const DEVELOPMENT_CONFIG = {\n\tapiUrl: 'https://app.dev.braingrid.ai',\n\tworkosAuthUrl: 'https://balanced-celebration-78-staging.authkit.app',\n\tworkosClientId: 'client_01K6H04GF21T4JXNS3JDQM3YNE',\n} as const;\n","import { BUILD_ENV, PRODUCTION_CONFIG, DEVELOPMENT_CONFIG } from '../build-config.js';\n\nexport interface BrainGridConfig {\n\tapiUrl: string;\n\torganizationId?: string;\n\tclientId?: string;\n\toauthClientId?: string;\n\tgetWorkOSAuthUrl(): string;\n\tgetWebAppUrl(): string;\n}\n\nexport function getConfig(): BrainGridConfig {\n\t// Determine base config based on BUILD_ENV\n\tconst baseConfig = BUILD_ENV === 'production' ? PRODUCTION_CONFIG : DEVELOPMENT_CONFIG;\n\n\t// In development builds, allow NODE_ENV to override\n\tlet apiUrl: string = baseConfig.apiUrl;\n\tif (BUILD_ENV === 'development') {\n\t\tif (process.env.NODE_ENV === 'local' || process.env.NODE_ENV === 'test') {\n\t\t\t// In local/test environment, use localhost\n\t\t\tapiUrl = 'http://localhost:3377';\n\t\t} else if (process.env.NODE_ENV === 'development') {\n\t\t\t// In development, use dev server\n\t\t\tapiUrl = DEVELOPMENT_CONFIG.apiUrl;\n\t\t}\n\t}\n\n\t// Determine WorkOS AuthKit URL based on environment\n\tconst getWorkOSAuthUrl = (): string => {\n\t\t// Allow override via environment variable\n\t\tif (process.env.WORKOS_AUTH_URL) {\n\t\t\treturn process.env.WORKOS_AUTH_URL;\n\t\t}\n\n\t\t// In production builds, always use production URL\n\t\tif (BUILD_ENV === 'production') {\n\t\t\treturn PRODUCTION_CONFIG.workosAuthUrl;\n\t\t}\n\n\t\t// In development builds, respect NODE_ENV\n\t\tconst env = process.env.NODE_ENV || 'development';\n\t\tif (env === 'local' || env === 'test' || env === 'development' || env === 'staging') {\n\t\t\treturn DEVELOPMENT_CONFIG.workosAuthUrl;\n\t\t}\n\t\treturn PRODUCTION_CONFIG.workosAuthUrl;\n\t};\n\n\t// Determine WorkOS OAuth client ID based on environment\n\tconst getOAuthClientId = (): string => {\n\t\t// Allow override via environment variable\n\t\tif (process.env.WORKOS_CLIENT_ID) {\n\t\t\treturn process.env.WORKOS_CLIENT_ID;\n\t\t}\n\n\t\t// In production builds, always use production client ID\n\t\tif (BUILD_ENV === 'production') {\n\t\t\treturn PRODUCTION_CONFIG.workosClientId;\n\t\t}\n\n\t\t// In development builds, respect NODE_ENV\n\t\tconst env = process.env.NODE_ENV || 'development';\n\t\tif (env === 'local' || env === 'test' || env === 'development' || env === 'staging') {\n\t\t\treturn DEVELOPMENT_CONFIG.workosClientId;\n\t\t}\n\t\treturn PRODUCTION_CONFIG.workosClientId;\n\t};\n\n\t// Determine web app URL based on environment\n\tconst getWebAppUrl = (): string => {\n\t\t// Allow override via environment variable\n\t\tif (process.env.BRAINGRID_WEB_URL) {\n\t\t\treturn process.env.BRAINGRID_WEB_URL;\n\t\t}\n\n\t\t// In production builds, always use production URL\n\t\tif (BUILD_ENV === 'production') {\n\t\t\treturn PRODUCTION_CONFIG.apiUrl;\n\t\t}\n\n\t\t// In development builds, respect NODE_ENV\n\t\tconst env = process.env.NODE_ENV || 'development';\n\t\tif (env === 'local' || env === 'test') {\n\t\t\treturn 'http://localhost:3377';\n\t\t}\n\t\treturn DEVELOPMENT_CONFIG.apiUrl;\n\t};\n\n\treturn {\n\t\tapiUrl: process.env.BRAINGRID_API_URL || apiUrl,\n\t\torganizationId: process.env.BRAINGRID_ORG_ID,\n\t\tclientId: process.env.BRAINGRID_CLIENT_ID || 'braingrid-cli',\n\t\toauthClientId: getOAuthClientId(),\n\t\tgetWorkOSAuthUrl,\n\t\tgetWebAppUrl,\n\t};\n}\n","/**\n * JWT utility functions\n * Note: This is basic JWT decoding without signature verification\n * The server validates the token signature when we make API calls\n */\n\nexport interface JWTPayload {\n\t// Standard JWT claims\n\tsub?: string; // Subject (user ID)\n\texp?: number; // Expiration time\n\tiat?: number; // Issued at\n\tnbf?: number; // Not before\n\tiss?: string; // Issuer\n\taud?: string | string[]; // Audience\n\n\t// Custom claims that might be in the token\n\temail?: string;\n\tfirstName?: string;\n\tfirst_name?: string;\n\tlastName?: string;\n\tlast_name?: string;\n\tname?: string;\n\tgiven_name?: string;\n\tfamily_name?: string;\n\torganizationId?: string;\n\torganization_id?: string;\n\torg?: string;\n\tmetadata?: Record<string, unknown>;\n}\n\n/**\n * Decode a JWT token to extract the payload\n * Note: This does NOT verify the signature - that's the server's job\n */\nexport function decodeJWT(token: string): JWTPayload | null {\n\ttry {\n\t\t// JWT format: header.payload.signature\n\t\tconst parts = token.split('.');\n\t\tif (parts.length !== 3) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Decode the payload (base64url)\n\t\tconst payload = parts[1];\n\t\t// Replace URL-safe characters with standard base64 characters\n\t\tconst base64 = payload.replace(/-/g, '+').replace(/_/g, '/');\n\t\t// Add padding if necessary\n\t\tconst padded = base64 + '=='.substring(0, (4 - (base64.length % 4)) % 4);\n\n\t\tconst decoded = Buffer.from(padded, 'base64').toString('utf-8');\n\t\treturn JSON.parse(decoded);\n\t} catch {\n\t\t// Invalid token format or JSON\n\t\treturn null;\n\t}\n}\n\n/**\n * Check if a JWT token is expired\n */\nexport function isJWTExpired(token: string): boolean {\n\tconst payload = decodeJWT(token);\n\tif (!payload || !payload.exp) {\n\t\t// If we can't decode or no expiry, assume it's invalid\n\t\treturn true;\n\t}\n\n\t// exp is in seconds, Date.now() is in milliseconds\n\treturn Date.now() >= payload.exp * 1000;\n}\n\n/**\n * Extract user information from JWT payload\n */\nexport function extractUserFromJWT(payload: JWTPayload): {\n\tid: string;\n\temail: string;\n\tfirstName: string;\n\tlastName: string;\n\torganizationId: string;\n} {\n\treturn {\n\t\tid: payload.sub || '',\n\t\temail: payload.email || '',\n\t\t// Try different naming conventions for first name\n\t\tfirstName:\n\t\t\tpayload.firstName ||\n\t\t\tpayload.first_name ||\n\t\t\tpayload.given_name ||\n\t\t\t(payload.name ? payload.name.split(' ')[0] : ''),\n\t\t// Try different naming conventions for last name\n\t\tlastName:\n\t\t\tpayload.lastName ||\n\t\t\tpayload.last_name ||\n\t\t\tpayload.family_name ||\n\t\t\t(payload.name ? payload.name.split(' ').slice(1).join(' ') : ''),\n\t\t// Try different naming conventions for organization\n\t\torganizationId: payload.organizationId || payload.organization_id || payload.org || 'default',\n\t};\n}\n","/**\n * Credential Store - Encrypted credential storage using conf\n *\n * Provides a keytar-compatible API for storing credentials securely\n * using file-based encrypted storage.\n *\n * Storage locations:\n * - macOS: ~/Library/Preferences/BrainGrid/config.json\n * - Linux: ~/.config/BrainGrid/config.json\n * - Windows: %APPDATA%\\BrainGrid\\config.json\n *\n * Security:\n * - Encrypted using AES-256-CBC\n * - Encryption key derived from machine ID + app salt\n * - File permissions automatically set to 0600 on Unix systems\n */\n\nimport Conf from 'conf';\nimport machineId from 'node-machine-id';\nimport crypto from 'crypto';\n\n// App-specific salt for key derivation\nconst APP_SALT = 'braingrid-cli-v1-credentials';\n\n// Derive encryption key from machine ID + salt\n// This makes the encryption key machine-specific\nfunction deriveEncryptionKey(): string {\n\ttry {\n\t\tconst id = machineId.machineIdSync();\n\t\treturn crypto\n\t\t\t.createHash('sha256')\n\t\t\t.update(id + APP_SALT)\n\t\t\t.digest('hex')\n\t\t\t.substring(0, 32); // 32 bytes for AES-256\n\t} catch {\n\t\t// Fallback if machine ID fails (unlikely)\n\t\t// This is still better than plain text\n\t\tconsole.warn('⚠️ Could not derive machine-specific encryption key, using fallback');\n\t\treturn crypto.createHash('sha256').update(APP_SALT).digest('hex').substring(0, 32);\n\t}\n}\n\n// Initialize encrypted configuration store\nconst store = new Conf({\n\tprojectName: 'BrainGrid',\n\tprojectSuffix: '', // Override default 'nodejs' suffix for cleaner directory name\n\tencryptionKey: deriveEncryptionKey(),\n\tclearInvalidConfig: true, // Clear config if decryption fails\n});\n\n/**\n * Credential store with keytar-compatible API\n */\nexport const credentialStore = {\n\t/**\n\t * Get a stored password/credential\n\t * @param service Service name (e.g., 'braingrid-cli')\n\t * @param account Account name (e.g., 'session', 'refresh-token')\n\t * @returns The stored credential or null if not found\n\t */\n\tasync getPassword(service: string, account: string): Promise<string | null> {\n\t\tconst key = `${service}.${account}`;\n\t\tconst value = store.get(key);\n\t\treturn value !== undefined ? String(value) : null;\n\t},\n\n\t/**\n\t * Store a password/credential\n\t * @param service Service name\n\t * @param account Account name\n\t * @param password The credential to store\n\t */\n\tasync setPassword(service: string, account: string, password: string): Promise<void> {\n\t\tconst key = `${service}.${account}`;\n\t\tstore.set(key, password);\n\t},\n\n\t/**\n\t * Delete a stored password/credential\n\t * @param service Service name\n\t * @param account Account name\n\t */\n\tasync deletePassword(service: string, account: string): Promise<void> {\n\t\tconst key = `${service}.${account}`;\n\t\tstore.delete(key);\n\t},\n\n\t/**\n\t * Get the path to the encrypted config file\n\t * Useful for informing users where credentials are stored\n\t */\n\tgetStoragePath(): string {\n\t\treturn store.path;\n\t},\n};\n","/**\n * Error Formatter Utility\n *\n * Extracts user-friendly error messages from API errors (AxiosError)\n * and provides context-aware error messages for common scenarios.\n */\n\nimport { AxiosError } from 'axios';\nimport chalk from 'chalk';\nimport type { ErrorResponse } from '../types/api.js';\nimport { handleError } from './error-handler.js';\n\n/**\n * Format an error for display to the user\n * Extracts API error details from AxiosError responses\n */\nexport function formatError(error: unknown, context?: string): string {\n\t// Handle AxiosError specifically\n\tif (isAxiosError(error)) {\n\t\treturn formatAxiosError(error, context);\n\t}\n\n\t// Handle objects with response property (mock AxiosError in tests)\n\tif (error && typeof error === 'object' && 'response' in error) {\n\t\treturn formatAxiosError(error as AxiosError, context);\n\t}\n\n\t// Handle regular Error objects\n\tif (error instanceof Error) {\n\t\treturn chalk.red(`❌ ${error.message}`);\n\t}\n\n\t// Fallback for unknown error types\n\treturn chalk.red(`❌ ${String(error)}`);\n}\n\n/**\n * Type guard to check if error is an AxiosError\n */\nfunction isAxiosError(error: unknown): error is AxiosError {\n\treturn (\n\t\ttypeof error === 'object' &&\n\t\terror !== null &&\n\t\t'isAxiosError' in error &&\n\t\terror.isAxiosError === true\n\t);\n}\n\n/**\n * Format AxiosError with API response details\n */\nfunction formatAxiosError(error: AxiosError, context?: string): string {\n\tconst status = error.response?.status;\n\tconst data = error.response?.data;\n\n\t// Try to extract structured error from API response\n\tif (data && typeof data === 'object' && 'error' in data) {\n\t\tconst errorResponse = data as ErrorResponse;\n\t\tif (errorResponse.error?.message) {\n\t\t\t// Use API error message if available\n\t\t\treturn chalk.red(`❌ ${errorResponse.error.message}`);\n\t\t}\n\t}\n\n\t// Use new enhanced error handler for common status codes (404, 401, 402, 403, 422)\n\tif (status && [404, 401, 402, 403, 422].includes(status)) {\n\t\treturn handleError(error, context);\n\t}\n\n\t// Handle other HTTP status codes with basic messages\n\tif (status) {\n\t\treturn chalk.red(`❌ ${getStatusMessage(status, context, error)}`);\n\t}\n\n\t// Handle network errors (no response)\n\tif (error.code === 'ECONNREFUSED') {\n\t\treturn chalk.red(\n\t\t\t'❌ Could not connect to BrainGrid API. Please check your network connection.'\n\t\t);\n\t}\n\n\tif (error.code === 'ETIMEDOUT') {\n\t\treturn chalk.red('❌ Request timed out. Please try again.');\n\t}\n\n\t// Fallback to error message\n\treturn chalk.red(`❌ ${error.message}`);\n}\n\n/**\n * Get user-friendly message for HTTP status codes\n */\nfunction getStatusMessage(status: number, context?: string, error?: AxiosError): string {\n\tswitch (status) {\n\t\tcase 400: {\n\t\t\t// Bad Request - try to extract details from response\n\t\t\tconst data = error?.response?.data;\n\t\t\tif (data && typeof data === 'object') {\n\t\t\t\t// Check for validation errors or detailed message\n\t\t\t\tif ('message' in data && typeof data.message === 'string') {\n\t\t\t\t\treturn data.message;\n\t\t\t\t}\n\t\t\t\tif ('detail' in data && typeof data.detail === 'string') {\n\t\t\t\t\treturn data.detail;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn context\n\t\t\t\t? `Invalid ${context} - please check your input and try again`\n\t\t\t\t: 'Invalid request - please check your input and try again';\n\t\t}\n\n\t\tcase 401:\n\t\t\treturn 'Authentication required. Please run \"braingrid login\" to authenticate.';\n\n\t\tcase 403:\n\t\t\treturn context\n\t\t\t\t? `You don't have permission to access this ${context}`\n\t\t\t\t: \"You don't have permission to perform this action\";\n\n\t\tcase 404:\n\t\t\treturn context ? `${context} not found` : 'Resource not found';\n\n\t\tcase 409:\n\t\t\treturn context\n\t\t\t\t? `${context} already exists or conflicts with existing data`\n\t\t\t\t: 'Resource already exists or conflicts with existing data';\n\n\t\tcase 422:\n\t\t\treturn 'Validation failed - please check your input';\n\n\t\tcase 429:\n\t\t\treturn 'Too many requests. Please wait a moment and try again.';\n\n\t\tcase 500:\n\t\t\treturn 'Server error. Please try again later.';\n\n\t\tcase 502:\n\t\tcase 503:\n\t\tcase 504:\n\t\t\treturn 'BrainGrid service is temporarily unavailable. Please try again later.';\n\n\t\tdefault:\n\t\t\treturn `Request failed with status ${status}`;\n\t}\n}\n\n/**\n * Format context string for error messages\n * Converts resource names to user-friendly format\n */\nexport function getResourceContext(resourceType: string, id?: string): string {\n\tconst formatted = resourceType.charAt(0).toUpperCase() + resourceType.slice(1);\n\treturn id ? `${formatted} '${id}'` : formatted;\n}\n","/**\n * Error Handler - Centralized error handling with context-aware messages\n *\n * Provides specialized error handling for common API errors:\n * - 404: Resource not found (project/requirement/task)\n * - 401: Authentication required\n * - 403: Permission denied\n * - 422: Validation errors\n */\n\nimport chalk from 'chalk';\nimport type { AxiosError } from 'axios';\n\n/**\n * Extract project ID from API URL\n * Matches patterns like: /api/v1/projects/PROJ-123/...\n */\nfunction extractProjectIdFromUrl(url?: string): string | null {\n\tif (!url) return null;\n\tconst match = url.match(/\\/projects\\/([A-Z]+-\\d+)/);\n\treturn match ? match[1] : null;\n}\n\n/**\n * Extract requirement ID from API URL\n * Matches patterns like: /api/v1/projects/{projectId}/requirements/REQ-456/...\n */\nfunction extractRequirementIdFromUrl(url?: string): string | null {\n\tif (!url) return null;\n\tconst match = url.match(/\\/requirements\\/([A-Z]+-\\d+)/);\n\treturn match ? match[1] : null;\n}\n\n/**\n * Extract task ID from API URL\n * Matches patterns like: /api/v1/projects/{projectId}/requirements/{reqId}/tasks/TASK-789\n */\nfunction extractTaskIdFromUrl(url?: string): string | null {\n\tif (!url) return null;\n\tconst match = url.match(/\\/tasks\\/([A-Z]+-\\d+)/);\n\treturn match ? match[1] : null;\n}\n\n/**\n * Detect resource type from URL\n */\nfunction detectResourceType(url?: string): 'project' | 'requirement' | 'task' | 'unknown' {\n\tif (!url) return 'unknown';\n\n\t// Check for task first (most specific)\n\tif (url.includes('/tasks/') || url.endsWith('/tasks')) return 'task';\n\t// Then requirement\n\tif (url.includes('/requirements/') || url.endsWith('/requirements')) return 'requirement';\n\t// Then project (matches both /projects/PROJ-123 and /projects)\n\tif (url.includes('/projects')) return 'project';\n\n\treturn 'unknown';\n}\n\n/**\n * Handle 404 Resource Not Found errors\n * Provides context-aware messages based on the resource type\n */\nexport function handleResourceNotFound(error: AxiosError, context?: string): string {\n\tconst url = error.config?.url;\n\tconst resourceType = detectResourceType(url);\n\n\t// Extract resource IDs\n\tconst projectId = extractProjectIdFromUrl(url);\n\tconst requirementId = extractRequirementIdFromUrl(url);\n\tconst taskId = extractTaskIdFromUrl(url);\n\n\t// Build error message based on resource type\n\tlet message = chalk.red('❌ ');\n\n\tswitch (resourceType) {\n\t\tcase 'task': {\n\t\t\tif (taskId) {\n\t\t\t\tmessage += `Task '${taskId}' not found`;\n\t\t\t} else {\n\t\t\t\tmessage += 'Task not found';\n\t\t\t}\n\t\t\tmessage += '\\n\\n' + chalk.dim('The task may have been deleted or the ID is incorrect.');\n\t\t\tif (projectId && requirementId) {\n\t\t\t\tmessage +=\n\t\t\t\t\t'\\n' +\n\t\t\t\t\tchalk.dim('List tasks with:\\n') +\n\t\t\t\t\tchalk.cyan(` braingrid task list ${requirementId}`);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 'requirement': {\n\t\t\tif (requirementId) {\n\t\t\t\tmessage += `Requirement '${requirementId}' not found`;\n\t\t\t} else {\n\t\t\t\tmessage += 'Requirement not found';\n\t\t\t}\n\t\t\tmessage +=\n\t\t\t\t'\\n\\n' + chalk.dim('The requirement may have been deleted or the ID is incorrect.');\n\t\t\tif (projectId) {\n\t\t\t\tmessage +=\n\t\t\t\t\t'\\n' +\n\t\t\t\t\tchalk.dim('List requirements with:\\n') +\n\t\t\t\t\tchalk.cyan(` braingrid requirement list -p ${projectId}`);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 'project': {\n\t\t\tif (projectId) {\n\t\t\t\tmessage += `Project '${projectId}' not found`;\n\t\t\t} else {\n\t\t\t\tmessage += 'Project not found';\n\t\t\t}\n\t\t\tmessage +=\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('The project may not exist or you may not have access to it.') +\n\t\t\t\t'\\n' +\n\t\t\t\tchalk.dim('List your projects with:\\n') +\n\t\t\t\tchalk.cyan(' braingrid project list');\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\t// Unknown resource type, fall back to generic message\n\t\t\tif (context) {\n\t\t\t\tmessage += `Error ${context}: not found`;\n\t\t\t} else {\n\t\t\t\tmessage += 'Resource not found';\n\t\t\t}\n\t\t\tmessage +=\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('The requested resource does not exist or you may not have access to it.');\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn message;\n}\n\n/**\n * Handle 401 Authentication errors\n */\nexport function handleAuthError(_error: AxiosError, _context?: string): string {\n\treturn (\n\t\tchalk.red('❌ Authentication required') +\n\t\t'\\n\\n' +\n\t\tchalk.dim('Your session may have expired or you are not logged in.') +\n\t\t'\\n' +\n\t\tchalk.dim('Please authenticate with:\\n') +\n\t\tchalk.cyan(' braingrid login')\n\t);\n}\n\n/**\n * Handle 403 Permission errors\n */\nexport function handlePermissionError(error: AxiosError, context?: string): string {\n\tconst url = error.config?.url;\n\tconst resourceType = detectResourceType(url);\n\tconst projectId = extractProjectIdFromUrl(url);\n\n\tlet message = chalk.red('❌ Permission denied');\n\n\tif (context) {\n\t\tmessage = chalk.red(`❌ Permission denied: ${context}`);\n\t}\n\n\tmessage += '\\n\\n' + chalk.dim('You do not have permission to perform this action.');\n\n\tif (resourceType === 'project' && projectId) {\n\t\tmessage +=\n\t\t\t'\\n' +\n\t\t\tchalk.dim('Check if you have access to this project:\\n') +\n\t\t\tchalk.cyan(` braingrid project show -p ${projectId}`);\n\t} else {\n\t\tmessage += '\\n' + chalk.dim('Contact your project administrator for access.');\n\t}\n\n\treturn message;\n}\n\n/**\n * Handle 402 Payment Required errors\n * Handles billing and quota limit errors\n */\nexport function handlePaymentRequiredError(error: AxiosError, context?: string): string {\n\t// Try to extract error details from response\n\tconst responseData = error.response?.data as\n\t\t| { error?: string; code?: string; errorCode?: string; quotaKey?: string }\n\t\t| undefined;\n\n\tconst errorCode = responseData?.errorCode || responseData?.code;\n\tconst quotaKey = responseData?.quotaKey;\n\n\tlet message = chalk.red('❌ Usage limit reached');\n\n\t// Handle organization unfunded error\n\tif (errorCode === 'ORG_UNFUNDED') {\n\t\tmessage = chalk.red('❌ Organization subscription required');\n\t\tmessage +=\n\t\t\t'\\n\\n' +\n\t\t\tchalk.dim('Your organization needs an active subscription to use this feature.') +\n\t\t\t'\\n\\n' +\n\t\t\tchalk.dim('Please contact your organization administrator or visit:\\n') +\n\t\t\tchalk.cyan(' https://braingrid.ai/pricing');\n\t\treturn message;\n\t}\n\n\t// Handle quota exceeded error with specific quota key\n\tif (errorCode === 'QUOTA_EXCEEDED' && quotaKey) {\n\t\tmessage = chalk.red(`❌ Quota exceeded: ${quotaKey}`);\n\t\tmessage +=\n\t\t\t'\\n\\n' +\n\t\t\tchalk.dim(`Your organization has reached its usage limit for ${quotaKey}.`) +\n\t\t\t'\\n\\n' +\n\t\t\tchalk.dim('To continue using this feature:\\n') +\n\t\t\tchalk.dim(' • Upgrade your plan at ') +\n\t\t\tchalk.cyan('https://braingrid.ai/pricing') +\n\t\t\t'\\n' +\n\t\t\tchalk.dim(' • Contact your administrator to increase quota');\n\t\treturn message;\n\t}\n\n\t// Handle quota exceeded without specific key\n\tif (errorCode === 'QUOTA_EXCEEDED') {\n\t\tmessage +=\n\t\t\t'\\n\\n' +\n\t\t\tchalk.dim('Your organization has reached its usage limit.') +\n\t\t\t'\\n\\n' +\n\t\t\tchalk.dim('To continue:\\n') +\n\t\t\tchalk.dim(' • Upgrade your plan at ') +\n\t\t\tchalk.cyan('https://braingrid.ai/pricing') +\n\t\t\t'\\n' +\n\t\t\tchalk.dim(' • Contact your administrator');\n\t\treturn message;\n\t}\n\n\t// Generic 402 error (no specific error code)\n\tif (context) {\n\t\tmessage = chalk.red(`❌ Usage limit reached: ${context}`);\n\t}\n\n\tmessage +=\n\t\t'\\n\\n' +\n\t\tchalk.dim('Your organization has reached its usage limit.') +\n\t\t'\\n\\n' +\n\t\tchalk.dim('To continue:\\n') +\n\t\tchalk.dim(' • Upgrade your plan at ') +\n\t\tchalk.cyan('https://braingrid.ai/pricing') +\n\t\t'\\n' +\n\t\tchalk.dim(' • Contact support at ') +\n\t\tchalk.cyan('support@braingrid.ai');\n\n\treturn message;\n}\n\n/**\n * Handle 422 Validation errors\n * Extracts validation error details from response\n */\nexport function handleValidationError(error: AxiosError, context?: string): string {\n\tlet message = chalk.red('❌ Validation error');\n\n\tif (context) {\n\t\tmessage = chalk.red(`❌ Validation error: ${context}`);\n\t}\n\n\t// Try to extract validation details from response\n\tconst responseData = error.response?.data as\n\t\t| { message?: string; errors?: Record<string, string[]> }\n\t\t| undefined;\n\n\tif (responseData?.message) {\n\t\tmessage += '\\n\\n' + chalk.yellow(responseData.message);\n\t}\n\n\tif (responseData?.errors) {\n\t\tmessage += '\\n\\n' + chalk.dim('Validation errors:');\n\t\tfor (const [field, errors] of Object.entries(responseData.errors)) {\n\t\t\tmessage += '\\n' + chalk.dim(` ${field}:`);\n\t\t\tfor (const error of errors) {\n\t\t\t\tmessage += '\\n' + chalk.dim(` - ${error}`);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tmessage += '\\n\\n' + chalk.dim('Please check your input and try again.');\n\t}\n\n\treturn message;\n}\n\n/**\n * Main error handler - routes to appropriate specialized handler\n */\nexport function handleError(error: AxiosError, context?: string): string {\n\tconst status = error.response?.status;\n\n\tswitch (status) {\n\t\tcase 404: {\n\t\t\treturn handleResourceNotFound(error, context);\n\t\t}\n\t\tcase 401: {\n\t\t\treturn handleAuthError(error, context);\n\t\t}\n\t\tcase 402: {\n\t\t\treturn handlePaymentRequiredError(error, context);\n\t\t}\n\t\tcase 403: {\n\t\t\treturn handlePermissionError(error, context);\n\t\t}\n\t\tcase 422: {\n\t\t\treturn handleValidationError(error, context);\n\t\t}\n\t\tdefault: {\n\t\t\t// Fallback for other errors\n\t\t\tconst responseData = error.response?.data as { message?: string } | undefined;\n\t\t\tconst apiMessage = responseData?.message;\n\n\t\t\tif (apiMessage) {\n\t\t\t\treturn context ? `Error ${context}: ${apiMessage}` : apiMessage;\n\t\t\t}\n\n\t\t\tif (error.message) {\n\t\t\t\treturn context ? `Error ${context}: ${error.message}` : error.message;\n\t\t\t}\n\n\t\t\treturn context ? `Error ${context}` : 'An unexpected error occurred';\n\t\t}\n\t}\n}\n","/**\n * Generic ID normalization utility for resource identifiers\n *\n * This module provides a unified approach to normalizing resource IDs\n * (Projects, Requirements, Tasks) from various user input formats.\n */\n\n/**\n * Normalize a resource ID from various formats to API-compatible format:\n * - \"PREFIX-123\" -> \"PREFIX-123\" (already normalized)\n * - \"prefix-123\" -> \"PREFIX-123\" (uppercase prefix)\n * - \"PREFIX 123\" -> \"PREFIX-123\" (replace space with dash, uppercase)\n * - \"prefix 123\" -> \"PREFIX-123\" (replace space with dash, uppercase)\n * - \"123\" -> \"PREFIX-123\" (add prefix)\n * - \"uuid-string\" -> \"uuid-string\" (UUID, return as-is)\n *\n * @param prefix The resource prefix (e.g., 'PROJ', 'REQ', 'TASK')\n * @param input The user-provided ID string\n * @returns The normalized ID suitable for API calls\n *\n * @example\n * normalizeId('PROJ', 'proj-123') // Returns 'PROJ-123'\n * normalizeId('REQ', 'REQ 456') // Returns 'REQ-456'\n * normalizeId('TASK', '789') // Returns 'TASK-789'\n */\nexport function normalizeId(prefix: string, input: string): string {\n\tconst trimmed = input.trim();\n\tconst upperPrefix = prefix.toUpperCase();\n\n\t// Handle \"PREFIX-123\" or \"prefix-123\" format (already has dash)\n\tconst dashMatch = trimmed.match(new RegExp(`^${prefix}-(\\\\d+)$`, 'i'));\n\tif (dashMatch) {\n\t\t// Strip leading zeros by parsing as integer\n\t\tconst num = parseInt(dashMatch[1], 10);\n\t\treturn `${upperPrefix}-${num}`;\n\t}\n\n\t// Handle \"PREFIX 123\" or \"prefix 123\" format (space instead of dash)\n\tconst spaceMatch = trimmed.match(new RegExp(`^${prefix}\\\\s+(\\\\d+)$`, 'i'));\n\tif (spaceMatch) {\n\t\t// Strip leading zeros by parsing as integer\n\t\tconst num = parseInt(spaceMatch[1], 10);\n\t\treturn `${upperPrefix}-${num}`;\n\t}\n\n\t// Handle plain number format \"123\"\n\tif (/^\\d+$/.test(trimmed)) {\n\t\t// Strip leading zeros by parsing as integer\n\t\tconst num = parseInt(trimmed, 10);\n\t\treturn `${upperPrefix}-${num}`;\n\t}\n\n\t// Assume it's a UUID - return as-is\n\treturn trimmed;\n}\n","import { Project } from '../types/project.js';\nimport { normalizeId } from './id-normalization.js';\n\n/**\n * Format a project with friendly PROJ-<number> format\n * Note: short_id already contains \"PROJ-123\" format\n */\nexport function formatProjectId(project: Project): string {\n\treturn project.short_id;\n}\n\n/**\n * Normalize project ID from various formats to API-compatible format:\n * - \"PROJ-123\" -> \"PROJ-123\" (already normalized)\n * - \"proj-123\" -> \"PROJ-123\" (uppercase)\n * - \"PROJ 123\" -> \"PROJ-123\" (add dash, uppercase)\n * - \"proj 123\" -> \"PROJ-123\" (add dash, uppercase)\n * - \"123\" -> \"PROJ-123\" (add prefix)\n * - \"uuid-string\" -> \"uuid-string\" (UUID, return as-is)\n *\n * This function takes user input and returns the ID that should be used in API calls\n */\nexport function parseProjectId(input: string): string {\n\treturn normalizeId('PROJ', input);\n}\n\n/**\n * Find a project by either short_id or UUID\n */\nexport function findProjectById(projects: Project[], identifier: string): Project | undefined {\n\tconst normalized = parseProjectId(identifier);\n\n\t// Try to find by short_id first (handles PROJ-X format)\n\tconst byShortId = projects.find(proj => proj.short_id === normalized);\n\tif (byShortId) {\n\t\treturn byShortId;\n\t}\n\n\t// Try to find by UUID\n\treturn projects.find(proj => proj.id === normalized);\n}\n","/**\n * Workspace Manager\n *\n * Manages workspace-level state including:\n * - Current project resolution (from .braingrid/project.json)\n * - Active requirement context (session-scoped)\n *\n * This provides a centralized way to access workspace context across handlers.\n */\n\nimport chalk from 'chalk';\nimport { getLocalProjectId } from './local-store.js';\nimport { parseProjectId } from './projects.js';\nimport { getCurrentBranch, parseRequirementFromBranch } from './git.js';\nimport { normalizeRequirementId } from './requirements.js';\n\n/**\n * Result type for project resolution\n */\nexport type WorkspaceProjectResult =\n\t| {\n\t\t\tsuccess: true;\n\t\t\tprojectId: string; // normalized (e.g., \"PROJ-123\")\n\t }\n\t| {\n\t\t\tsuccess: false;\n\t\t\terror: string; // formatted error message with chalk\n\t };\n\n/**\n * Result type for requirement resolution\n */\nexport type WorkspaceRequirementResult =\n\t| {\n\t\t\tsuccess: true;\n\t\t\trequirementId: string; // normalized (e.g., \"REQ-123\")\n\t }\n\t| {\n\t\t\tsuccess: false;\n\t\t\terror: string; // formatted error message with chalk\n\t };\n\n/**\n * Manages workspace-level state\n *\n * Singleton pattern - one instance per CLI session\n */\nexport class WorkspaceManager {\n\tprivate activeRequirementId: string | null = null;\n\n\t/**\n\t * Get the project ID for the current workspace\n\t *\n\t * Resolution order:\n\t * 1. If explicitProjectId provided → normalize and return it\n\t * 2. Check .braingrid/project.json for configured project (at git root)\n\t * 3. If not initialized → return error with initialization instructions\n\t *\n\t * @param explicitProjectId - Optional project ID from -p or --project flag\n\t * @returns Result with either projectId (normalized) or error message\n\t */\n\tasync getProject(explicitProjectId?: string): Promise<WorkspaceProjectResult> {\n\t\t// If explicit project provided via flag\n\t\tif (explicitProjectId) {\n\t\t\tconst normalized = parseProjectId(explicitProjectId);\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tprojectId: normalized,\n\t\t\t};\n\t\t}\n\n\t\t// Try to get from .braingrid/project.json (searches git root first)\n\t\tconst localProjectId = await getLocalProjectId();\n\t\tif (localProjectId) {\n\t\t\tconst normalized = parseProjectId(localProjectId);\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tprojectId: normalized,\n\t\t\t};\n\t\t}\n\n\t\t// Not initialized\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror:\n\t\t\t\tchalk.red('❌ No project specified and no local project found.') +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('To initialize this workspace, run:\\n') +\n\t\t\t\tchalk.cyan(' braingrid init') +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('Or specify a project explicitly:\\n') +\n\t\t\t\tchalk.cyan(' braingrid <command> -p PROJ-123'),\n\t\t};\n\t}\n\n\t/**\n\t * Get the requirement ID for the current workspace\n\t *\n\t * Resolution order:\n\t * 1. If explicitRequirementId provided → normalize and return it\n\t * 2. Try to parse from current git branch name (e.g., \"feature/REQ-123-description\")\n\t * 3. If not found → return error with usage instructions\n\t *\n\t * @param explicitRequirementId - Optional requirement ID from -r or --requirement flag or [id] argument\n\t * @returns Result with either requirementId (normalized) or error message\n\t */\n\tasync getRequirement(explicitRequirementId?: string): Promise<WorkspaceRequirementResult> {\n\t\t// If explicit requirement provided via flag or argument\n\t\tif (explicitRequirementId) {\n\t\t\tconst normalized = normalizeRequirementId(explicitRequirementId);\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\trequirementId: normalized,\n\t\t\t};\n\t\t}\n\n\t\t// Try to parse from git branch name\n\t\tconst branchName = await getCurrentBranch();\n\t\tif (branchName) {\n\t\t\tconst requirementId = parseRequirementFromBranch(branchName);\n\t\t\tif (requirementId) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\trequirementId,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Not found\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror:\n\t\t\t\tchalk.red('❌ No requirement specified.') +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('Unable to auto-detect requirement from branch name.\\n') +\n\t\t\t\tchalk.dim('Please provide a requirement ID explicitly:\\n') +\n\t\t\t\tchalk.cyan(' braingrid requirement show REQ-123') +\n\t\t\t\t'\\n' +\n\t\t\t\tchalk.dim(' or\\n') +\n\t\t\t\tchalk.cyan(' braingrid task list -r REQ-123') +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim(\n\t\t\t\t\t'Tip: Name your branch with a requirement ID (e.g., feature/REQ-123-description)\\n'\n\t\t\t\t) +\n\t\t\t\tchalk.dim('to enable auto-detection.'),\n\t\t};\n\t}\n\n\t/**\n\t * Set the active requirement for this workspace session\n\t *\n\t * This is used to automatically include requirement context in agent conversations\n\t *\n\t * @param requirementId - The requirement ID to set as active\n\t */\n\tsetActiveRequirement(requirementId: string): void {\n\t\tthis.activeRequirementId = requirementId;\n\t}\n\n\t/**\n\t * Get the currently active requirement ID\n\t *\n\t * @returns The active requirement ID or null if none set\n\t */\n\tgetActiveRequirement(): string | null {\n\t\treturn this.activeRequirementId;\n\t}\n\n\t/**\n\t * Clear the active requirement\n\t */\n\tclearActiveRequirement(): void {\n\t\tthis.activeRequirementId = null;\n\t}\n\n\t/**\n\t * Check if there is an active requirement set\n\t *\n\t * @returns true if a requirement is active, false otherwise\n\t */\n\thasActiveRequirement(): boolean {\n\t\treturn this.activeRequirementId !== null;\n\t}\n}\n\n// Export singleton instance\nexport const workspaceManager = new WorkspaceManager();\n","/**\n * Local Project Store\n * Handles reading/writing .braingrid/project.json\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { LocalProjectConfig, LocalProjectConfigSchema } from '../types/local-project.js';\nimport { getGitRoot } from './git.js';\n\nconst BRAINGRID_DIR = '.braingrid';\nconst PROJECT_CONFIG_FILE = 'project.json';\n\n/**\n * Get the default directory for .braingrid folder\n * Prefers git repository root, falls back to current working directory\n */\nasync function getDefaultCwd(): Promise<string> {\n\tconst gitRoot = await getGitRoot();\n\treturn gitRoot || process.cwd();\n}\n\n/**\n * Get the path to the .braingrid directory\n */\nexport async function getBraingridDir(cwd?: string): Promise<string> {\n\tconst dir = cwd ?? (await getDefaultCwd());\n\treturn path.join(dir, BRAINGRID_DIR);\n}\n\n/**\n * Get the path to the project.json file\n */\nexport async function getProjectConfigPath(cwd?: string): Promise<string> {\n\tconst braingridDir = await getBraingridDir(cwd);\n\treturn path.join(braingridDir, PROJECT_CONFIG_FILE);\n}\n\n/**\n * Check if .braingrid/project.json exists\n */\nexport async function projectConfigExists(cwd?: string): Promise<boolean> {\n\tconst configPath = await getProjectConfigPath(cwd);\n\treturn fs.existsSync(configPath);\n}\n\n/**\n * Ensure .braingrid directory exists\n */\nasync function ensureBraingridDir(cwd?: string): Promise<void> {\n\tconst dir = await getBraingridDir(cwd);\n\tif (!fs.existsSync(dir)) {\n\t\tfs.mkdirSync(dir, { recursive: true });\n\t}\n}\n\n/**\n * Load project configuration from .braingrid/project.json\n * @throws Error if file doesn't exist or is invalid\n */\nexport async function loadProjectConfig(cwd?: string): Promise<LocalProjectConfig> {\n\tconst configPath = await getProjectConfigPath(cwd);\n\n\tif (!fs.existsSync(configPath)) {\n\t\tthrow new Error(`Project not initialized. Run 'braingrid init' to initialize this repository.`);\n\t}\n\n\tconst content = fs.readFileSync(configPath, 'utf8');\n\tconst data = JSON.parse(content);\n\n\t// Validate with Zod schema\n\treturn LocalProjectConfigSchema.parse(data);\n}\n\n/**\n * Save project configuration to .braingrid/project.json\n */\nexport async function saveProjectConfig(config: LocalProjectConfig, cwd?: string): Promise<void> {\n\tawait ensureBraingridDir(cwd);\n\n\tconst configPath = await getProjectConfigPath(cwd);\n\tconst content = JSON.stringify(config, null, 2);\n\n\tfs.writeFileSync(configPath, content, 'utf8');\n}\n\n/**\n * Delete .braingrid/project.json\n */\nexport async function deleteProjectConfig(cwd?: string): Promise<void> {\n\tconst configPath = await getProjectConfigPath(cwd);\n\tif (fs.existsSync(configPath)) {\n\t\tfs.unlinkSync(configPath);\n\t}\n}\n\n/**\n * Get the local project ID from .braingrid/project.json\n * Returns the short_id (e.g., PROJ-123) if project.json exists, null otherwise\n */\nexport async function getLocalProjectId(cwd?: string): Promise<string | null> {\n\ttry {\n\t\tconst config = await loadProjectConfig(cwd);\n\t\treturn config.project_short_id;\n\t} catch {\n\t\treturn null;\n\t}\n}\n","/**\n * Local Project Configuration Types\n * Stores project information in .braingrid/project.json\n */\n\nimport { z } from 'zod';\n\n// Repository schema (internal use only)\nconst LocalRepositorySchema = z.object({\n\tid: z.string().uuid(),\n\towner: z.string(),\n\tname: z.string(),\n\tfull_name: z.string(),\n\turl: z.string().url().optional(),\n});\n\nexport type LocalRepository = z.infer<typeof LocalRepositorySchema>;\n\n// Local project configuration schema\nexport const LocalProjectConfigSchema = z.object({\n\torganization_id: z.string(),\n\tproject_id: z.string().uuid(),\n\tproject_short_id: z.string(),\n\tproject_name: z.string(),\n\tproject_description: z.string().nullable(),\n\trepository: LocalRepositorySchema.nullable(),\n\tcreated_at: z.string(),\n});\n\nexport type LocalProjectConfig = z.infer<typeof LocalProjectConfigSchema>;\n","/**\n * Git Utilities\n *\n * Provides functions to interact with git repositories:\n * - Detect if current directory is a git repository\n * - Get remote repository information (owner/name)\n * - Get current branch\n * - Get git user configuration\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\n\nconst execAsync = promisify(exec);\n\nexport interface GitRepoInfo {\n\tisRepo: boolean;\n\towner: string | null;\n\tname: string | null;\n\tbranch: string | null;\n\tuserName: string | null;\n\tuserEmail: string | null;\n\tremoteUrl: string | null;\n}\n\nexport interface GitUser {\n\tname: string | null;\n\temail: string | null;\n}\n\nexport interface GitHubRepo {\n\towner: string;\n\tname: string;\n}\n\n/**\n * Check if current directory is inside a git repository\n */\nexport async function isGitRepository(): Promise<boolean> {\n\ttry {\n\t\tconst { stdout } = await execAsync('git rev-parse --is-inside-work-tree');\n\t\treturn stdout.trim() === 'true';\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Get the URL of the 'origin' remote\n */\nexport async function getRemoteUrl(): Promise<string | null> {\n\ttry {\n\t\tconst { stdout } = await execAsync('git config --get remote.origin.url');\n\t\treturn stdout.trim() || null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Parse GitHub repository owner and name from a git remote URL\n * Supports both HTTPS and SSH formats:\n * - https://github.com/owner/repo.git\n * - git@github.com:owner/repo.git\n */\nexport function parseGitHubRepo(url: string): GitHubRepo | null {\n\tif (!url) return null;\n\n\t// Match HTTPS format: https://github.com/owner/repo.git\n\tconst httpsMatch = url.match(/https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+?)(\\.git)?$/);\n\tif (httpsMatch) {\n\t\treturn {\n\t\t\towner: httpsMatch[1],\n\t\t\tname: httpsMatch[2],\n\t\t};\n\t}\n\n\t// Match SSH format: git@github.com:owner/repo.git\n\tconst sshMatch = url.match(/git@github\\.com:([^/]+)\\/([^/]+?)(\\.git)?$/);\n\tif (sshMatch) {\n\t\treturn {\n\t\t\towner: sshMatch[1],\n\t\t\tname: sshMatch[2],\n\t\t};\n\t}\n\n\treturn null;\n}\n\n/**\n * Get the current branch name\n */\nexport async function getCurrentBranch(): Promise<string | null> {\n\ttry {\n\t\tconst { stdout } = await execAsync('git rev-parse --abbrev-ref HEAD');\n\t\treturn stdout.trim() || null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Parse requirement ID from a git branch name\n * Supports patterns like: REQ-123, feature/REQ-123, feature/REQ-123-description, req-456-feature\n * Returns the requirement ID in uppercase format (e.g., \"REQ-123\") or null if not found\n */\nexport function parseRequirementFromBranch(branchName: string): string | null {\n\tif (!branchName) return null;\n\n\t// Match REQ-digits pattern (case-insensitive)\n\tconst match = branchName.match(/REQ-(\\d+)/i);\n\tif (match) {\n\t\t// Return in uppercase format: REQ-123\n\t\treturn `REQ-${match[1]}`;\n\t}\n\n\treturn null;\n}\n\n/**\n * Get the git repository root directory\n * Returns the absolute path to the repository root, or null if not in a git repository\n */\nexport async function getGitRoot(): Promise<string | null> {\n\ttry {\n\t\tconst { stdout } = await execAsync('git rev-parse --show-toplevel');\n\t\treturn stdout.trim() || null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Get git user configuration (name and email)\n */\nexport async function getGitUser(): Promise<GitUser> {\n\tlet name: string | null = null;\n\tlet email: string | null = null;\n\n\ttry {\n\t\tconst { stdout: nameStdout } = await execAsync('git config --get user.name');\n\t\tname = nameStdout.trim() || null;\n\t} catch {\n\t\t// user.name not configured\n\t}\n\n\ttry {\n\t\tconst { stdout: emailStdout } = await execAsync('git config --get user.email');\n\t\temail = emailStdout.trim() || null;\n\t} catch {\n\t\t// user.email not configured\n\t}\n\n\treturn { name, email };\n}\n\n/**\n * Get comprehensive git repository information\n * Returns null if not in a git repository\n */\nexport async function getGitRepositoryInfo(): Promise<GitRepoInfo | null> {\n\tconst isRepo = await isGitRepository();\n\n\tif (!isRepo) {\n\t\treturn {\n\t\t\tisRepo: false,\n\t\t\towner: null,\n\t\t\tname: null,\n\t\t\tbranch: null,\n\t\t\tuserName: null,\n\t\t\tuserEmail: null,\n\t\t\tremoteUrl: null,\n\t\t};\n\t}\n\n\tconst [remoteUrl, branch, gitUser] = await Promise.all([\n\t\tgetRemoteUrl(),\n\t\tgetCurrentBranch(),\n\t\tgetGitUser(),\n\t]);\n\n\tconst repo = remoteUrl ? parseGitHubRepo(remoteUrl) : null;\n\n\treturn {\n\t\tisRepo: true,\n\t\towner: repo?.owner || null,\n\t\tname: repo?.name || null,\n\t\tbranch,\n\t\tuserName: gitUser.name,\n\t\tuserEmail: gitUser.email,\n\t\tremoteUrl,\n\t};\n}\n","import { Requirement } from '../types/requirement.js';\nimport { normalizeId } from './id-normalization.js';\n\n/**\n * Format a requirement with friendly REQ-<number> format\n * Note: short_id already contains \"REQ-123\" format\n */\nexport function formatRequirementId(requirement: Requirement): string {\n\treturn requirement.short_id || `REQ-${requirement.req_id || 0}`;\n}\n\n/**\n * Normalize requirement ID from various formats to API-compatible format:\n * - \"REQ-123\" -> \"REQ-123\" (already normalized)\n * - \"req-123\" -> \"REQ-123\" (uppercase)\n * - \"REQ 123\" -> \"REQ-123\" (add dash, uppercase)\n * - \"req 123\" -> \"REQ-123\" (add dash, uppercase)\n * - \"123\" -> \"REQ-123\" (add prefix)\n * - \"uuid-string\" -> \"uuid-string\" (UUID, return as-is)\n *\n * This function takes user input and returns the ID that should be used in API calls\n */\nexport function normalizeRequirementId(input: string): string {\n\treturn normalizeId('REQ', input);\n}\n\n/**\n * Parse a requirement ID from various formats:\n * - \"REQ-123\" -> { type: 'req_id', value: 123 }\n * - \"req-123\" -> { type: 'req_id', value: 123 }\n * - \"REQ 123\" -> { type: 'req_id', value: 123 }\n * - \"req 123\" -> { type: 'req_id', value: 123 }\n * - \"123\" -> { type: 'req_id', value: 123 }\n * - \"uuid-string\" -> { type: 'uuid', value: 'uuid-string' }\n */\nexport function parseRequirementId(input: string): {\n\ttype: 'req_id' | 'uuid';\n\tvalue: string | number;\n} {\n\t// Trim whitespace\n\tconst trimmed = input.trim();\n\n\t// Handle \"REQ-123\" or \"req-123\" format (with dash)\n\tconst reqDashMatch = trimmed.match(/^REQ-(\\d+)$/i);\n\tif (reqDashMatch) {\n\t\treturn { type: 'req_id', value: parseInt(reqDashMatch[1], 10) };\n\t}\n\n\t// Handle \"REQ 123\" or \"req 123\" format (with space)\n\tconst reqSpaceMatch = trimmed.match(/^REQ\\s+(\\d+)$/i);\n\tif (reqSpaceMatch) {\n\t\treturn { type: 'req_id', value: parseInt(reqSpaceMatch[1], 10) };\n\t}\n\n\t// Handle plain number format\n\tconst numberMatch = trimmed.match(/^\\d+$/);\n\tif (numberMatch) {\n\t\treturn { type: 'req_id', value: parseInt(trimmed, 10) };\n\t}\n\n\t// Assume it's a UUID\n\treturn { type: 'uuid', value: trimmed };\n}\n\n/**\n * Find a requirement by either req_id or UUID\n */\nexport function findRequirementById(\n\trequirements: Requirement[],\n\tidentifier: string\n): Requirement | undefined {\n\tconst parsed = parseRequirementId(identifier);\n\n\tif (parsed.type === 'req_id') {\n\t\treturn requirements.find(req => req.short_id === `REQ-${parsed.value}`);\n\t} else {\n\t\treturn requirements.find(req => req.id === parsed.value);\n\t}\n}\n\n/**\n * Get query parameters for API calls based on identifier type\n * Note: API doesn't support req_id parameter, so we only return id for UUIDs\n */\nexport function getRequirementQueryParams(identifier: string): { id?: string } {\n\tconst parsed = parseRequirementId(identifier);\n\n\tif (parsed.type === 'uuid') {\n\t\treturn { id: parsed.value as string };\n\t} else {\n\t\t// For req_id, we'll need to search differently\n\t\treturn {};\n\t}\n}\n","/**\n * Spinner Utility\n *\n * Provides a simple polling spinner for async operations with user feedback.\n * Shows an animated spinner while waiting for a condition to become true.\n */\n\nimport chalk from 'chalk';\n\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\n/**\n * Wait for a condition with animated spinner\n *\n * Polls an async check function and displays a spinner while waiting.\n * Clears the spinner on completion or timeout.\n *\n * @param message - Message to display next to spinner\n * @param checkFn - Async function that returns true when condition is met\n * @param intervalMs - Polling interval in milliseconds (default: 3000)\n * @param maxAttempts - Maximum number of attempts (default: 60 = 3 minutes at 3s interval)\n * @returns Promise that resolves to true if condition met, false if timeout\n *\n * @example\n * ```typescript\n * const success = await waitWithSpinner(\n * 'Waiting for repository access',\n * async () => await checkAccess(),\n * 3000,\n * 60\n * );\n * ```\n */\nexport async function waitWithSpinner(\n\tmessage: string,\n\tcheckFn: () => Promise<boolean>,\n\tintervalMs: number = 3000,\n\tmaxAttempts: number = 60\n): Promise<boolean> {\n\tlet frameIndex = 0;\n\tlet spinnerInterval: NodeJS.Timeout | null = null;\n\n\t// Function to update spinner\n\tconst updateSpinner = (): void => {\n\t\tconst frame = SPINNER_FRAMES[frameIndex];\n\t\tframeIndex = (frameIndex + 1) % SPINNER_FRAMES.length;\n\n\t\t// Clear current line and write new spinner\n\t\tprocess.stdout.write(`\\r${chalk.cyan(frame)} ${message}...`);\n\t};\n\n\t// Start spinner animation (update every 100ms for smooth animation)\n\tspinnerInterval = setInterval(updateSpinner, 100);\n\n\ttry {\n\t\t// Poll with the specified interval\n\t\tfor (let attempt = 0; attempt < maxAttempts; attempt++) {\n\t\t\tconst result = await checkFn();\n\n\t\t\tif (result) {\n\t\t\t\t// Success! Clear spinner and return\n\t\t\t\tif (spinnerInterval) clearInterval(spinnerInterval);\n\t\t\t\tprocess.stdout.write('\\r' + ' '.repeat(message.length + 10) + '\\r'); // Clear line\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// Wait before next attempt (unless this was the last attempt)\n\t\t\tif (attempt < maxAttempts - 1) {\n\t\t\t\tawait new Promise(resolve => setTimeout(resolve, intervalMs));\n\t\t\t}\n\t\t}\n\n\t\t// Timeout - clear spinner and return false\n\t\tif (spinnerInterval) clearInterval(spinnerInterval);\n\t\tprocess.stdout.write('\\r' + ' '.repeat(message.length + 10) + '\\r'); // Clear line\n\t\treturn false;\n\t} catch (error) {\n\t\t// Error during polling - clean up and rethrow\n\t\tif (spinnerInterval) clearInterval(spinnerInterval);\n\t\tprocess.stdout.write('\\r' + ' '.repeat(message.length + 10) + '\\r'); // Clear line\n\t\tthrow error;\n\t}\n}\n\n/**\n * Simple one-time spinner display\n *\n * Shows a spinner without polling. Useful for operations that manage their own timing.\n * Returns a cleanup function to clear the spinner.\n *\n * @param message - Message to display\n * @param color - Chalk color function (default: cyan for AI operations, use gray for CRUD)\n * @returns Cleanup function to stop and clear the spinner\n *\n * @example\n * ```typescript\n * const stop = showSpinner('Loading');\n * await doWork();\n * stop();\n * ```\n */\nexport function showSpinner(message: string, color: typeof chalk.cyan = chalk.cyan): () => void {\n\tlet frameIndex = 0;\n\tconst interval = setInterval(() => {\n\t\tconst frame = SPINNER_FRAMES[frameIndex];\n\t\tframeIndex = (frameIndex + 1) % SPINNER_FRAMES.length;\n\t\tprocess.stdout.write(`\\r${color(frame)} ${message}...`);\n\t}, 100);\n\n\treturn (): void => {\n\t\tclearInterval(interval);\n\t\tprocess.stdout.write('\\r' + ' '.repeat(message.length + 10) + '\\r');\n\t};\n}\n","/**\n * Internal Repository Service\n *\n * For internal use only - not exposed as CLI commands.\n * Handles API interactions with BrainGrid v1 Repository endpoints.\n *\n * This service provides methods to:\n * - List repositories with filtering and pagination\n * - Get detailed information about specific repositories\n *\n * @internal\n */\n\nimport { AxiosInstance } from 'axios';\nimport { BraingridAuth } from '../auth.js';\nimport { createAuthenticatedAxios } from '../../utils/axios-with-auth.js';\nimport { Repository, ListRepositoriesResponse } from '../../types/github.js';\n\n/**\n * Internal service for Repository API operations\n */\nexport class RepositoryService {\n\tprivate baseUrl: string;\n\tprivate auth: BraingridAuth;\n\tprivate axios: AxiosInstance;\n\n\tconstructor(baseUrl: string, auth: BraingridAuth) {\n\t\tthis.baseUrl = baseUrl;\n\t\tthis.auth = auth;\n\t\tthis.axios = createAuthenticatedAxios(auth);\n\t}\n\n\tprivate getHeaders(): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t};\n\t}\n\n\t/**\n\t * List repositories for the authenticated organization\n\t *\n\t * @param params - Optional filtering and pagination parameters\n\t * @param params.page - Page number (default: 1, min: 1)\n\t * @param params.limit - Number of repositories per page (default: 10, min: 1, max: 100)\n\t * @param params.owner - Filter repositories by owner name\n\t * @param params.name - Filter repositories by name (requires owner parameter)\n\t * @returns List of repositories with pagination\n\t * @throws {Error} On API errors (401, 404, 422, 500)\n\t *\n\t * @example\n\t * ```typescript\n\t * // List all repositories with pagination\n\t * const result = await repositoryService.listRepositories({ page: 1, limit: 10 });\n\t * console.log(result.repositories);\n\t * console.log(result.pagination);\n\t *\n\t * // Filter by owner\n\t * const microsoftRepos = await repositoryService.listRepositories({ owner: 'microsoft' });\n\t *\n\t * // Filter by owner and name\n\t * const tsRepo = await repositoryService.listRepositories({ owner: 'microsoft', name: 'typescript' });\n\t * ```\n\t */\n\tasync listRepositories(params?: {\n\t\tpage?: number;\n\t\tlimit?: number;\n\t\towner?: string;\n\t\tname?: string;\n\t}): Promise<ListRepositoriesResponse> {\n\t\tconst url = `${this.baseUrl}/api/v1/repositories`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<ListRepositoriesResponse>(url, { headers, params });\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Get detailed information about a specific repository\n\t *\n\t * Supports both UUID and short ID formats (e.g., \"REPO-1\").\n\t * Returns repository details including metadata and sync status.\n\t *\n\t * @param repositoryId - Repository UUID or short ID (e.g., \"REPO-1\")\n\t * @returns Detailed repository information\n\t * @throws {Error} On API errors (401, 404, 422, 500)\n\t *\n\t * @example\n\t * ```typescript\n\t * // Using short ID\n\t * const repo = await repositoryService.getRepository('REPO-1');\n\t *\n\t * // Using UUID\n\t * const repo = await repositoryService.getRepository('550e8400-e29b-41d4-a716-446655440000');\n\t *\n\t * console.log(repo.full_name);\n\t * console.log(repo.last_synced_at);\n\t * ```\n\t */\n\tasync getRepository(repositoryId: string): Promise<Repository> {\n\t\tconst url = `${this.baseUrl}/api/v1/repositories/${repositoryId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<Repository>(url, { headers });\n\t\treturn response.data;\n\t}\n}\n","/**\n * Repository Access Utility\n *\n * Helpers for checking GitHub installation and repository access during project initialization.\n * Handles detection of owner-specific installations and repository visibility in BrainGrid.\n */\n\nimport { GitHubInstallation } from '../types/github.js';\nimport { RepositoryService } from '../services/internal/repository-service.js';\n\n/**\n * Find a GitHub installation for a specific repository owner\n *\n * @param owner - The GitHub repository owner (org or user)\n * @param installations - List of GitHub installations to search\n * @returns The matching installation or null if not found\n *\n * @example\n * ```typescript\n * const installation = findInstallationForOwner('myorg', installations);\n * if (installation) {\n * console.log(`Found installation for ${installation.account_name}`);\n * }\n * ```\n */\nexport function findInstallationForOwner(\n\towner: string,\n\tinstallations: GitHubInstallation[]\n): GitHubInstallation | null {\n\t// Case-insensitive match on account_name\n\tconst normalizedOwner = owner.toLowerCase();\n\n\treturn installations.find(inst => inst.account_name.toLowerCase() === normalizedOwner) || null;\n}\n\n/**\n * Check if a repository is accessible in BrainGrid\n *\n * Queries the repository API to see if the specific owner/name combination\n * is visible to the authenticated user's organization.\n *\n * @param repositoryService - Repository service instance\n * @param owner - GitHub repository owner\n * @param name - GitHub repository name\n * @returns True if repository is accessible, false otherwise\n *\n * @example\n * ```typescript\n * const hasAccess = await checkRepositoryAccess(repoService, 'myorg', 'myrepo');\n * if (hasAccess) {\n * console.log('Repository is accessible in BrainGrid');\n * }\n * ```\n */\nexport async function checkRepositoryAccess(\n\trepositoryService: RepositoryService,\n\towner: string,\n\tname: string\n): Promise<boolean> {\n\ttry {\n\t\tconst response = await repositoryService.listRepositories({\n\t\t\towner,\n\t\t\tname,\n\t\t\tlimit: 1,\n\t\t});\n\n\t\t// If we get results, the repository is accessible\n\t\treturn response.repositories.length > 0;\n\t} catch {\n\t\t// If the API call fails, assume no access\n\t\treturn false;\n\t}\n}\n\n/**\n * Poll for repository access with timeout\n *\n * Continuously checks if a repository becomes accessible in BrainGrid.\n * Useful when waiting for a user to grant access through the web UI.\n *\n * @param repositoryService - Repository service instance\n * @param owner - GitHub repository owner\n * @param name - GitHub repository name\n * @param intervalMs - Polling interval in milliseconds (default: 3000)\n * @param maxAttempts - Maximum number of polling attempts (default: 60 = 3 minutes at 3s interval)\n * @returns Promise that resolves to true if access is granted, false if timeout\n *\n * @example\n * ```typescript\n * const granted = await pollForRepositoryAccess(repoService, 'myorg', 'myrepo');\n * if (granted) {\n * console.log('Access granted!');\n * } else {\n * console.log('Timeout - access not granted within 3 minutes');\n * }\n * ```\n */\nexport async function pollForRepositoryAccess(\n\trepositoryService: RepositoryService,\n\towner: string,\n\tname: string,\n\tintervalMs: number = 3000,\n\tmaxAttempts: number = 60\n): Promise<boolean> {\n\tfor (let attempt = 0; attempt < maxAttempts; attempt++) {\n\t\tconst hasAccess = await checkRepositoryAccess(repositoryService, owner, name);\n\n\t\tif (hasAccess) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Wait before next attempt (unless this was the last attempt)\n\t\tif (attempt < maxAttempts - 1) {\n\t\t\tawait new Promise(resolve => setTimeout(resolve, intervalMs));\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Get repository ID from BrainGrid API\n *\n * Fetches the repository details to get its BrainGrid UUID, which is needed\n * for linking repositories to projects.\n *\n * @param repositoryService - Repository service instance\n * @param owner - GitHub repository owner\n * @param name - GitHub repository name\n * @returns Repository UUID or null if not found\n *\n * @example\n * ```typescript\n * const repoId = await getRepositoryId(repoService, 'myorg', 'myrepo');\n * if (repoId) {\n * await projectService.createProject({ name: 'My Project', repository_ids: [repoId] });\n * }\n * ```\n */\nexport async function getRepositoryId(\n\trepositoryService: RepositoryService,\n\towner: string,\n\tname: string\n): Promise<string | null> {\n\ttry {\n\t\tconst response = await repositoryService.listRepositories({\n\t\t\towner,\n\t\t\tname,\n\t\t\tlimit: 1,\n\t\t});\n\n\t\tif (response.repositories.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn response.repositories[0].id;\n\t} catch {\n\t\treturn null;\n\t}\n}\n","import chalk from 'chalk';\nimport {\n\tRequirement,\n\tRequirementDetail,\n\tRequirementTask as Task,\n\tRequirementStatus,\n} from '../types/requirement.js';\nimport { Task as TaskType } from '../types/task.js';\nimport { Project } from '../types/project.js';\nimport { formatRequirementId } from './requirements.js';\nimport { formatTaskId, getTaskStatusIcon } from './tasks.js';\n\n/**\n * Convert API URL to web UI URL\n * @param apiUrl - The API base URL (e.g., \"https://app.braingrid.ai\" or \"https://app.dev.braingrid.ai\")\n * @returns Web UI base URL\n */\nfunction getWebUiUrl(apiUrl: string): string {\n\t// If API URL contains dev.braingrid.ai, use dev web UI\n\tif (apiUrl.includes('dev.braingrid.ai')) {\n\t\treturn 'https://app.dev.braingrid.ai';\n\t}\n\t// Default to production\n\treturn 'https://app.braingrid.ai';\n}\n\nexport function formatRequirementsList(requirements: Requirement[], total: number): string {\n\tif (requirements.length === 0) {\n\t\treturn chalk.yellow('No requirements found.\\n');\n\t}\n\n\tlet output = chalk.bold.cyan(`📋 Requirements (${requirements.length} of ${total})\\n\\n`);\n\n\trequirements.forEach((req, index) => {\n\t\tconst statusColor = getStatusColor(req.status);\n\t\tconst statusIcon = getStatusIcon(req.status);\n\n\t\toutput += chalk.bold(`${index + 1}. ${req.name}\\n`);\n\t\toutput += ` ${statusIcon} Status: ${statusColor(req.status)}\\n`;\n\t\toutput += ` 📝 ${req.description}\\n`;\n\t\toutput += ` 🆔 ID: ${chalk.gray(formatRequirementId(req))}\\n`;\n\t\toutput += ` 📎 UUID: ${chalk.gray(req.id)}\\n`;\n\n\t\tif (req.assigned_to) {\n\t\t\toutput += ` 👤 Assigned: ${chalk.blue(req.assigned_to)}\\n`;\n\t\t}\n\n\t\toutput += ` 📅 Updated: ${chalk.gray(new Date(req.updated_at).toLocaleDateString())}\\n\\n`;\n\t});\n\n\treturn output;\n}\n\nexport function formatRequirementDetail(requirement: Requirement): string {\n\tconst statusColor = getStatusColor(requirement.status);\n\tconst statusIcon = getStatusIcon(requirement.status);\n\n\tlet output = chalk.bold.cyan(`📋 Requirement Details\\n`);\n\toutput += chalk.gray('━'.repeat(50)) + '\\n\\n';\n\n\toutput += chalk.bold(`Name: ${requirement.name}\\n`);\n\toutput += `${statusIcon} Status: ${statusColor(requirement.status)}\\n`;\n\toutput += `🆔 ID: ${chalk.gray(formatRequirementId(requirement))}\\n`;\n\toutput += `📎 UUID: ${chalk.gray(requirement.id)}\\n`;\n\n\tif (requirement.assigned_to) {\n\t\toutput += `👤 Assigned: ${chalk.blue(requirement.assigned_to)}\\n`;\n\t}\n\n\toutput += `📅 Created: ${chalk.gray(new Date(requirement.created_at).toLocaleDateString())}\\n`;\n\toutput += `📅 Updated: ${chalk.gray(new Date(requirement.updated_at).toLocaleDateString())}\\n\\n`;\n\n\toutput += chalk.bold('Description:\\n');\n\toutput += `${requirement.description}\\n\\n`;\n\n\treturn output;\n}\n\nexport function formatTasksList(tasks: Task[], total?: number): string {\n\tif (tasks.length === 0) {\n\t\treturn chalk.yellow('No tasks found.\\n');\n\t}\n\n\tconst displayTotal = total !== undefined ? ` of ${total}` : '';\n\tlet output = chalk.bold.cyan(`📝 Tasks (${tasks.length}${displayTotal})\\n\\n`);\n\n\ttasks.forEach((task, index) => {\n\t\tconst statusColor = getStatusColor(task.status);\n\t\tconst statusIcon = getTaskStatusIcon(task.status);\n\n\t\toutput += chalk.bold(`${index + 1}. ${task.title}\\n`);\n\t\toutput += ` ${statusIcon} Status: ${statusColor(task.status)}\\n`;\n\t\toutput += ` 📄 ${task.content}\\n`;\n\t\toutput += ` 🆔 ID: ${chalk.gray(formatTaskId(task))}\\n`;\n\t\toutput += ` 📎 UUID: ${chalk.gray(task.id)}\\n`;\n\n\t\tif (task.assigned_to) {\n\t\t\toutput += ` 👤 Assigned: ${chalk.blue(task.assigned_to)}\\n`;\n\t\t}\n\n\t\toutput += ` 📅 Updated: ${chalk.gray(new Date(task.updated_at).toLocaleDateString())}\\n\\n`;\n\t});\n\n\treturn output;\n}\n\n/**\n * Format task list with support for multiple output formats\n */\nexport function formatTasksListOutput(\n\ttasks: TaskType[],\n\tformat: 'table' | 'json' | 'xml' | 'markdown',\n\tverbose: boolean,\n\toptions?: {\n\t\trequirementId?: string;\n\t\tprojectShortId?: string;\n\t\trequirementShortId?: string;\n\t\tapiUrl?: string;\n\t}\n): string {\n\tif (tasks.length === 0) {\n\t\treturn chalk.yellow('No tasks found.');\n\t}\n\n\t// Handle format + verbose combinations\n\tswitch (format) {\n\t\tcase 'json':\n\t\t\tif (verbose) {\n\t\t\t\t// Full task objects with content\n\t\t\t\treturn JSON.stringify(tasks, null, 2);\n\t\t\t} else {\n\t\t\t\t// Subset of fields (table columns only)\n\t\t\t\treturn formatTasksListJsonSubset(tasks);\n\t\t\t}\n\n\t\tcase 'xml':\n\t\t\tif (verbose) {\n\t\t\t\t// Full tasks with content\n\t\t\t\treturn formatTasksListXml(tasks);\n\t\t\t} else {\n\t\t\t\t// Subset of fields (table columns only)\n\t\t\t\treturn formatTasksListXmlSubset(tasks);\n\t\t\t}\n\n\t\tcase 'markdown':\n\t\t\tif (verbose) {\n\t\t\t\t// Detailed markdown with content per task\n\t\t\t\treturn formatTasksListMarkdownVerbose(tasks, options);\n\t\t\t} else {\n\t\t\t\t// Markdown table\n\t\t\t\treturn formatTasksListMarkdown(tasks);\n\t\t\t}\n\n\t\tcase 'table':\n\t\tdefault:\n\t\t\tif (verbose) {\n\t\t\t\t// Multi-line detailed view with content\n\t\t\t\treturn formatTasksListVerbose(tasks, options);\n\t\t\t} else {\n\t\t\t\t// Compact table\n\t\t\t\treturn formatTasksListTable(tasks);\n\t\t\t}\n\t}\n}\n\n/**\n * Table format (default) - compact table view\n */\nfunction formatTasksListTable(tasks: TaskType[]): string {\n\tlet output = chalk.bold(`📋 Tasks (${tasks.length})\\n\\n`);\n\toutput +=\n\t\t'ID Short ID Status Title Assigned To Blocked\\n';\n\toutput += '─'.repeat(120) + '\\n';\n\n\tfor (const task of tasks) {\n\t\tconst id = task.id.substring(0, 36).padEnd(36);\n\t\tconst shortId = `TASK-${task.number}`.padEnd(8);\n\t\tconst statusEmoji = getTaskStatusEmoji(task.status);\n\t\tconst statusText = task.status.padEnd(12);\n\t\tconst title = task.title.substring(0, 28).padEnd(28);\n\t\tconst assignedTo = (task.assigned_to || 'Unassigned').substring(0, 13).padEnd(13);\n\t\tconst blocked = task.blocked_by.length > 0 ? task.blocked_by.join(', ') : 'None';\n\t\toutput += `${id} ${shortId} ${statusEmoji} ${statusText} ${title} ${assignedTo} ${blocked}\\n`;\n\t}\n\n\treturn output;\n}\n\n/**\n * Verbose format - detailed multi-line format per task\n */\nfunction formatTasksListVerbose(\n\ttasks: TaskType[],\n\toptions?: {\n\t\trequirementId?: string;\n\t\tprojectShortId?: string;\n\t\trequirementShortId?: string;\n\t\tapiUrl?: string;\n\t}\n): string {\n\tlet output = chalk.bold(`📋 Tasks (${tasks.length})\\n\\n`);\n\tconst divider = chalk.gray('─'.repeat(50));\n\n\tfor (let i = 0; i < tasks.length; i++) {\n\t\tconst task = tasks[i];\n\t\tconst statusEmoji = getTaskStatusEmoji(task.status);\n\n\t\t// Task header\n\t\toutput += `${statusEmoji} ${chalk.bold(task.title)}\\n`;\n\n\t\t// Short ID\n\t\toutput += `${chalk.bold('Short ID:')} TASK-${task.number}\\n`;\n\n\t\t// ID (UUID)\n\t\toutput += `${chalk.bold('ID:')} ${task.id}\\n`;\n\n\t\t// URL (if options provided)\n\t\tif (options?.apiUrl && options?.requirementId) {\n\t\t\tconst webUiUrl = getWebUiUrl(options.apiUrl);\n\t\t\toutput += `${chalk.bold('URL:')} ${webUiUrl}/requirements/overview?id=${options.requirementId}&tab=tasks\\n`;\n\t\t}\n\n\t\t// Project\n\t\toutput += `${chalk.bold('Project:')} ${options?.projectShortId || 'N/A'}\\n`;\n\n\t\t// Requirement\n\t\toutput += `${chalk.bold('Requirement:')} ${options?.requirementShortId || 'N/A'}\\n`;\n\n\t\t// Status\n\t\toutput += `${chalk.bold('Status:')} ${task.status}\\n`;\n\n\t\t// Assigned to\n\t\tif (task.assigned_to) {\n\t\t\toutput += `${chalk.bold('Assigned to:')} ${task.assigned_to}\\n`;\n\t\t} else {\n\t\t\toutput += `${chalk.bold('Assigned to:')} Unassigned\\n`;\n\t\t}\n\n\t\t// Timestamps\n\t\tif (task.created_at) {\n\t\t\toutput += `${chalk.bold('Created:')} ${new Date(task.created_at).toLocaleString()}\\n`;\n\t\t}\n\t\tif (task.updated_at) {\n\t\t\toutput += `${chalk.bold('Updated:')} ${new Date(task.updated_at).toLocaleString()}\\n`;\n\t\t}\n\t\tif (task.started_at) {\n\t\t\toutput += `${chalk.bold('Started:')} ${new Date(task.started_at).toLocaleString()}\\n`;\n\t\t}\n\t\tif (task.finished_at) {\n\t\t\toutput += `${chalk.bold('Finished:')} ${new Date(task.finished_at).toLocaleString()}\\n`;\n\t\t}\n\n\t\t// Content (with dividers)\n\t\tif (task.content) {\n\t\t\toutput += `\\n${divider}\\n`;\n\t\t\toutput += `${chalk.bold('Content:')}\\n${task.content}\\n`;\n\t\t\toutput += `${divider}\\n`;\n\t\t}\n\n\t\t// Blocked by\n\t\tif (task.blocked_by && task.blocked_by.length > 0) {\n\t\t\toutput += `\\n${chalk.bold('Blocked by:')} ${task.blocked_by.join(', ')}\\n`;\n\t\t}\n\n\t\t// Separator between tasks (except last)\n\t\tif (i < tasks.length - 1) {\n\t\t\toutput += '\\n' + chalk.gray('═'.repeat(50)) + '\\n\\n';\n\t\t}\n\t}\n\n\treturn output;\n}\n\n/**\n * JSON subset format - returns only table columns in JSON\n */\nfunction formatTasksListJsonSubset(tasks: TaskType[]): string {\n\tconst subset = tasks.map(task => ({\n\t\tid: task.id,\n\t\tnumber: task.number,\n\t\ttitle: task.title,\n\t\tstatus: task.status,\n\t\tassigned_to: task.assigned_to,\n\t\tblocked_by: task.blocked_by,\n\t}));\n\treturn JSON.stringify(subset, null, 2);\n}\n\n/**\n * XML format - structured XML output\n */\nfunction formatTasksListXml(tasks: TaskType[]): string {\n\tlet xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n\txml += '<tasks>\\n';\n\n\tfor (const task of tasks) {\n\t\txml += ' <task>\\n';\n\t\txml += ` <id>${escapeXml(task.id)}</id>\\n`;\n\t\txml += ` <number>${escapeXml(task.number)}</number>\\n`;\n\t\txml += ` <title>${escapeXml(task.title)}</title>\\n`;\n\t\tif (task.content) {\n\t\t\txml += ` <content>${escapeXml(task.content)}</content>\\n`;\n\t\t}\n\t\txml += ` <status>${escapeXml(task.status)}</status>\\n`;\n\t\tif (task.assigned_to) {\n\t\t\txml += ` <assigned_to>${escapeXml(task.assigned_to)}</assigned_to>\\n`;\n\t\t}\n\t\tif (task.created_at) {\n\t\t\txml += ` <created_at>${escapeXml(task.created_at)}</created_at>\\n`;\n\t\t}\n\t\tif (task.updated_at) {\n\t\t\txml += ` <updated_at>${escapeXml(task.updated_at)}</updated_at>\\n`;\n\t\t}\n\t\tif (task.started_at) {\n\t\t\txml += ` <started_at>${escapeXml(task.started_at)}</started_at>\\n`;\n\t\t}\n\t\tif (task.finished_at) {\n\t\t\txml += ` <finished_at>${escapeXml(task.finished_at)}</finished_at>\\n`;\n\t\t}\n\t\tif (task.blocked_by && task.blocked_by.length > 0) {\n\t\t\txml += ' <blocked_by>\\n';\n\t\t\tfor (const blocker of task.blocked_by) {\n\t\t\t\txml += ` <task>${escapeXml(blocker)}</task>\\n`;\n\t\t\t}\n\t\t\txml += ' </blocked_by>\\n';\n\t\t}\n\t\txml += ' </task>\\n';\n\t}\n\n\txml += '</tasks>';\n\treturn xml;\n}\n\n/**\n * XML subset format - returns only table columns in XML\n */\nfunction formatTasksListXmlSubset(tasks: TaskType[]): string {\n\tlet xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n\txml += '<tasks>\\n';\n\n\tfor (const task of tasks) {\n\t\txml += ' <task>\\n';\n\t\txml += ` <id>${escapeXml(task.id)}</id>\\n`;\n\t\txml += ` <number>${escapeXml(task.number)}</number>\\n`;\n\t\txml += ` <title>${escapeXml(task.title)}</title>\\n`;\n\t\txml += ` <status>${escapeXml(task.status)}</status>\\n`;\n\t\tif (task.assigned_to) {\n\t\t\txml += ` <assigned_to>${escapeXml(task.assigned_to)}</assigned_to>\\n`;\n\t\t}\n\t\tif (task.blocked_by && task.blocked_by.length > 0) {\n\t\t\txml += ' <blocked_by>\\n';\n\t\t\tfor (const blocker of task.blocked_by) {\n\t\t\t\txml += ` <task>${escapeXml(blocker)}</task>\\n`;\n\t\t\t}\n\t\t\txml += ' </blocked_by>\\n';\n\t\t}\n\t\txml += ' </task>\\n';\n\t}\n\n\txml += '</tasks>';\n\treturn xml;\n}\n\n/**\n * Markdown format - Markdown table\n */\nfunction formatTasksListMarkdown(tasks: TaskType[]): string {\n\tlet md = `# Tasks (${tasks.length})\\n\\n`;\n\tmd += '| ID | Short ID | Status | Title | Assigned To | Blocked | Updated |\\n';\n\tmd += '|----|----------|--------|-------|-------------|---------|----------|\\n';\n\n\tfor (const task of tasks) {\n\t\tconst id = task.id;\n\t\tconst shortId = `TASK-${task.number}`;\n\t\tconst status = task.status;\n\t\tconst title = task.title;\n\t\tconst assignedTo = task.assigned_to || 'Unassigned';\n\t\tconst blocked = task.blocked_by.length > 0 ? task.blocked_by.join(', ') : 'None';\n\t\tconst updated = task.updated_at ? new Date(task.updated_at).toLocaleDateString() : 'N/A';\n\n\t\tmd += `| ${id} | ${shortId} | ${status} | ${title} | ${assignedTo} | ${blocked} | ${updated} |\\n`;\n\t}\n\n\treturn md;\n}\n\n/**\n * Markdown verbose format - detailed markdown with content per task\n */\nfunction formatTasksListMarkdownVerbose(\n\ttasks: TaskType[],\n\toptions?: {\n\t\trequirementId?: string;\n\t\tprojectShortId?: string;\n\t\trequirementShortId?: string;\n\t\tapiUrl?: string;\n\t}\n): string {\n\tlet md = `# Tasks (${tasks.length})\\n\\n`;\n\n\tfor (let i = 0; i < tasks.length; i++) {\n\t\tconst task = tasks[i];\n\t\tconst statusEmoji = getTaskStatusEmoji(task.status);\n\n\t\tmd += `## ${statusEmoji} ${task.title}\\n\\n`;\n\t\tmd += `**Short ID:** TASK-${task.number}\\n\\n`;\n\t\tmd += `**ID:** ${task.id}\\n\\n`;\n\n\t\tif (options?.apiUrl && options?.requirementId) {\n\t\t\tconst webUiUrl = getWebUiUrl(options.apiUrl);\n\t\t\tmd += `**URL:** ${webUiUrl}/requirements/overview?id=${options.requirementId}&tab=tasks\\n\\n`;\n\t\t}\n\n\t\tmd += `**Project:** ${options?.projectShortId || 'N/A'}\\n\\n`;\n\t\tmd += `**Requirement:** ${options?.requirementShortId || 'N/A'}\\n\\n`;\n\t\tmd += `**Status:** ${task.status}\\n\\n`;\n\t\tmd += `**Assigned to:** ${task.assigned_to || 'Unassigned'}\\n\\n`;\n\n\t\t// Timestamps\n\t\tif (task.created_at) {\n\t\t\tmd += `**Created:** ${new Date(task.created_at).toLocaleString()}\\n\\n`;\n\t\t}\n\t\tif (task.updated_at) {\n\t\t\tmd += `**Updated:** ${new Date(task.updated_at).toLocaleString()}\\n\\n`;\n\t\t}\n\t\tif (task.started_at) {\n\t\t\tmd += `**Started:** ${new Date(task.started_at).toLocaleString()}\\n\\n`;\n\t\t}\n\t\tif (task.finished_at) {\n\t\t\tmd += `**Finished:** ${new Date(task.finished_at).toLocaleString()}\\n\\n`;\n\t\t}\n\n\t\t// Content\n\t\tif (task.content) {\n\t\t\tmd += `### Content\\n\\n${task.content}\\n\\n`;\n\t\t}\n\n\t\t// Blocked by\n\t\tif (task.blocked_by && task.blocked_by.length > 0) {\n\t\t\tmd += `**Blocked by:** ${task.blocked_by.join(', ')}\\n\\n`;\n\t\t}\n\n\t\t// Separator between tasks (except last)\n\t\tif (i < tasks.length - 1) {\n\t\t\tmd += '---\\n\\n';\n\t\t}\n\t}\n\n\treturn md;\n}\n\n/**\n * Escape XML special characters\n */\nfunction escapeXml(str: string | null | undefined): string {\n\t// Convert null/undefined to empty string to prevent crashes\n\tconst safeStr = str ?? '';\n\treturn safeStr\n\t\t.replace(/&/g, '&')\n\t\t.replace(/</g, '<')\n\t\t.replace(/>/g, '>')\n\t\t.replace(/\"/g, '"')\n\t\t.replace(/'/g, ''');\n}\n\nexport function formatTaskDetail(task: Task): string {\n\tconst statusColor = getStatusColor(task.status);\n\tconst statusIcon = getTaskStatusIcon(task.status);\n\n\tlet output = chalk.bold.cyan(`📝 Task Details\\n`);\n\toutput += chalk.gray('━'.repeat(50)) + '\\n\\n';\n\n\toutput += chalk.bold(`Title: ${task.title}\\n`);\n\toutput += `${statusIcon} Status: ${statusColor(task.status)}\\n`;\n\toutput += `🆔 ID: ${chalk.gray(formatTaskId(task))}\\n`;\n\toutput += `📎 UUID: ${chalk.gray(task.id)}\\n`;\n\toutput += `🔗 Requirement: ${chalk.gray(task.requirement_id)}\\n`;\n\n\tif (task.assigned_to) {\n\t\toutput += `👤 Assigned: ${chalk.blue(task.assigned_to)}\\n`;\n\t}\n\n\toutput += `📅 Created: ${chalk.gray(new Date(task.created_at).toLocaleDateString())}\\n`;\n\toutput += `📅 Updated: ${chalk.gray(new Date(task.updated_at).toLocaleDateString())}\\n\\n`;\n\n\toutput += chalk.bold('Content:\\n');\n\toutput += `${task.content}\\n\\n`;\n\n\treturn output;\n}\n\n/**\n * Get emoji for requirement status\n */\nexport function getRequirementStatusEmoji(status: RequirementStatus): string {\n\tswitch (status) {\n\t\tcase 'IDEA':\n\t\t\treturn '💡';\n\t\tcase 'PLANNED':\n\t\t\treturn '📝';\n\t\tcase 'IN_PROGRESS':\n\t\t\treturn '🚧';\n\t\tcase 'REVIEW':\n\t\t\treturn '👀';\n\t\tcase 'COMPLETED':\n\t\t\treturn '✅';\n\t\tcase 'CANCELLED':\n\t\t\treturn '❌';\n\t\tdefault:\n\t\t\treturn '❓';\n\t}\n}\n\n/**\n * Format requirement output with consistent field order and dividers\n * Field order: Short ID, ID (UUID), URL, Project, Branch, Status, Assigned to, Created at, Updated at, Description, Content, Tasks\n * Includes dividers before/after content and after tasks count\n */\nexport function formatRequirementOutput(\n\trequirement: RequirementDetail,\n\toptions?: {\n\t\tshowContent?: boolean;\n\t\tshowTasks?: boolean;\n\t\tshowTaskList?: boolean;\n\t\tshowDescription?: boolean;\n\t\tshowUpdated?: boolean;\n\t\tsuccessMessage?: string;\n\t\tapiUrl?: string;\n\t\tprojectShortId?: string;\n\t}\n): string {\n\tconst statusEmoji = getRequirementStatusEmoji(requirement.status);\n\tconst divider = chalk.gray('─'.repeat(50));\n\n\tlet message = '';\n\n\t// Success message header (if provided)\n\tif (options?.successMessage) {\n\t\tmessage += chalk.green(`✅ ${options.successMessage}\\n\\n`);\n\t}\n\n\t// Requirement name with status emoji\n\tmessage += `${statusEmoji} ${chalk.bold(requirement.name)}\\n\\n`;\n\n\t// Short ID\n\tmessage += `${chalk.bold('Short ID:')} ${requirement.short_id || 'N/A'}\\n`;\n\n\t// ID (UUID)\n\tmessage += `${chalk.bold('ID:')} ${requirement.id}\\n`;\n\n\t// URL\n\tif (options?.apiUrl) {\n\t\tconst webUiUrl = getWebUiUrl(options.apiUrl);\n\t\tmessage += `${chalk.bold('URL:')} ${webUiUrl}/requirements/overview?id=${requirement.id}\\n`;\n\t}\n\n\t// Project\n\tmessage += `${chalk.bold('Project:')} ${options?.projectShortId || 'N/A'}\\n`;\n\n\t// Branch\n\tif (requirement.branch) {\n\t\tmessage += `${chalk.bold('Branch:')} ${requirement.branch}\\n`;\n\t}\n\n\t// Status\n\tmessage += `${chalk.bold('Status:')} ${requirement.status}\\n`;\n\n\t// Assigned to (always show)\n\tif (requirement.assignee) {\n\t\tconst assigneeName =\n\t\t\trequirement.assignee.first_name || requirement.assignee.last_name\n\t\t\t\t? `${requirement.assignee.first_name || ''} ${requirement.assignee.last_name || ''}`.trim()\n\t\t\t\t: requirement.assignee.email;\n\t\tmessage += `${chalk.bold('Assigned to:')} ${assigneeName} (${requirement.assignee.email})\\n`;\n\t} else {\n\t\tmessage += `${chalk.bold('Assigned to:')} Unassigned\\n`;\n\t}\n\n\t// Created timestamp\n\tmessage += `${chalk.bold('Created:')} ${new Date(requirement.created_at).toLocaleString()}\\n`;\n\n\t// Updated timestamp (optional)\n\tif (options?.showUpdated) {\n\t\tmessage += `${chalk.bold('Updated:')} ${new Date(requirement.updated_at).toLocaleString()}\\n`;\n\t}\n\n\t// Description section (with dividers)\n\tif (options?.showDescription && requirement.description) {\n\t\tmessage += `\\n${divider}\\n`;\n\t\tmessage += `${chalk.bold('Description:')}\\n${requirement.description}\\n`;\n\t\tmessage += `${divider}\\n`;\n\t}\n\n\t// Content section (with dividers)\n\tif (options?.showContent && requirement.content) {\n\t\tmessage += `\\n${divider}\\n`;\n\t\tmessage += `${chalk.bold('Content:')}\\n${requirement.content}\\n`;\n\t\tmessage += `${divider}\\n`;\n\t}\n\n\t// Tasks section (with divider after count or list)\n\tif (options?.showTaskList) {\n\t\t// Show detailed task list\n\t\tmessage += `\\n${chalk.bold('Tasks:')}\\n`;\n\t\tif (requirement.tasks && requirement.tasks.length > 0) {\n\t\t\tfor (const task of requirement.tasks) {\n\t\t\t\tconst taskEmoji = getRequirementStatusEmoji(task.status);\n\t\t\t\tmessage += ` ${taskEmoji} ${task.number}. ${task.title} (${task.status})\\n`;\n\t\t\t}\n\t\t}\n\t\tmessage += `${divider}\\n`;\n\t} else if (options?.showTasks) {\n\t\t// Show task count only (always show, even if 0/0)\n\t\tconst tasks = requirement.tasks || [];\n\t\tconst completedTasks = tasks.filter(task => task.status === 'COMPLETED').length;\n\t\tconst totalTasks = tasks.length;\n\t\tmessage += `\\n${chalk.bold('Tasks:')} ${completedTasks}/${totalTasks} completed\\n`;\n\t\tmessage += `${divider}\\n`;\n\t}\n\n\treturn message;\n}\n\n/**\n * Get emoji for task status (internal use only)\n */\nfunction getTaskStatusEmoji(status: string): string {\n\tswitch (status) {\n\t\tcase 'PLANNED':\n\t\t\treturn '📝';\n\t\tcase 'IN_PROGRESS':\n\t\t\treturn '🚧';\n\t\tcase 'COMPLETED':\n\t\t\treturn '✅';\n\t\tcase 'CANCELLED':\n\t\t\treturn '❌';\n\t\tdefault:\n\t\t\treturn '❓';\n\t}\n}\n\n/**\n * Format task output with consistent field order and dividers\n * Field order: Short ID, ID (UUID), URL, Project, Requirement, Status, Assigned to, Created, Updated, Started, Finished, Content, Blocked by\n * Includes dividers before/after content\n */\nexport function formatTaskOutput(\n\ttask: TaskType,\n\toptions?: {\n\t\tshowContent?: boolean;\n\t\tsuccessMessage?: string;\n\t\tapiUrl?: string;\n\t\tprojectShortId?: string;\n\t\trequirementShortId?: string;\n\t\trequirementId?: string;\n\t}\n): string {\n\tconst statusEmoji = getTaskStatusEmoji(task.status);\n\tconst divider = chalk.gray('─'.repeat(50));\n\n\tlet message = '';\n\n\t// Success message header (if provided)\n\tif (options?.successMessage) {\n\t\tmessage += chalk.green(`✅ ${options.successMessage}\\n\\n`);\n\t}\n\n\t// Task title with status emoji\n\tmessage += `${statusEmoji} ${chalk.bold(task.title)}\\n\\n`;\n\n\t// Short ID (TASK-{number})\n\tmessage += `${chalk.bold('Short ID:')} TASK-${task.number}\\n`;\n\n\t// ID (UUID)\n\tmessage += `${chalk.bold('ID:')} ${task.id}\\n`;\n\n\t// URL - use requirement UUID with tab=tasks\n\tif (options?.apiUrl && options?.requirementId) {\n\t\tconst webUiUrl = getWebUiUrl(options.apiUrl);\n\t\tmessage += `${chalk.bold('URL:')} ${webUiUrl}/requirements/overview?id=${options.requirementId}&tab=tasks\\n`;\n\t}\n\n\t// Project\n\tmessage += `${chalk.bold('Project:')} ${options?.projectShortId || 'N/A'}\\n`;\n\n\t// Requirement\n\tmessage += `${chalk.bold('Requirement:')} ${options?.requirementShortId || 'N/A'}\\n`;\n\n\t// Status\n\tmessage += `${chalk.bold('Status:')} ${task.status}\\n`;\n\n\t// Assigned to (always show)\n\tif (task.assigned_to) {\n\t\t// TODO: Fetch assignee details from API when available\n\t\tmessage += `${chalk.bold('Assigned to:')} ${task.assigned_to}\\n`;\n\t} else {\n\t\tmessage += `${chalk.bold('Assigned to:')} Unassigned\\n`;\n\t}\n\n\t// Created timestamp (if available)\n\tif (task.created_at) {\n\t\tmessage += `${chalk.bold('Created:')} ${new Date(task.created_at).toLocaleString()}\\n`;\n\t}\n\n\t// Updated timestamp (if available)\n\tif (task.updated_at) {\n\t\tmessage += `${chalk.bold('Updated:')} ${new Date(task.updated_at).toLocaleString()}\\n`;\n\t}\n\n\t// Started timestamp (if available)\n\tif (task.started_at) {\n\t\tmessage += `${chalk.bold('Started:')} ${new Date(task.started_at).toLocaleString()}\\n`;\n\t}\n\n\t// Finished timestamp (if available)\n\tif (task.finished_at) {\n\t\tmessage += `${chalk.bold('Finished:')} ${new Date(task.finished_at).toLocaleString()}\\n`;\n\t}\n\n\t// Content section (with dividers)\n\tif (options?.showContent && task.content) {\n\t\tmessage += `\\n${divider}\\n`;\n\t\tmessage += `${chalk.bold('Content:')}\\n${task.content}\\n`;\n\t\tmessage += `${divider}\\n`;\n\t}\n\n\t// Blocked by section\n\tif (task.blocked_by && task.blocked_by.length > 0) {\n\t\tmessage += `\\n${chalk.bold('Blocked by:')} ${task.blocked_by.join(', ')}\\n`;\n\t}\n\n\treturn message;\n}\n\nexport function formatErrorMessage(message: string): string {\n\treturn chalk.red(`❌ ${message}`);\n}\n\nexport function formatSuccessMessage(message: string): string {\n\treturn chalk.green(`✅ ${message}`);\n}\n\nexport function formatInfoMessage(message: string): string {\n\treturn chalk.blue(`ℹ️ ${message}`);\n}\n\nexport function formatWarningMessage(message: string): string {\n\treturn chalk.yellow(`⚠️ ${message}`);\n}\n\nfunction getStatusColor(status: string) {\n\tswitch (status) {\n\t\tcase 'PLANNED':\n\t\t\treturn chalk.blue;\n\t\tcase 'IN_PROGRESS':\n\t\t\treturn chalk.yellow;\n\t\tcase 'COMPLETED':\n\t\t\treturn chalk.green;\n\t\tcase 'CANCELLED':\n\t\t\treturn chalk.red;\n\t\tdefault:\n\t\t\treturn chalk.gray;\n\t}\n}\n\nfunction getStatusIcon(status: string): string {\n\tswitch (status) {\n\t\tcase 'PLANNED':\n\t\t\treturn '📋';\n\t\tcase 'IN_PROGRESS':\n\t\t\treturn '🔄';\n\t\tcase 'COMPLETED':\n\t\t\treturn '✅';\n\t\tcase 'CANCELLED':\n\t\t\treturn '❌';\n\t\tdefault:\n\t\t\treturn '❓';\n\t}\n}\n\n/**\n * Format requirement list output in Markdown format\n */\nexport function formatRequirementListMarkdown(\n\trequirements: Requirement[],\n\tpagination?: { page: number; limit: number; total: number }\n): string {\n\tlet md = '# Requirements\\n\\n';\n\n\tif (requirements.length === 0) {\n\t\tmd += '_No requirements found._\\n';\n\t\treturn md;\n\t}\n\n\tmd += '| Short ID | Status | Name | Branch | Progress |\\n';\n\tmd += '|----------|--------|------|--------|----------|\\n';\n\n\tfor (const req of requirements) {\n\t\tconst shortId = req.short_id || req.id.slice(0, 11);\n\t\tconst status = req.status;\n\t\tconst name = req.name;\n\t\tconst branch = req.branch || 'N/A';\n\t\tconst progress = req.task_progress ? `${req.task_progress.progress_percentage}%` : 'N/A';\n\n\t\tmd += `| ${shortId} | ${status} | ${name} | ${branch} | ${progress} |\\n`;\n\t}\n\n\tif (pagination) {\n\t\tmd += '\\n';\n\t\tconst totalPages = Math.ceil(pagination.total / pagination.limit);\n\t\tmd += `_Page ${pagination.page} of ${totalPages} (${pagination.total} total)_\\n`;\n\t}\n\n\treturn md;\n}\n\n/**\n * Format requirement list output in XML format\n */\nexport function formatRequirementListXml(\n\trequirements: Requirement[],\n\tpagination?: { page: number; limit: number; total: number }\n): string {\n\tlet xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n\txml += '<requirements>\\n';\n\n\tif (pagination) {\n\t\txml += ' <pagination>\\n';\n\t\txml += ` <page>${pagination.page}</page>\\n`;\n\t\txml += ` <limit>${pagination.limit}</limit>\\n`;\n\t\txml += ` <total>${pagination.total}</total>\\n`;\n\t\txml += ` <total_pages>${Math.ceil(pagination.total / pagination.limit)}</total_pages>\\n`;\n\t\txml += ' </pagination>\\n';\n\t}\n\n\txml += ' <items>\\n';\n\tfor (const req of requirements) {\n\t\txml += ' <requirement>\\n';\n\t\txml += ` <id>${escapeXml(req.id)}</id>\\n`;\n\t\tif (req.short_id) {\n\t\t\txml += ` <short_id>${escapeXml(req.short_id)}</short_id>\\n`;\n\t\t}\n\t\txml += ` <name>${escapeXml(req.name)}</name>\\n`;\n\t\tif (req.description) {\n\t\t\txml += ` <description>${escapeXml(req.description)}</description>\\n`;\n\t\t}\n\t\txml += ` <status>${escapeXml(req.status)}</status>\\n`;\n\t\tif (req.branch) {\n\t\t\txml += ` <branch>${escapeXml(req.branch)}</branch>\\n`;\n\t\t}\n\t\tif (req.task_progress) {\n\t\t\txml += ' <task_progress>\\n';\n\t\t\txml += ` <total>${req.task_progress.total}</total>\\n`;\n\t\t\txml += ` <completed>${req.task_progress.completed}</completed>\\n`;\n\t\t\txml += ` <progress_percentage>${req.task_progress.progress_percentage}</progress_percentage>\\n`;\n\t\t\txml += ' </task_progress>\\n';\n\t\t}\n\t\tif (req.assigned_to) {\n\t\t\txml += ` <assigned_to>${escapeXml(req.assigned_to)}</assigned_to>\\n`;\n\t\t}\n\t\tif (req.assignee) {\n\t\t\txml += ' <assignee>\\n';\n\t\t\txml += ` <id>${escapeXml(req.assignee.id)}</id>\\n`;\n\t\t\txml += ` <first_name>${escapeXml(req.assignee.first_name)}</first_name>\\n`;\n\t\t\txml += ` <last_name>${escapeXml(req.assignee.last_name)}</last_name>\\n`;\n\t\t\txml += ` <email>${escapeXml(req.assignee.email)}</email>\\n`;\n\t\t\txml += ' </assignee>\\n';\n\t\t}\n\t\txml += ` <created_at>${escapeXml(req.created_at)}</created_at>\\n`;\n\t\txml += ` <updated_at>${escapeXml(req.updated_at)}</updated_at>\\n`;\n\t\txml += ' </requirement>\\n';\n\t}\n\txml += ' </items>\\n';\n\txml += '</requirements>\\n';\n\n\treturn xml;\n}\n\n/**\n * Format requirement breakdown output in Markdown format\n */\nexport function formatRequirementBreakdownMarkdown(\n\trequirementShortId: string,\n\ttasks: Array<{\n\t\tnumber: string;\n\t\ttitle: string;\n\t\tstatus: string;\n\t\tcontent?: string;\n\t\tblocked_by: string[];\n\t\tid: string;\n\t}>\n): string {\n\tlet md = `# Breakdown: ${requirementShortId}\\n\\n`;\n\tmd += `Generated ${tasks.length} task${tasks.length !== 1 ? 's' : ''}\\n\\n`;\n\n\tif (tasks.length === 0) {\n\t\tmd += '_No tasks generated._\\n';\n\t\treturn md;\n\t}\n\n\tfor (const task of tasks) {\n\t\tmd += `## Task ${task.number}: ${task.title}\\n\\n`;\n\t\tmd += `- **Status:** ${task.status}\\n`;\n\t\tmd += `- **ID:** ${task.id}\\n`;\n\t\tif (task.blocked_by.length > 0) {\n\t\t\tmd += `- **Blocked by:** ${task.blocked_by.join(', ')}\\n`;\n\t\t}\n\t\tif (task.content) {\n\t\t\tmd += `\\n### Content\\n\\n${task.content}\\n`;\n\t\t}\n\t\tmd += '\\n';\n\t}\n\n\treturn md;\n}\n\n/**\n * Format requirement breakdown output in XML format\n */\nexport function formatRequirementBreakdownXml(\n\trequirementShortId: string,\n\ttasks: Array<{\n\t\tnumber: string;\n\t\ttitle: string;\n\t\tstatus: string;\n\t\tcontent?: string;\n\t\tblocked_by: string[];\n\t\tid: string;\n\t\tcreated_at: string;\n\t\tupdated_at: string;\n\t\tassigned_to: string | null;\n\t}>\n): string {\n\tlet xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n\txml += '<breakdown>\\n';\n\txml += ` <requirement_short_id>${escapeXml(requirementShortId)}</requirement_short_id>\\n`;\n\txml += ` <task_count>${tasks.length}</task_count>\\n`;\n\txml += ' <tasks>\\n';\n\n\tfor (const task of tasks) {\n\t\txml += ' <task>\\n';\n\t\txml += ` <number>${escapeXml(task.number)}</number>\\n`;\n\t\txml += ` <title>${escapeXml(task.title)}</title>\\n`;\n\t\txml += ` <status>${escapeXml(task.status)}</status>\\n`;\n\t\txml += ` <id>${escapeXml(task.id)}</id>\\n`;\n\t\tif (task.content) {\n\t\t\txml += ` <content>${escapeXml(task.content)}</content>\\n`;\n\t\t}\n\t\tif (task.blocked_by.length > 0) {\n\t\t\txml += ' <blocked_by>\\n';\n\t\t\tfor (const blocker of task.blocked_by) {\n\t\t\t\txml += ` <task>${escapeXml(blocker)}</task>\\n`;\n\t\t\t}\n\t\t\txml += ' </blocked_by>\\n';\n\t\t}\n\t\tif (task.assigned_to) {\n\t\t\txml += ` <assigned_to>${escapeXml(task.assigned_to)}</assigned_to>\\n`;\n\t\t}\n\t\txml += ` <created_at>${escapeXml(task.created_at)}</created_at>\\n`;\n\t\txml += ` <updated_at>${escapeXml(task.updated_at)}</updated_at>\\n`;\n\t\txml += ' </task>\\n';\n\t}\n\n\txml += ' </tasks>\\n';\n\txml += '</breakdown>\\n';\n\n\treturn xml;\n}\n\n/**\n * Format requirement build output in Markdown format\n * Includes full requirement details and all tasks with content\n */\nexport function formatRequirementBuildMarkdown(\n\trequirement: RequirementDetail,\n\toptions?: {\n\t\tapiUrl?: string;\n\t\tprojectShortId?: string;\n\t}\n): string {\n\tconst statusEmoji = getRequirementStatusEmoji(requirement.status);\n\n\tlet md = `# ${statusEmoji} ${requirement.name}\\n\\n`;\n\n\t// Requirement metadata\n\tmd += `**Short ID:** ${requirement.short_id || 'N/A'}\\n\\n`;\n\tmd += `**ID:** ${requirement.id}\\n\\n`;\n\n\tif (options?.apiUrl) {\n\t\tconst webUiUrl = getWebUiUrl(options.apiUrl);\n\t\tmd += `**URL:** ${webUiUrl}/requirements/overview?id=${requirement.id}\\n\\n`;\n\t}\n\n\tmd += `**Project:** ${options?.projectShortId || 'N/A'}\\n\\n`;\n\tif (requirement.branch) {\n\t\tmd += `**Branch:** ${requirement.branch}\\n\\n`;\n\t}\n\tmd += `**Status:** ${requirement.status}\\n\\n`;\n\n\t// Assigned to\n\tif (requirement.assignee) {\n\t\tconst assigneeName =\n\t\t\trequirement.assignee.first_name || requirement.assignee.last_name\n\t\t\t\t? `${requirement.assignee.first_name || ''} ${requirement.assignee.last_name || ''}`.trim()\n\t\t\t\t: requirement.assignee.email;\n\t\tmd += `**Assigned to:** ${assigneeName} (${requirement.assignee.email})\\n\\n`;\n\t} else {\n\t\tmd += `**Assigned to:** Unassigned\\n\\n`;\n\t}\n\n\tmd += `**Created:** ${new Date(requirement.created_at).toLocaleString()}\\n\\n`;\n\tmd += `**Updated:** ${new Date(requirement.updated_at).toLocaleString()}\\n\\n`;\n\n\t// Description\n\tif (requirement.description) {\n\t\tmd += `## Description\\n\\n${requirement.description}\\n\\n`;\n\t}\n\n\t// Content\n\tif (requirement.content) {\n\t\tmd += `## Content\\n\\n${requirement.content}\\n\\n`;\n\t}\n\n\t// Tasks\n\tconst tasks = requirement.tasks || [];\n\tmd += `## Tasks (${tasks.length})\\n\\n`;\n\n\tif (tasks.length === 0) {\n\t\tmd += '_No tasks available_\\n\\n';\n\t\tmd += '💡 _Run `braingrid requirement breakdown [id]` to generate tasks using AI_\\n';\n\t} else {\n\t\tfor (let i = 0; i < tasks.length; i++) {\n\t\t\tconst task = tasks[i];\n\t\t\tconst taskEmoji = getRequirementStatusEmoji(task.status);\n\n\t\t\tmd += `### ${taskEmoji} Task ${task.number}: ${task.title}\\n\\n`;\n\t\t\tmd += `**Short ID:** TASK-${task.number}\\n\\n`;\n\t\t\tmd += `**ID:** ${task.id}\\n\\n`;\n\n\t\t\tif (options?.apiUrl) {\n\t\t\t\tconst webUiUrl = getWebUiUrl(options.apiUrl);\n\t\t\t\tmd += `**URL:** ${webUiUrl}/requirements/overview?id=${requirement.id}&tab=tasks\\n\\n`;\n\t\t\t}\n\n\t\t\tmd += `**Status:** ${task.status}\\n\\n`;\n\n\t\t\tif (task.assigned_to) {\n\t\t\t\tmd += `**Assigned to:** ${task.assigned_to}\\n\\n`;\n\t\t\t} else {\n\t\t\t\tmd += `**Assigned to:** Unassigned\\n\\n`;\n\t\t\t}\n\n\t\t\tif (task.created_at) {\n\t\t\t\tmd += `**Created:** ${new Date(task.created_at).toLocaleString()}\\n\\n`;\n\t\t\t}\n\t\t\tif (task.updated_at) {\n\t\t\t\tmd += `**Updated:** ${new Date(task.updated_at).toLocaleString()}\\n\\n`;\n\t\t\t}\n\t\t\tif (task.started_at) {\n\t\t\t\tmd += `**Started:** ${new Date(task.started_at).toLocaleString()}\\n\\n`;\n\t\t\t}\n\t\t\tif (task.finished_at) {\n\t\t\t\tmd += `**Finished:** ${new Date(task.finished_at).toLocaleString()}\\n\\n`;\n\t\t\t}\n\n\t\t\t// Task content\n\t\t\tif (task.content) {\n\t\t\t\tmd += `#### Content\\n\\n${task.content}\\n\\n`;\n\t\t\t}\n\n\t\t\t// Blocked by\n\t\t\tif (task.blocked_by && task.blocked_by.length > 0) {\n\t\t\t\tmd += `**Blocked by:** ${task.blocked_by.join(', ')}\\n\\n`;\n\t\t\t}\n\n\t\t\t// Separator between tasks (except last)\n\t\t\tif (i < tasks.length - 1) {\n\t\t\t\tmd += '---\\n\\n';\n\t\t\t}\n\t\t}\n\t}\n\n\treturn md;\n}\n\n/**\n * Format requirement build output in JSON format\n * Includes full requirement details and all tasks with content\n */\nexport function formatRequirementBuildJson(requirement: RequirementDetail): string {\n\t// Add hint if no tasks are available\n\tconst tasks = requirement.tasks || [];\n\tif (tasks.length === 0) {\n\t\treturn JSON.stringify(\n\t\t\t{\n\t\t\t\t...requirement,\n\t\t\t\t_hint: \"Run 'braingrid requirement breakdown [id]' to generate tasks using AI\",\n\t\t\t},\n\t\t\tnull,\n\t\t\t2\n\t\t);\n\t}\n\treturn JSON.stringify(requirement, null, 2);\n}\n\n/**\n * Format requirement build output in XML format\n * Includes full requirement details and all tasks with content\n */\nexport function formatRequirementBuildXml(requirement: RequirementDetail): string {\n\tlet xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n\txml += '<requirement>\\n';\n\n\t// Requirement metadata\n\txml += ` <id>${escapeXml(requirement.id)}</id>\\n`;\n\txml += ` <short_id>${escapeXml(requirement.short_id || '')}</short_id>\\n`;\n\txml += ` <name>${escapeXml(requirement.name)}</name>\\n`;\n\txml += ` <status>${escapeXml(requirement.status)}</status>\\n`;\n\tif (requirement.branch) {\n\t\txml += ` <branch>${escapeXml(requirement.branch)}</branch>\\n`;\n\t}\n\n\t// Assigned to\n\tif (requirement.assignee) {\n\t\txml += ' <assignee>\\n';\n\t\txml += ` <email>${escapeXml(requirement.assignee.email)}</email>\\n`;\n\t\tif (requirement.assignee.first_name) {\n\t\t\txml += ` <first_name>${escapeXml(requirement.assignee.first_name)}</first_name>\\n`;\n\t\t}\n\t\tif (requirement.assignee.last_name) {\n\t\t\txml += ` <last_name>${escapeXml(requirement.assignee.last_name)}</last_name>\\n`;\n\t\t}\n\t\txml += ' </assignee>\\n';\n\t}\n\n\t// Timestamps\n\txml += ` <created_at>${escapeXml(requirement.created_at)}</created_at>\\n`;\n\txml += ` <updated_at>${escapeXml(requirement.updated_at)}</updated_at>\\n`;\n\n\t// Description\n\tif (requirement.description) {\n\t\txml += ` <description>${escapeXml(requirement.description)}</description>\\n`;\n\t}\n\n\t// Content\n\tif (requirement.content) {\n\t\txml += ` <content>${escapeXml(requirement.content)}</content>\\n`;\n\t}\n\n\t// Tasks\n\tconst tasks = requirement.tasks || [];\n\txml += ` <tasks count=\"${tasks.length}\">\\n`;\n\n\tif (tasks.length === 0) {\n\t\txml += ` <hint>Run 'braingrid requirement breakdown [id]' to generate tasks using AI</hint>\\n`;\n\t} else {\n\t\tfor (const task of tasks) {\n\t\t\txml += ' <task>\\n';\n\t\t\txml += ` <id>${escapeXml(task.id)}</id>\\n`;\n\t\t\txml += ` <number>${escapeXml(String(task.number))}</number>\\n`;\n\t\t\txml += ` <title>${escapeXml(task.title)}</title>\\n`;\n\t\t\txml += ` <status>${escapeXml(task.status)}</status>\\n`;\n\n\t\t\tif (task.content) {\n\t\t\t\txml += ` <content>${escapeXml(task.content)}</content>\\n`;\n\t\t\t}\n\n\t\t\tif (task.assigned_to) {\n\t\t\t\txml += ` <assigned_to>${escapeXml(task.assigned_to)}</assigned_to>\\n`;\n\t\t\t}\n\n\t\t\tif (task.created_at) {\n\t\t\t\txml += ` <created_at>${escapeXml(task.created_at)}</created_at>\\n`;\n\t\t\t}\n\t\t\tif (task.updated_at) {\n\t\t\t\txml += ` <updated_at>${escapeXml(task.updated_at)}</updated_at>\\n`;\n\t\t\t}\n\t\t\tif (task.started_at) {\n\t\t\t\txml += ` <started_at>${escapeXml(task.started_at)}</started_at>\\n`;\n\t\t\t}\n\t\t\tif (task.finished_at) {\n\t\t\t\txml += ` <finished_at>${escapeXml(task.finished_at)}</finished_at>\\n`;\n\t\t\t}\n\n\t\t\tif (task.blocked_by && task.blocked_by.length > 0) {\n\t\t\t\txml += ' <blocked_by>\\n';\n\t\t\t\tfor (const blocker of task.blocked_by) {\n\t\t\t\t\txml += ` <task>${escapeXml(blocker)}</task>\\n`;\n\t\t\t\t}\n\t\t\t\txml += ' </blocked_by>\\n';\n\t\t\t}\n\n\t\t\txml += ' </task>\\n';\n\t\t}\n\t}\n\n\txml += ' </tasks>\\n';\n\txml += '</requirement>';\n\n\treturn xml;\n}\n\n/**\n * Format project list output in Markdown format\n * Includes table with pagination metadata\n */\nexport function formatProjectListMarkdown(\n\tprojects: Project[],\n\tpagination?: { page: number; limit: number; total: number; has_more?: boolean }\n): string {\n\tif (projects.length === 0) {\n\t\treturn '# Projects\\n\\n_No projects found._\\n';\n\t}\n\n\tlet md = pagination\n\t\t? `# Projects (${projects.length} of ${pagination.total})\\n\\n`\n\t\t: `# Projects (${projects.length})\\n\\n`;\n\tmd += '| Short ID | Name | Repository | Created | Updated |\\n';\n\tmd += '|----------|------|------------|---------|----------|\\n';\n\n\tfor (const project of projects) {\n\t\tconst shortId = project.short_id || 'N/A';\n\t\tconst name = project.name;\n\t\tconst repo = project.repository?.full_name || 'N/A';\n\t\tconst created = new Date(project.created_at).toLocaleDateString();\n\t\tconst updated = new Date(project.updated_at).toLocaleDateString();\n\n\t\tmd += `| ${shortId} | ${name} | ${repo} | ${created} | ${updated} |\\n`;\n\t}\n\n\tif (pagination) {\n\t\tmd += `\\n**Page ${pagination.page} of ${Math.ceil(pagination.total / pagination.limit)}** (${pagination.total} total)\\n`;\n\t}\n\n\treturn md;\n}\n\n/**\n * Format project list output in XML format\n * Includes pagination metadata\n */\nexport function formatProjectListXml(\n\tprojects: Project[],\n\tpagination?: { page: number; limit: number; total: number; has_more?: boolean }\n): string {\n\tlet xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n\txml += '<projects>\\n';\n\tif (pagination) {\n\t\txml += ' <pagination>\\n';\n\t\txml += ` <page>${pagination.page}</page>\\n`;\n\t\txml += ` <limit>${pagination.limit}</limit>\\n`;\n\t\txml += ` <total>${pagination.total}</total>\\n`;\n\t\txml += ' </pagination>\\n';\n\t}\n\txml += ' <items>\\n';\n\n\tfor (const project of projects) {\n\t\txml += ' <project>\\n';\n\t\txml += ` <id>${escapeXml(project.id)}</id>\\n`;\n\t\txml += ` <short_id>${escapeXml(project.short_id || '')}</short_id>\\n`;\n\t\txml += ` <name>${escapeXml(project.name)}</name>\\n`;\n\n\t\tif (project.description) {\n\t\t\txml += ` <description>${escapeXml(project.description)}</description>\\n`;\n\t\t}\n\n\t\tif (project.repository) {\n\t\t\txml += ' <repository>\\n';\n\t\t\txml += ` <id>${escapeXml(project.repository.id)}</id>\\n`;\n\t\t\txml += ` <full_name>${escapeXml(project.repository.full_name)}</full_name>\\n`;\n\t\t\txml += ` <name>${escapeXml(project.repository.name)}</name>\\n`;\n\t\t\txml += ' </repository>\\n';\n\t\t}\n\n\t\txml += ` <created_at>${escapeXml(project.created_at)}</created_at>\\n`;\n\t\txml += ` <updated_at>${escapeXml(project.updated_at)}</updated_at>\\n`;\n\t\txml += ' </project>\\n';\n\t}\n\n\txml += ' </items>\\n';\n\txml += '</projects>';\n\n\treturn xml;\n}\n\n/**\n * Format single project output in Markdown format\n */\nexport function formatProjectShowMarkdown(project: Project): string {\n\tlet md = `# ${project.name}\\n\\n`;\n\n\tmd += `**Short ID:** ${project.short_id || 'N/A'}\\n\\n`;\n\tmd += `**ID:** ${project.id}\\n\\n`;\n\n\tif (project.description) {\n\t\tmd += `**Description:** ${project.description}\\n\\n`;\n\t}\n\n\tif (project.repository) {\n\t\tmd += `**Repository:** ${project.repository.full_name}\\n\\n`;\n\t}\n\n\tmd += `**Created:** ${new Date(project.created_at).toLocaleString()}\\n\\n`;\n\tmd += `**Updated:** ${new Date(project.updated_at).toLocaleString()}\\n`;\n\n\treturn md;\n}\n\n/**\n * Format single project output in XML format\n */\nexport function formatProjectShowXml(project: Project): string {\n\tlet xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n\txml += '<project>\\n';\n\txml += ` <id>${escapeXml(project.id)}</id>\\n`;\n\txml += ` <short_id>${escapeXml(project.short_id || '')}</short_id>\\n`;\n\txml += ` <name>${escapeXml(project.name)}</name>\\n`;\n\n\tif (project.description) {\n\t\txml += ` <description>${escapeXml(project.description)}</description>\\n`;\n\t}\n\n\tif (project.repository) {\n\t\txml += ' <repository>\\n';\n\t\txml += ` <id>${escapeXml(project.repository.id)}</id>\\n`;\n\t\txml += ` <full_name>${escapeXml(project.repository.full_name)}</full_name>\\n`;\n\t\txml += ` <name>${escapeXml(project.repository.name)}</name>\\n`;\n\t\txml += ' </repository>\\n';\n\t}\n\n\txml += ` <created_at>${escapeXml(project.created_at)}</created_at>\\n`;\n\txml += ` <updated_at>${escapeXml(project.updated_at)}</updated_at>\\n`;\n\txml += '</project>';\n\n\treturn xml;\n}\n","import { RequirementTask as Task } from '../types/requirement.js';\nimport { normalizeId } from './id-normalization.js';\n\nexport function formatTaskId(task: Task): string {\n\treturn `TASK-${task.number}`;\n}\n\n/**\n * Normalize task ID from various formats to API-compatible format:\n * - \"TASK-123\" -> \"TASK-123\" (already normalized)\n * - \"task-123\" -> \"TASK-123\" (uppercase)\n * - \"TASK 123\" -> \"TASK-123\" (add dash, uppercase)\n * - \"task 123\" -> \"TASK-123\" (add dash, uppercase)\n * - \"123\" -> \"TASK-123\" (add prefix)\n * - \"uuid-string\" -> \"uuid-string\" (UUID, return as-is)\n *\n * This function takes user input and returns the ID that should be used in API calls\n */\nexport function normalizeTaskId(input: string): string {\n\treturn normalizeId('TASK', input);\n}\n\nexport function parseTaskId(input: string): { type: 'number' | 'uuid'; value: string | number } {\n\t// Trim whitespace\n\tconst trimmed = input.trim();\n\n\t// Handle \"TASK-123\" or \"task-123\" format (with dash)\n\tconst taskDashMatch = trimmed.match(/^TASK-(\\d+)$/i);\n\tif (taskDashMatch) {\n\t\treturn { type: 'number', value: parseInt(taskDashMatch[1], 10) };\n\t}\n\n\t// Handle \"TASK 123\" or \"task 123\" format (with space)\n\tconst taskSpaceMatch = trimmed.match(/^TASK\\s+(\\d+)$/i);\n\tif (taskSpaceMatch) {\n\t\treturn { type: 'number', value: parseInt(taskSpaceMatch[1], 10) };\n\t}\n\n\t// Handle plain number format\n\tconst numberMatch = trimmed.match(/^\\d+$/);\n\tif (numberMatch) {\n\t\treturn { type: 'number', value: parseInt(trimmed, 10) };\n\t}\n\n\t// Assume it's a UUID\n\treturn { type: 'uuid', value: trimmed };\n}\n\nexport function findTaskById(tasks: Task[], identifier: string): Task | null {\n\tconst parsed = parseTaskId(identifier);\n\n\tif (parsed.type === 'number') {\n\t\treturn tasks.find(task => task.number === parsed.value) || null;\n\t} else {\n\t\treturn tasks.find(task => task.id === parsed.value) || null;\n\t}\n}\n\nexport function getTaskStatusIcon(status: string): string {\n\tswitch (status) {\n\t\tcase 'PLANNED':\n\t\t\treturn '📋';\n\t\tcase 'IN_PROGRESS':\n\t\t\treturn '🔄';\n\t\tcase 'COMPLETED':\n\t\t\treturn '✅';\n\t\tcase 'CANCELLED':\n\t\t\treturn '❌';\n\t\tdefault:\n\t\t\treturn '📋';\n\t}\n}\n","/**\n * Requirement Resource Handlers\n *\n * Handles all requirement-related commands:\n * - list: List all requirements\n * - show: Show requirement details\n * - create: Create a new requirement\n * - update: Update requirement information\n * - delete: Delete a requirement\n */\n\nimport chalk from 'chalk';\nimport { RequirementService } from '../services/requirement-service.js';\nimport { BraingridAuth } from '../services/auth.js';\nimport { getConfig } from '../utils/config.js';\nimport { formatError, getResourceContext } from '../utils/error-formatter.js';\nimport { handleError } from '../utils/error-handler.js';\nimport { workspaceManager } from '../utils/workspace-manager.js';\nimport { normalizeRequirementId } from '../utils/requirements.js';\nimport { showSpinner } from '../utils/spinner.js';\nimport {\n\tformatRequirementOutput,\n\tgetRequirementStatusEmoji,\n\tformatRequirementBuildMarkdown,\n\tformatRequirementBuildJson,\n\tformatRequirementBuildXml,\n\tformatRequirementListMarkdown,\n\tformatRequirementListXml,\n\tformatRequirementBreakdownMarkdown,\n\tformatRequirementBreakdownXml,\n} from '../utils/formatting.js';\nimport type { HandlerResult } from './types.js';\nimport type { RequirementStatus } from '../types/requirement.js';\nimport type { AxiosError } from 'axios';\n\nfunction getServices(): {\n\trequirementService: RequirementService;\n\tauth: BraingridAuth;\n\tconfig: ReturnType<typeof getConfig>;\n} {\n\tconst config = getConfig();\n\tconst auth = new BraingridAuth(config.apiUrl);\n\tconst requirementService = new RequirementService(config.apiUrl, auth);\n\treturn { requirementService, auth, config };\n}\n\nexport async function handleRequirementList(opts: {\n\tproject?: string;\n\tstatus?: string;\n\tformat?: string;\n\tpage?: string;\n\tlimit?: string;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { requirementService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Validate format option\n\t\tconst format = opts.format || 'table';\n\t\tif (!['table', 'json', 'xml', 'markdown'].includes(format)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t`❌ Invalid format: ${format}. Supported formats: table, json, xml, markdown`\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\tstopSpinner = showSpinner('Loading requirements', chalk.gray);\n\t\tconst response = await requirementService.listProjectRequirements(projectId, {\n\t\t\tstatus: opts.status as RequirementStatus | undefined,\n\t\t\tpage: opts.page ? parseInt(opts.page, 10) : 1,\n\t\t\tlimit: opts.limit ? parseInt(opts.limit, 10) : 20,\n\t\t});\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\t// Format output based on requested format\n\t\tlet output: string;\n\t\tswitch (format) {\n\t\t\tcase 'json': {\n\t\t\t\toutput = JSON.stringify(response, null, 2);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'xml': {\n\t\t\t\toutput = formatRequirementListXml(response.requirements, response.pagination);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'markdown': {\n\t\t\t\toutput = formatRequirementListMarkdown(response.requirements, response.pagination);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'table':\n\t\t\tdefault: {\n\t\t\t\t// Table format\n\t\t\t\tif (response.requirements.length === 0) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tmessage: chalk.yellow('No requirements found.'),\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\toutput = chalk.bold('📋 Requirements\\n\\n');\n\t\t\t\toutput +=\n\t\t\t\t\t'Short ID Status Name Branch Progress\\n';\n\t\t\t\toutput += '─'.repeat(90) + '\\n';\n\n\t\t\t\tfor (const req of response.requirements) {\n\t\t\t\t\tconst shortId = (req.short_id || req.id.slice(0, 11)).padEnd(11);\n\t\t\t\t\tconst statusEmoji = getRequirementStatusEmoji(req.status);\n\t\t\t\t\tconst statusText = req.status.padEnd(12);\n\t\t\t\t\tconst name = req.name.substring(0, 23).padEnd(23);\n\t\t\t\t\tconst branch = (req.branch || 'N/A').substring(0, 18).padEnd(18);\n\t\t\t\t\tconst progress = req.task_progress ? `${req.task_progress.progress_percentage}%` : 'N/A';\n\t\t\t\t\toutput += `${shortId} ${statusEmoji} ${statusText} ${name} ${branch} ${progress}\\n`;\n\t\t\t\t}\n\n\t\t\t\toutput += '\\n';\n\t\t\t\toutput += `Page ${response.pagination.page} of ${Math.ceil(response.pagination.total / response.pagination.limit)}`;\n\t\t\t\toutput += ` (${response.pagination.total} total)`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: response,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'listing requirements'),\n\t\t};\n\t}\n}\n\nexport async function handleRequirementShow(opts?: {\n\tid?: string;\n\tproject?: string;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { requirementService, auth, config } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Get requirement ID (explicit or auto-detected from git branch)\n\t\tconst requirementResult = await workspaceManager.getRequirement(opts?.id);\n\t\tif (!requirementResult.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: requirementResult.error,\n\t\t\t};\n\t\t}\n\t\tconst requirementId = requirementResult.requirementId;\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts?.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement ID\n\t\tconst normalizedId = normalizeRequirementId(requirementId);\n\t\tstopSpinner = showSpinner('Loading requirement', chalk.gray);\n\t\tconst requirement = await requirementService.getProjectRequirement(projectId, normalizedId);\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\t// Use centralized formatting function\n\t\tconst output = formatRequirementOutput(requirement, {\n\t\t\tshowDescription: true,\n\t\t\tshowContent: true,\n\t\t\tshowTasks: true,\n\t\t\tshowUpdated: true,\n\t\t\tapiUrl: config.apiUrl,\n\t\t\tprojectShortId: projectId,\n\t\t});\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: '\\n' + output,\n\t\t\tdata: requirement,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('requirement', opts?.id || 'unknown')),\n\t\t};\n\t}\n}\n\nexport async function handleRequirementCreate(opts: {\n\tproject?: string;\n\tname: string;\n\tcontent?: string;\n\tassignedTo?: string;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { requirementService, auth, config } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Validate assigned_to is a UUID if provided\n\t\tif (opts.assignedTo) {\n\t\t\tconst uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\t\t\tconst emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\n\t\t\tif (emailRegex.test(opts.assignedTo)) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t\t'❌ Email addresses are not supported for --assigned-to yet.\\n' +\n\t\t\t\t\t\t\t'Please use the user UUID instead.\\n' +\n\t\t\t\t\t\t\t'Email lookup will be supported when the API provides a user lookup endpoint.'\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (!uuidRegex.test(opts.assignedTo)) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t\t'❌ Invalid UUID format for --assigned-to.\\n' +\n\t\t\t\t\t\t\t'Please provide a valid user UUID (e.g., \"550e8400-e29b-41d4-a716-446655440000\")'\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tstopSpinner = showSpinner('Creating requirement', chalk.gray);\n\t\tconst requirement = await requirementService.createProjectRequirement(projectId, {\n\t\t\tname: opts.name,\n\t\t\tcontent: opts.content || null,\n\t\t\tassigned_to: opts.assignedTo || null,\n\t\t});\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\t// Use centralized formatting function\n\t\tconst message = formatRequirementOutput(requirement, {\n\t\t\tshowContent: !!opts.content,\n\t\t\tshowTasks: true,\n\t\t\tsuccessMessage: `Created requirement ${requirement.short_id}`,\n\t\t\tapiUrl: config.apiUrl,\n\t\t\tprojectShortId: projectId,\n\t\t});\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage,\n\t\t\tdata: requirement,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\t// Use new centralized error handler\n\t\tif (error && typeof error === 'object' && 'response' in error) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: handleError(error as AxiosError, 'creating requirement'),\n\t\t\t};\n\t\t}\n\n\t\t// Fallback for non-Axios errors\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: chalk.red(`❌ Error creating requirement: ${errorMessage}`),\n\t\t};\n\t}\n}\n\nexport async function handleRequirementSpecify(opts: {\n\tproject?: string;\n\tprompt: string;\n\tformat?: string;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { requirementService, auth, config } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Validate format option\n\t\tconst format = opts.format || 'table';\n\t\tif (!['table', 'json', 'xml', 'markdown'].includes(format)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t`❌ Invalid format: ${format}. Supported formats: table, json, xml, markdown`\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Validate prompt length (API requires 10-5000 chars)\n\t\tif (opts.prompt.length < 10) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Prompt must be at least 10 characters long'),\n\t\t\t};\n\t\t}\n\t\tif (opts.prompt.length > 5000) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Prompt must be no more than 5000 characters long'),\n\t\t\t};\n\t\t}\n\n\t\t// Show spinner while processing\n\t\tstopSpinner = showSpinner('Specifying requirement...');\n\n\t\tconst requirement = await requirementService.specifyRequirement(projectId, {\n\t\t\tprompt: opts.prompt,\n\t\t});\n\n\t\t// Stop spinner and format the requirement\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\t// Format output based on requested format\n\t\tlet output: string;\n\t\tswitch (format) {\n\t\t\tcase 'json': {\n\t\t\t\toutput = JSON.stringify(requirement, null, 2);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'xml': {\n\t\t\t\toutput = formatRequirementBuildXml(requirement);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'markdown': {\n\t\t\t\toutput = formatRequirementBuildMarkdown(requirement, {\n\t\t\t\t\tapiUrl: config.apiUrl,\n\t\t\t\t\tprojectShortId: projectId,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'table':\n\t\t\tdefault: {\n\t\t\t\t// Use centralized formatting function\n\t\t\t\toutput = formatRequirementOutput(requirement, {\n\t\t\t\t\tshowContent: true,\n\t\t\t\t\tshowTasks: true,\n\t\t\t\t\tsuccessMessage: `Created and refined requirement ${requirement.short_id}`,\n\t\t\t\t\tapiUrl: config.apiUrl,\n\t\t\t\t\tprojectShortId: projectId,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: requirement,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'specifying requirement'),\n\t\t};\n\t}\n}\n\nexport async function handleRequirementUpdate(opts: {\n\tid?: string;\n\tproject?: string;\n\tstatus?: string;\n\tname?: string;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { requirementService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.status && !opts.name) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Please provide at least one field to update (--status or --name)'),\n\t\t\t};\n\t\t}\n\n\t\t// Get requirement ID (explicit or auto-detected from git branch)\n\t\tconst requirementResult = await workspaceManager.getRequirement(opts.id);\n\t\tif (!requirementResult.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: requirementResult.error,\n\t\t\t};\n\t\t}\n\t\tconst requirementId = requirementResult.requirementId;\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement ID\n\t\tconst normalizedId = normalizeRequirementId(requirementId);\n\t\tstopSpinner = showSpinner('Updating requirement', chalk.gray);\n\t\tconst requirement = await requirementService.updateProjectRequirement(projectId, normalizedId, {\n\t\t\tstatus: opts.status as RequirementStatus | undefined,\n\t\t\tname: opts.name,\n\t\t});\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green(`✅ Updated requirement ${requirement.short_id}: ${requirement.name}`),\n\t\t\tdata: requirement,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('requirement', opts.id || 'unknown')),\n\t\t};\n\t}\n}\n\nexport async function handleRequirementDelete(opts: {\n\tid?: string;\n\tproject?: string;\n\tforce?: boolean;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { requirementService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.force) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.yellow(\n\t\t\t\t\t'⚠️ Deleting a requirement is permanent. Use --force to confirm deletion.'\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Get requirement ID (explicit or auto-detected from git branch)\n\t\tconst requirementResult = await workspaceManager.getRequirement(opts.id);\n\t\tif (!requirementResult.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: requirementResult.error,\n\t\t\t};\n\t\t}\n\t\tconst requirementId = requirementResult.requirementId;\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement ID\n\t\tconst normalizedId = normalizeRequirementId(requirementId);\n\t\tstopSpinner = showSpinner('Deleting requirement', chalk.gray);\n\t\tawait requirementService.deleteProjectRequirement(projectId, normalizedId);\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green(`✅ Deleted requirement ${requirementId}`),\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('requirement', opts.id || 'unknown')),\n\t\t};\n\t}\n}\n\nexport async function handleRequirementBreakdown(opts: {\n\tid?: string;\n\tproject?: string;\n\tformat?: string;\n}): Promise<HandlerResult> {\n\tlet stop: (() => void) | undefined;\n\ttry {\n\t\tconst { requirementService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Validate format option\n\t\tconst format = opts.format || 'table';\n\t\tif (!['table', 'json', 'xml', 'markdown'].includes(format)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t`❌ Invalid format: ${format}. Supported formats: table, json, xml, markdown`\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Get requirement ID (explicit or auto-detected from git branch)\n\t\tconst requirementResult = await workspaceManager.getRequirement(opts.id);\n\t\tif (!requirementResult.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: requirementResult.error,\n\t\t\t};\n\t\t}\n\t\tconst requirementId = requirementResult.requirementId;\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement ID\n\t\tconst normalizedId = normalizeRequirementId(requirementId);\n\n\t\t// Show spinner while processing\n\t\tstop = showSpinner('Breaking down requirement into tasks...');\n\n\t\tconst response = await requirementService.breakdownRequirement(projectId, normalizedId, {});\n\n\t\t// Stop spinner and format the tasks\n\t\tstop();\n\n\t\t// Format output based on requested format\n\t\tlet output: string;\n\t\tswitch (format) {\n\t\t\tcase 'json': {\n\t\t\t\toutput = JSON.stringify(response, null, 2);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'xml': {\n\t\t\t\toutput = formatRequirementBreakdownXml(response.requirement_short_id, response.tasks);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'markdown': {\n\t\t\t\toutput = formatRequirementBreakdownMarkdown(response.requirement_short_id, response.tasks);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'table':\n\t\t\tdefault: {\n\t\t\t\t// Table view - compact display\n\t\t\t\toutput = chalk.green(\n\t\t\t\t\t`✅ Generated ${response.tasks.length} tasks for ${response.requirement_short_id}\\n\\n`\n\t\t\t\t);\n\t\t\t\toutput += 'Number Status Title\\n';\n\t\t\t\toutput += '─'.repeat(80) + '\\n';\n\n\t\t\t\tfor (const task of response.tasks) {\n\t\t\t\t\tconst statusEmoji = getRequirementStatusEmoji(task.status);\n\t\t\t\t\tconst number = task.number.padEnd(6);\n\t\t\t\t\tconst statusText = task.status.padEnd(12);\n\t\t\t\t\tconst title = task.title.substring(0, 55);\n\t\t\t\t\toutput += `${number} ${statusEmoji} ${statusText} ${title}\\n`;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: response,\n\t\t};\n\t} catch (error: unknown) {\n\t\tstop?.(); // Clear spinner on error if it was started\n\t\t// Use centralized error handler\n\t\tif (error && typeof error === 'object' && 'response' in error) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: handleError(\n\t\t\t\t\terror as AxiosError,\n\t\t\t\t\t`breaking down requirement ${opts.id || 'unknown'}`\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Fallback for non-Axios errors\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: chalk.red(`❌ Error breaking down requirement: ${errorMessage}`),\n\t\t};\n\t}\n}\n\nexport async function handleRequirementBuild(opts: {\n\tid?: string;\n\tproject?: string;\n\tformat?: string;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { requirementService, auth, config } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Validate format option\n\t\tconst format = opts.format || 'markdown';\n\t\tif (!['markdown', 'json', 'xml'].includes(format)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Invalid format. Must be one of: markdown, json, xml'),\n\t\t\t};\n\t\t}\n\n\t\t// Get requirement ID (explicit or auto-detected from git branch)\n\t\tconst requirementResult = await workspaceManager.getRequirement(opts.id);\n\t\tif (!requirementResult.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: requirementResult.error,\n\t\t\t};\n\t\t}\n\t\tconst requirementId = requirementResult.requirementId;\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement ID\n\t\tconst normalizedId = normalizeRequirementId(requirementId);\n\t\tstopSpinner = showSpinner('Building requirement with tasks', chalk.gray);\n\t\tconst requirement = await requirementService.getProjectRequirement(projectId, normalizedId);\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\t// Format output based on selected format\n\t\tlet output: string;\n\t\tswitch (format) {\n\t\t\tcase 'json': {\n\t\t\t\toutput = formatRequirementBuildJson(requirement);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'xml': {\n\t\t\t\toutput = formatRequirementBuildXml(requirement);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'markdown':\n\t\t\tdefault: {\n\t\t\t\toutput = formatRequirementBuildMarkdown(requirement, {\n\t\t\t\t\tapiUrl: config.apiUrl,\n\t\t\t\t\tprojectShortId: projectId,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: requirement,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('requirement', opts.id || 'unknown')),\n\t\t};\n\t}\n}\n","/**\n * Requirement Service\n * Handles all API interactions for requirements\n */\n\nimport { AxiosInstance } from 'axios';\nimport { BraingridAuth } from './auth.js';\nimport { createAuthenticatedAxios } from '../utils/axios-with-auth.js';\nimport {\n\tRequirement,\n\tRequirementDetail,\n\tCreateRequirementRequest,\n\tSpecifyRequirementRequest,\n\tUpdateRequirementRequest,\n\tListRequirementsResponse,\n\tRequirementStatus,\n\tBreakdownRequest,\n\tBreakdownResponse,\n} from '../types/requirement.js';\n\nexport class RequirementService {\n\tprivate baseUrl: string;\n\tprivate auth: BraingridAuth;\n\tprivate axios: AxiosInstance;\n\n\tconstructor(baseUrl: string, auth: BraingridAuth) {\n\t\tthis.baseUrl = baseUrl;\n\t\tthis.auth = auth;\n\t\tthis.axios = createAuthenticatedAxios(auth);\n\t}\n\n\tprivate getHeaders(): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t};\n\t}\n\n\t// Project-scoped requirements\n\tasync listProjectRequirements(\n\t\tprojectId: string,\n\t\tparams?: {\n\t\t\tstatus?: RequirementStatus;\n\t\t\tpage?: number;\n\t\t\tlimit?: number;\n\t\t}\n\t): Promise<ListRequirementsResponse> {\n\t\tconst queryParams = new URLSearchParams();\n\t\tif (params?.status) queryParams.append('status', params.status);\n\t\tif (params?.page) queryParams.append('page', params.page.toString());\n\t\tif (params?.limit) queryParams.append('limit', params.limit.toString());\n\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements?${queryParams.toString()}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<ListRequirementsResponse>(url, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync getProjectRequirement(\n\t\tprojectId: string,\n\t\trequirementId: string\n\t): Promise<RequirementDetail> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<RequirementDetail>(url, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync createProjectRequirement(\n\t\tprojectId: string,\n\t\tdata: CreateRequirementRequest\n\t): Promise<Requirement> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.post<Requirement>(url, data, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync specifyRequirement(\n\t\tprojectId: string,\n\t\tdata: SpecifyRequirementRequest\n\t): Promise<RequirementDetail> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/specify`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.post<RequirementDetail>(url, data, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync updateProjectRequirement(\n\t\tprojectId: string,\n\t\trequirementId: string,\n\t\tdata: UpdateRequirementRequest\n\t): Promise<Requirement> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.patch<Requirement>(url, data, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync deleteProjectRequirement(projectId: string, requirementId: string): Promise<void> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tawait this.axios.delete(url, { headers });\n\t}\n\n\tasync breakdownRequirement(\n\t\tprojectId: string,\n\t\trequirementId: string,\n\t\tdata: BreakdownRequest\n\t): Promise<BreakdownResponse> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}/breakdown`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.post<BreakdownResponse>(url, data, { headers });\n\t\treturn response.data;\n\t}\n}\n","/**\n * Task Resource Handlers\n *\n * Handles all task-related commands:\n * - list: List tasks for a requirement\n * - show: Show task details\n * - create: Create a new task\n * - update: Update task information\n * - delete: Delete a task\n */\n\nimport chalk from 'chalk';\nimport { TaskService } from '../services/task-service.js';\nimport { BraingridAuth } from '../services/auth.js';\nimport { getConfig } from '../utils/config.js';\nimport { formatError, getResourceContext } from '../utils/error-formatter.js';\nimport { formatTaskOutput, formatTasksListOutput } from '../utils/formatting.js';\nimport { workspaceManager } from '../utils/workspace-manager.js';\nimport { normalizeRequirementId } from '../utils/requirements.js';\nimport { normalizeTaskId } from '../utils/tasks.js';\nimport { showSpinner } from '../utils/spinner.js';\nimport type { HandlerResult } from './types.js';\nimport type { TaskStatus } from '../types/task.js';\n\nfunction getServices(): { taskService: TaskService; auth: BraingridAuth } {\n\tconst config = getConfig();\n\tconst auth = new BraingridAuth(config.apiUrl);\n\tconst taskService = new TaskService(config.apiUrl, auth);\n\treturn { taskService, auth };\n}\n\nexport async function handleTaskList(opts: {\n\trequirement?: string;\n\tproject?: string;\n\tformat?: 'table' | 'json' | 'xml' | 'markdown';\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { taskService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.requirement) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.red('❌ No requirement specified.\\n\\n') +\n\t\t\t\t\tchalk.dim('Please provide a requirement ID:\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task list -r REQ-456') +\n\t\t\t\t\tchalk.dim(' (if initialized) or\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task list -r REQ-456 -p PROJ-123'),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement ID\n\t\tconst requirementId = normalizeRequirementId(opts.requirement);\n\n\t\tstopSpinner = showSpinner('Loading tasks', chalk.gray);\n\t\tconst response = await taskService.listTasks(projectId, requirementId);\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\t// Handle empty task list\n\t\tif (response.tasks.length === 0) {\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: chalk.yellow('No tasks found.'),\n\t\t\t\tdata: response,\n\t\t\t};\n\t\t}\n\n\t\t// Use project and requirement short IDs for formatting\n\t\tconst projectShortId = projectId;\n\t\tconst requirementShortId = opts.requirement;\n\n\t\t// Determine format (default to markdown for full content)\n\t\tconst format = opts.format || 'markdown';\n\n\t\t// Use formatTasksListOutput - always show full content\n\t\tconst config = getConfig();\n\t\tconst output = formatTasksListOutput(response.tasks, format, true, {\n\t\t\trequirementId,\n\t\t\tprojectShortId,\n\t\t\trequirementShortId,\n\t\t\tapiUrl: config.apiUrl,\n\t\t});\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: response,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'listing tasks'),\n\t\t};\n\t}\n}\n\nexport async function handleTaskSummary(opts: {\n\trequirement?: string;\n\tproject?: string;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { taskService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.requirement) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.red('❌ No requirement specified.\\n\\n') +\n\t\t\t\t\tchalk.dim('Please provide a requirement ID:\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task summary -r REQ-456') +\n\t\t\t\t\tchalk.dim(' (if initialized) or\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task summary -r REQ-456 -p PROJ-123'),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement ID\n\t\tconst requirementId = normalizeRequirementId(opts.requirement);\n\n\t\tstopSpinner = showSpinner('Loading tasks', chalk.gray);\n\t\tconst response = await taskService.listTasks(projectId, requirementId);\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\t// Handle empty task list\n\t\tif (response.tasks.length === 0) {\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: chalk.yellow('No tasks found.'),\n\t\t\t\tdata: response,\n\t\t\t};\n\t\t}\n\n\t\t// Use project and requirement short IDs for formatting\n\t\tconst projectShortId = projectId;\n\t\tconst requirementShortId = opts.requirement;\n\n\t\t// Always use table format without content (verbose=false)\n\t\tconst config = getConfig();\n\t\tconst output = formatTasksListOutput(response.tasks, 'table', false, {\n\t\t\trequirementId,\n\t\t\tprojectShortId,\n\t\t\trequirementShortId,\n\t\t\tapiUrl: config.apiUrl,\n\t\t});\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: response,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'listing tasks'),\n\t\t};\n\t}\n}\n\nexport async function handleTaskShow(\n\tid: string,\n\topts?: { requirement?: string; project?: string }\n): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { taskService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts?.requirement) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.red('❌ No requirement specified.\\n\\n') +\n\t\t\t\t\tchalk.dim('Please provide a requirement ID:\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task show TASK-789 -r REQ-456') +\n\t\t\t\t\tchalk.dim(' (if initialized) or\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task show TASK-789 -r REQ-456 -p PROJ-123'),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement and task IDs\n\t\tconst requirementId = normalizeRequirementId(opts.requirement);\n\t\tconst taskId = normalizeTaskId(id);\n\n\t\tconst config = getConfig();\n\t\tstopSpinner = showSpinner('Loading task', chalk.gray);\n\t\tconst task = await taskService.getTask(projectId, requirementId, taskId);\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\tconst output = formatTaskOutput(task, {\n\t\t\tshowContent: true,\n\t\t\tapiUrl: config.apiUrl,\n\t\t\tprojectShortId: projectId,\n\t\t\trequirementShortId: opts.requirement,\n\t\t\trequirementId,\n\t\t});\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: task,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('task', id)),\n\t\t};\n\t}\n}\n\nexport async function handleTaskCreate(opts: {\n\trequirement?: string;\n\tproject?: string;\n\ttitle: string;\n\tcontent?: string;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { taskService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.requirement) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.red('❌ No requirement specified.\\n\\n') +\n\t\t\t\t\tchalk.dim('Please provide a requirement ID:\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task create -r REQ-456 --title \"...\"') +\n\t\t\t\t\tchalk.dim(' (if initialized) or\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task create -r REQ-456 -p PROJ-123 --title \"...\"'),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement ID\n\t\tconst requirementId = normalizeRequirementId(opts.requirement);\n\n\t\t// Use short IDs for display\n\t\tconst projectShortId = projectId;\n\t\tconst requirementShortId = opts.requirement;\n\n\t\tconst config = getConfig();\n\t\tstopSpinner = showSpinner('Creating task', chalk.gray);\n\t\tconst task = await taskService.createTask(projectId, requirementId, {\n\t\t\ttitle: opts.title,\n\t\t\tcontent: opts.content,\n\t\t});\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\tconst output = formatTaskOutput(task, {\n\t\t\tshowContent: !!opts.content,\n\t\t\tsuccessMessage: `Created task ${task.number}`,\n\t\t\tapiUrl: config.apiUrl,\n\t\t\tprojectShortId,\n\t\t\trequirementShortId,\n\t\t\trequirementId,\n\t\t});\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: task,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'creating task'),\n\t\t};\n\t}\n}\n\nexport async function handleTaskUpdate(\n\tid: string,\n\topts: {\n\t\trequirement?: string;\n\t\tproject?: string;\n\t\tstatus?: string;\n\t\ttitle?: string;\n\t}\n): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { taskService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.status && !opts.title) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Please provide at least one field to update (--status or --title)'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.requirement) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.red('❌ No requirement specified.\\n\\n') +\n\t\t\t\t\tchalk.dim('Please provide a requirement ID:\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task update TASK-789 -r REQ-456 --status COMPLETED') +\n\t\t\t\t\tchalk.dim(' (if initialized) or\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task update TASK-789 -r REQ-456 -p PROJ-123 --status COMPLETED'),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement and task IDs\n\t\tconst requirementId = normalizeRequirementId(opts.requirement);\n\t\tconst taskId = normalizeTaskId(id);\n\n\t\tconst config = getConfig();\n\t\tstopSpinner = showSpinner('Updating task', chalk.gray);\n\t\tconst task = await taskService.updateTask(projectId, requirementId, taskId, {\n\t\t\tstatus: opts.status as TaskStatus | undefined,\n\t\t\ttitle: opts.title,\n\t\t});\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\tconst output = formatTaskOutput(task, {\n\t\t\tshowContent: true,\n\t\t\tsuccessMessage: `Updated task ${task.number}`,\n\t\t\tapiUrl: config.apiUrl,\n\t\t\tprojectShortId: projectId,\n\t\t\trequirementShortId: opts.requirement,\n\t\t\trequirementId,\n\t\t});\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: task,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('task', id)),\n\t\t};\n\t}\n}\n\nexport async function handleTaskDelete(\n\tid: string,\n\topts: { requirement?: string; project?: string; force?: boolean }\n): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { taskService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.force) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.yellow('⚠️ Deleting a task is permanent. Use --force to confirm deletion.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.requirement) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.red('❌ No requirement specified.\\n\\n') +\n\t\t\t\t\tchalk.dim('Please provide a requirement ID:\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task delete TASK-789 -r REQ-456 --force') +\n\t\t\t\t\tchalk.dim(' (if initialized) or\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task delete TASK-789 -r REQ-456 -p PROJ-123 --force'),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement and task IDs\n\t\tconst requirementId = normalizeRequirementId(opts.requirement);\n\t\tconst taskId = normalizeTaskId(id);\n\n\t\tstopSpinner = showSpinner('Deleting task', chalk.gray);\n\t\tawait taskService.deleteTask(projectId, requirementId, taskId);\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green(`✅ Deleted task ${id}`),\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('task', id)),\n\t\t};\n\t}\n}\n","/**\n * Task Service\n * Handles all API interactions for tasks\n */\n\nimport { AxiosInstance } from 'axios';\nimport { BraingridAuth } from './auth.js';\nimport { createAuthenticatedAxios } from '../utils/axios-with-auth.js';\nimport { Task, CreateTaskRequest, UpdateTaskRequest, ListTasksResponse } from '../types/task.js';\n\nexport class TaskService {\n\tprivate baseUrl: string;\n\tprivate auth: BraingridAuth;\n\tprivate axios: AxiosInstance;\n\n\tconstructor(baseUrl: string, auth: BraingridAuth) {\n\t\tthis.baseUrl = baseUrl;\n\t\tthis.auth = auth;\n\t\tthis.axios = createAuthenticatedAxios(auth);\n\t}\n\n\tprivate getHeaders(): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t};\n\t}\n\n\tasync listTasks(\n\t\tprojectId: string,\n\t\trequirementId: string,\n\t\tparams?: {\n\t\t\tpage?: number;\n\t\t\tlimit?: number;\n\t\t}\n\t): Promise<ListTasksResponse> {\n\t\tconst queryParams = new URLSearchParams();\n\t\tif (params?.page) queryParams.append('page', params.page.toString());\n\t\tif (params?.limit) queryParams.append('limit', params.limit.toString());\n\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}/tasks?${queryParams.toString()}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<ListTasksResponse>(url, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync getTask(projectId: string, requirementId: string, taskId: string): Promise<Task> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}/tasks/${taskId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<Task>(url, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync createTask(\n\t\tprojectId: string,\n\t\trequirementId: string,\n\t\tdata: CreateTaskRequest\n\t): Promise<Task> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}/tasks`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.post<Task>(url, data, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync updateTask(\n\t\tprojectId: string,\n\t\trequirementId: string,\n\t\ttaskId: string,\n\t\tdata: UpdateTaskRequest\n\t): Promise<Task> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}/tasks/${taskId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.patch<Task>(url, data, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync deleteTask(projectId: string, requirementId: string, taskId: string): Promise<void> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}/tasks/${taskId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tawait this.axios.delete(url, { headers });\n\t}\n}\n","/**\n * Auth Handlers\n *\n * Handles authentication-related commands:\n * - login: Authenticate with BrainGrid\n * - logout: Sign out from BrainGrid\n * - whoami: Show current user information\n */\n\nimport chalk from 'chalk';\nimport { BraingridAuth } from '../services/auth.js';\nimport { getConfig } from '../utils/config.js';\nimport { formatError } from '../utils/error-formatter.js';\nimport { getGitUser } from '../utils/git.js';\nimport { getLogger } from '../utils/logger.js';\nimport type { HandlerResult } from './types.js';\n\nconst logger = getLogger();\n\nfunction getAuth(): BraingridAuth {\n\tconst config = getConfig();\n\treturn new BraingridAuth(config.apiUrl);\n}\n\nexport async function handleLogin(): Promise<HandlerResult> {\n\ttry {\n\t\tconst auth = getAuth();\n\n\t\tconsole.log(chalk.blue('🔐 Starting OAuth2 authentication flow...'));\n\t\tconsole.log(chalk.dim('Your browser will open to complete authentication.\\n'));\n\n\t\t// Capture git user info (best effort - won't fail if git not configured)\n\t\tconst gitUser = await getGitUser();\n\n\t\t// Set up callback to display auth URL if browser fails to open\n\t\tconst session = await auth.login((authUrl: string) => {\n\t\t\tconsole.log(chalk.dim(\"If your browser didn't open automatically, visit:\"));\n\t\t\tconsole.log(chalk.bold.cyan(authUrl));\n\t\t\tconsole.log(chalk.dim('\\nWaiting for authentication...\\n'));\n\t\t}, gitUser);\n\n\t\tif (!session) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Login failed. Please try again.'),\n\t\t\t};\n\t\t}\n\n\t\t// Debug: Log JWT token\n\t\tconst storedSession = await auth.getStoredSession();\n\t\tif (storedSession) {\n\t\t\tlogger.debug('[AUTH_HANDLER] Login successful', { jwt: storedSession.sealed_session });\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green('✅ Successfully logged in to BrainGrid!'),\n\t\t\tdata: session,\n\t\t};\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error),\n\t\t};\n\t}\n}\n\nexport async function handleLogout(): Promise<HandlerResult> {\n\ttry {\n\t\tconst auth = getAuth();\n\n\t\tawait auth.clearSession();\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green('✅ Successfully logged out.'),\n\t\t};\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error),\n\t\t};\n\t}\n}\n\nexport async function handleWhoami(): Promise<HandlerResult> {\n\ttry {\n\t\tconst auth = getAuth();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.yellow('⚠️ Not logged in. Run `braingrid login` to authenticate.'),\n\t\t\t};\n\t\t}\n\n\t\tconst session = await auth.getStoredSession();\n\t\tif (!session) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ No session found.'),\n\t\t\t};\n\t\t}\n\n\t\t// Debug: Log JWT token\n\t\tlogger.debug('[AUTH_HANDLER] whoami - Current session', { jwt: session.sealed_session });\n\n\t\tlet output = chalk.bold('\\n👤 Current User\\n\\n');\n\t\toutput += `${chalk.bold('User ID:')} ${session.user.id}\\n`;\n\t\toutput += `${chalk.bold('Email:')} ${session.user.email}\\n`;\n\t\toutput += `${chalk.bold('Name:')} ${session.user.firstName} ${session.user.lastName}\\n`;\n\t\toutput += `${chalk.bold('Org ID:')} ${session.organization_id}\\n`;\n\t\toutput += `${chalk.bold('Session:')} ${new Date(session.created_at).toLocaleString()}\\n`;\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: session,\n\t\t};\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error),\n\t\t};\n\t}\n}\n","/**\n * Status Handler\n *\n * Handles the status command which displays:\n * - Authentication status\n * - Git repository information\n * - Configuration details\n * - Overall CLI status\n */\n\nimport chalk from 'chalk';\nimport { BraingridAuth } from '../services/auth.js';\nimport { credentialStore } from '../services/credential-store.js';\nimport { getConfig } from '../utils/config.js';\nimport { getGitRepositoryInfo } from '../utils/git.js';\nimport { checkInstalledCliTools } from '../utils/cli-tools.js';\nimport { formatError } from '../utils/error-formatter.js';\nimport { showSpinner } from '../utils/spinner.js';\nimport type { HandlerResult } from './types.js';\n\nfunction getAuth(): BraingridAuth {\n\tconst config = getConfig();\n\treturn new BraingridAuth(config.apiUrl);\n}\n\nexport async function handleStatus(): Promise<HandlerResult> {\n\ttry {\n\t\tconst config = getConfig();\n\t\tconst auth = getAuth();\n\n\t\tconst stop = showSpinner('Checking status', chalk.gray);\n\n\t\t// Check authentication (force server validation to detect expired tokens)\n\t\tconst isAuthenticated = await auth.isAuthenticated(true);\n\n\t\tstop();\n\n\t\t// Build status output\n\t\tlet output = chalk.bold.cyan('\\n🧠 BrainGrid CLI Status\\n\\n');\n\n\t\t// Authentication Section\n\t\toutput += chalk.bold('Authentication\\n');\n\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\n\t\tif (!isAuthenticated) {\n\t\t\toutput += chalk.red('❌ Not authenticated\\n');\n\t\t\toutput += chalk.dim(' Run ') + chalk.cyan('braingrid login') + chalk.dim(' to sign in\\n\\n');\n\n\t\t\t// Git Repository Section\n\t\t\toutput += chalk.bold('Git Repository\\n');\n\t\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\n\t\t\tconst gitInfo = await getGitRepositoryInfo();\n\n\t\t\tif (!gitInfo || !gitInfo.isRepo) {\n\t\t\t\toutput += chalk.yellow('⚠️ Not in a git repository\\n\\n');\n\t\t\t} else {\n\t\t\t\toutput += chalk.green('✅ Repository detected!\\n');\n\n\t\t\t\t// Show repository owner/name\n\t\t\t\tif (gitInfo.owner && gitInfo.name) {\n\t\t\t\t\toutput += `${chalk.bold('Owner:')} ${gitInfo.owner}\\n`;\n\t\t\t\t\toutput += `${chalk.bold('Name:')} ${gitInfo.name}\\n`;\n\t\t\t\t} else if (gitInfo.remoteUrl) {\n\t\t\t\t\toutput += `${chalk.bold('Remote:')} ${gitInfo.remoteUrl}\\n`;\n\t\t\t\t} else {\n\t\t\t\t\toutput += chalk.yellow('⚠️ Local repository (no remote)\\n');\n\t\t\t\t}\n\n\t\t\t\t// Show branch\n\t\t\t\tif (gitInfo.branch) {\n\t\t\t\t\toutput += `${chalk.bold('Branch:')} ${gitInfo.branch}\\n`;\n\t\t\t\t}\n\n\t\t\t\t// Show git user\n\t\t\t\tif (gitInfo.userName || gitInfo.userEmail) {\n\t\t\t\t\tconst userDisplay =\n\t\t\t\t\t\tgitInfo.userName && gitInfo.userEmail\n\t\t\t\t\t\t\t? `${gitInfo.userName} <${gitInfo.userEmail}>`\n\t\t\t\t\t\t\t: gitInfo.userName || gitInfo.userEmail;\n\t\t\t\t\toutput += `${chalk.bold('Git User:')} ${userDisplay}\\n`;\n\t\t\t\t} else {\n\t\t\t\t\toutput +=\n\t\t\t\t\t\t`${chalk.bold('Git User:')} ` +\n\t\t\t\t\t\tchalk.yellow('⚠️ Not configured (run git config --global user.name/email)\\n');\n\t\t\t\t}\n\n\t\t\t\toutput += '\\n';\n\t\t\t}\n\n\t\t\t// Installed Coding Tools Section\n\t\t\toutput += chalk.bold('Installed Coding Tools\\n');\n\t\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\n\t\t\tconst cliToolsUnauthenticated = await checkInstalledCliTools();\n\n\t\t\tif (cliToolsUnauthenticated.every(tool => !tool.installed)) {\n\t\t\t\toutput += chalk.yellow('⚠️ No coding tools detected\\n\\n');\n\t\t\t} else {\n\t\t\t\tcliToolsUnauthenticated.forEach(tool => {\n\t\t\t\t\tif (tool.installed) {\n\t\t\t\t\t\tconst versionInfo = tool.version ? chalk.dim(` (${tool.version})`) : '';\n\t\t\t\t\t\toutput += `${chalk.green('✅')} ${tool.name}${versionInfo}\\n`;\n\t\t\t\t\t} else {\n\t\t\t\t\t\toutput += `${chalk.dim('○')} ${tool.name} ${chalk.dim('(not installed)')}\\n`;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\toutput += '\\n';\n\t\t\t}\n\n\t\t\t// Configuration Section\n\t\t\toutput += chalk.bold('Configuration\\n');\n\t\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\t\t\toutput += `${chalk.bold('API URL:')} ${config.apiUrl}\\n`;\n\t\t\toutput += `${chalk.bold('OAuth Client:')} ${config.oauthClientId}\\n`;\n\t\t\toutput += `${chalk.bold('Redirect URI:')} http://127.0.0.1:34536/callback\\n`;\n\t\t\toutput += `${chalk.bold('Config Path:')} ${credentialStore.getStoragePath()}\\n\\n`;\n\n\t\t\t// Overall Status\n\t\t\toutput += chalk.bold('Overall Status\\n');\n\t\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\t\t\toutput += chalk.yellow('⚠️ Setup required - please authenticate\\n');\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: output,\n\t\t\t\tdata: { authenticated: false },\n\t\t\t};\n\t\t}\n\n\t\tconst session = await auth.getStoredSession();\n\t\tif (!session) {\n\t\t\toutput += chalk.red('❌ Session not found\\n\\n');\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: output,\n\t\t\t\tdata: { authenticated: false },\n\t\t\t};\n\t\t}\n\n\t\t// Show authentication details\n\t\toutput += chalk.green('✅ Authenticated\\n');\n\t\tconst userName = `${session.user.firstName || ''} ${session.user.lastName || ''}`.trim();\n\t\tif (userName) {\n\t\t\toutput += `${chalk.bold('Name:')} ${userName}\\n`;\n\t\t}\n\t\toutput += `${chalk.bold('Email:')} ${session.user.email}\\n`;\n\t\toutput += `${chalk.bold('User ID:')} ${session.user.id}\\n`;\n\t\toutput += `${chalk.bold('Organization:')} ${session.organization_id}\\n`;\n\n\t\t// Session info\n\t\tconst sessionAge = Math.floor((Date.now() - session.created_at.getTime()) / 1000 / 60);\n\t\toutput += `${chalk.bold('Session Age:')} ${sessionAge} minutes\\n`;\n\t\toutput += `${chalk.bold('API URL:')} ${config.apiUrl}\\n`;\n\t\toutput += `${chalk.bold('Config Path:')} ${credentialStore.getStoragePath()}\\n\\n`;\n\n\t\t// Git Repository Section\n\t\toutput += chalk.bold('Git Repository\\n');\n\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\n\t\tconst gitInfo = await getGitRepositoryInfo();\n\n\t\tif (!gitInfo || !gitInfo.isRepo) {\n\t\t\toutput += chalk.yellow('⚠️ Not in a git repository\\n\\n');\n\t\t} else {\n\t\t\toutput += chalk.green('✅ Repository detected!\\n');\n\n\t\t\t// Show repository owner/name\n\t\t\tif (gitInfo.owner && gitInfo.name) {\n\t\t\t\toutput += `${chalk.bold('Owner:')} ${gitInfo.owner}\\n`;\n\t\t\t\toutput += `${chalk.bold('Name:')} ${gitInfo.name}\\n`;\n\t\t\t} else if (gitInfo.remoteUrl) {\n\t\t\t\toutput += `${chalk.bold('Remote:')} ${gitInfo.remoteUrl}\\n`;\n\t\t\t} else {\n\t\t\t\toutput += chalk.yellow('⚠️ Local repository (no remote)\\n');\n\t\t\t}\n\n\t\t\t// Show branch\n\t\t\tif (gitInfo.branch) {\n\t\t\t\toutput += `${chalk.bold('Branch:')} ${gitInfo.branch}\\n`;\n\t\t\t}\n\n\t\t\t// Show git user\n\t\t\tif (gitInfo.userName || gitInfo.userEmail) {\n\t\t\t\tconst userDisplay =\n\t\t\t\t\tgitInfo.userName && gitInfo.userEmail\n\t\t\t\t\t\t? `${gitInfo.userName} <${gitInfo.userEmail}>`\n\t\t\t\t\t\t: gitInfo.userName || gitInfo.userEmail;\n\t\t\t\toutput += `${chalk.bold('Git User:')} ${userDisplay}\\n`;\n\t\t\t} else {\n\t\t\t\toutput +=\n\t\t\t\t\t`${chalk.bold('Git User:')} ` +\n\t\t\t\t\tchalk.yellow('⚠️ Not configured (run git config --global user.name/email)\\n');\n\t\t\t}\n\n\t\t\toutput += '\\n';\n\t\t}\n\n\t\t// Installed Coding Tools Section\n\t\toutput += chalk.bold('Installed Coding Tools\\n');\n\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\n\t\tconst cliTools = await checkInstalledCliTools();\n\n\t\tif (cliTools.every(tool => !tool.installed)) {\n\t\t\toutput += chalk.yellow('⚠️ No coding tools detected\\n\\n');\n\t\t} else {\n\t\t\tcliTools.forEach(tool => {\n\t\t\t\tif (tool.installed) {\n\t\t\t\t\tconst versionInfo = tool.version ? chalk.dim(` (${tool.version})`) : '';\n\t\t\t\t\toutput += `${chalk.green('✅')} ${tool.name}${versionInfo}\\n`;\n\t\t\t\t} else {\n\t\t\t\t\toutput += `${chalk.dim('○')} ${tool.name} ${chalk.dim('(not installed)')}\\n`;\n\t\t\t\t}\n\t\t\t});\n\t\t\toutput += '\\n';\n\t\t}\n\n\t\t// Configuration Section\n\t\toutput += chalk.bold('Configuration\\n');\n\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\t\toutput += `${chalk.bold('OAuth Client:')} ${config.oauthClientId}\\n`;\n\t\toutput += `${chalk.bold('Redirect URI:')} http://127.0.0.1:34536/callback\\n`;\n\t\toutput += `${chalk.bold('Auth Server:')} ${config.getWorkOSAuthUrl()}\\n\\n`;\n\n\t\t// Overall Status\n\t\toutput += chalk.bold('Overall Status\\n');\n\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\t\toutput += chalk.green('✅ Ready to use BrainGrid CLI\\n');\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: { authenticated: true, session },\n\t\t};\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error),\n\t\t};\n\t}\n}\n","/**\n * Init Handler\n * Handles the `braingrid init` command for initializing a repository with a BrainGrid project\n */\n\nimport chalk from 'chalk';\nimport { confirm, select, input } from '@inquirer/prompts';\nimport { BraingridAuth } from '../services/auth.js';\nimport { ProjectService } from '../services/project-service.js';\nimport { GitHubService } from '../services/internal/github-service.js';\nimport { getConfig } from '../utils/config.js';\nimport { getGitRepositoryInfo } from '../utils/git.js';\nimport {\n\tisGitInstalled,\n\tinstallGit,\n\tgetManualInstallInstructions,\n} from '../utils/git-installer.js';\nimport { isGhInstalled, installGh } from '../utils/gh-installer.js';\nimport { formatError } from '../utils/error-formatter.js';\nimport { projectConfigExists, saveProjectConfig, loadProjectConfig } from '../utils/local-store.js';\nimport { handleLogin } from './auth.handlers.js';\nimport { RepositoryService } from '../services/internal/repository-service.js';\nimport {\n\tfindInstallationForOwner,\n\tcheckRepositoryAccess,\n\tgetRepositoryId,\n} from '../utils/repository-access.js';\nimport { waitWithSpinner } from '../utils/spinner.js';\nimport {\n\tcanUseGhAutomation,\n\tinitGitRepo,\n\tcreateGitHubRepoWithGh,\n\tgetCurrentDirectoryName,\n} from '../utils/github-repo.js';\nimport type { HandlerResult } from './types.js';\nimport type { LocalProjectConfig } from '../types/local-project.js';\nimport type { ListProjectsWithRepositoryResponse } from '../types/project.js';\nimport type { GitRepoInfo } from '../utils/git.js';\nimport type { GitHubInstallation } from '../types/github.js';\n\nfunction getServices(): {\n\tprojectService: ProjectService;\n\tgithubService: GitHubService;\n\trepositoryService: RepositoryService;\n\tauth: BraingridAuth;\n} {\n\tconst config = getConfig();\n\tconst auth = new BraingridAuth(config.apiUrl);\n\tconst projectService = new ProjectService(config.apiUrl, auth);\n\tconst githubService = new GitHubService(config.apiUrl, auth);\n\tconst repositoryService = new RepositoryService(config.apiUrl, auth);\n\treturn { projectService, githubService, repositoryService, auth };\n}\n\n/**\n * Prompt user to add a GitHub organization installation\n */\nfunction promptToAddOrganization(owner: string, webUrl: string): HandlerResult {\n\treturn {\n\t\tsuccess: false,\n\t\tmessage:\n\t\t\tchalk.yellow('⚠️ No projects found for this repository.\\n\\n') +\n\t\t\tchalk.dim(`Repository: ${owner}/*\\n\\n`) +\n\t\t\tchalk.dim(`You have GitHub connected, but not for the \"${owner}\" organization.\\n\\n`) +\n\t\t\tchalk.dim('To connect ') +\n\t\t\tchalk.cyan(owner) +\n\t\t\tchalk.dim(':\\n') +\n\t\t\tchalk.dim(' 1. Visit: ') +\n\t\t\tchalk.cyan(`${webUrl}/integrations`) +\n\t\t\tchalk.dim('\\n') +\n\t\t\tchalk.dim(' 2. Click \"Add GitHub Organization\"\\n') +\n\t\t\tchalk.dim(` 3. Select \"${owner}\"\\n`) +\n\t\t\tchalk.dim(' 4. Run ') +\n\t\t\tchalk.cyan('braingrid init') +\n\t\t\tchalk.dim(' again'),\n\t};\n}\n\n/**\n * Prompt user to create a project with repository linking\n */\nasync function promptToCreateProject(\n\tgitInfo: GitRepoInfo,\n\tprojectService: ProjectService,\n\trepositoryService: RepositoryService\n): Promise<HandlerResult> {\n\tconst webUrl = getConfig().getWebAppUrl();\n\n\tif (!gitInfo.owner || !gitInfo.name) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: chalk.red('❌ Repository information is incomplete'),\n\t\t};\n\t}\n\n\t// Get repository ID for linking\n\tconst repositoryId = await getRepositoryId(repositoryService, gitInfo.owner, gitInfo.name);\n\n\tif (!repositoryId) {\n\t\t// This shouldn't happen since we checked access, but handle gracefully\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.yellow('⚠️ Repository accessible but could not retrieve details.\\n\\n') +\n\t\t\t\tchalk.dim(`Repository: ${gitInfo.owner}/${gitInfo.name}\\n\\n`) +\n\t\t\t\tchalk.dim('Please try again or create a project manually at: ') +\n\t\t\t\tchalk.cyan(webUrl),\n\t\t};\n\t}\n\n\t// Prompt user to create project\n\tconsole.log(\n\t\tchalk.yellow('⚠️ Repository accessible but no project exists.\\n\\n') +\n\t\t\tchalk.dim(`Repository: ${gitInfo.owner}/${gitInfo.name}\\n`)\n\t);\n\n\tconst shouldCreate = await confirm({\n\t\tmessage: `Would you like to create a project for ${gitInfo.name} now?`,\n\t\tdefault: true,\n\t});\n\n\tif (!shouldCreate) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.dim('\\nProject creation cancelled.\\n\\n') +\n\t\t\t\tchalk.dim('Create a project at ') +\n\t\t\t\tchalk.cyan(webUrl) +\n\t\t\t\tchalk.dim(' and link it to this repository, or use:\\n') +\n\t\t\t\tchalk.cyan(\n\t\t\t\t\t`braingrid project create --name \"${gitInfo.name}\" --repositories \"${gitInfo.owner}/${gitInfo.name}\"`\n\t\t\t\t),\n\t\t};\n\t}\n\n\t// Create project with repository linked\n\ttry {\n\t\tconst project = await projectService.createProject({\n\t\t\tname: gitInfo.name,\n\t\t\tdescription: `Project for ${gitInfo.owner}/${gitInfo.name}`,\n\t\t\trepository_id: repositoryId,\n\t\t});\n\n\t\tconsole.log(chalk.green(`\\n✅ Created project ${project.short_id}: ${project.name}`));\n\t\tconsole.log(chalk.green(`✅ Linked repository ${gitInfo.owner}/${gitInfo.name}\\n`));\n\n\t\treturn { success: true, message: '', data: project };\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'creating project'),\n\t\t};\n\t}\n}\n\n/**\n * Prompt user to grant repository access and poll until granted\n */\nasync function promptToGrantRepositoryAccess(\n\tgitInfo: GitRepoInfo,\n\twebUrl: string,\n\trepositoryService: RepositoryService,\n\tprojectService: ProjectService\n): Promise<HandlerResult> {\n\tif (!gitInfo.owner || !gitInfo.name) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: chalk.red('❌ Repository information is incomplete'),\n\t\t};\n\t}\n\n\tconst owner = gitInfo.owner;\n\tconst name = gitInfo.name;\n\n\tconsole.log(\n\t\tchalk.yellow('⚠️ Repository found but BrainGrid needs access.\\n\\n') +\n\t\t\tchalk.dim(`Repository: ${owner}/${name}\\n\\n`) +\n\t\t\tchalk.dim('Please grant BrainGrid access to this repository:\\n') +\n\t\t\tchalk.dim(' 1. Visit: ') +\n\t\t\tchalk.cyan(`${webUrl}/integrations`) +\n\t\t\tchalk.dim('\\n') +\n\t\t\tchalk.dim(\n\t\t\t\t` 2. Click on your \"${owner}\" installation \"Add/Remove\" to grant BrainGrid access to your repository\\n`\n\t\t\t) +\n\t\t\tchalk.dim(` 3. Select \"${name}\" and save\\n\\n`)\n\t);\n\n\t// Poll for repository access (3 minutes max)\n\tconst accessGranted = await waitWithSpinner(\n\t\t'Waiting for repository access (up to 3 minutes)',\n\t\tasync () => await checkRepositoryAccess(repositoryService, owner, name),\n\t\t3000,\n\t\t60\n\t);\n\n\tif (!accessGranted) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.yellow('\\n⚠️ Repository access not detected within 3 minutes.\\n\\n') +\n\t\t\t\tchalk.dim('Please grant access at: ') +\n\t\t\t\tchalk.cyan(`${webUrl}/integrations`) +\n\t\t\t\tchalk.dim(' and run ') +\n\t\t\t\tchalk.cyan('braingrid init') +\n\t\t\t\tchalk.dim(' again.'),\n\t\t};\n\t}\n\n\tconsole.log(chalk.green('✅ Repository access granted!\\n'));\n\n\t// Now create project with the repository\n\treturn promptToCreateProject(gitInfo, projectService, repositoryService);\n}\n\n/**\n * Handle the case when no project is found for a repository\n * Checks GitHub installations, validates owner, checks repository access, and prompts for project creation\n */\nasync function handleNoProjectForRepository(\n\towner: string,\n\tname: string,\n\tgitInfo: GitRepoInfo,\n\tgithubService: GitHubService,\n\trepositoryService: RepositoryService,\n\tprojectService: ProjectService,\n\tconfig: ReturnType<typeof getConfig>\n): Promise<HandlerResult> {\n\t// Check if user has any GitHub installations\n\tlet allInstallations: GitHubInstallation[];\n\ttry {\n\t\tconst installationsResponse = await githubService.listInstallations({ limit: 100 });\n\t\tallInstallations = installationsResponse.installations;\n\t} catch {\n\t\t// If we can't check installations, proceed with default message\n\t\tallInstallations = [];\n\t}\n\n\tconst webUrl = config.getWebAppUrl();\n\n\tif (allInstallations.length === 0) {\n\t\t// No GitHub installations - prompt to connect GitHub\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.yellow('⚠️ No projects found for this repository.\\n\\n') +\n\t\t\t\tchalk.dim(`Repository: ${owner}/${name}\\n\\n`) +\n\t\t\t\tchalk.dim(\"It looks like you haven't connected your GitHub account yet.\\n\") +\n\t\t\t\tchalk.dim('Please connect GitHub at: ') +\n\t\t\t\tchalk.cyan(`${webUrl}/integrations`) +\n\t\t\t\tchalk.dim('\\n\\nOnce connected, create a project and link it to this repository.'),\n\t\t};\n\t}\n\n\t// Has installations - check if we have the right owner\n\tconst ownerInstallation = findInstallationForOwner(owner, allInstallations);\n\n\tif (!ownerInstallation) {\n\t\t// User has GitHub connected but not for this owner\n\t\treturn promptToAddOrganization(owner, webUrl);\n\t}\n\n\t// Check if repository is accessible\n\tconst hasRepoAccess = await checkRepositoryAccess(repositoryService, owner, name);\n\n\tif (!hasRepoAccess) {\n\t\t// Installation exists but repo not accessible - need to grant access\n\t\treturn promptToGrantRepositoryAccess(gitInfo, webUrl, repositoryService, projectService);\n\t}\n\n\t// Repo accessible but no project - create one\n\treturn promptToCreateProject(gitInfo, projectService, repositoryService);\n}\n\n/**\n * Show setup instructions for users without automation\n */\nfunction showSetupInstructions(scenario: 'no-git' | 'no-remote'): string {\n\tlet message = '';\n\n\tif (scenario === 'no-git') {\n\t\tmessage += chalk.dim('To initialize BrainGrid locally:\\n\\n');\n\t\tmessage += chalk.dim(' 1. Initialize git:\\n');\n\t\tmessage += chalk.cyan(' git init\\n\\n');\n\t} else {\n\t\tmessage += chalk.dim('To connect to GitHub:\\n\\n');\n\t}\n\n\tmessage += chalk.dim(' 2. Create GitHub repository:\\n');\n\tmessage += chalk.dim(' • Install GitHub CLI: ') + chalk.cyan('https://cli.github.com\\n');\n\tmessage += chalk.dim(' Then: ') + chalk.cyan('gh repo create --private --source=.\\n');\n\tmessage += chalk.dim(' • Or manually: ') + chalk.cyan('https://github.com/new\\n\\n');\n\n\tif (scenario === 'no-git') {\n\t\tmessage += chalk.dim(' 3. Run: ') + chalk.cyan('braingrid init\\n\\n');\n\t} else {\n\t\tmessage += chalk.dim(' 3. Add remote and run init:\\n');\n\t\tmessage += chalk.cyan(' git remote add origin <url>\\n');\n\t\tmessage += chalk.cyan(' braingrid init\\n\\n');\n\t}\n\n\tmessage += chalk.bold('Or use BrainGrid without local initialization:\\n\\n');\n\tmessage += chalk.dim(' All commands support the --project flag:\\n');\n\tmessage += chalk.cyan(' braingrid requirement list --project PROJ-123\\n');\n\tmessage += chalk.cyan(' braingrid task create --project PROJ-123 --title \"Task\"\\n\\n');\n\tmessage +=\n\t\tchalk.dim(' Note: Without local init, you must specify --project for each command.') + '\\n';\n\n\treturn message;\n}\n\n/**\n * Handle initialization when directory is not a git repository\n */\nasync function handleNoGitRepository(): Promise<HandlerResult> {\n\tconst canAutomate = await canUseGhAutomation();\n\n\tif (canAutomate) {\n\t\t// Offer one-click setup\n\t\tconst shouldSetup = await confirm({\n\t\t\tmessage: 'Would you like to initialize git and create a GitHub repository?',\n\t\t\tdefault: true,\n\t\t});\n\n\t\tif (shouldSetup) {\n\t\t\t// Initialize git\n\t\t\tconsole.log();\n\t\t\tconst gitInitSuccess = await initGitRepo();\n\n\t\t\tif (!gitInitSuccess) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.red('❌ Failed to initialize git repository'),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconsole.log(chalk.green('✅ Initialized git repository'));\n\n\t\t\t// Get repository name suggestion\n\t\t\tconst dirName = getCurrentDirectoryName();\n\n\t\t\t// Prompt for visibility\n\t\t\tconst isPrivate = await select({\n\t\t\t\tmessage: 'Repository visibility:',\n\t\t\t\tchoices: [\n\t\t\t\t\t{ value: true, name: 'Private' },\n\t\t\t\t\t{ value: false, name: 'Public' },\n\t\t\t\t],\n\t\t\t\tdefault: true,\n\t\t\t});\n\n\t\t\t// Prompt for repository name\n\t\t\tconst repoName = await input({\n\t\t\t\tmessage: 'Repository name:',\n\t\t\t\tdefault: dirName,\n\t\t\t});\n\n\t\t\t// Create GitHub repository\n\t\t\tconsole.log(chalk.dim('\\nCreating repository...\\n'));\n\t\t\tconst repo = await createGitHubRepoWithGh(repoName, isPrivate);\n\n\t\t\tif (!repo) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.red('❌ Failed to create GitHub repository\\n\\n') +\n\t\t\t\t\t\tshowSetupInstructions('no-git'),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconsole.log(chalk.green(`✅ Created repository: ${repo.url}`));\n\t\t\tconsole.log(chalk.green('✅ Added remote origin\\n'));\n\n\t\t\t// Return success with a special flag to continue init\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: 'continue-init', // Special marker to retry init\n\t\t\t\tdata: { repo },\n\t\t\t};\n\t\t}\n\t}\n\n\t// Fallback to instructions\n\treturn {\n\t\tsuccess: false,\n\t\tmessage:\n\t\t\tchalk.yellow('⚠️ This directory is not a git repository.\\n\\n') +\n\t\t\tshowSetupInstructions('no-git'),\n\t};\n}\n\n/**\n * Handle initialization when git repository has no remote\n */\nasync function handleNoGitRemote(): Promise<HandlerResult> {\n\tconst canAutomate = await canUseGhAutomation();\n\n\tif (canAutomate) {\n\t\t// Offer to create GitHub repo\n\t\tconst shouldCreate = await confirm({\n\t\t\tmessage: 'Would you like to create a GitHub repository now?',\n\t\t\tdefault: true,\n\t\t});\n\n\t\tif (shouldCreate) {\n\t\t\t// Get repository name suggestion\n\t\t\tconst dirName = getCurrentDirectoryName();\n\n\t\t\t// Prompt for visibility\n\t\t\tconst isPrivate = await select({\n\t\t\t\tmessage: 'Repository visibility:',\n\t\t\t\tchoices: [\n\t\t\t\t\t{ value: true, name: 'Private' },\n\t\t\t\t\t{ value: false, name: 'Public' },\n\t\t\t\t],\n\t\t\t\tdefault: true,\n\t\t\t});\n\n\t\t\t// Prompt for repository name\n\t\t\tconst repoName = await input({\n\t\t\t\tmessage: 'Repository name:',\n\t\t\t\tdefault: dirName,\n\t\t\t});\n\n\t\t\t// Create GitHub repository\n\t\t\tconsole.log(chalk.dim('\\nCreating repository...\\n'));\n\t\t\tconst repo = await createGitHubRepoWithGh(repoName, isPrivate);\n\n\t\t\tif (!repo) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.red('❌ Failed to create GitHub repository\\n\\n') +\n\t\t\t\t\t\tshowSetupInstructions('no-remote'),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconsole.log(chalk.green(`✅ Created repository: ${repo.url}`));\n\t\t\tconsole.log(chalk.green('✅ Added remote origin\\n'));\n\n\t\t\t// Return success with a special flag to continue init\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: 'continue-init', // Special marker to retry init\n\t\t\t\tdata: { repo },\n\t\t\t};\n\t\t}\n\t}\n\n\t// Fallback to instructions\n\treturn {\n\t\tsuccess: false,\n\t\tmessage:\n\t\t\tchalk.yellow('⚠️ Git repository detected but no GitHub remote configured.\\n\\n') +\n\t\t\tshowSetupInstructions('no-remote'),\n\t};\n}\n\nexport async function handleInit(opts: {\n\tproject?: string;\n\tforce?: boolean;\n}): Promise<HandlerResult> {\n\ttry {\n\t\tconst config = getConfig();\n\t\tconst { projectService, githubService, repositoryService, auth } = getServices();\n\n\t\t// Check if Git is installed (required for BrainGrid CLI)\n\t\tif (!(await isGitInstalled())) {\n\t\t\tconst shouldInstall = await confirm({\n\t\t\t\tmessage: 'Git is required but not installed. Would you like to install it now?',\n\t\t\t\tdefault: true,\n\t\t\t});\n\n\t\t\tif (!shouldInstall) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.yellow('⚠️ Git installation cancelled.\\n\\n') + getManualInstallInstructions(),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Install Git\n\t\t\tconsole.log(); // Add spacing\n\t\t\tconst installResult = await installGit();\n\n\t\t\tif (!installResult.success) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: installResult.message,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Display success message\n\t\t\tconsole.log(installResult.message);\n\t\t\tconsole.log(); // Add spacing\n\n\t\t\t// Verify Git is now available\n\t\t\tif (!(await isGitInstalled())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.red('❌ Git installation completed but git command not found\\n\\n') +\n\t\t\t\t\t\tchalk.dim('You may need to restart your terminal or add Git to your PATH.\\n') +\n\t\t\t\t\t\tgetManualInstallInstructions(),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Check if GitHub CLI is installed (recommended but optional)\n\t\tif (!(await isGhInstalled())) {\n\t\t\tconsole.log(chalk.blue('\\n💡 GitHub CLI is highly recommended for working with BrainGrid.'));\n\t\t\tconsole.log(\n\t\t\t\tchalk.dim(' It enables seamless GitHub integration and repository management.\\n')\n\t\t\t);\n\n\t\t\tconst shouldInstallGh = await confirm({\n\t\t\t\tmessage: 'Would you like to install GitHub CLI now?',\n\t\t\t\tdefault: true,\n\t\t\t});\n\n\t\t\tif (shouldInstallGh) {\n\t\t\t\tconsole.log(); // Add spacing\n\t\t\t\tconst ghInstallResult = await installGh();\n\n\t\t\t\tif (ghInstallResult.success) {\n\t\t\t\t\tconsole.log(ghInstallResult.message);\n\t\t\t\t\tconsole.log(); // Add spacing\n\t\t\t\t} else {\n\t\t\t\t\t// Show error but don't fail - it's optional\n\t\t\t\t\tconsole.log(ghInstallResult.message);\n\t\t\t\t\tconsole.log(chalk.dim('You can install it manually later.\\n'));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconsole.log(chalk.dim('Skipping GitHub CLI installation.\\n'));\n\t\t\t}\n\t\t}\n\n\t\t// Check if already initialized (unless --force)\n\t\tif ((await projectConfigExists()) && !opts.force) {\n\t\t\ttry {\n\t\t\t\tconst existing = await loadProjectConfig();\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.yellow('⚠️ Already initialized.\\n\\n') +\n\t\t\t\t\t\tchalk.dim(`Project: ${existing.project_name} (${existing.project_short_id})\\n`) +\n\t\t\t\t\t\tchalk.dim(`Repository: ${existing.repository?.full_name || 'N/A'}\\n\\n`) +\n\t\t\t\t\t\tchalk.dim('Use --force to reinitialize'),\n\t\t\t\t};\n\t\t\t} catch {\n\t\t\t\t// If config exists but is invalid, continue with init\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.yellow('⚠️ Invalid project configuration found.\\n') +\n\t\t\t\t\t\tchalk.dim('Use --force to reinitialize'),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Check authentication\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\t// Prompt user to log in / sign up\n\t\t\tconst shouldLogin = await confirm({\n\t\t\t\tmessage: 'You need to be authenticated. Would you like to log in / sign up now?',\n\t\t\t\tdefault: true,\n\t\t\t});\n\n\t\t\tif (!shouldLogin) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.yellow('⚠️ Authentication required.\\n') +\n\t\t\t\t\t\tchalk.dim('Run ') +\n\t\t\t\t\t\tchalk.cyan('braingrid login') +\n\t\t\t\t\t\tchalk.dim(\" when you're ready to authenticate.\"),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Call login handler\n\t\t\tconsole.log(); // Add spacing before login output\n\t\t\tconst loginResult = await handleLogin();\n\n\t\t\tif (!loginResult.success) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.red('❌ Login failed.\\n') +\n\t\t\t\t\t\tchalk.dim('Please try running ') +\n\t\t\t\t\t\tchalk.cyan('braingrid login') +\n\t\t\t\t\t\tchalk.dim(' again.'),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Verify authentication succeeded\n\t\t\tif (!(await auth.isAuthenticated())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.red('❌ Login was not completed.\\n') +\n\t\t\t\t\t\tchalk.dim('Please try running ') +\n\t\t\t\t\t\tchalk.cyan('braingrid login') +\n\t\t\t\t\t\tchalk.dim(' again.'),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Login successful, continue with init\n\t\t\tconsole.log(); // Add spacing before continuing with init\n\t\t}\n\n\t\t// Get session to retrieve organization_id\n\t\tconst session = await auth.getStoredSession();\n\t\tif (!session) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ No session found. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Get git repository info (always needed for URL, even when using --project)\n\t\tlet gitInfo = await getGitRepositoryInfo();\n\n\t\t// Fetch project from API\n\t\tlet project;\n\n\t\tif (opts.project) {\n\t\t\t// Manual mode: fetch project by ID\n\t\t\ttry {\n\t\t\t\tproject = await projectService.getProject(opts.project);\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.red(`❌ Project not found: ${opts.project}\\n\\n`) +\n\t\t\t\t\t\tchalk.dim('Make sure the project ID is correct and you have access to it.'),\n\t\t\t\t};\n\t\t\t}\n\t\t} else {\n\t\t\t// Auto-detect mode: fetch project by git repository\n\t\t\tif (!gitInfo || !gitInfo.isRepo) {\n\t\t\t\t// Not a git repository - offer to initialize\n\t\t\t\tconst result = await handleNoGitRepository();\n\t\t\t\tif (result.success && result.message === 'continue-init') {\n\t\t\t\t\t// Repository was created - re-fetch git info and continue\n\t\t\t\t\tgitInfo = await getGitRepositoryInfo();\n\t\t\t\t\tif (!gitInfo || !gitInfo.owner || !gitInfo.name) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\tmessage: chalk.red('❌ Failed to get repository information after setup'),\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!gitInfo || !gitInfo.owner || !gitInfo.name) {\n\t\t\t\t// Git repo but no remote - offer to create GitHub repo\n\t\t\t\tconst result = await handleNoGitRemote();\n\t\t\t\tif (result.success && result.message === 'continue-init') {\n\t\t\t\t\t// Repository was created - re-fetch git info and continue\n\t\t\t\t\tgitInfo = await getGitRepositoryInfo();\n\t\t\t\t\tif (!gitInfo || !gitInfo.owner || !gitInfo.name) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\tmessage: chalk.red('❌ Failed to get repository information after setup'),\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// At this point, gitInfo, owner and name are guaranteed to exist\n\t\t\tif (!gitInfo) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.red('❌ Repository information is missing'),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst owner = gitInfo.owner;\n\t\t\tconst name = gitInfo.name;\n\n\t\t\tif (!owner || !name) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.red('❌ Repository information is incomplete'),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlet response: ListProjectsWithRepositoryResponse;\n\t\t\ttry {\n\t\t\t\tresponse = (await projectService.listProjects({\n\t\t\t\t\trepository_owner: owner,\n\t\t\t\t\trepository_name: name,\n\t\t\t\t})) as ListProjectsWithRepositoryResponse;\n\t\t\t} catch (error: unknown) {\n\t\t\t\t// Check if it's a 404 error\n\t\t\t\tif (error && typeof error === 'object' && 'response' in error) {\n\t\t\t\t\tconst axiosError = error as { response?: { status: number } };\n\t\t\t\t\tif (axiosError.response?.status === 404) {\n\t\t\t\t\t\t// No project found - handle the scenario\n\t\t\t\t\t\treturn await handleNoProjectForRepository(\n\t\t\t\t\t\t\towner,\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\tgitInfo,\n\t\t\t\t\t\t\tgithubService,\n\t\t\t\t\t\t\trepositoryService,\n\t\t\t\t\t\t\tprojectService,\n\t\t\t\t\t\t\tconfig\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tif (response.projects.length === 0) {\n\t\t\t\t// No project found - handle the scenario\n\t\t\t\treturn await handleNoProjectForRepository(\n\t\t\t\t\towner,\n\t\t\t\t\tname,\n\t\t\t\t\tgitInfo,\n\t\t\t\t\tgithubService,\n\t\t\t\t\trepositoryService,\n\t\t\t\t\tprojectService,\n\t\t\t\t\tconfig\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Use the first project (could add selection logic if multiple projects)\n\t\t\tproject = response.projects[0];\n\t\t}\n\n\t\t// Display project information\n\t\tconst projectInfo =\n\t\t\tchalk.bold('\\n📦 BrainGrid Project Found\\n\\n') +\n\t\t\tchalk.dim('Project: ') +\n\t\t\tchalk.cyan(project.name) +\n\t\t\t'\\n' +\n\t\t\tchalk.dim('ID: ') +\n\t\t\tchalk.gray(project.short_id) +\n\t\t\t'\\n' +\n\t\t\t(project.description\n\t\t\t\t? chalk.dim('Description: ') + chalk.gray(project.description) + '\\n'\n\t\t\t\t: '') +\n\t\t\tchalk.dim('Repository: ') +\n\t\t\tchalk.gray(project.repository?.full_name || 'N/A') +\n\t\t\t'\\n\\n';\n\n\t\tconsole.log(projectInfo);\n\n\t\t// Always ask for confirmation (unless --force)\n\t\tif (!opts.force) {\n\t\t\tconst shouldInit = await confirm({\n\t\t\t\tmessage: 'Initialize this repository with the above project?',\n\t\t\t\tdefault: true,\n\t\t\t});\n\n\t\t\tif (!shouldInit) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.yellow('Initialization cancelled.'),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Create local project config\n\t\tconst localConfig: LocalProjectConfig = {\n\t\t\torganization_id: session.organization_id,\n\t\t\tproject_id: project.id,\n\t\t\tproject_short_id: project.short_id,\n\t\t\tproject_name: project.name,\n\t\t\tproject_description: project.description || null,\n\t\t\trepository: project.repository\n\t\t\t\t? {\n\t\t\t\t\t\tid: project.repository.id,\n\t\t\t\t\t\towner: project.repository.full_name.split('/')[0], // Parse owner from API full_name\n\t\t\t\t\t\tname: project.repository.name, // Use API name, not git name\n\t\t\t\t\t\tfull_name: project.repository.full_name,\n\t\t\t\t\t\turl: gitInfo?.remoteUrl || undefined,\n\t\t\t\t\t}\n\t\t\t\t: null,\n\t\t\tcreated_at: project.created_at,\n\t\t};\n\n\t\t// Save to .braingrid/project.json (at git repository root)\n\t\tawait saveProjectConfig(localConfig);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage:\n\t\t\t\tchalk.green('✅ Repository initialized successfully!\\n\\n') +\n\t\t\t\tchalk.dim('Project: ') +\n\t\t\t\tchalk.cyan(project.name) +\n\t\t\t\tchalk.dim(` (${project.short_id})`) +\n\t\t\t\t'\\n' +\n\t\t\t\tchalk.dim('Config: ') +\n\t\t\t\tchalk.gray('.braingrid/project.json') +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('You can now use project-scoped commands without specifying a project ID.'),\n\t\t\tdata: localConfig,\n\t\t};\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'initializing repository'),\n\t\t};\n\t}\n}\n","/**\n * Internal GitHub Service\n *\n * For internal use only - not exposed as CLI commands.\n * Handles API interactions with BrainGrid v1 GitHub endpoints.\n *\n * This service provides methods to:\n * - List GitHub installations for the authenticated organization\n * - Get detailed information about specific installations\n *\n * @internal\n */\n\nimport { AxiosInstance } from 'axios';\nimport { BraingridAuth } from '../auth.js';\nimport { createAuthenticatedAxios } from '../../utils/axios-with-auth.js';\nimport { GitHubInstallationDetail, ListGitHubInstallationsResponse } from '../../types/github.js';\n\n/**\n * Internal service for GitHub API operations\n */\nexport class GitHubService {\n\tprivate baseUrl: string;\n\tprivate auth: BraingridAuth;\n\tprivate axios: AxiosInstance;\n\n\tconstructor(baseUrl: string, auth: BraingridAuth) {\n\t\tthis.baseUrl = baseUrl;\n\t\tthis.auth = auth;\n\t\tthis.axios = createAuthenticatedAxios(auth);\n\t}\n\n\tprivate getHeaders(): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t};\n\t}\n\n\t/**\n\t * List GitHub installations for the authenticated organization\n\t *\n\t * @param params - Optional pagination parameters\n\t * @param params.page - Page number (default: 1, min: 1)\n\t * @param params.limit - Number of installations per page (default: 20, min: 1, max: 100)\n\t * @returns List of GitHub installations with pagination\n\t * @throws {Error} On API errors (401, 404, 422, 500)\n\t *\n\t * @example\n\t * ```typescript\n\t * const result = await githubService.listInstallations({ page: 1, limit: 20 });\n\t * console.log(result.installations);\n\t * console.log(result.pagination);\n\t * ```\n\t */\n\tasync listInstallations(params?: {\n\t\tpage?: number;\n\t\tlimit?: number;\n\t}): Promise<ListGitHubInstallationsResponse> {\n\t\tconst url = `${this.baseUrl}/api/v1/github/installations`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<ListGitHubInstallationsResponse>(url, {\n\t\t\theaders,\n\t\t\tparams,\n\t\t});\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Get detailed information about a specific GitHub installation\n\t *\n\t * Supports both UUID and short ID formats (e.g., \"GITHUB-1\").\n\t * Returns installation details including all associated repositories.\n\t *\n\t * @param installationId - Installation UUID or short ID (e.g., \"GITHUB-1\")\n\t * @returns Detailed installation information with repositories\n\t * @throws {Error} On API errors (401, 404, 422, 500)\n\t *\n\t * @example\n\t * ```typescript\n\t * // Using short ID\n\t * const installation = await githubService.getInstallation('GITHUB-1');\n\t *\n\t * // Using UUID\n\t * const installation = await githubService.getInstallation('550e8400-e29b-41d4-a716-446655440000');\n\t *\n\t * console.log(installation.repositories);\n\t * ```\n\t */\n\tasync getInstallation(installationId: string): Promise<GitHubInstallationDetail> {\n\t\tconst url = `${this.baseUrl}/api/v1/github/installations/${installationId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<GitHubInstallationDetail>(url, { headers });\n\t\treturn response.data;\n\t}\n}\n","/**\n * Git Installer Utility\n *\n * Automatically installs Git on the user's system using platform-specific package managers:\n * - macOS: Homebrew (if installed) or Xcode Command Line Tools\n * - Windows: winget\n * - Linux: apt/dnf/pacman (auto-detected)\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport chalk from 'chalk';\nimport { isCliInstalled, getCliVersion } from './cli-tools.js';\nimport {\n\tisHomebrewInstalled,\n\tisWingetAvailable,\n\tdetectLinuxPackageManager,\n} from './package-manager-installer.js';\n\nconst execAsync = promisify(exec);\n\nexport interface GitInstallResult {\n\tsuccess: boolean;\n\tmessage: string;\n\tversion?: string;\n}\n\n/**\n * Check if Git is installed\n */\nexport async function isGitInstalled(): Promise<boolean> {\n\treturn isCliInstalled('git');\n}\n\n/**\n * Get Git version if installed\n */\nexport async function getGitVersion(): Promise<string | null> {\n\treturn getCliVersion('git', '--version', output => {\n\t\tconst match = output.match(/git version ([\\d.]+)/);\n\t\treturn match ? match[1] : null;\n\t});\n}\n\n/**\n * Install Git on macOS via Homebrew (when Homebrew is already installed)\n */\nasync function installViaHomebrew(): Promise<GitInstallResult> {\n\tconsole.log(chalk.blue('📦 Installing Git via Homebrew...'));\n\n\ttry {\n\t\tawait execAsync('brew install git', {\n\t\t\ttimeout: 300000, // 5 minutes\n\t\t});\n\n\t\t// Verify installation\n\t\tconst version = await getGitVersion();\n\t\tif (!version) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Git installation completed but git command not found'),\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green(`✅ Git installed successfully (version ${version})!`),\n\t\t\tversion,\n\t\t};\n\t} catch (error: unknown) {\n\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.red('❌ Failed to install Git via Homebrew\\n\\n') +\n\t\t\t\tchalk.dim('Error: ') +\n\t\t\t\terrorMsg +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('Please install Git manually from: ') +\n\t\t\t\tchalk.cyan('https://git-scm.com/download/mac'),\n\t\t};\n\t}\n}\n\n/**\n * Install Git on macOS via Xcode Command Line Tools\n */\nasync function installViaXcodeSelect(): Promise<GitInstallResult> {\n\tconsole.log(chalk.blue('📦 Installing Git via Xcode Command Line Tools...'));\n\tconsole.log(chalk.dim('A system dialog will appear - click \"Install\" to continue.\\n'));\n\n\ttry {\n\t\tawait execAsync('xcode-select --install', {\n\t\t\ttimeout: 600000, // 10 minutes (user interaction required)\n\t\t});\n\n\t\t// Verify installation\n\t\tconst version = await getGitVersion();\n\t\tif (!version) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Git installation completed but git command not found'),\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green(`✅ Git installed successfully (version ${version})!`),\n\t\t\tversion,\n\t\t};\n\t} catch (error: unknown) {\n\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.red('❌ Failed to install Git via Xcode Command Line Tools\\n\\n') +\n\t\t\t\tchalk.dim('Error: ') +\n\t\t\t\terrorMsg +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('Please install Git manually from: ') +\n\t\t\t\tchalk.cyan('https://git-scm.com/download/mac'),\n\t\t};\n\t}\n}\n\n/**\n * Install Git on macOS using best available method\n * Strategy: Use Homebrew if installed, otherwise use xcode-select\n */\nasync function installGitMacOS(): Promise<GitInstallResult> {\n\t// Check if Homebrew is already installed\n\tconst hasHomebrew = await isHomebrewInstalled();\n\n\tif (hasHomebrew) {\n\t\t// User already has Homebrew - use it (fast and familiar)\n\t\treturn installViaHomebrew();\n\t}\n\n\t// No Homebrew - use Xcode Command Line Tools (no need to install Homebrew)\n\treturn installViaXcodeSelect();\n}\n\n/**\n * Install Git on Windows using winget\n */\nasync function installGitWindows(): Promise<GitInstallResult> {\n\t// Check if winget is available\n\tconst hasWinget = await isWingetAvailable();\n\n\tif (!hasWinget) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.red('❌ winget is not available on this system\\n\\n') +\n\t\t\t\tchalk.dim('winget is included in Windows 10 (version 1809+) and Windows 11.\\n') +\n\t\t\t\tchalk.dim('Please install Git manually from: ') +\n\t\t\t\tchalk.cyan('https://git-scm.com/download/win'),\n\t\t};\n\t}\n\n\tconsole.log(chalk.blue('📦 Installing Git via winget...'));\n\n\ttry {\n\t\tawait execAsync('winget install --id Git.Git -e --source winget --silent', {\n\t\t\ttimeout: 300000, // 5 minutes\n\t\t});\n\n\t\t// Verify installation\n\t\tconst version = await getGitVersion();\n\t\tif (!version) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Git installation completed but git command not found'),\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green(`✅ Git installed successfully (version ${version})!`),\n\t\t\tversion,\n\t\t};\n\t} catch (error: unknown) {\n\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.red('❌ Failed to install Git via winget\\n\\n') +\n\t\t\t\tchalk.dim('Error: ') +\n\t\t\t\terrorMsg +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('Please install Git manually from: ') +\n\t\t\t\tchalk.cyan('https://git-scm.com/download/win'),\n\t\t};\n\t}\n}\n\n/**\n * Install Git on Linux using detected package manager\n */\nasync function installGitLinux(): Promise<GitInstallResult> {\n\tconst packageManager = await detectLinuxPackageManager();\n\n\tif (!packageManager) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.red('❌ Could not detect a supported package manager\\n\\n') +\n\t\t\t\tchalk.dim('Supported package managers: apt, dnf, yum, pacman\\n') +\n\t\t\t\tchalk.dim('Please install Git manually from: ') +\n\t\t\t\tchalk.cyan('https://git-scm.com/download/linux'),\n\t\t};\n\t}\n\n\tconsole.log(chalk.blue(`📦 Installing Git via ${packageManager.name}...`));\n\tconsole.log(chalk.dim('This may prompt for your sudo password.\\n'));\n\n\ttry {\n\t\tlet installCommand: string;\n\n\t\tswitch (packageManager.name) {\n\t\t\tcase 'apt':\n\t\t\t\tinstallCommand = 'sudo apt-get update && sudo apt-get install -y git';\n\t\t\t\tbreak;\n\t\t\tcase 'dnf':\n\t\t\t\tinstallCommand = 'sudo dnf install -y git';\n\t\t\t\tbreak;\n\t\t\tcase 'yum':\n\t\t\t\tinstallCommand = 'sudo yum install -y git';\n\t\t\t\tbreak;\n\t\t\tcase 'pacman':\n\t\t\t\tinstallCommand = 'sudo pacman -S --noconfirm git';\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.red(`❌ Unsupported package manager: ${packageManager.name}`),\n\t\t\t\t};\n\t\t}\n\n\t\tawait execAsync(installCommand, {\n\t\t\ttimeout: 300000, // 5 minutes\n\t\t});\n\n\t\t// Verify installation\n\t\tconst version = await getGitVersion();\n\t\tif (!version) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Git installation completed but git command not found'),\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green(`✅ Git installed successfully (version ${version})!`),\n\t\t\tversion,\n\t\t};\n\t} catch (error: unknown) {\n\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.red('❌ Failed to install Git\\n\\n') +\n\t\t\t\tchalk.dim('Error: ') +\n\t\t\t\terrorMsg +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('Please install Git manually from: ') +\n\t\t\t\tchalk.cyan('https://git-scm.com/download/linux'),\n\t\t};\n\t}\n}\n\n/**\n * Install Git on the current platform\n * Auto-detects platform and uses appropriate package manager\n */\nexport async function installGit(): Promise<GitInstallResult> {\n\tconst platform = process.platform;\n\n\tswitch (platform) {\n\t\tcase 'darwin':\n\t\t\treturn installGitMacOS();\n\n\t\tcase 'win32':\n\t\t\treturn installGitWindows();\n\n\t\tcase 'linux':\n\t\t\treturn installGitLinux();\n\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.red(`❌ Unsupported platform: ${platform}\\n\\n`) +\n\t\t\t\t\tchalk.dim('Please install Git manually from: ') +\n\t\t\t\t\tchalk.cyan('https://git-scm.com/downloads'),\n\t\t\t};\n\t}\n}\n\n/**\n * Get manual installation instructions for the current platform\n */\nexport function getManualInstallInstructions(): string {\n\tconst platform = process.platform;\n\n\tswitch (platform) {\n\t\tcase 'darwin':\n\t\t\treturn (\n\t\t\t\tchalk.yellow('📖 Manual Git Installation (macOS)\\n\\n') +\n\t\t\t\tchalk.dim('Option 1 - Xcode Command Line Tools (recommended):\\n') +\n\t\t\t\tchalk.cyan(' xcode-select --install\\n\\n') +\n\t\t\t\tchalk.dim('Option 2 - Homebrew (if you use package managers):\\n') +\n\t\t\t\tchalk.cyan(\n\t\t\t\t\t' /bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\\n'\n\t\t\t\t) +\n\t\t\t\tchalk.cyan(' brew install git\\n\\n') +\n\t\t\t\tchalk.dim('Option 3 - Official installer:\\n') +\n\t\t\t\tchalk.cyan(' Download from: https://git-scm.com/download/mac')\n\t\t\t);\n\n\t\tcase 'win32':\n\t\t\treturn (\n\t\t\t\tchalk.yellow('📖 Manual Git Installation (Windows)\\n\\n') +\n\t\t\t\tchalk.dim('Option 1 - winget (Windows 10+):\\n') +\n\t\t\t\tchalk.cyan(' winget install --id Git.Git -e --source winget\\n\\n') +\n\t\t\t\tchalk.dim('Option 2 - Official installer:\\n') +\n\t\t\t\tchalk.cyan(' Download from: https://git-scm.com/download/win')\n\t\t\t);\n\n\t\tcase 'linux':\n\t\t\treturn (\n\t\t\t\tchalk.yellow('📖 Manual Git Installation (Linux)\\n\\n') +\n\t\t\t\tchalk.dim('Debian/Ubuntu:\\n') +\n\t\t\t\tchalk.cyan(' sudo apt-get update && sudo apt-get install -y git\\n\\n') +\n\t\t\t\tchalk.dim('Fedora/RHEL:\\n') +\n\t\t\t\tchalk.cyan(' sudo dnf install -y git\\n\\n') +\n\t\t\t\tchalk.dim('Arch Linux:\\n') +\n\t\t\t\tchalk.cyan(' sudo pacman -S git\\n\\n') +\n\t\t\t\tchalk.dim('Or download from: ') +\n\t\t\t\tchalk.cyan('https://git-scm.com/download/linux')\n\t\t\t);\n\n\t\tdefault:\n\t\t\treturn (\n\t\t\t\tchalk.yellow('📖 Manual Git Installation\\n\\n') +\n\t\t\t\tchalk.dim('Download from: ') +\n\t\t\t\tchalk.cyan('https://git-scm.com/downloads')\n\t\t\t);\n\t}\n}\n","/**\n * GitHub Repository Utilities\n *\n * Provides functions to automate GitHub repository creation and setup using GitHub CLI.\n * Falls back to manual instructions when automation is not available.\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport path from 'path';\n\nconst execAsync = promisify(exec);\n\nexport interface RepoInfo {\n\towner: string;\n\tname: string;\n\turl: string;\n}\n\n/**\n * Initialize a git repository in the current directory\n */\nexport async function initGitRepo(): Promise<boolean> {\n\ttry {\n\t\tawait execAsync('git init');\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Check if GitHub CLI is authenticated (internal use only)\n */\nasync function isGhAuthenticated(): Promise<boolean> {\n\ttry {\n\t\tawait execAsync('gh auth status');\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Get the current directory name (for suggesting repository name)\n */\nexport function getCurrentDirectoryName(): string {\n\treturn path.basename(process.cwd());\n}\n\n/**\n * Create a GitHub repository using GitHub CLI\n *\n * @param name - Repository name\n * @param isPrivate - Whether the repository should be private\n * @returns Repository information or null if failed\n */\nexport async function createGitHubRepoWithGh(\n\tname: string,\n\tisPrivate: boolean\n): Promise<RepoInfo | null> {\n\ttry {\n\t\tconst visibility = isPrivate ? '--private' : '--public';\n\n\t\t// Create repository with gh CLI\n\t\t// --source=. creates repo from current directory and adds remote\n\t\tconst { stdout } = await execAsync(\n\t\t\t`gh repo create ${name} ${visibility} --source=. --remote=origin`,\n\t\t\t{ timeout: 60000 }\n\t\t);\n\n\t\t// Parse the repository URL from output\n\t\tconst urlMatch = stdout.match(/https:\\/\\/github\\.com\\/([^/]+)\\/([^/\\s]+)/);\n\t\tif (!urlMatch) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\towner: urlMatch[1],\n\t\t\tname: urlMatch[2],\n\t\t\turl: urlMatch[0],\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Check if we can use GitHub CLI automation\n * (both GitHub CLI installed and authenticated)\n */\nexport async function canUseGhAutomation(): Promise<boolean> {\n\tconst { isGhInstalled } = await import('./gh-installer.js');\n\tconst ghInstalled = await isGhInstalled();\n\n\tif (!ghInstalled) {\n\t\treturn false;\n\t}\n\n\treturn isGhAuthenticated();\n}\n","/**\n * Update Handler\n *\n * Handles the update command which:\n * - Detects which package manager was used to install the CLI\n * - Checks for available updates\n * - Updates the CLI to the latest version\n */\n\nimport chalk from 'chalk';\nimport axios from 'axios';\nimport { detectPackageManager, executeUpdate, getUpdateCommand } from '../utils/package-manager.js';\nimport { formatError } from '../utils/error-formatter.js';\nimport { CLI_VERSION } from '../build-config.js';\nimport type { HandlerResult } from './types.js';\n\nconst PACKAGE_NAME = '@braingrid/cli';\nconst NPM_REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}`;\n\n/**\n * Get the current version of the CLI from build config\n * Version is injected at build time from package.json\n */\nfunction getCurrentVersion(): string {\n\treturn CLI_VERSION;\n}\n\n/**\n * Get the latest version from npm registry\n */\nasync function getLatestVersion(): Promise<string> {\n\ttry {\n\t\tconst response = await axios.get(NPM_REGISTRY_URL, {\n\t\t\ttimeout: 10000,\n\t\t});\n\n\t\treturn response.data['dist-tags'].latest;\n\t} catch (error) {\n\t\tthrow new Error(`Failed to fetch latest version: ${formatError(error)}`);\n\t}\n}\n\n/**\n * Compare two semver versions\n * Returns: -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2\n */\nfunction compareVersions(v1: string, v2: string): number {\n\tconst v1Parts = v1.split('.').map(Number);\n\tconst v2Parts = v2.split('.').map(Number);\n\n\tfor (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {\n\t\tconst v1Part = v1Parts[i] || 0;\n\t\tconst v2Part = v2Parts[i] || 0;\n\n\t\tif (v1Part < v2Part) return -1;\n\t\tif (v1Part > v2Part) return 1;\n\t}\n\n\treturn 0;\n}\n\n/**\n * Handle the update command\n */\nexport async function handleUpdate(opts: { check?: boolean }): Promise<HandlerResult> {\n\ttry {\n\t\tconst currentVersion = getCurrentVersion();\n\t\tlet output = chalk.bold.cyan('\\n🔄 BrainGrid CLI Update\\n\\n');\n\n\t\toutput += `${chalk.bold('Current version:')} ${currentVersion}\\n`;\n\n\t\t// Check for latest version\n\t\toutput += chalk.dim('Checking for updates...\\n');\n\t\tconst latestVersion = await getLatestVersion();\n\t\toutput += `${chalk.bold('Latest version:')} ${latestVersion}\\n\\n`;\n\n\t\t// Compare versions\n\t\tconst comparison = compareVersions(currentVersion, latestVersion);\n\n\t\tif (comparison === 0) {\n\t\t\toutput += chalk.green('✅ You are already on the latest version!\\n');\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: output,\n\t\t\t\tdata: { currentVersion, latestVersion, upToDate: true },\n\t\t\t};\n\t\t}\n\n\t\tif (comparison > 0) {\n\t\t\toutput += chalk.yellow('⚠️ You are on a newer version than what is published.\\n');\n\t\t\toutput += chalk.dim(' This is expected if you are developing locally.\\n');\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: output,\n\t\t\t\tdata: { currentVersion, latestVersion, upToDate: false },\n\t\t\t};\n\t\t}\n\n\t\t// Update available\n\t\toutput += chalk.yellow(`⬆️ Update available: ${currentVersion} → ${latestVersion}\\n\\n`);\n\n\t\t// If --check flag, just show the info and exit\n\t\tif (opts.check) {\n\t\t\toutput += chalk.dim('Run ') + chalk.cyan('braingrid update') + chalk.dim(' to update\\n');\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: output,\n\t\t\t\tdata: { currentVersion, latestVersion, upToDate: false },\n\t\t\t};\n\t\t}\n\n\t\t// Detect package manager\n\t\toutput += chalk.dim('Detecting package manager...\\n');\n\t\tconst packageManager = await detectPackageManager(PACKAGE_NAME);\n\t\toutput += `${chalk.bold('Package manager:')} ${packageManager}\\n\\n`;\n\n\t\t// Show update command\n\t\tconst updateCommand = getUpdateCommand(packageManager, PACKAGE_NAME);\n\t\toutput += chalk.dim('Running: ') + chalk.cyan(updateCommand) + '\\n\\n';\n\n\t\tconsole.log(output);\n\n\t\t// Execute update\n\t\texecuteUpdate(packageManager, PACKAGE_NAME);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green('\\n✅ Successfully updated BrainGrid CLI!\\n'),\n\t\t\tdata: { currentVersion, latestVersion, packageManager },\n\t\t};\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error),\n\t\t};\n\t}\n}\n","/**\n * Package Manager Detection Utility\n *\n * Detects which package manager (npm, pnpm, yarn) was used to install the CLI\n * by checking global installation directories.\n */\n\nimport { execSync } from 'child_process';\nimport { select } from '@inquirer/prompts';\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn';\n\ninterface PackageManagerInfo {\n\tname: PackageManager;\n\tinstalled: boolean;\n\thasPackage: boolean;\n}\n\n/**\n * Check if a package manager is installed on the system\n */\nfunction isPackageManagerInstalled(pm: PackageManager): boolean {\n\ttry {\n\t\texecSync(`which ${pm}`, { stdio: 'ignore', timeout: 2000 });\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Check if the CLI package is installed globally with a specific package manager\n */\nfunction checkGlobalInstallation(pm: PackageManager, packageName: string): boolean {\n\ttry {\n\t\tlet command: string;\n\n\t\tswitch (pm) {\n\t\t\tcase 'npm': {\n\t\t\t\tcommand = `npm list -g ${packageName} 2>&1`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'pnpm': {\n\t\t\t\tcommand = `pnpm list -g ${packageName} 2>&1`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'yarn': {\n\t\t\t\tcommand = `yarn global list 2>&1`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tconst output = execSync(command, {\n\t\t\tencoding: 'utf-8',\n\t\t\ttimeout: 5000,\n\t\t});\n\n\t\t// For npm and pnpm, check if output contains the package name and not \"(empty)\"\n\t\tif (pm === 'npm' || pm === 'pnpm') {\n\t\t\treturn output.includes(packageName) && !output.includes('(empty)');\n\t\t}\n\n\t\t// For yarn, check if package is in the list\n\t\tif (pm === 'yarn') {\n\t\t\treturn output.includes(packageName);\n\t\t}\n\n\t\treturn false;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Get information about available package managers and whether they have the CLI installed\n */\nexport async function getPackageManagerInfo(packageName: string): Promise<PackageManagerInfo[]> {\n\tconst packageManagers: PackageManager[] = ['npm', 'pnpm', 'yarn'];\n\n\treturn packageManagers.map(pm => {\n\t\tconst installed = isPackageManagerInstalled(pm);\n\t\treturn {\n\t\t\tname: pm,\n\t\t\tinstalled,\n\t\t\thasPackage: installed ? checkGlobalInstallation(pm, packageName) : false,\n\t\t};\n\t});\n}\n\n/**\n * Detect which package manager was used to install the CLI\n * Returns the detected package manager or prompts the user if detection fails\n */\nexport async function detectPackageManager(packageName: string): Promise<PackageManager> {\n\tconst pmInfo = await getPackageManagerInfo(packageName);\n\n\t// First, check if any package manager has the package installed\n\tconst installedWith = pmInfo.find(pm => pm.hasPackage);\n\n\tif (installedWith) {\n\t\treturn installedWith.name;\n\t}\n\n\t// If detection failed, check which package managers are available and prompt\n\tconst availablePMs = pmInfo.filter(pm => pm.installed);\n\n\tif (availablePMs.length === 0) {\n\t\tthrow new Error('No package manager found. Please install npm, pnpm, or yarn.');\n\t}\n\n\tif (availablePMs.length === 1) {\n\t\treturn availablePMs[0].name;\n\t}\n\n\t// Multiple package managers available, prompt user\n\tconst selected = await select({\n\t\tmessage: 'Unable to detect which package manager was used. Please select one:',\n\t\tchoices: availablePMs.map(pm => ({\n\t\t\tname: pm.name,\n\t\t\tvalue: pm.name,\n\t\t})),\n\t});\n\n\treturn selected as PackageManager;\n}\n\n/**\n * Get the update command for a specific package manager\n */\nexport function getUpdateCommand(pm: PackageManager, packageName: string): string {\n\tswitch (pm) {\n\t\tcase 'npm': {\n\t\t\treturn `npm install -g ${packageName}@latest`;\n\t\t}\n\t\tcase 'pnpm': {\n\t\t\treturn `pnpm add -g ${packageName}@latest`;\n\t\t}\n\t\tcase 'yarn': {\n\t\t\treturn `yarn global add ${packageName}@latest`;\n\t\t}\n\t}\n}\n\n/**\n * Execute the update command\n */\nexport function executeUpdate(pm: PackageManager, packageName: string): void {\n\tconst command = getUpdateCommand(pm, packageName);\n\n\ttry {\n\t\texecSync(command, {\n\t\t\tstdio: 'inherit',\n\t\t\ttimeout: 120000, // 2 minutes timeout\n\t\t});\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to update package: ${error instanceof Error ? error.message : String(error)}`\n\t\t);\n\t}\n}\n","/**\n * Setup Resource Handlers\n *\n * Handles setup commands for IDE integrations:\n * - setup claude-code: Install Claude Code integration files\n * - setup cursor: Install Cursor integration files\n */\n\nimport chalk from 'chalk';\nimport { select } from '@inquirer/prompts';\nimport * as path from 'path';\nimport * as fs from 'fs/promises';\nimport { execAsync } from '../utils/command-execution.js';\nimport {\n\tfetchFileFromGitHub,\n\tlistGitHubDirectory,\n\tcopyFileFromGitHub,\n\tinjectContentIntoFile,\n\tinstallStatusLineScript,\n\tupdateClaudeSettings,\n} from '../services/setup-service.js';\nimport type { HandlerResult } from './types.js';\n\nexport interface SetupOptions {\n\tforce?: boolean;\n\tdryRun?: boolean;\n}\n\ninterface FileOperation {\n\ttype: 'copy' | 'inject';\n\tsourcePath: string;\n\ttargetPath: string;\n\texists: boolean;\n}\n\ninterface SetupIntegrationConfig {\n\tname: string;\n\tsourceDirs: string[];\n\ttargetDirs: string[];\n\tinjection: {\n\t\tsourceFile: string;\n\t\ttargetFile: string;\n\t};\n\tdocsUrl: string;\n}\n\n/**\n * Check if a file exists at the given path\n */\nasync function fileExists(filePath: string): Promise<boolean> {\n\ttry {\n\t\tawait fs.access(filePath);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Check if GitHub CLI is installed and user is authenticated\n */\nasync function checkPrerequisites(): Promise<HandlerResult | null> {\n\t// Check if GitHub CLI is installed\n\ttry {\n\t\tawait execAsync('gh --version');\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.red('❌ GitHub CLI is not installed.\\n\\n') +\n\t\t\t\tchalk.dim('Install instructions:\\n') +\n\t\t\t\tchalk.dim(' macOS: ') +\n\t\t\t\tchalk.cyan('brew install gh') +\n\t\t\t\tchalk.dim('\\n') +\n\t\t\t\tchalk.dim(' Windows: ') +\n\t\t\t\tchalk.cyan('winget install GitHub.CLI') +\n\t\t\t\tchalk.dim('\\n') +\n\t\t\t\tchalk.dim(' Linux: See ') +\n\t\t\t\tchalk.cyan('https://cli.github.com/manual/installation') +\n\t\t\t\tchalk.dim('\\n\\n') +\n\t\t\t\tchalk.dim('After installing, run: ') +\n\t\t\t\tchalk.cyan('gh auth login'),\n\t\t};\n\t}\n\n\t// Check if user is authenticated\n\ttry {\n\t\tawait execAsync('gh auth status');\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.red('❌ Not authenticated with GitHub CLI.\\n\\n') +\n\t\t\t\tchalk.dim('Please run: ') +\n\t\t\t\tchalk.cyan('gh auth login'),\n\t\t};\n\t}\n\n\treturn null;\n}\n\n/**\n * Get list of files to be installed\n */\nasync function getFileList(sourcePaths: string[], targetPaths: string[]): Promise<FileOperation[]> {\n\tconst operations: FileOperation[] = [];\n\n\tfor (let i = 0; i < sourcePaths.length; i++) {\n\t\tconst sourcePath = sourcePaths[i];\n\t\tconst targetPath = targetPaths[i];\n\n\t\ttry {\n\t\t\tconst items = await listGitHubDirectory(sourcePath);\n\n\t\t\t// Add file operations for each item\n\t\t\tfor (const item of items) {\n\t\t\t\tif (item.type === 'file') {\n\t\t\t\t\tconst itemTargetPath = path.join(targetPath, item.name);\n\t\t\t\t\tconst exists = await fileExists(itemTargetPath);\n\n\t\t\t\t\toperations.push({\n\t\t\t\t\t\ttype: 'copy',\n\t\t\t\t\t\tsourcePath: item.path,\n\t\t\t\t\t\ttargetPath: itemTargetPath,\n\t\t\t\t\t\texists,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// If directory doesn't exist in repo, skip it\n\t\t\tconsole.warn(\n\t\t\t\tchalk.yellow(`⚠️ Could not list directory: ${sourcePath}`),\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t);\n\t\t}\n\t}\n\n\treturn operations;\n}\n\n/**\n * Display installation plan\n */\nfunction displayInstallationPlan(operations: FileOperation[], injectionFile: string): void {\n\tconsole.log(chalk.bold('\\n📋 Installation Plan:\\n'));\n\n\t// Show injection\n\tconsole.log(chalk.cyan(' Content Injection:'));\n\tconsole.log(chalk.dim(` ${injectionFile}`));\n\n\t// Show file copies\n\tconst newFiles = operations.filter(op => !op.exists);\n\tconst existingFiles = operations.filter(op => op.exists);\n\n\tif (newFiles.length > 0) {\n\t\tconsole.log(chalk.cyan('\\n New Files:'));\n\t\tfor (const op of newFiles) {\n\t\t\tconsole.log(chalk.dim(` ${op.targetPath}`));\n\t\t}\n\t}\n\n\tif (existingFiles.length > 0) {\n\t\tconsole.log(chalk.yellow('\\n Existing Files (will prompt):'));\n\t\tfor (const op of existingFiles) {\n\t\t\tconsole.log(chalk.dim(` ${op.targetPath}`));\n\t\t}\n\t}\n\n\tconsole.log('');\n}\n\n/**\n * Prompt user for file conflict resolution\n */\nasync function promptForConflict(filePath: string): Promise<'overwrite' | 'skip' | 'all' | 'quit'> {\n\tconst answer = await select({\n\t\tmessage: chalk.yellow(`File exists: ${filePath}`),\n\t\tchoices: [\n\t\t\t{ name: '[O]verwrite - Replace this file', value: 'overwrite' },\n\t\t\t{ name: '[S]kip - Keep existing file', value: 'skip' },\n\t\t\t{ name: '[A]ll - Overwrite all remaining', value: 'all' },\n\t\t\t{ name: '[Q]uit - Cancel installation', value: 'quit' },\n\t\t],\n\t});\n\n\treturn answer as 'overwrite' | 'skip' | 'all' | 'quit';\n}\n\n/**\n * Execute file installation\n */\nasync function installFiles(\n\toperations: FileOperation[],\n\tforce: boolean\n): Promise<{ installed: number; skipped: number; cancelled: boolean }> {\n\tlet installed = 0;\n\tlet skipped = 0;\n\tlet overwriteAll = force;\n\n\tfor (const operation of operations) {\n\t\t// Handle file conflicts\n\t\tif (operation.exists && !overwriteAll) {\n\t\t\tconst response = await promptForConflict(operation.targetPath);\n\n\t\t\tif (response === 'quit') {\n\t\t\t\treturn { installed, skipped, cancelled: true };\n\t\t\t} else if (response === 'skip') {\n\t\t\t\tskipped++;\n\t\t\t\tcontinue;\n\t\t\t} else if (response === 'all') {\n\t\t\t\toverwriteAll = true;\n\t\t\t}\n\t\t}\n\n\t\t// Copy file\n\t\ttry {\n\t\t\tawait copyFileFromGitHub(operation.sourcePath, operation.targetPath);\n\t\t\tinstalled++;\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\tchalk.red(`Failed to copy ${operation.targetPath}:`),\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t);\n\t\t\tskipped++;\n\t\t}\n\t}\n\n\treturn { installed, skipped, cancelled: false };\n}\n\n/**\n * Generic setup handler for IDE integrations\n * @private\n */\nasync function _handleSetup(\n\tconfig: SetupIntegrationConfig,\n\topts: SetupOptions\n): Promise<HandlerResult> {\n\ttry {\n\t\t// Check prerequisites\n\t\tconst prerequisiteError = await checkPrerequisites();\n\t\tif (prerequisiteError) {\n\t\t\treturn prerequisiteError;\n\t\t}\n\n\t\tconsole.log(chalk.bold(`🚀 Setting up ${config.name} integration...\\n`));\n\n\t\t// Get file list\n\t\tconst operations = await getFileList(config.sourceDirs, config.targetDirs);\n\n\t\t// Add injection operation\n\t\tconst injectionFileExists = await fileExists(config.injection.targetFile);\n\n\t\toperations.push({\n\t\t\ttype: 'inject',\n\t\t\tsourcePath: config.injection.sourceFile,\n\t\t\ttargetPath: config.injection.targetFile,\n\t\t\texists: injectionFileExists,\n\t\t});\n\n\t\t// Display installation plan\n\t\tdisplayInstallationPlan(\n\t\t\toperations.filter(op => op.type === 'copy'),\n\t\t\tconfig.injection.targetFile\n\t\t);\n\n\t\t// Dry-run mode\n\t\tif (opts.dryRun) {\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.green('✅ Dry-run complete. No files were modified.\\n\\n') +\n\t\t\t\t\tchalk.dim(`Would install ${operations.length} files.`),\n\t\t\t};\n\t\t}\n\n\t\t// Install files\n\t\tconst copyOps = operations.filter(op => op.type === 'copy');\n\t\tconst result = await installFiles(copyOps, opts.force || false);\n\n\t\tif (result.cancelled) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.yellow('⚠️ Installation cancelled.\\n\\n') +\n\t\t\t\t\tchalk.dim(`Installed: ${result.installed}, Skipped: ${result.skipped}`),\n\t\t\t\tcode: 'CANCELLED',\n\t\t\t};\n\t\t}\n\n\t\t// Inject content into target file\n\t\ttry {\n\t\t\tconst content = await fetchFileFromGitHub(config.injection.sourceFile);\n\t\t\tawait injectContentIntoFile(config.injection.targetFile, content);\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\tchalk.red(`Failed to inject content into ${config.injection.targetFile}:`),\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t);\n\t\t}\n\n\t\t// Install status line script (Claude Code only)\n\t\tlet statusLineInstalled = false;\n\t\tif (config.name === 'Claude Code') {\n\t\t\ttry {\n\t\t\t\t// Fetch status line script from GitHub (like other files)\n\t\t\t\tconst scriptContent = await fetchFileFromGitHub('claude-code/statusline.sh');\n\t\t\t\tawait installStatusLineScript(scriptContent);\n\t\t\t\tawait updateClaudeSettings();\n\t\t\t\tstatusLineInstalled = true;\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\tchalk.yellow('⚠️ Failed to install status line script:'),\n\t\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Success message\n\t\tconst statusLineMessage = statusLineInstalled\n\t\t\t? chalk.dim(' Status line: .claude/statusline.sh\\n')\n\t\t\t: '';\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage:\n\t\t\t\tchalk.green(`✅ ${config.name} integration installed successfully!\\n\\n`) +\n\t\t\t\tchalk.dim('Files installed:\\n') +\n\t\t\t\tchalk.dim(` Commands: ${result.installed} files\\n`) +\n\t\t\t\tstatusLineMessage +\n\t\t\t\tchalk.dim(` Content injected into: ${config.injection.targetFile}\\n\\n`) +\n\t\t\t\tchalk.dim('Next steps:\\n') +\n\t\t\t\tchalk.dim(' 1. Review the integration files\\n') +\n\t\t\t\tchalk.dim(` 2. Open ${config.name}\\n`) +\n\t\t\t\tchalk.dim(' 3. Try the /specify or /breakdown commands\\n') +\n\t\t\t\tchalk.dim(' 4. Learn more: ') +\n\t\t\t\tchalk.cyan(config.docsUrl),\n\t\t};\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: chalk.red(`❌ Setup failed: ${errorMessage}`),\n\t\t};\n\t}\n}\n\n/**\n * Handle Claude Code setup\n */\nexport async function handleSetupClaudeCode(opts: SetupOptions): Promise<HandlerResult> {\n\tconst config: SetupIntegrationConfig = {\n\t\tname: 'Claude Code',\n\t\tsourceDirs: ['claude-code/commands', 'claude-code/skills'],\n\t\ttargetDirs: ['.claude/commands', '.claude/skills/braingrid-cli'],\n\t\tinjection: {\n\t\t\tsourceFile: 'claude-code/CLAUDE.md',\n\t\t\ttargetFile: 'CLAUDE.md',\n\t\t},\n\t\tdocsUrl: 'https://braingrid.ai/docs/claude-code',\n\t};\n\n\treturn _handleSetup(config, opts);\n}\n\n/**\n * Handle Cursor setup\n */\nexport async function handleSetupCursor(opts: SetupOptions): Promise<HandlerResult> {\n\tconst config: SetupIntegrationConfig = {\n\t\tname: 'Cursor',\n\t\tsourceDirs: ['cursor/commands', 'cursor/rules'],\n\t\ttargetDirs: ['.cursor/commands', '.cursor/rules'],\n\t\tinjection: {\n\t\t\tsourceFile: 'cursor/AGENTS.md',\n\t\t\ttargetFile: 'AGENTS.md',\n\t\t},\n\t\tdocsUrl: 'https://braingrid.ai/docs/cursor',\n\t};\n\n\treturn _handleSetup(config, opts);\n}\n","import { exec, spawn } from 'child_process';\nimport { promisify } from 'util';\n\nexport interface ExecResult {\n\tstdout: string;\n\tstderr: string;\n}\n\nexport interface ExecOptions {\n\tmaxBuffer?: number;\n\ttimeout?: number;\n\tcwd?: string;\n\tenv?: NodeJS.ProcessEnv;\n}\n\nconst execAsyncReal = promisify(exec);\n\n/**\n * Execute a command asynchronously with proper buffer limits and timeout handling\n */\nexport async function execAsync(\n\tcommand: string,\n\toptions?: ExecOptions,\n\tisTestMode: boolean = false,\n\tmockExecHandler?: (command: string) => Promise<ExecResult>\n): Promise<ExecResult> {\n\tif (isTestMode && mockExecHandler) {\n\t\treturn mockExecHandler(command);\n\t}\n\n\t// Set appropriate buffer limits based on command type\n\tconst defaultOptions: ExecOptions = {\n\t\tmaxBuffer: 1024 * 1024 * 10, // 10MB default\n\t\ttimeout: 300000, // 5 minutes\n\t\t...options,\n\t};\n\n\t// Increase buffer for Claude commands that may produce large outputs\n\tif (command.includes('claude')) {\n\t\tdefaultOptions.maxBuffer = 1024 * 1024 * 50; // 50MB for Claude commands\n\t\tdefaultOptions.timeout = 600000; // 10 minutes for Claude\n\t}\n\n\treturn execAsyncReal(command, defaultOptions);\n}\n\n/**\n * Execute a command with streaming output support\n */\nexport async function execStreamAsync(\n\tcommand: string,\n\tonOutput?: (chunk: string) => void,\n\tisTestMode: boolean = false,\n\tmockExecHandler?: (command: string) => Promise<ExecResult>,\n\toptions?: {\n\t\ttimeout?: number;\n\t\tinactivityTimeout?: number;\n\t}\n): Promise<ExecResult> {\n\tif (isTestMode && mockExecHandler) {\n\t\t// For test mode, simulate streaming\n\t\tconst result = await mockExecHandler(command);\n\t\tif (onOutput) {\n\t\t\t// Simulate streaming by sending output in chunks\n\t\t\tconst lines = result.stdout.split('\\n');\n\t\t\tfor (const line of lines) {\n\t\t\t\tif (line.trim()) {\n\t\t\t\t\tonOutput(line + '\\n');\n\t\t\t\t\tawait new Promise(resolve => setTimeout(resolve, 200));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\treturn new Promise((resolve, reject) => {\n\t\t// Parse command to handle quotes properly\n\t\tlet cmd: string;\n\t\tlet args: string[];\n\n\t\tif (command.startsWith('claude -p --dangerously-skip-permissions \"')) {\n\t\t\tcmd = 'claude';\n\t\t\t// Extract the quoted content for non-interactive mode with skip permissions\n\t\t\tconst promptMatch = command.match(/^claude -p --dangerously-skip-permissions \"(.*)\"/s);\n\t\t\targs = promptMatch ? ['-p', '--dangerously-skip-permissions', promptMatch[1]] : [];\n\t\t} else if (command.startsWith('claude -p \"')) {\n\t\t\tcmd = 'claude';\n\t\t\t// Extract the quoted content for non-interactive mode\n\t\t\tconst promptMatch = command.match(/^claude -p \"(.*)\"/s);\n\t\t\targs = promptMatch ? ['-p', promptMatch[1]] : [];\n\t\t} else if (command.startsWith('claude \"')) {\n\t\t\tcmd = 'claude';\n\t\t\t// Extract the quoted content for interactive mode\n\t\t\tconst promptMatch = command.match(/^claude \"(.*)\"/s);\n\t\t\targs = promptMatch ? [promptMatch[1]] : [];\n\t\t} else if (command.startsWith('git commit')) {\n\t\t\t// Special handling for git commit to properly parse the message\n\t\t\tconst parts = command.match(/^git\\s+commit\\s+(.*)$/);\n\t\t\tif (parts && parts[1]) {\n\t\t\t\tcmd = 'git';\n\t\t\t\targs = ['commit'];\n\t\t\t\t// Parse the rest of the arguments, handling -m \"message\" properly\n\t\t\t\tconst argString = parts[1];\n\t\t\t\tconst messageMatch = argString.match(/-m\\s+\"([^\"]+)\"/);\n\t\t\t\tif (messageMatch) {\n\t\t\t\t\targs.push('-m', messageMatch[1]);\n\t\t\t\t\t// Add any other arguments that might be before or after -m\n\t\t\t\t\tconst beforeMessage = argString.substring(0, argString.indexOf('-m')).trim();\n\t\t\t\t\tconst afterMessage = argString\n\t\t\t\t\t\t.substring(argString.indexOf(messageMatch[0]) + messageMatch[0].length)\n\t\t\t\t\t\t.trim();\n\t\t\t\t\tif (beforeMessage) args.unshift(...beforeMessage.split(' '));\n\t\t\t\t\tif (afterMessage) args.push(...afterMessage.split(' '));\n\t\t\t\t} else {\n\t\t\t\t\targs.push(...argString.split(' '));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t[cmd, ...args] = command.split(' ');\n\t\t\t}\n\t\t} else {\n\t\t\t// Simple command splitting for other commands\n\t\t\t[cmd, ...args] = command.split(' ');\n\t\t}\n\n\t\tconst child = spawn(cmd, args, {\n\t\t\tshell: false,\n\t\t\tstdio: ['inherit', 'pipe', 'pipe'],\n\t\t});\n\n\t\tlet stdout = '';\n\t\tlet stderr = '';\n\n\t\t// Smart timeout handling\n\t\tconst isGitCommit = cmd === 'git' && args[0] === 'commit';\n\t\tconst maxTimeout = options?.timeout || (isGitCommit ? 900000 : 300000); // 15 min for git commit, 5 min default\n\t\tconst inactivityTimeout = options?.inactivityTimeout || (isGitCommit ? 60000 : 30000); // 60s for git commit, 30s default\n\n\t\tlet globalTimeoutId: NodeJS.Timeout | null = null;\n\t\tlet inactivityTimeoutId: NodeJS.Timeout | null = null;\n\n\t\tconst clearTimeouts = () => {\n\t\t\tif (globalTimeoutId) clearTimeout(globalTimeoutId);\n\t\t\tif (inactivityTimeoutId) clearTimeout(inactivityTimeoutId);\n\t\t};\n\n\t\tconst resetInactivityTimeout = () => {\n\t\t\tif (inactivityTimeoutId) clearTimeout(inactivityTimeoutId);\n\n\t\t\tinactivityTimeoutId = setTimeout(() => {\n\t\t\t\tclearTimeouts();\n\t\t\t\tchild.kill('SIGTERM');\n\t\t\t\treject(new Error(`Command timed out due to ${inactivityTimeout / 1000}s of inactivity`));\n\t\t\t}, inactivityTimeout);\n\t\t};\n\n\t\t// Set global timeout\n\t\tglobalTimeoutId = setTimeout(() => {\n\t\t\tclearTimeouts();\n\t\t\tchild.kill('SIGTERM');\n\t\t\treject(new Error(`Command exceeded maximum timeout of ${maxTimeout / 1000}s`));\n\t\t}, maxTimeout);\n\n\t\t// Start inactivity timeout\n\t\tresetInactivityTimeout();\n\n\t\tchild.stdout?.on('data', data => {\n\t\t\tconst chunk = data.toString();\n\t\t\tstdout += chunk;\n\t\t\tif (onOutput) {\n\t\t\t\tonOutput(chunk);\n\t\t\t}\n\t\t\t// Reset inactivity timeout on any output\n\t\t\tresetInactivityTimeout();\n\t\t});\n\n\t\tchild.stderr?.on('data', data => {\n\t\t\tconst chunk = data.toString();\n\t\t\tstderr += chunk;\n\t\t\tif (onOutput) {\n\t\t\t\tonOutput(chunk);\n\t\t\t}\n\t\t\t// Reset inactivity timeout on any output (pre-commit hooks often write to stderr)\n\t\t\tresetInactivityTimeout();\n\t\t});\n\n\t\tchild.on('close', code => {\n\t\t\tclearTimeouts();\n\t\t\tif (code === 0) {\n\t\t\t\tresolve({ stdout, stderr });\n\t\t\t} else {\n\t\t\t\treject(new Error(`Command failed with exit code ${code}: ${stderr}`));\n\t\t\t}\n\t\t});\n\n\t\tchild.on('error', error => {\n\t\t\tclearTimeouts();\n\t\t\treject(error);\n\t\t});\n\t});\n}\n\n/**\n * Mock execution handler for testing\n */\nexport async function createMockExecHandler(\n\taddMessage?: (type: 'info' | 'error' | 'system', content: string) => void\n): Promise<(command: string) => Promise<ExecResult>> {\n\treturn async (command: string): Promise<ExecResult> => {\n\t\tif (addMessage) {\n\t\t\taddMessage('info', `🧪 TEST MODE: Simulating command: ${command}`);\n\t\t}\n\n\t\t// Simulate delays\n\t\tawait new Promise(resolve => setTimeout(resolve, 500));\n\n\t\t// Git commands\n\t\tif (command.includes('git branch --show-current')) {\n\t\t\treturn { stdout: 'feature/test-branch', stderr: '' };\n\t\t}\n\t\tif (command.includes('gh repo view')) {\n\t\t\treturn { stdout: 'main', stderr: '' };\n\t\t}\n\t\tif (command.includes('git checkout -b')) {\n\t\t\tconst branchName = command.split(' ').pop();\n\t\t\treturn { stdout: `Switched to a new branch '${branchName}'`, stderr: '' };\n\t\t}\n\t\tif (command.includes('git checkout main')) {\n\t\t\treturn { stdout: 'Switched to branch main', stderr: '' };\n\t\t}\n\t\tif (command.includes('git pull')) {\n\t\t\treturn { stdout: 'Already up to date.', stderr: '' };\n\t\t}\n\t\tif (command.includes('git add .')) {\n\t\t\treturn { stdout: '', stderr: '' };\n\t\t}\n\t\tif (command.includes('git diff --cached --quiet')) {\n\t\t\tthrow new Error('Changes to commit'); // Simulate changes exist\n\t\t}\n\t\tif (command.includes('git commit')) {\n\t\t\treturn { stdout: '[feature/test abc123] feat: mock commit', stderr: '' };\n\t\t}\n\t\tif (command.includes('git push')) {\n\t\t\tconst branchName = command.includes('feature/') ? 'feature/test-branch' : 'current-branch';\n\t\t\treturn {\n\t\t\t\tstdout: `To github.com:test/repo.git\\n * [new branch] ${branchName} -> ${branchName}\\nBranch '${branchName}' set up to track remote branch '${branchName}' from 'origin'.`,\n\t\t\t\tstderr: '',\n\t\t\t};\n\t\t}\n\n\t\t// CLI version checks\n\t\tif (command.includes('claude --version')) {\n\t\t\treturn { stdout: 'claude version 2.1.3', stderr: '' };\n\t\t}\n\t\tif (command.includes('gh --version')) {\n\t\t\treturn { stdout: 'gh version 2.40.1', stderr: '' };\n\t\t}\n\n\t\t// GitHub commands\n\t\tif (command.includes('gh pr create')) {\n\t\t\treturn { stdout: 'https://github.com/test/repo/pull/123', stderr: '' };\n\t\t}\n\n\t\t// Claude commands\n\t\tif (command.includes('Generate a conventional commit')) {\n\t\t\tconst taskTitle = command.includes('login')\n\t\t\t\t? 'login component'\n\t\t\t\t: command.includes('JWT')\n\t\t\t\t\t? 'JWT authentication'\n\t\t\t\t\t: command.includes('logout')\n\t\t\t\t\t\t? 'logout functionality'\n\t\t\t\t\t\t: 'test feature';\n\t\t\treturn { stdout: `feat(auth): add ${taskTitle}`, stderr: '' };\n\t\t}\n\t\tif (command.includes('Generate a comprehensive GitHub Pull Request')) {\n\t\t\treturn {\n\t\t\t\tstdout: `## Summary\\nImplemented mock authentication system with all required functionality.\\n\\n## Tasks Completed\\n- [x] Mock login component\\n- [x] Mock JWT authentication\\n- [x] Mock logout functionality\\n\\n## Testing\\nTest the mock implementation thoroughly.\\n\\n## Notes\\nThis is a test implementation.`,\n\t\t\t\tstderr: '',\n\t\t\t};\n\t\t}\n\t\tif (\n\t\t\tcommand.startsWith('claude -p --dangerously-skip-permissions \"') ||\n\t\t\tcommand.startsWith('claude -p \"') ||\n\t\t\tcommand.startsWith('claude \"')\n\t\t) {\n\t\t\t// Handle task content and other prompts\n\t\t\tconst taskTitle = command.includes('login')\n\t\t\t\t? 'Login Component'\n\t\t\t\t: command.includes('JWT')\n\t\t\t\t\t? 'JWT Authentication'\n\t\t\t\t\t: command.includes('logout')\n\t\t\t\t\t\t? 'Logout Functionality'\n\t\t\t\t\t\t: 'Test Feature';\n\t\t\treturn {\n\t\t\t\tstdout: `# ${taskTitle} Implementation\\n\\n## Files Created/Modified\\n- src/components/auth/${taskTitle.replace(' ', '')}.tsx\\n- src/hooks/useAuth.ts\\n- src/utils/auth.ts\\n\\n## Implementation Details\\nCreated comprehensive ${taskTitle.toLowerCase()} with modern React patterns, TypeScript support, and proper error handling.\\n\\n## Testing\\nAdded unit tests and integration tests for the ${taskTitle.toLowerCase()}.`,\n\t\t\t\tstderr: '',\n\t\t\t};\n\t\t}\n\n\t\t// Default response\n\t\treturn { stdout: 'Mock command executed successfully', stderr: '' };\n\t};\n}\n","import { execAsync } from '../utils/command-execution.js';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\n\nconst GITHUB_OWNER = 'BrainGridAI';\nconst GITHUB_REPO = 'braingrid';\nconst MAX_RETRIES = 3;\nconst INITIAL_RETRY_DELAY = 100;\n\n// Content injection markers\nconst BEGIN_MARKER = '<!-- BEGIN BRAINGRID INTEGRATION -->';\nconst END_MARKER = '<!-- END BRAINGRID INTEGRATION -->';\n\nexport interface GitHubFile {\n\tname: string;\n\ttype: 'file' | 'dir';\n\tpath: string;\n}\n\ninterface GitHubApiFileResponse {\n\tname: string;\n\tpath: string;\n\ttype: 'file' | 'dir';\n\tcontent?: string;\n\tencoding?: string;\n}\n\ninterface GitHubApiError {\n\tmessage: string;\n\tdocumentation_url?: string;\n}\n\n/**\n * Retry a function with exponential backoff\n */\nasync function withRetry<T>(\n\tfn: () => Promise<T>,\n\tretries: number = MAX_RETRIES,\n\tdelay: number = INITIAL_RETRY_DELAY\n): Promise<T> {\n\ttry {\n\t\treturn await fn();\n\t} catch (error) {\n\t\tif (retries === 0) {\n\t\t\tthrow error;\n\t\t}\n\n\t\t// Only retry on network errors, not on 404, 401, etc.\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tconst isNetworkError =\n\t\t\terrorMessage.includes('ECONNRESET') ||\n\t\t\terrorMessage.includes('ETIMEDOUT') ||\n\t\t\terrorMessage.includes('ENOTFOUND') ||\n\t\t\terrorMessage.includes('network');\n\n\t\tif (!isNetworkError) {\n\t\t\tthrow error;\n\t\t}\n\n\t\t// Wait before retrying\n\t\tawait new Promise(resolve => setTimeout(resolve, delay));\n\n\t\t// Retry with exponential backoff\n\t\treturn withRetry(fn, retries - 1, delay * 2);\n\t}\n}\n\n/**\n * Parse GitHub API error response\n */\nfunction parseGitHubError(error: unknown): string {\n\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\n\t// Check for specific GitHub API errors\n\tif (errorMessage.includes('404') || errorMessage.includes('Not Found')) {\n\t\treturn 'File or directory not found in BrainGrid repository';\n\t}\n\n\tif (errorMessage.includes('403') || errorMessage.includes('rate limit')) {\n\t\treturn 'GitHub API rate limit exceeded. Please wait a few minutes and try again.\\nCheck rate limit status: gh api rate_limit';\n\t}\n\n\tif (errorMessage.includes('401') || errorMessage.includes('Unauthorized')) {\n\t\treturn 'GitHub CLI is not authenticated. Run: gh auth login';\n\t}\n\n\t// Try to parse JSON error response\n\ttry {\n\t\tconst match = errorMessage.match(/\\{.*\\}/s);\n\t\tif (match) {\n\t\t\tconst errorData = JSON.parse(match[0]) as GitHubApiError;\n\t\t\treturn errorData.message || errorMessage;\n\t\t}\n\t} catch {\n\t\t// Not JSON, return original message\n\t}\n\n\treturn errorMessage;\n}\n\n/**\n * Fetch a single file from GitHub repository\n * @param path Path to file in repository (e.g., 'claude-code/README.md')\n * @returns File content as string\n */\nexport async function fetchFileFromGitHub(path: string): Promise<string> {\n\treturn withRetry(async () => {\n\t\ttry {\n\t\t\tconst command = `gh api repos/${GITHUB_OWNER}/${GITHUB_REPO}/contents/${path}`;\n\t\t\tconst { stdout } = await execAsync(command);\n\n\t\t\tconst response = JSON.parse(stdout) as GitHubApiFileResponse;\n\n\t\t\t// Verify it's a file\n\t\t\tif (response.type !== 'file') {\n\t\t\t\tthrow new Error(`Path ${path} is not a file`);\n\t\t\t}\n\n\t\t\t// Decode base64 content\n\t\t\tif (!response.content || !response.encoding) {\n\t\t\t\tthrow new Error(`No content found for file ${path}`);\n\t\t\t}\n\n\t\t\tif (response.encoding !== 'base64') {\n\t\t\t\tthrow new Error(`Unexpected encoding: ${response.encoding}`);\n\t\t\t}\n\n\t\t\t// Decode base64 content\n\t\t\tconst content = Buffer.from(response.content, 'base64').toString('utf8');\n\t\t\treturn content;\n\t\t} catch (error) {\n\t\t\tconst parsedError = parseGitHubError(error);\n\t\t\tthrow new Error(`Failed to fetch file ${path}: ${parsedError}`);\n\t\t}\n\t});\n}\n\n/**\n * List files and directories in a GitHub repository directory\n * @param path Path to directory in repository (e.g., 'claude-code/commands')\n * @returns Array of files and directories\n */\nexport async function listGitHubDirectory(path: string): Promise<GitHubFile[]> {\n\treturn withRetry(async () => {\n\t\ttry {\n\t\t\tconst command = `gh api repos/${GITHUB_OWNER}/${GITHUB_REPO}/contents/${path}`;\n\t\t\tconst { stdout } = await execAsync(command);\n\n\t\t\tconst response = JSON.parse(stdout) as GitHubApiFileResponse | GitHubApiFileResponse[];\n\n\t\t\t// Handle single file response (shouldn't happen but be safe)\n\t\t\tif (!Array.isArray(response)) {\n\t\t\t\tthrow new Error(`Path ${path} is not a directory`);\n\t\t\t}\n\n\t\t\t// Map to GitHubFile interface\n\t\t\treturn response.map(item => ({\n\t\t\t\tname: item.name,\n\t\t\t\ttype: item.type,\n\t\t\t\tpath: item.path,\n\t\t\t}));\n\t\t} catch (error) {\n\t\t\tconst parsedError = parseGitHubError(error);\n\t\t\tthrow new Error(`Failed to list directory ${path}: ${parsedError}`);\n\t\t}\n\t});\n}\n\n/**\n * Copy a single file from GitHub to local filesystem\n * @param sourcePath Path to file in GitHub repository\n * @param targetPath Local file path to write to\n */\nexport async function copyFileFromGitHub(sourcePath: string, targetPath: string): Promise<void> {\n\ttry {\n\t\t// Fetch file content from GitHub\n\t\tconst content = await fetchFileFromGitHub(sourcePath);\n\n\t\t// Create parent directories if they don't exist\n\t\tconst parentDir = path.dirname(targetPath);\n\t\tawait fs.mkdir(parentDir, { recursive: true });\n\n\t\t// Write file to local filesystem\n\t\tawait fs.writeFile(targetPath, content, { encoding: 'utf8', mode: 0o644 });\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to copy file ${sourcePath} to ${targetPath}: ${errorMessage}`);\n\t}\n}\n\n/**\n * Copy a directory recursively from GitHub to local filesystem\n *\n * This is a utility function for bulk directory copying with conflict detection.\n * Note: Not currently used by setup command handlers, which use a file-by-file approach\n * for better user experience (progress tracking and interactive conflict resolution).\n * Kept as a utility for future integrations, advanced use cases, or manual scripts.\n *\n * @param sourcePath Path to directory in GitHub repository\n * @param targetPath Local directory path to write to\n * @param existingFiles Set of files that already exist (for conflict tracking)\n * @returns Array of file paths that already exist locally (conflicts)\n */\nexport async function copyDirectoryFromGitHub(\n\tsourcePath: string,\n\ttargetPath: string,\n\texistingFiles: Set<string> = new Set()\n): Promise<string[]> {\n\tconst conflicts: string[] = [];\n\n\ttry {\n\t\t// List directory contents from GitHub\n\t\tconst items = await listGitHubDirectory(sourcePath);\n\n\t\t// Create target directory\n\t\tawait fs.mkdir(targetPath, { recursive: true });\n\n\t\t// Process each item\n\t\tfor (const item of items) {\n\t\t\tconst itemTargetPath = path.join(targetPath, item.name);\n\n\t\t\tif (item.type === 'file') {\n\t\t\t\t// Check if file already exists\n\t\t\t\ttry {\n\t\t\t\t\tawait fs.access(itemTargetPath);\n\t\t\t\t\t// File exists, add to conflicts\n\t\t\t\t\tconflicts.push(itemTargetPath);\n\t\t\t\t\texistingFiles.add(itemTargetPath);\n\t\t\t\t} catch {\n\t\t\t\t\t// File doesn't exist, will be created\n\t\t\t\t}\n\t\t\t} else if (item.type === 'dir') {\n\t\t\t\t// Recursively copy subdirectory\n\t\t\t\tconst subConflicts = await copyDirectoryFromGitHub(\n\t\t\t\t\titem.path,\n\t\t\t\t\titemTargetPath,\n\t\t\t\t\texistingFiles\n\t\t\t\t);\n\t\t\t\tconflicts.push(...subConflicts);\n\t\t\t}\n\t\t}\n\n\t\treturn conflicts;\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to copy directory ${sourcePath} to ${targetPath}: ${errorMessage}`);\n\t}\n}\n\n/**\n * Inject content into a file using markers\n * If file exists with markers, replace content between markers\n * If file exists without markers, append new section with markers\n * If file doesn't exist, create with content wrapped in markers\n * @param targetPath Local file path\n * @param content Content to inject\n */\nexport async function injectContentIntoFile(targetPath: string, content: string): Promise<void> {\n\ttry {\n\t\tlet fileContent: string;\n\t\tlet fileExists = false;\n\n\t\t// Check if file exists\n\t\ttry {\n\t\t\tfileContent = await fs.readFile(targetPath, 'utf8');\n\t\t\tfileExists = true;\n\t\t} catch {\n\t\t\tfileContent = '';\n\t\t}\n\n\t\tif (fileExists) {\n\t\t\t// File exists, check for existing markers\n\t\t\tconst beginIndex = fileContent.indexOf(BEGIN_MARKER);\n\t\t\tconst endIndex = fileContent.indexOf(END_MARKER);\n\n\t\t\tif (beginIndex !== -1 && endIndex !== -1 && endIndex > beginIndex) {\n\t\t\t\t// Markers found, replace content between them\n\t\t\t\tconst before = fileContent.substring(0, beginIndex);\n\t\t\t\tconst after = fileContent.substring(endIndex + END_MARKER.length);\n\t\t\t\tconst newContent = `${before}${BEGIN_MARKER}\\n${content}\\n${END_MARKER}${after}`;\n\t\t\t\tawait fs.writeFile(targetPath, newContent, { encoding: 'utf8' });\n\t\t\t} else {\n\t\t\t\t// No markers found, append new section\n\t\t\t\tconst newContent = `${fileContent}\\n\\n${BEGIN_MARKER}\\n${content}\\n${END_MARKER}\\n`;\n\t\t\t\tawait fs.writeFile(targetPath, newContent, { encoding: 'utf8' });\n\t\t\t}\n\t\t} else {\n\t\t\t// File doesn't exist, create with markers\n\t\t\tconst parentDir = path.dirname(targetPath);\n\t\t\tawait fs.mkdir(parentDir, { recursive: true });\n\n\t\t\tconst newContent = `${BEGIN_MARKER}\\n${content}\\n${END_MARKER}\\n`;\n\t\t\tawait fs.writeFile(targetPath, newContent, { encoding: 'utf8', mode: 0o644 });\n\t\t}\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to inject content into ${targetPath}: ${errorMessage}`);\n\t}\n}\n\n/**\n * Install status line script to .claude directory\n * @param scriptContent Content of the status line script\n * @param targetPath Path to install script (default: .claude/statusline.sh)\n */\nexport async function installStatusLineScript(\n\tscriptContent: string,\n\ttargetPath: string = '.claude/statusline.sh'\n): Promise<void> {\n\ttry {\n\t\t// Ensure .claude directory exists\n\t\tconst parentDir = path.dirname(targetPath);\n\t\tawait fs.mkdir(parentDir, { recursive: true });\n\n\t\t// Write script file with executable permissions\n\t\tawait fs.writeFile(targetPath, scriptContent, { encoding: 'utf8', mode: 0o755 });\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to install status line script to ${targetPath}: ${errorMessage}`);\n\t}\n}\n\n/**\n * Update Claude Code settings.json with status line configuration\n * @param settingsPath Path to settings.json (default: .claude/settings.json)\n * @param scriptPath Path to status line script (default: .claude/statusline.sh)\n */\nexport async function updateClaudeSettings(\n\tsettingsPath: string = '.claude/settings.json',\n\tscriptPath: string = '.claude/statusline.sh'\n): Promise<void> {\n\ttry {\n\t\tlet settings: Record<string, unknown> = {};\n\n\t\t// Read existing settings if file exists\n\t\ttry {\n\t\t\tconst content = await fs.readFile(settingsPath, 'utf8');\n\t\t\tsettings = JSON.parse(content) as Record<string, unknown>;\n\t\t} catch {\n\t\t\t// File doesn't exist or is invalid, start with empty settings\n\t\t}\n\n\t\t// Update statusLine configuration with correct format\n\t\tsettings.statusLine = {\n\t\t\ttype: 'command',\n\t\t\tcommand: scriptPath,\n\t\t\tpadding: 0,\n\t\t};\n\n\t\t// Ensure .claude directory exists\n\t\tconst parentDir = path.dirname(settingsPath);\n\t\tawait fs.mkdir(parentDir, { recursive: true });\n\n\t\t// Write updated settings\n\t\tconst content = JSON.stringify(settings, null, 2);\n\t\tawait fs.writeFile(settingsPath, content, { encoding: 'utf8' });\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to update Claude settings at ${settingsPath}: ${errorMessage}`);\n\t}\n}\n"],"mappings":"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","names":["chalk","axios","axios","axios","AxiosError","logger","axios","AxiosError","validationResult","axios","chalk","error","chalk","input","input","chalk","fs","path","path","fs","input","chalk","chalk","chalk","input","chalk","task","requirement","chalk","task","task","requirement","project","chalk","project","stop","chalk","getServices","chalk","requirement","task","chalk","getServices","chalk","task","chalk","logger","chalk","chalk","getAuth","chalk","gitInfo","chalk","exec","promisify","chalk","execAsync","promisify","exec","chalk","exec","promisify","path","execAsync","isGhInstalled","getServices","chalk","project","chalk","axios","select","axios","chalk","chalk","select","path","fs","exec","promisify","execAsync","fs","path","execAsync","fileExists","content","execAsync","chalk","select","require"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/handlers/project.handlers.ts","../src/utils/axios-with-auth.ts","../src/utils/logger.ts","../src/services/project-service.ts","../src/services/auth.ts","../src/utils/axios-retry.ts","../src/services/oauth2-auth.ts","../src/build-config.ts","../src/utils/config.ts","../src/utils/jwt.ts","../src/services/credential-store.ts","../src/utils/error-formatter.ts","../src/utils/error-handler.ts","../src/utils/id-normalization.ts","../src/utils/projects.ts","../src/utils/workspace-manager.ts","../src/utils/local-store.ts","../src/types/local-project.ts","../src/utils/git.ts","../src/utils/requirements.ts","../src/utils/spinner.ts","../src/services/internal/repository-service.ts","../src/utils/repository-access.ts","../src/utils/formatting.ts","../src/utils/tasks.ts","../src/handlers/requirement.handlers.ts","../src/services/requirement-service.ts","../src/handlers/task.handlers.ts","../src/services/task-service.ts","../src/handlers/auth.handlers.ts","../src/handlers/status.handlers.ts","../src/handlers/init.handlers.ts","../src/services/internal/github-service.ts","../src/utils/git-installer.ts","../src/handlers/setup.handlers.ts","../src/utils/command-execution.ts","../src/services/setup-service.ts","../src/utils/github-repo.ts","../src/handlers/update.handlers.ts","../src/utils/package-manager.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { createRequire } from 'module';\nimport * as handlers from './handlers/index.js';\n\nconst require = createRequire(import.meta.url);\nconst packageJson = require('../package.json');\n\nconst program = new Command();\n\nprogram\n\t.name('braingrid')\n\t.description('BrainGrid CLI - Manage projects, requirements, and tasks')\n\t.version(packageJson.version, '-v, --version', 'output the current version')\n\t.showHelpAfterError('(use --help for usage)');\n\n// ============================================\n// AUTH COMMANDS\n// ============================================\nprogram\n\t.command('login')\n\t.description('Authenticate with BrainGrid')\n\t.action(async () => {\n\t\tconst result = await handlers.handleLogin();\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('logout')\n\t.description('Sign out from BrainGrid')\n\t.action(async () => {\n\t\tconst result = await handlers.handleLogout();\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('whoami')\n\t.description('Show current user information')\n\t.action(async () => {\n\t\tconst result = await handlers.handleWhoami();\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('status')\n\t.description('Show CLI status (authentication, git, config)')\n\t.action(async () => {\n\t\tconst result = await handlers.handleStatus();\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('init')\n\t.description('Initialize BrainGrid project in current repository')\n\t.option('--project <id>', 'project ID to initialize with (auto-detects if not provided)')\n\t.option('--force', 'skip confirmation and force reinitialization if already initialized')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleInit(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('update')\n\t.description('Update BrainGrid CLI to the latest version')\n\t.option('--check', 'check for updates without installing')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleUpdate(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('specify')\n\t.description('Create AI-refined requirement from prompt')\n\t.option(\n\t\t'-p, --project <id>',\n\t\t'project ID (auto-detects from .braingrid/project.json if not provided)'\n\t)\n\t.requiredOption('--prompt <prompt>', 'requirement description (10-5000 characters)')\n\t.option('--format <format>', 'output format (table, json, xml, markdown)', 'table')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleRequirementSpecify(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\n// ============================================\n// SETUP COMMANDS\n// ============================================\nconst createSetupAction = (\n\thandler: (opts: { force?: boolean; dryRun?: boolean }) => Promise<handlers.HandlerResult>\n) => {\n\treturn async (opts: { force?: boolean; dryRun?: boolean }) => {\n\t\tconst result = await handler(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t};\n};\n\nconst setup = program\n\t.command('setup')\n\t.description('Setup BrainGrid integrations for AI coding tools');\n\nsetup\n\t.command('claude-code')\n\t.description('Install Claude Code integration')\n\t.option('--force', 'overwrite existing files without prompting')\n\t.option('--dry-run', 'show what would be done without making changes')\n\t.action(createSetupAction(handlers.handleSetupClaudeCode));\n\nsetup\n\t.command('cursor')\n\t.description('Install Cursor integration')\n\t.option('--force', 'overwrite existing files without prompting')\n\t.option('--dry-run', 'show what would be done without making changes')\n\t.action(createSetupAction(handlers.handleSetupCursor));\n\n// ============================================\n// PROJECT RESOURCE COMMANDS\n// ============================================\nconst project = program.command('project').description('Manage projects');\n\nproject\n\t.command('list')\n\t.description('List all projects')\n\t.option('--format <format>', 'output format (table, json, xml, markdown)', 'table')\n\t.option('--page <page>', 'page number for pagination', '1')\n\t.option('--limit <limit>', 'number of projects per page', '20')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleProjectList(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nproject\n\t.command('show [id]')\n\t.description('Show current or specified project (or use --repository to list by repo)')\n\t.option(\n\t\t'--repository, --repo <owner/name>',\n\t\t'list projects for repository (e.g., microsoft/vscode)'\n\t)\n\t.option('--format <format>', 'output format (table, json, xml, markdown)', 'table')\n\t.option('--page <page>', 'page number for pagination', '1')\n\t.option('--limit <limit>', 'number of projects per page', '20')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleProjectShow({ id, ...opts });\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nproject\n\t.command('create')\n\t.description('Create a new project')\n\t.requiredOption('--name <name>', 'project name')\n\t.option('--description <description>', 'project description')\n\t.option('--repository-id <uuid>', 'repository UUID to link to project')\n\t.option('--repository <owner/name>', 'repository in owner/name format (e.g., microsoft/vscode)')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleProjectCreate(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nproject\n\t.command('update <id>')\n\t.description('Update project information')\n\t.option('--name <name>', 'new project name')\n\t.option('--description <description>', 'new project description')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleProjectUpdate(id, opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nproject\n\t.command('delete <id>')\n\t.description('Delete a project')\n\t.option('--force', 'force deletion without confirmation')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleProjectDelete(id, opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\n// ============================================\n// REQUIREMENT RESOURCE COMMANDS\n// ============================================\nconst requirement = program.command('requirement').description('Manage requirements');\n\nrequirement\n\t.command('list')\n\t.description('List requirements for a project')\n\t.option(\n\t\t'-p, --project <id>',\n\t\t'project ID (auto-detects from .braingrid/project.json if not provided)'\n\t)\n\t.option(\n\t\t'--status <status>',\n\t\t'filter by status (IDEA, PLANNED, IN_PROGRESS, REVIEW, COMPLETED, CANCELLED)'\n\t)\n\t.option('--format <format>', 'output format (table, json, xml, markdown)', 'table')\n\t.option('--page <page>', 'page number for pagination', '1')\n\t.option('--limit <limit>', 'number of requirements per page', '20')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleRequirementList(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nrequirement\n\t.command('show [id]')\n\t.description('Show requirement details (auto-detects ID from git branch if not provided)')\n\t.option(\n\t\t'-p, --project <id>',\n\t\t'project ID (auto-detects from .braingrid/project.json if not provided)'\n\t)\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleRequirementShow({ ...opts, id });\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nrequirement\n\t.command('create')\n\t.description('Create a new requirement')\n\t.option(\n\t\t'-p, --project <id>',\n\t\t'project ID (auto-detects from .braingrid/project.json if not provided)'\n\t)\n\t.requiredOption('-n, --name <name>', 'requirement name')\n\t.option('-c, --content <content>', 'requirement content/description')\n\t.option('-a, --assigned-to <uuid>', 'user UUID to assign the requirement to')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleRequirementCreate(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nrequirement\n\t.command('update [id]')\n\t.description('Update requirement information (auto-detects ID from git branch if not provided)')\n\t.option('-p, --project <id>', 'project ID (auto-detects from workspace if not specified)')\n\t.option(\n\t\t'--status <status>',\n\t\t'new status (IDEA, PLANNED, IN_PROGRESS, REVIEW, COMPLETED, CANCELLED)'\n\t)\n\t.option('--name <name>', 'new requirement name')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleRequirementUpdate({ ...opts, id });\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nrequirement\n\t.command('delete [id]')\n\t.description('Delete a requirement (auto-detects ID from git branch if not provided)')\n\t.option('-p, --project <id>', 'project ID (auto-detects from workspace if not specified)')\n\t.option('--force', 'force deletion without confirmation')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleRequirementDelete({ ...opts, id });\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nrequirement\n\t.command('breakdown [id]')\n\t.description(\n\t\t'Break down a requirement into actionable tasks using AI (auto-detects ID from git branch if not provided)'\n\t)\n\t.option(\n\t\t'-p, --project <id>',\n\t\t'project ID (auto-detects from .braingrid/project.json if not provided)'\n\t)\n\t.option('--format <format>', 'output format (table, json, xml, markdown)', 'markdown')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleRequirementBreakdown({ ...opts, id });\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nrequirement\n\t.command('build [id]')\n\t.description(\n\t\t'Build requirement with all tasks in specified format (auto-detects ID from git branch if not provided)'\n\t)\n\t.option(\n\t\t'-p, --project <id>',\n\t\t'project ID (auto-detects from .braingrid/project.json if not provided)'\n\t)\n\t.option('--format <format>', 'output format (markdown, json, xml)', 'markdown')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleRequirementBuild({ ...opts, id });\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\n// ============================================\n// TASK RESOURCE COMMANDS\n// ============================================\nconst task = program.command('task').description('Manage tasks');\n\ntask\n\t.command('list')\n\t.description('List tasks for a requirement')\n\t.option('-r, --requirement <id>', 'requirement ID (REQ-456, auto-detects project if initialized)')\n\t.option('-p, --project <id>', 'project ID (PROJ-123, optional if project is initialized)')\n\t.option('--format <format>', 'output format (table, json, xml, markdown)', 'markdown')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleTaskList(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\ntask\n\t.command('summary')\n\t.description('Show task summary table (quick overview without content)')\n\t.option('-r, --requirement <id>', 'requirement ID (REQ-456, auto-detects project if initialized)')\n\t.option('-p, --project <id>', 'project ID (PROJ-123, optional if project is initialized)')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleTaskSummary(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\ntask\n\t.command('show <id>')\n\t.description('Show task details')\n\t.option('-r, --requirement <id>', 'requirement ID (REQ-456, auto-detects project if initialized)')\n\t.option('-p, --project <id>', 'project ID (PROJ-123, optional if project is initialized)')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleTaskShow(id, opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\ntask\n\t.command('create')\n\t.description('Create a new task')\n\t.option('-r, --requirement <id>', 'requirement ID (REQ-456, auto-detects project if initialized)')\n\t.option('-p, --project <id>', 'project ID (PROJ-123, optional if project is initialized)')\n\t.requiredOption('--title <title>', 'task title')\n\t.option('--content <content>', 'task content/description')\n\t.action(async opts => {\n\t\tconst result = await handlers.handleTaskCreate(opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\ntask\n\t.command('update <id>')\n\t.description('Update task information')\n\t.option('-r, --requirement <id>', 'requirement ID (REQ-456, auto-detects project if initialized)')\n\t.option('-p, --project <id>', 'project ID (PROJ-123, optional if project is initialized)')\n\t.option('--status <status>', 'new status (PLANNED, IN_PROGRESS, COMPLETED, CANCELLED)')\n\t.option('--title <title>', 'new task title')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleTaskUpdate(id, opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\ntask\n\t.command('delete <id>')\n\t.description('Delete a task')\n\t.option('-r, --requirement <id>', 'requirement ID (REQ-456, auto-detects project if initialized)')\n\t.option('-p, --project <id>', 'project ID (PROJ-123, optional if project is initialized)')\n\t.option('--force', 'force deletion without confirmation')\n\t.action(async (id, opts) => {\n\t\tconst result = await handlers.handleTaskDelete(id, opts);\n\t\tconsole.log(result.message);\n\t\tif (!result.success) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram.parse();\n","/**\n * Project Resource Handlers\n *\n * Handles all project-related commands:\n * - list: List all projects\n * - show: Show current project, specific project by ID, or projects for a repository\n * - create: Create a new project\n * - update: Update project information\n * - delete: Delete a project\n */\n\nimport chalk from 'chalk';\nimport { ProjectService } from '../services/project-service.js';\nimport { BraingridAuth } from '../services/auth.js';\nimport { getConfig } from '../utils/config.js';\nimport { formatError, getResourceContext } from '../utils/error-formatter.js';\nimport { parseProjectId } from '../utils/projects.js';\nimport { workspaceManager } from '../utils/workspace-manager.js';\nimport { showSpinner } from '../utils/spinner.js';\nimport { RepositoryService } from '../services/internal/repository-service.js';\nimport { getRepositoryId } from '../utils/repository-access.js';\nimport {\n\tformatProjectListMarkdown,\n\tformatProjectListXml,\n\tformatProjectShowMarkdown,\n\tformatProjectShowXml,\n} from '../utils/formatting.js';\nimport type { HandlerResult } from './types.js';\nimport type { ListProjectsResponse, ListProjectsWithRepositoryResponse } from '../types/project.js';\n\n/**\n * Format pagination or total count display for project list responses\n */\nfunction formatProjectListPagination(\n\tresponse: ListProjectsResponse | ListProjectsWithRepositoryResponse\n): string {\n\tif ('pagination' in response) {\n\t\tconst totalPages = Math.ceil(response.pagination.total / response.pagination.limit);\n\t\treturn `Page ${response.pagination.page} of ${totalPages} (${response.pagination.total} total)`;\n\t}\n\treturn `Total: ${response.total_count || response.projects.length}`;\n}\n\nfunction getServices(): { projectService: ProjectService; auth: BraingridAuth } {\n\tconst config = getConfig();\n\tconst auth = new BraingridAuth(config.apiUrl);\n\tconst projectService = new ProjectService(config.apiUrl, auth);\n\treturn { projectService, auth };\n}\n\nexport async function handleProjectList(opts: {\n\tformat?: string;\n\tpage?: string;\n\tlimit?: string;\n}): Promise<HandlerResult> {\n\ttry {\n\t\tconst { projectService, auth } = getServices();\n\n\t\t// Check authentication\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Validate format option\n\t\tconst format = opts.format || 'table';\n\t\tif (!['table', 'json', 'xml', 'markdown'].includes(format)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t`❌ Invalid format: ${format}. Supported formats: table, json, xml, markdown`\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\tconst stop = showSpinner('Loading projects', chalk.gray);\n\t\ttry {\n\t\t\tconst response = await projectService.listProjects({\n\t\t\t\tpage: opts.page ? parseInt(opts.page, 10) : 1,\n\t\t\t\tlimit: opts.limit ? parseInt(opts.limit, 10) : 20,\n\t\t\t});\n\t\t\tstop();\n\n\t\t\t// Format output based on requested format\n\t\t\tlet output: string;\n\t\t\tswitch (format) {\n\t\t\t\tcase 'json': {\n\t\t\t\t\toutput = JSON.stringify(response, null, 2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'xml': {\n\t\t\t\t\tconst pagination = 'pagination' in response ? response.pagination : undefined;\n\t\t\t\t\toutput = formatProjectListXml(response.projects, pagination);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'markdown': {\n\t\t\t\t\tconst pagination = 'pagination' in response ? response.pagination : undefined;\n\t\t\t\t\toutput = formatProjectListMarkdown(response.projects, pagination);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'table':\n\t\t\t\tdefault: {\n\t\t\t\t\t// Table format\n\t\t\t\t\tif (response.projects.length === 0) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\tmessage: chalk.yellow('No projects found.'),\n\t\t\t\t\t\t\tdata: response,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\toutput = chalk.bold('📋 Projects\\n\\n');\n\t\t\t\t\toutput +=\n\t\t\t\t\t\t'ID Short ID Name Created\\n';\n\t\t\t\t\toutput += '─'.repeat(100) + '\\n';\n\n\t\t\t\t\tfor (const project of response.projects) {\n\t\t\t\t\t\tconst id = project.id.padEnd(36);\n\t\t\t\t\t\tconst shortId = project.short_id.padEnd(11);\n\t\t\t\t\t\tconst name = project.name.substring(0, 28).padEnd(28);\n\t\t\t\t\t\tconst created = new Date(project.created_at).toLocaleDateString();\n\t\t\t\t\t\toutput += `${id} ${shortId} ${name} ${created}\\n`;\n\t\t\t\t\t}\n\n\t\t\t\t\toutput += '\\n';\n\t\t\t\t\toutput += formatProjectListPagination(response);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: output,\n\t\t\t\tdata: response,\n\t\t\t};\n\t\t} finally {\n\t\t\tstop();\n\t\t}\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'listing projects'),\n\t\t};\n\t}\n}\n\nexport async function handleProjectShow(opts: {\n\tid?: string;\n\trepo?: string;\n\trepository?: string;\n\tformat?: string;\n\tpage?: string;\n\tlimit?: string;\n}): Promise<HandlerResult> {\n\ttry {\n\t\tconst { projectService, auth } = getServices();\n\n\t\t// Check authentication\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Validate format option\n\t\tconst format = opts.format || 'table';\n\t\tif (!['table', 'json', 'xml', 'markdown'].includes(format)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t`❌ Invalid format: ${format}. Supported formats: table, json, xml, markdown`\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Case 1: Specific project ID provided - show that project\n\t\tif (opts.id) {\n\t\t\tconst normalizedId = parseProjectId(opts.id);\n\t\t\tconst stop = showSpinner('Loading project', chalk.gray);\n\t\t\ttry {\n\t\t\t\tconst project = await projectService.getProject(normalizedId);\n\t\t\t\tstop();\n\n\t\t\t\tlet output: string;\n\t\t\t\tswitch (format) {\n\t\t\t\t\tcase 'json': {\n\t\t\t\t\t\toutput = JSON.stringify(project, null, 2);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'xml': {\n\t\t\t\t\t\toutput = formatProjectShowXml(project);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'markdown': {\n\t\t\t\t\t\toutput = formatProjectShowMarkdown(project);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'table':\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\toutput = chalk.bold(`\\n📁 Project: ${project.name}\\n\\n`);\n\t\t\t\t\t\toutput += `${chalk.bold('ID:')} ${project.id}\\n`;\n\t\t\t\t\t\toutput += `${chalk.bold('Short ID:')} ${project.short_id}\\n`;\n\t\t\t\t\t\toutput += `${chalk.bold('Name:')} ${project.name}\\n`;\n\t\t\t\t\t\tif (project.description) {\n\t\t\t\t\t\t\toutput += `${chalk.bold('Description:')} ${project.description}\\n`;\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutput += `${chalk.bold('Created:')} ${new Date(project.created_at).toLocaleString()}\\n`;\n\t\t\t\t\t\toutput += `${chalk.bold('Updated:')} ${new Date(project.updated_at).toLocaleString()}\\n`;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tmessage: output,\n\t\t\t\t\tdata: project,\n\t\t\t\t};\n\t\t\t} finally {\n\t\t\t\tstop();\n\t\t\t}\n\t\t}\n\n\t\t// Case 2: Repository flag provided - list all projects for that repository\n\t\tconst repoInput = opts.repository || opts.repo;\n\t\tif (repoInput) {\n\t\t\tconst parts = repoInput.split('/');\n\t\t\tif (parts.length !== 2) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t\t'❌ Invalid repository format. Use: --repository owner/name (e.g., --repository microsoft/vscode)'\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst [repositoryOwner, repositoryName] = parts;\n\n\t\t\tconst stop = showSpinner('Loading projects', chalk.gray);\n\t\t\ttry {\n\t\t\t\tconst response = await projectService.listProjects({\n\t\t\t\t\trepository_owner: repositoryOwner,\n\t\t\t\t\trepository_name: repositoryName,\n\t\t\t\t\tpage: opts.page ? parseInt(opts.page, 10) : 1,\n\t\t\t\t\tlimit: opts.limit ? parseInt(opts.limit, 10) : 20,\n\t\t\t\t});\n\t\t\t\tstop();\n\n\t\t\t\t// Format output based on requested format\n\t\t\t\tlet output: string;\n\t\t\t\tswitch (format) {\n\t\t\t\t\tcase 'json': {\n\t\t\t\t\t\toutput = JSON.stringify(response, null, 2);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'xml': {\n\t\t\t\t\t\tconst pagination = 'pagination' in response ? response.pagination : undefined;\n\t\t\t\t\t\toutput = formatProjectListXml(response.projects, pagination);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'markdown': {\n\t\t\t\t\t\tconst pagination = 'pagination' in response ? response.pagination : undefined;\n\t\t\t\t\t\toutput = formatProjectListMarkdown(response.projects, pagination);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'table':\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\t// Table format\n\t\t\t\t\t\tconst repoDisplay = chalk.cyan(`${repositoryOwner}/${repositoryName}`);\n\n\t\t\t\t\t\tif (response.projects.length === 0) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\t\tmessage: chalk.yellow(`No projects found for repository ${repoDisplay}`),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\toutput = chalk.bold(`📋 Projects for ${repoDisplay}\\n\\n`);\n\t\t\t\t\t\toutput +=\n\t\t\t\t\t\t\t'ID Short ID Name Created\\n';\n\t\t\t\t\t\toutput += '─'.repeat(100) + '\\n';\n\n\t\t\t\t\t\tfor (const project of response.projects) {\n\t\t\t\t\t\t\tconst id = project.id.padEnd(36);\n\t\t\t\t\t\t\tconst shortId = project.short_id.padEnd(11);\n\t\t\t\t\t\t\tconst name = project.name.substring(0, 28).padEnd(28);\n\t\t\t\t\t\t\tconst created = new Date(project.created_at).toLocaleDateString();\n\t\t\t\t\t\t\toutput += `${id} ${shortId} ${name} ${created}\\n`;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\toutput += '\\n';\n\t\t\t\t\t\toutput += formatProjectListPagination(response);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tmessage: output,\n\t\t\t\t\tdata: response,\n\t\t\t\t};\n\t\t\t} finally {\n\t\t\t\tstop();\n\t\t\t}\n\t\t}\n\n\t\t// Case 3: No arguments - show initialized project from workspace\n\t\tconst workspace = await workspaceManager.getProject();\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\n\t\tconst stop = showSpinner('Loading project', chalk.gray);\n\t\ttry {\n\t\t\tconst project = await projectService.getProject(workspace.projectId);\n\t\t\tstop();\n\n\t\t\tlet output: string;\n\t\t\tswitch (format) {\n\t\t\t\tcase 'json': {\n\t\t\t\t\toutput = JSON.stringify(project, null, 2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'xml': {\n\t\t\t\t\toutput = formatProjectShowXml(project);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'markdown': {\n\t\t\t\t\toutput = formatProjectShowMarkdown(project);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'table':\n\t\t\t\tdefault: {\n\t\t\t\t\toutput = chalk.bold(`\\n📁 Project: ${project.name}\\n\\n`);\n\t\t\t\t\toutput += `${chalk.bold('ID:')} ${project.id}\\n`;\n\t\t\t\t\toutput += `${chalk.bold('Short ID:')} ${project.short_id}\\n`;\n\t\t\t\t\toutput += `${chalk.bold('Name:')} ${project.name}\\n`;\n\t\t\t\t\tif (project.description) {\n\t\t\t\t\t\toutput += `${chalk.bold('Description:')} ${project.description}\\n`;\n\t\t\t\t\t}\n\t\t\t\t\toutput += `${chalk.bold('Created:')} ${new Date(project.created_at).toLocaleString()}\\n`;\n\t\t\t\t\toutput += `${chalk.bold('Updated:')} ${new Date(project.updated_at).toLocaleString()}\\n`;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: output,\n\t\t\t\tdata: project,\n\t\t\t};\n\t\t} finally {\n\t\t\tstop();\n\t\t}\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'showing project'),\n\t\t};\n\t}\n}\n\nexport async function handleProjectCreate(opts: {\n\tname: string;\n\tdescription?: string;\n\trepositoryId?: string;\n\trepository?: string;\n}): Promise<HandlerResult> {\n\ttry {\n\t\tconst { projectService, auth } = getServices();\n\t\tconst config = getConfig();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Resolve repository ID from either --repository-id or --repository\n\t\tlet repositoryId: string | undefined;\n\n\t\t// Option 1: Direct UUID (highest priority)\n\t\tif (opts.repositoryId) {\n\t\t\trepositoryId = opts.repositoryId;\n\t\t}\n\t\t// Option 2: Lookup by owner/name\n\t\telse if (opts.repository) {\n\t\t\tconst parts = opts.repository.split('/');\n\t\t\tif (parts.length !== 2) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t\t'❌ Invalid repository format. Use: --repository owner/name (e.g., microsoft/vscode)'\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst [owner, name] = parts;\n\t\t\tconst repositoryService = new RepositoryService(config.apiUrl, auth);\n\n\t\t\tconst stop = showSpinner(`Looking up repository ${opts.repository}`, chalk.gray);\n\t\t\ttry {\n\t\t\t\tconst repoId = await getRepositoryId(repositoryService, owner, name);\n\t\t\t\tstop();\n\n\t\t\t\tif (!repoId) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t\t\t`❌ Repository '${opts.repository}' not found. Please check the name or ensure you have access.`\n\t\t\t\t\t\t),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\trepositoryId = repoId;\n\t\t\t} finally {\n\t\t\t\tstop();\n\t\t\t}\n\t\t}\n\n\t\tconst stop = showSpinner('Creating project', chalk.gray);\n\t\ttry {\n\t\t\tconst project = await projectService.createProject({\n\t\t\t\tname: opts.name,\n\t\t\t\tdescription: opts.description,\n\t\t\t\trepository_id: repositoryId,\n\t\t\t});\n\t\t\tstop();\n\n\t\t\tlet message = chalk.green(`✅ Created project ${project.short_id}: ${project.name}`);\n\t\t\tif (opts.repository && repositoryId) {\n\t\t\t\tmessage += chalk.gray(` (linked to ${opts.repository})`);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage,\n\t\t\t\tdata: project,\n\t\t\t};\n\t\t} finally {\n\t\t\tstop();\n\t\t}\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'creating project'),\n\t\t};\n\t}\n}\n\nexport async function handleProjectUpdate(\n\tid: string,\n\topts: {\n\t\tname?: string;\n\t\tdescription?: string;\n\t}\n): Promise<HandlerResult> {\n\ttry {\n\t\tconst { projectService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.name && !opts.description) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t'❌ Please provide at least one field to update (--name or --description)'\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Normalize the project ID\n\t\tconst normalizedId = parseProjectId(id);\n\t\tconst stop = showSpinner('Updating project', chalk.gray);\n\t\ttry {\n\t\t\tconst project = await projectService.updateProject(normalizedId, {\n\t\t\t\tname: opts.name,\n\t\t\t\tdescription: opts.description,\n\t\t\t});\n\t\t\tstop();\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: chalk.green(`✅ Updated project ${project.short_id}: ${project.name}`),\n\t\t\t\tdata: project,\n\t\t\t};\n\t\t} finally {\n\t\t\tstop();\n\t\t}\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('project', id)),\n\t\t};\n\t}\n}\n\nexport async function handleProjectDelete(\n\tid: string,\n\topts: { force?: boolean }\n): Promise<HandlerResult> {\n\ttry {\n\t\tconst { projectService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.force) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.yellow(\n\t\t\t\t\t'⚠️ Deleting a project is permanent. Use --force to confirm deletion.'\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Normalize the project ID\n\t\tconst normalizedId = parseProjectId(id);\n\t\tconst stop = showSpinner('Deleting project', chalk.gray);\n\t\ttry {\n\t\t\tawait projectService.deleteProject(normalizedId);\n\t\t\tstop();\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: chalk.green(`✅ Deleted project ${id}`),\n\t\t\t};\n\t\t} finally {\n\t\t\tstop();\n\t\t}\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('project', id)),\n\t\t};\n\t}\n}\n","/**\n * Axios instance with authentication and automatic token refresh\n */\n\nimport axios, { AxiosInstance, AxiosError, InternalAxiosRequestConfig } from 'axios';\nimport { BraingridAuth } from '../services/auth.js';\nimport { getLogger } from './logger.js';\n\nconst logger = getLogger();\n\n/**\n * Check if a response is a redirect to an auth endpoint\n */\nfunction isAuthRedirect(error: AxiosError): boolean {\n\tconst status = error.response?.status;\n\tif (!status || (status !== 302 && status !== 307 && status !== 303)) {\n\t\treturn false;\n\t}\n\n\tconst location = error.response?.headers?.location as string | undefined;\n\tif (!location) {\n\t\treturn false;\n\t}\n\n\t// Check if redirecting to auth endpoints (WorkOS, AuthKit, etc.)\n\tconst authPatterns = [\n\t\t'/auth/',\n\t\t'/oauth2/',\n\t\t'workos.com',\n\t\t'authkit.app',\n\t\t'/user_management/authorize',\n\t];\n\n\treturn authPatterns.some(pattern => location.toLowerCase().includes(pattern));\n}\n\n/**\n * Create an axios instance with automatic token refresh on 401 errors and auth redirects\n */\nexport function createAuthenticatedAxios(auth: BraingridAuth): AxiosInstance {\n\tconst instance = axios.create({\n\t\tmaxRedirects: 0, // Don't follow redirects - treat them as errors\n\t\tvalidateStatus: status => status >= 200 && status < 300, // Only accept 2xx as success\n\t});\n\n\t// Request interceptor to add auth headers\n\tinstance.interceptors.request.use(\n\t\tasync config => {\n\t\t\tconst session = await auth.getStoredSession();\n\t\t\tif (session) {\n\t\t\t\tconfig.headers.Authorization = `Bearer ${session.sealed_session}`;\n\t\t\t}\n\t\t\treturn config;\n\t\t},\n\t\terror => Promise.reject(error)\n\t);\n\n\t// Response interceptor to handle 401 errors, auth redirects, and refresh token\n\tinstance.interceptors.response.use(\n\t\tresponse => {\n\t\t\t// Log successful API calls for debugging/testing\n\t\t\tconst method = response.config.method?.toUpperCase() || 'UNKNOWN';\n\t\t\tconst url = response.config.url || 'unknown';\n\t\t\tconst status = response.status;\n\n\t\t\tlogger.debug(`[API] ${method} ${url} -> ${status}`);\n\n\t\t\treturn response;\n\t\t},\n\t\tasync (error: AxiosError) => {\n\t\t\tconst originalRequest = error.config as InternalAxiosRequestConfig & { _retry?: boolean };\n\n\t\t\t// Log API error details for debugging/testing\n\t\t\tconst method = error.config?.method?.toUpperCase() || 'UNKNOWN';\n\t\t\tconst url = error.config?.url || 'unknown';\n\t\t\tconst status = error.response?.status || 'NO_RESPONSE';\n\n\t\t\t// Extract request params (query params or request body)\n\t\t\tlet params = '';\n\t\t\tif (error.config?.params) {\n\t\t\t\tparams = JSON.stringify(error.config.params);\n\t\t\t} else if (error.config?.data) {\n\t\t\t\ttry {\n\t\t\t\t\tconst data =\n\t\t\t\t\t\ttypeof error.config.data === 'string'\n\t\t\t\t\t\t\t? JSON.parse(error.config.data)\n\t\t\t\t\t\t\t: error.config.data;\n\t\t\t\t\t// Truncate long prompts for readability\n\t\t\t\t\tif (data.prompt && data.prompt.length > 100) {\n\t\t\t\t\t\tdata.prompt = data.prompt.substring(0, 100) + '...';\n\t\t\t\t\t}\n\t\t\t\t\tparams = JSON.stringify(data);\n\t\t\t\t} catch {\n\t\t\t\t\tparams = String(error.config.data).substring(0, 200);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlogger.debug(`[API] ${method} ${url} -> ${status}`, { params });\n\n\t\t\t// Check if this is an auth failure (401 or redirect to auth)\n\t\t\tconst is401 = error.response?.status === 401;\n\t\t\tconst isRedirectToAuth = isAuthRedirect(error);\n\n\t\t\t// If auth failure and we haven't retried yet, attempt token refresh\n\t\t\tif ((is401 || isRedirectToAuth) && !originalRequest._retry) {\n\t\t\t\toriginalRequest._retry = true;\n\n\t\t\t\tif (isRedirectToAuth) {\n\t\t\t\t\tlogger.debug('[AUTH] Received redirect to auth endpoint - token likely expired');\n\t\t\t\t} else {\n\t\t\t\t\tlogger.debug('[AUTH] Received 401 error - attempting token refresh');\n\t\t\t\t}\n\n\t\t\t\t// Attempt to refresh the token\n\t\t\t\tconst refreshed = await auth.refreshSession();\n\n\t\t\t\tif (refreshed) {\n\t\t\t\t\tlogger.debug('[AUTH] Token refreshed - retrying request');\n\n\t\t\t\t\t// Get the new session and update the request headers\n\t\t\t\t\tconst session = await auth.getStoredSession();\n\t\t\t\t\tif (session && originalRequest.headers) {\n\t\t\t\t\t\toriginalRequest.headers.Authorization = `Bearer ${session.sealed_session}`;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Retry the original request with the new token\n\t\t\t\t\treturn instance(originalRequest);\n\t\t\t\t} else {\n\t\t\t\t\tlogger.warn('[AUTH] Token refresh failed - clearing session');\n\t\t\t\t\t// Refresh failed, clear the session\n\t\t\t\t\tawait auth.clearSession();\n\n\t\t\t\t\t// Return a more user-friendly error\n\t\t\t\t\tconst authError = new Error(\n\t\t\t\t\t\t'Authentication expired. Please run \"braingrid login\" to re-authenticate.'\n\t\t\t\t\t);\n\t\t\t\t\treturn Promise.reject(authError);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// For all other errors or if retry already happened, just reject\n\t\t\treturn Promise.reject(error);\n\t\t}\n\t);\n\n\treturn instance;\n}\n","import fs from 'fs';\nimport path from 'path';\nimport os from 'os';\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\nexport type MessageType = 'user' | 'system' | 'error' | 'info' | 'debug';\n\ninterface LogEntry {\n\ttimestamp: Date;\n\tlevel: LogLevel;\n\ttype: MessageType;\n\tmessage: string;\n\tcontext?: Record<string, unknown>;\n}\n\ninterface LoggerConfig {\n\tlogToFile: boolean;\n\tlogLevel: LogLevel;\n\tlogFilePath?: string;\n\tmaxFileSize: number;\n\tmaxFiles: number;\n\tconsoleOutput: boolean; // Whether to print debug logs to console\n}\n\nclass Logger {\n\tprivate config: LoggerConfig;\n\tprivate logFilePath: string;\n\n\tconstructor(config: Partial<LoggerConfig> = {}) {\n\t\tconst isDebugMode = process.env.DEBUG === 'true';\n\t\tthis.config = {\n\t\t\tlogToFile: false,\n\t\t\tlogLevel: isDebugMode ? 'debug' : 'info', // Set log level to debug when DEBUG=true\n\t\t\tmaxFileSize: 10 * 1024 * 1024, // 10MB\n\t\t\tmaxFiles: 5,\n\t\t\tconsoleOutput: isDebugMode, // Enable console output when DEBUG=true\n\t\t\t...config,\n\t\t};\n\n\t\tthis.logFilePath =\n\t\t\tthis.config.logFilePath || path.join(os.homedir(), '.braingrid', 'logs', 'braingrid-cli.log');\n\n\t\tif (this.config.logToFile) {\n\t\t\tthis.ensureLogDirectory();\n\t\t}\n\t}\n\n\tprivate ensureLogDirectory(): void {\n\t\tconst logDir = path.dirname(this.logFilePath);\n\t\tif (!fs.existsSync(logDir)) {\n\t\t\tfs.mkdirSync(logDir, { recursive: true });\n\t\t}\n\t}\n\n\tprivate shouldLog(level: LogLevel): boolean {\n\t\tconst levels: LogLevel[] = ['debug', 'info', 'warn', 'error'];\n\t\treturn levels.indexOf(level) >= levels.indexOf(this.config.logLevel);\n\t}\n\n\tprivate formatLogEntry(entry: LogEntry): string {\n\t\tconst timestamp = entry.timestamp.toISOString();\n\t\tconst level = entry.level.toUpperCase().padEnd(5);\n\t\tconst type = entry.type.toUpperCase().padEnd(7);\n\t\tconst contextStr = entry.context ? ` | ${JSON.stringify(entry.context)}` : '';\n\t\treturn `[${timestamp}] ${level} [${type}] ${entry.message}${contextStr}`;\n\t}\n\n\tprivate writeToFile(entry: LogEntry): void {\n\t\tif (!this.config.logToFile) return;\n\n\t\ttry {\n\t\t\tconst logLine = this.formatLogEntry(entry) + '\\n';\n\n\t\t\t// Check file size and rotate if necessary\n\t\t\tif (fs.existsSync(this.logFilePath)) {\n\t\t\t\tconst stats = fs.statSync(this.logFilePath);\n\t\t\t\tif (stats.size > this.config.maxFileSize) {\n\t\t\t\t\tthis.rotateLogFile();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfs.appendFileSync(this.logFilePath, logLine);\n\t\t} catch (error) {\n\t\t\tconsole.error('Failed to write to log file:', error);\n\t\t}\n\t}\n\n\tprivate rotateLogFile(): void {\n\t\ttry {\n\t\t\t// Rotate log files\n\t\t\tfor (let i = this.config.maxFiles - 1; i >= 1; i--) {\n\t\t\t\tconst oldFile = `${this.logFilePath}.${i}`;\n\t\t\t\tconst newFile = `${this.logFilePath}.${i + 1}`;\n\n\t\t\t\tif (fs.existsSync(oldFile)) {\n\t\t\t\t\tif (i === this.config.maxFiles - 1) {\n\t\t\t\t\t\tfs.unlinkSync(oldFile); // Delete oldest file\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfs.renameSync(oldFile, newFile);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Move current log to .1\n\t\t\tif (fs.existsSync(this.logFilePath)) {\n\t\t\t\tfs.renameSync(this.logFilePath, `${this.logFilePath}.1`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error('Failed to rotate log file:', error);\n\t\t}\n\t}\n\n\tprivate log(\n\t\tlevel: LogLevel,\n\t\ttype: MessageType,\n\t\tmessage: string,\n\t\tcontext?: Record<string, unknown>\n\t): void {\n\t\tif (!this.shouldLog(level)) return;\n\n\t\tconst entry: LogEntry = {\n\t\t\ttimestamp: new Date(),\n\t\t\tlevel,\n\t\t\ttype,\n\t\t\tmessage,\n\t\t\tcontext,\n\t\t};\n\n\t\t// Write to file if enabled\n\t\tthis.writeToFile(entry);\n\n\t\t// Write to console if enabled and it's a debug message\n\t\tif (this.config.consoleOutput && level === 'debug') {\n\t\t\tconst contextStr = context ? ` ${JSON.stringify(context)}` : '';\n\t\t\t// Write to stderr so it doesn't interfere with CLI output\n\t\t\tconsole.error(`${message}${contextStr}`);\n\t\t}\n\t}\n\n\tdebug(message: string, context?: Record<string, unknown>): void {\n\t\tthis.log('debug', 'debug', message, context);\n\t}\n\n\tinfo(message: string, context?: Record<string, unknown>): void {\n\t\tthis.log('info', 'info', message, context);\n\t}\n\n\twarn(message: string, context?: Record<string, unknown>): void {\n\t\tthis.log('warn', 'info', message, context);\n\t}\n\n\terror(message: string, context?: Record<string, unknown>): void {\n\t\tthis.log('error', 'error', message, context);\n\t}\n\n\tuserMessage(message: string, context?: Record<string, unknown>): void {\n\t\tthis.log('info', 'user', message, context);\n\t}\n\n\tsystemMessage(message: string, context?: Record<string, unknown>): void {\n\t\tthis.log('info', 'system', message, context);\n\t}\n\n\t// Log streaming output with full content\n\tstreamOutput(message: string, isError = false): void {\n\t\tthis.log(isError ? 'error' : 'info', isError ? 'error' : 'system', message);\n\t}\n\n\t// Update configuration\n\tupdateConfig(newConfig: Partial<LoggerConfig>): void {\n\t\tconst wasLoggingToFile = this.config.logToFile;\n\t\tthis.config = { ...this.config, ...newConfig };\n\n\t\tif (this.config.logToFile && !wasLoggingToFile) {\n\t\t\tthis.ensureLogDirectory();\n\t\t\tthis.info('File logging enabled', { logFilePath: this.logFilePath });\n\t\t} else if (!this.config.logToFile && wasLoggingToFile) {\n\t\t\tthis.info('File logging disabled');\n\t\t}\n\t}\n\n\t// Get current log file path\n\tgetLogFilePath(): string {\n\t\treturn this.logFilePath;\n\t}\n\n\t// Get log file size in MB\n\tgetLogFileSize(): number {\n\t\ttry {\n\t\t\tif (fs.existsSync(this.logFilePath)) {\n\t\t\t\tconst stats = fs.statSync(this.logFilePath);\n\t\t\t\treturn stats.size / (1024 * 1024);\n\t\t\t}\n\t\t\treturn 0;\n\t\t} catch {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t// Clear log file\n\tclearLogFile(): void {\n\t\ttry {\n\t\t\tif (fs.existsSync(this.logFilePath)) {\n\t\t\t\tfs.unlinkSync(this.logFilePath);\n\t\t\t\tthis.info('Log file cleared');\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error('Failed to clear log file:', error);\n\t\t}\n\t}\n}\n\n// Create singleton logger instance\nlet loggerInstance: Logger | null = null;\n\nexport function getLogger(config?: Partial<LoggerConfig>): Logger {\n\tif (!loggerInstance) {\n\t\tloggerInstance = new Logger(config);\n\t}\n\treturn loggerInstance;\n}\n\nexport function initializeLogger(config: Partial<LoggerConfig>): Logger {\n\tloggerInstance = new Logger(config);\n\treturn loggerInstance;\n}\n\nexport { Logger };\n","/**\n * Project Service\n * Handles all API interactions for projects\n */\n\nimport { AxiosInstance } from 'axios';\nimport { BraingridAuth } from './auth.js';\nimport { createAuthenticatedAxios } from '../utils/axios-with-auth.js';\nimport {\n\tProject,\n\tCreateProjectRequest,\n\tUpdateProjectRequest,\n\tListProjectsResponse,\n\tListProjectsWithRepositoryResponse,\n} from '../types/project.js';\n\nexport class ProjectService {\n\tprivate baseUrl: string;\n\tprivate auth: BraingridAuth;\n\tprivate axios: AxiosInstance;\n\n\tconstructor(baseUrl: string, auth: BraingridAuth) {\n\t\tthis.baseUrl = baseUrl;\n\t\tthis.auth = auth;\n\t\tthis.axios = createAuthenticatedAxios(auth);\n\t}\n\n\tprivate getHeaders(): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t};\n\t}\n\n\tasync listProjects(params: {\n\t\tpage?: number;\n\t\tlimit?: number;\n\t\trepository_owner?: string;\n\t\trepository_name?: string;\n\t}): Promise<ListProjectsResponse | ListProjectsWithRepositoryResponse> {\n\t\tconst queryParams = new URLSearchParams();\n\t\tif (params.page) queryParams.append('page', params.page.toString());\n\t\tif (params.limit) queryParams.append('limit', params.limit.toString());\n\t\tif (params.repository_owner) queryParams.append('repository_owner', params.repository_owner);\n\t\tif (params.repository_name) queryParams.append('repository_name', params.repository_name);\n\n\t\tconst url = `${this.baseUrl}/api/v1/projects?${queryParams.toString()}`;\n\t\tconst headers = this.getHeaders();\n\n\t\t// API returns different response structures based on query parameters:\n\t\t// - ListProjectsResponse (with pagination) for regular lists\n\t\t// - ListProjectsWithRepositoryResponse (with total_count) for repository filters\n\t\t// Handlers are equipped to handle both types via union type\n\t\tconst response = await this.axios.get<\n\t\t\tListProjectsResponse | ListProjectsWithRepositoryResponse\n\t\t>(url, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync getProject(projectId: string): Promise<Project> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<Project>(url, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync createProject(data: CreateProjectRequest): Promise<Project> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.post<Project>(url, data, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync updateProject(projectId: string, data: UpdateProjectRequest): Promise<Project> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.patch<Project>(url, data, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync deleteProject(projectId: string): Promise<void> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tawait this.axios.delete(url, { headers });\n\t}\n}\n","import axios from 'axios';\nimport { User, BraingridSession, GitUser } from '../types/auth.js';\nimport { axiosWithRetry } from '../utils/axios-retry.js';\nimport { OAuth2Handler } from './oauth2-auth.js';\nimport { getConfig } from '../utils/config.js';\nimport { decodeJWT, isJWTExpired, extractUserFromJWT } from '../utils/jwt.js';\nimport { getLogger } from '../utils/logger.js';\nimport { credentialStore } from './credential-store.js';\n\nconst KEYCHAIN_SERVICE = 'braingrid-cli';\nconst KEYCHAIN_ACCOUNT = 'session';\nconst GITHUB_KEYCHAIN_ACCOUNT = 'github-token';\n\nexport class BraingridAuth {\n\tprivate baseUrl: string;\n\tprivate lastValidationTime: number = 0;\n\tprivate lastValidationResult: boolean = false;\n\tprivate loginTime: number = 0;\n\tprivate readonly VALIDATION_CACHE_MS = 60 * 60 * 1000; // Cache validation for 1 hour\n\tprivate readonly POST_LOGIN_GRACE_MS = 24 * 60 * 60 * 1000; // 24 hours grace period after login\n\tprivate oauthHandler: OAuth2Handler | null = null;\n\tprivate refreshTokenValue?: string; // Store refresh token separately\n\tprivate logger = getLogger();\n\n\tconstructor(baseUrl?: string) {\n\t\tconst config = getConfig();\n\t\tthis.baseUrl = baseUrl || config.apiUrl || 'https://app.braingrid.ai';\n\t}\n\n\tasync isAuthenticated(forceValidation: boolean = false): Promise<boolean> {\n\t\ttry {\n\t\t\tconst session = await this.getStoredSession();\n\t\t\tif (!session) {\n\t\t\t\tthis.logger.debug('[AUTH] No stored session found');\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Debug: Log session dates\n\t\t\tthis.logger.debug('[AUTH] Session dates:', {\n\t\t\t\tcreated_at: session.created_at,\n\t\t\t\tupdated_at: session.updated_at,\n\t\t\t\tlogin_time: session.login_time,\n\t\t\t\tnow: new Date(),\n\t\t\t});\n\n\t\t\t// Check if session is expired (JWT tokens expire in 1 hour)\n\t\t\tif (this.isSessionExpired(session)) {\n\t\t\t\tthis.logger.debug(\n\t\t\t\t\t'[AUTH] Session expired (JWT token expired) - attempting automatic refresh'\n\t\t\t\t);\n\n\t\t\t\t// Attempt to refresh the session using refresh token\n\t\t\t\tconst refreshed = await this.refreshSession();\n\t\t\t\tif (refreshed) {\n\t\t\t\t\tthis.logger.debug('[AUTH] Session refreshed successfully');\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tthis.logger.debug('[AUTH] Session refresh failed - authentication required');\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst now = Date.now();\n\n\t\t\t// If forced validation is requested, skip all caching and validate with server\n\t\t\tif (forceValidation) {\n\t\t\t\tthis.logger.debug('[AUTH] Force validation requested - calling server');\n\t\t\t\tconst validationResult = await this.validateSessionWithServer(session);\n\t\t\t\tthis.lastValidationTime = now;\n\t\t\t\tthis.lastValidationResult = validationResult.isValid;\n\n\t\t\t\tthis.logger.debug(\n\t\t\t\t\t`[AUTH] Server validation result: isValid=${validationResult.isValid}, shouldClearSession=${validationResult.shouldClearSession}`\n\t\t\t\t);\n\n\t\t\t\tif (!validationResult.isValid && validationResult.shouldClearSession) {\n\t\t\t\t\tthis.logger.debug('[AUTH] Clearing session due to validation failure');\n\t\t\t\t\tawait this.clearSession();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn validationResult.isValid;\n\t\t\t}\n\n\t\t\t// Grace period: If we're within 1 hour of login, skip server validation\n\t\t\t// Reduced from 24 hours to 1 hour to catch auth issues faster\n\t\t\tlet effectiveLoginTime = this.loginTime;\n\t\t\tif (effectiveLoginTime === 0) {\n\t\t\t\t// Restore login time from session if not set (CLI restart scenario)\n\t\t\t\tif (session.login_time) {\n\t\t\t\t\teffectiveLoginTime = session.login_time.getTime();\n\t\t\t\t\tthis.loginTime = effectiveLoginTime;\n\t\t\t\t} else {\n\t\t\t\t\t// Fallback to updated_at if login_time is not available (old sessions)\n\t\t\t\t\teffectiveLoginTime = session.updated_at.getTime();\n\t\t\t\t\tthis.loginTime = effectiveLoginTime;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst timeSinceLogin = now - effectiveLoginTime;\n\t\t\tconst graceMs = 60 * 60 * 1000; // 1 hour instead of 24 hours\n\t\t\tthis.logger.debug(\n\t\t\t\t`[AUTH] Time since login: ${timeSinceLogin}ms (${Math.round(timeSinceLogin / 1000)}s), grace period: ${graceMs}ms`\n\t\t\t);\n\t\t\tthis.logger.debug(\n\t\t\t\t`[AUTH] Login time: ${new Date(effectiveLoginTime)}, Now: ${new Date(now)}`\n\t\t\t);\n\t\t\tif (timeSinceLogin < graceMs) {\n\t\t\t\t// Within 1-hour grace period after login - skip server validation\n\t\t\t\tthis.logger.debug('[AUTH] Within grace period - skipping server validation');\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// Use cached validation result if recent enough (15 minutes instead of 1 hour)\n\t\t\tconst cacheMs = 15 * 60 * 1000; // 15 minutes\n\t\t\tif (now - this.lastValidationTime < cacheMs && this.lastValidationResult) {\n\t\t\t\t// Only trust positive cached results, always revalidate failures\n\t\t\t\treturn this.lastValidationResult;\n\t\t\t}\n\n\t\t\t// Validate with server\n\t\t\tconst validationResult = await this.validateSessionWithServer(session);\n\t\t\tthis.lastValidationTime = now;\n\t\t\tthis.lastValidationResult = validationResult.isValid;\n\n\t\t\t// Update user data if validation returned fresh user info\n\t\t\tif (validationResult.user && session.user) {\n\t\t\t\tsession.user = validationResult.user;\n\t\t\t}\n\n\t\t\t// Only clear session for definitive authentication failures, not temporary issues\n\t\t\tif (!validationResult.isValid) {\n\t\t\t\tif (validationResult.shouldClearSession) {\n\t\t\t\t\t// Clear session only for permanent auth failures (401, 403, invalid token)\n\t\t\t\t\tawait this.clearSession();\n\t\t\t\t\treturn false;\n\t\t\t\t} else {\n\t\t\t\t\t// For temporary issues (network errors, 500s, redirects), don't clear session\n\t\t\t\t\t// Fall back to local session check to be more forgiving\n\t\t\t\t\treturn !this.isSessionExpired(session);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} catch {\n\t\t\t// On any error, check if we have a local session that isn't expired\n\t\t\ttry {\n\t\t\t\tconst session = await this.getStoredSession();\n\t\t\t\treturn session !== null && !this.isSessionExpired(session);\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync getCurrentUser(): Promise<User | null> {\n\t\ttry {\n\t\t\tconst session = await this.getStoredSession();\n\t\t\tif (!session) return null;\n\n\t\t\t// First try to get user from stored session\n\t\t\tif (session.user && session.user.id && session.user.email) {\n\t\t\t\treturn session.user;\n\t\t\t}\n\n\t\t\t// If user info is missing or incomplete, decode from JWT\n\t\t\tconst jwtPayload = decodeJWT(session.sealed_session);\n\t\t\tif (!jwtPayload) {\n\t\t\t\t// If we can't decode the JWT, return what we have\n\t\t\t\treturn session.user || null;\n\t\t\t}\n\n\t\t\t// Extract user info from JWT\n\t\t\tconst userInfo = extractUserFromJWT(jwtPayload);\n\n\t\t\t// Create a User object from JWT data\n\t\t\tconst user: User = {\n\t\t\t\tobject: 'user',\n\t\t\t\tid: userInfo.id,\n\t\t\t\temail: userInfo.email,\n\t\t\t\temailVerified: true, // Assume verified if they have a valid JWT\n\t\t\t\tfirstName: userInfo.firstName,\n\t\t\t\tlastName: userInfo.lastName,\n\t\t\t\tprofilePictureUrl: '', // Not available in JWT\n\t\t\t\tcreatedAt: new Date(jwtPayload.iat ? jwtPayload.iat * 1000 : Date.now()).toISOString(),\n\t\t\t\tupdatedAt: new Date().toISOString(),\n\t\t\t\tlastSignInAt: new Date().toISOString(),\n\t\t\t\texternalId: null,\n\t\t\t\tmetadata: jwtPayload.metadata || {},\n\t\t\t};\n\n\t\t\t// Update the stored session with user info from JWT\n\t\t\tsession.user = user;\n\t\t\tawait this.storeSession(session);\n\n\t\t\treturn user;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync hasStoredSession(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst session = await this.getStoredSession();\n\t\t\treturn session !== null && !this.isSessionExpired(session);\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync getStoredSession(): Promise<BraingridSession | null> {\n\t\ttry {\n\t\t\tconst sessionData = await credentialStore.getPassword(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT);\n\t\t\tif (!sessionData) return null;\n\n\t\t\tconst session = JSON.parse(sessionData) as BraingridSession;\n\t\t\treturn {\n\t\t\t\t...session,\n\t\t\t\tcreated_at: new Date(session.created_at),\n\t\t\t\tupdated_at: new Date(session.updated_at),\n\t\t\t\tlogin_time: session.login_time ? new Date(session.login_time) : undefined,\n\t\t\t};\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync storeSession(session: BraingridSession): Promise<void> {\n\t\tconst now = new Date();\n\t\t// Add login time to session data for persistence across CLI instances\n\t\tconst sessionWithLoginTime = {\n\t\t\t...session,\n\t\t\tlogin_time: now,\n\t\t};\n\t\tconst sessionData = JSON.stringify(sessionWithLoginTime);\n\t\tawait credentialStore.setPassword(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, sessionData);\n\t\t// Mark session as valid when we store it and record login time\n\t\tconst nowMs = now.getTime();\n\t\tthis.lastValidationTime = nowMs;\n\t\tthis.lastValidationResult = true;\n\t\tthis.loginTime = nowMs;\n\t}\n\n\tasync clearSession(): Promise<void> {\n\t\tawait credentialStore.deletePassword(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT);\n\t\t// Also clear refresh token\n\t\tawait credentialStore.deletePassword(KEYCHAIN_SERVICE, 'refresh-token');\n\t\tthis.refreshTokenValue = undefined;\n\t\t// Clear the validation cache when session is cleared\n\t\tthis.lastValidationTime = 0;\n\t\tthis.lastValidationResult = false;\n\t}\n\n\tasync handleAuthenticationError(): Promise<void> {\n\t\t// Clear validation cache but don't automatically clear session\n\t\t// Let the user explicitly re-authenticate if needed\n\t\tthis.lastValidationTime = 0;\n\t\tthis.lastValidationResult = false;\n\t}\n\n\t/**\n\t * Start login flow for RPC mode - returns auth URL without opening browser\n\t */\n\tasync startLoginForRpc(): Promise<{ authUrl: string; redirectUri: string }> {\n\t\ttry {\n\t\t\t// Use OAuth2 Authorization Code Flow with PKCE for authentication\n\t\t\tthis.oauthHandler = new OAuth2Handler();\n\n\t\t\t// Prepare auth URL without opening browser\n\t\t\tconst urlResult = await this.oauthHandler.prepareAuthUrl();\n\n\t\t\treturn {\n\t\t\t\tauthUrl: urlResult.authUrl,\n\t\t\t\tredirectUri: urlResult.redirectUri,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tif (this.oauthHandler) {\n\t\t\t\tthis.oauthHandler.abort();\n\t\t\t\tthis.oauthHandler = null;\n\t\t\t}\n\t\t\tthrow new Error(`Failed to start login: ${error}`);\n\t\t}\n\t}\n\n\t/**\n\t * Complete login flow for RPC mode - waits for browser callback\n\t */\n\tasync completeLoginForRpc(): Promise<{ user: User; success: boolean }> {\n\t\tif (!this.oauthHandler) {\n\t\t\tthrow new Error('Must call startLoginForRpc() first');\n\t\t}\n\n\t\ttry {\n\t\t\t// Wait for OAuth callback and get tokens\n\t\t\tconst authResult = await this.oauthHandler.completeAuth();\n\n\t\t\t// Process tokens and create session (same as regular login)\n\t\t\treturn await this.processAuthResult(authResult);\n\t\t} catch (error) {\n\t\t\tif (this.oauthHandler) {\n\t\t\t\tthis.oauthHandler.abort();\n\t\t\t\tthis.oauthHandler = null;\n\t\t\t}\n\t\t\tthrow new Error(`Login failed: ${error}`);\n\t\t}\n\t}\n\n\t/**\n\t * Process OAuth result and create session\n\t */\n\tprivate async processAuthResult(\n\t\tauthResult: {\n\t\t\taccessToken: string;\n\t\t\trefreshToken?: string;\n\t\t\tidToken?: string;\n\t\t},\n\t\tgitUser?: GitUser\n\t): Promise<{ user: User; success: boolean }> {\n\t\t// Store refresh token separately if available\n\t\tif (authResult.refreshToken) {\n\t\t\tthis.refreshTokenValue = authResult.refreshToken;\n\t\t\t// Store refresh token securely\n\t\t\tawait credentialStore.setPassword(KEYCHAIN_SERVICE, 'refresh-token', authResult.refreshToken);\n\t\t}\n\n\t\t// Use ID token if available, otherwise use access token\n\t\tconst tokenToProcess = authResult.idToken || authResult.accessToken;\n\n\t\t// Extract user info from JWT\n\t\tconst jwtPayload = decodeJWT(tokenToProcess);\n\t\tif (!jwtPayload) {\n\t\t\tthrow new Error('Invalid token received - unable to decode');\n\t\t}\n\n\t\t// Extract user info from JWT\n\t\tconst userInfo = extractUserFromJWT(jwtPayload);\n\n\t\t// Create user object from JWT data\n\t\tconst user: User = {\n\t\t\tobject: 'user',\n\t\t\tid: userInfo.id,\n\t\t\temail: userInfo.email,\n\t\t\temailVerified: true, // Assume verified if they have a valid JWT\n\t\t\tfirstName: userInfo.firstName,\n\t\t\tlastName: userInfo.lastName,\n\t\t\tprofilePictureUrl: '', // Not available in JWT\n\t\t\tcreatedAt: new Date(jwtPayload.iat ? jwtPayload.iat * 1000 : Date.now()).toISOString(),\n\t\t\tupdatedAt: new Date().toISOString(),\n\t\t\tlastSignInAt: new Date().toISOString(),\n\t\t\texternalId: null,\n\t\t\tmetadata: jwtPayload.metadata || {},\n\t\t};\n\n\t\t// Store the session\n\t\tconst session: BraingridSession = {\n\t\t\tuser: user,\n\t\t\tsealed_session: authResult.accessToken, // Store access token as sealed_session\n\t\t\torganization_id: jwtPayload.organization_id || 'default', // Use organization from token or default\n\t\t\tcreated_at: new Date(),\n\t\t\tupdated_at: new Date(),\n\t\t\tlogin_time: new Date(),\n\t\t\tgit_user: gitUser, // Store git user info if provided\n\t\t};\n\n\t\tawait this.storeSession(session);\n\n\t\treturn { user, success: true };\n\t}\n\n\tasync login(\n\t\tonAuthUrl?: (authUrl: string) => void,\n\t\tgitUser?: GitUser\n\t): Promise<{ user: User; success: boolean }> {\n\t\ttry {\n\t\t\t// Use OAuth2 Authorization Code Flow with PKCE for authentication\n\t\t\tthis.oauthHandler = new OAuth2Handler();\n\n\t\t\t// Set callback if provided\n\t\t\tif (onAuthUrl) {\n\t\t\t\tthis.oauthHandler.setAuthUrlCallback(onAuthUrl);\n\t\t\t}\n\n\t\t\tconst authResult = await this.oauthHandler.authenticate();\n\n\t\t\t// Process auth result and create session\n\t\t\treturn await this.processAuthResult(authResult, gitUser);\n\t\t} catch (error) {\n\t\t\tif (this.oauthHandler) {\n\t\t\t\tthis.oauthHandler.abort();\n\t\t\t\tthis.oauthHandler = null;\n\t\t\t}\n\t\t\tthrow new Error(`Login failed: ${error}`);\n\t\t}\n\t}\n\n\tcancelLogin(): void {\n\t\tif (this.oauthHandler) {\n\t\t\tthis.oauthHandler.abort();\n\t\t\tthis.oauthHandler = null;\n\t\t}\n\t}\n\n\tasync logout(): Promise<void> {\n\t\tawait this.clearSession();\n\t}\n\n\tasync refreshSession(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst session = await this.getStoredSession();\n\t\t\tif (!session) {\n\t\t\t\tthis.logger.debug('[AUTH] No session found for refresh');\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Get stored refresh token\n\t\t\tlet refreshToken = this.refreshTokenValue;\n\t\t\tif (!refreshToken) {\n\t\t\t\trefreshToken =\n\t\t\t\t\t(await credentialStore.getPassword(KEYCHAIN_SERVICE, 'refresh-token')) || undefined;\n\t\t\t}\n\n\t\t\tif (!refreshToken) {\n\t\t\t\t// No refresh token available, cannot refresh\n\t\t\t\tthis.logger.debug('[AUTH] No refresh token available');\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis.logger.debug('[AUTH] Attempting to refresh access token');\n\n\t\t\t// Use OAuth2 handler to refresh the token\n\t\t\tconst handler = new OAuth2Handler();\n\t\t\tconst authResult = await handler.refreshToken(refreshToken);\n\n\t\t\t// Update stored refresh token if new one provided\n\t\t\tif (authResult.refreshToken && authResult.refreshToken !== refreshToken) {\n\t\t\t\tthis.refreshTokenValue = authResult.refreshToken;\n\t\t\t\tawait credentialStore.setPassword(\n\t\t\t\t\tKEYCHAIN_SERVICE,\n\t\t\t\t\t'refresh-token',\n\t\t\t\t\tauthResult.refreshToken\n\t\t\t\t);\n\t\t\t\tthis.logger.debug('[AUTH] Refresh token rotated');\n\t\t\t}\n\n\t\t\t// Update session with new access token\n\t\t\tsession.sealed_session = authResult.accessToken;\n\t\t\tsession.updated_at = new Date();\n\t\t\tawait this.storeSession(session);\n\n\t\t\tthis.logger.debug('[AUTH] Access token refreshed successfully');\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\tthis.logger.warn(`[AUTH] Token refresh failed: ${errorMsg}`);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate async validateSessionWithServer(\n\t\tsession: BraingridSession\n\t): Promise<{ isValid: boolean; shouldClearSession: boolean; user?: User }> {\n\t\ttry {\n\t\t\tthis.logger.debug(\n\t\t\t\t`[AUTH] Making API call to ${this.baseUrl}/api/v1/auth/validate for session validation`\n\t\t\t);\n\t\t\t// Use the new v1 auth validate endpoint\n\t\t\tconst response = await axiosWithRetry(\n\t\t\t\t{\n\t\t\t\t\turl: `${this.baseUrl}/api/v1/auth/validate`,\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\tAuthorization: `Bearer ${session.sealed_session}`,\n\t\t\t\t\t},\n\t\t\t\t\tmaxRedirects: 0, // Don't follow redirects\n\t\t\t\t\tvalidateStatus: status => status < 500, // Accept all status codes < 500\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tmaxRetries: 2,\n\t\t\t\t\tinitialDelay: 500,\n\t\t\t\t\tonRetry: (attempt, delay) => {\n\t\t\t\t\t\tconsole.warn(`Retrying session validation (attempt ${attempt}) after ${delay}ms`);\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tthis.logger.debug(\n\t\t\t\t`[AUTH] API response: status=${response.status}, contentType=${response.headers['content-type']}`\n\t\t\t);\n\n\t\t\t// Debug response data\n\t\t\tif (response.headers['content-type']?.includes('application/json')) {\n\t\t\t\tthis.logger.debug('[AUTH] API response data:', {\n\t\t\t\t\tdata: JSON.stringify(response.data).substring(0, 200),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Handle redirects (302, 307) - likely temporary, don't clear session\n\t\t\tif (response.status === 302 || response.status === 307) {\n\t\t\t\tthis.logger.warn(\n\t\t\t\t\t`Session validation received ${response.status} redirect - treating as temporary issue`\n\t\t\t\t);\n\t\t\t\treturn { isValid: false, shouldClearSession: false };\n\t\t\t}\n\n\t\t\tif (response.status === 200) {\n\t\t\t\t// Parse the validation response\n\t\t\t\tconst validationData = response.data as {\n\t\t\t\t\tvalid: boolean;\n\t\t\t\t\texp?: number;\n\t\t\t\t\tuser?: {\n\t\t\t\t\t\tid: string;\n\t\t\t\t\t\temail: string;\n\t\t\t\t\t\tusername?: string;\n\t\t\t\t\t\tfirstName?: string;\n\t\t\t\t\t\tlastName?: string;\n\t\t\t\t\t\tavatar?: string;\n\t\t\t\t\t};\n\t\t\t\t\torganization?: {\n\t\t\t\t\t\tid: string;\n\t\t\t\t\t\tname: string;\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\tif (validationData.valid === true && validationData.user) {\n\t\t\t\t\t// Extract user information from the validation response\n\t\t\t\t\tconst user: User = {\n\t\t\t\t\t\tobject: 'user',\n\t\t\t\t\t\tid: validationData.user.id,\n\t\t\t\t\t\temail: validationData.user.email,\n\t\t\t\t\t\temailVerified: true, // Assume verified if they have a valid token\n\t\t\t\t\t\tfirstName: validationData.user.firstName || '',\n\t\t\t\t\t\tlastName: validationData.user.lastName || '',\n\t\t\t\t\t\tprofilePictureUrl: validationData.user.avatar || '',\n\t\t\t\t\t\tcreatedAt: session.user?.createdAt || new Date().toISOString(),\n\t\t\t\t\t\tupdatedAt: new Date().toISOString(),\n\t\t\t\t\t\tlastSignInAt: new Date().toISOString(),\n\t\t\t\t\t\texternalId: null,\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\tusername: validationData.user.username,\n\t\t\t\t\t\t\torganizationId: validationData.organization?.id,\n\t\t\t\t\t\t\torganizationName: validationData.organization?.name,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\n\t\t\t\t\t// Update the stored session with fresh user info\n\t\t\t\t\tif (\n\t\t\t\t\t\tsession.user?.id !== user.id ||\n\t\t\t\t\t\tsession.user?.email !== user.email ||\n\t\t\t\t\t\tsession.user?.firstName !== user.firstName ||\n\t\t\t\t\t\tsession.user?.lastName !== user.lastName\n\t\t\t\t\t) {\n\t\t\t\t\t\tsession.user = user;\n\t\t\t\t\t\tsession.organization_id = validationData.organization?.id || session.organization_id;\n\t\t\t\t\t\tawait this.storeSession(session);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn { isValid: true, shouldClearSession: false, user };\n\t\t\t\t} else if (validationData.valid === false) {\n\t\t\t\t\t// Token is explicitly invalid\n\t\t\t\t\tthis.logger.warn('Token validation failed: token is invalid');\n\t\t\t\t\treturn { isValid: false, shouldClearSession: true };\n\t\t\t\t}\n\n\t\t\t\t// Unexpected response format\n\t\t\t\tthis.logger.warn('Unexpected validation response format');\n\t\t\t\treturn { isValid: false, shouldClearSession: false };\n\t\t\t} else if (response.status === 401 || response.status === 403) {\n\t\t\t\t// Clear session for definitive authentication failures\n\t\t\t\tthis.logger.warn(\n\t\t\t\t\t`Session validation failed: ${response.status} ${response.statusText} - clearing session`\n\t\t\t\t);\n\t\t\t\treturn { isValid: false, shouldClearSession: true };\n\t\t\t} else {\n\t\t\t\t// For other errors (500, 404, etc.), don't clear session - might be temporary\n\t\t\t\tthis.logger.warn(\n\t\t\t\t\t`API error during session validation: ${response.status} - assuming session is valid`\n\t\t\t\t);\n\t\t\t\treturn { isValid: true, shouldClearSession: false }; // Assume session is still valid, server might be having issues\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Network error or API unavailable - don't clear session, might be temporary\n\t\t\tthis.logger.warn('Network error during session validation - assuming session is valid:', {\n\t\t\t\terror,\n\t\t\t});\n\t\t\treturn { isValid: true, shouldClearSession: false };\n\t\t}\n\t}\n\n\tprivate isSessionExpired(session: BraingridSession): boolean {\n\t\t// JWT tokens expire in 1 hour, so we only need to check JWT expiry\n\t\treturn isJWTExpired(session.sealed_session);\n\t}\n\n\tgetUserDisplayName(user: User): string {\n\t\tif (user.firstName && user.lastName) {\n\t\t\treturn `${user.firstName} ${user.lastName}`;\n\t\t}\n\t\tif (user.firstName) {\n\t\t\treturn user.firstName;\n\t\t}\n\t\tif (user.email) {\n\t\t\treturn user.email;\n\t\t}\n\t\treturn 'Unknown User';\n\t}\n\n\tisUserValid(user: User): boolean {\n\t\treturn Boolean(user.id && user.email);\n\t}\n\n\tisSessionValid(session: BraingridSession): boolean {\n\t\treturn this.isUserValid(session.user) && Boolean(session.sealed_session);\n\t}\n\n\t// GitHub token management methods\n\tasync getStoredGitHubToken(): Promise<string | null> {\n\t\ttry {\n\t\t\treturn await credentialStore.getPassword(KEYCHAIN_SERVICE, GITHUB_KEYCHAIN_ACCOUNT);\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync storeGitHubToken(token: string): Promise<void> {\n\t\tif (!token || !token.trim()) {\n\t\t\tthrow new Error('GitHub token cannot be empty');\n\t\t}\n\t\tawait credentialStore.setPassword(KEYCHAIN_SERVICE, GITHUB_KEYCHAIN_ACCOUNT, token.trim());\n\t}\n\n\tasync clearGitHubToken(): Promise<void> {\n\t\tawait credentialStore.deletePassword(KEYCHAIN_SERVICE, GITHUB_KEYCHAIN_ACCOUNT);\n\t}\n\n\tasync validateGitHubToken(\n\t\ttoken?: string\n\t): Promise<{ valid: boolean; user?: Record<string, unknown>; scopes?: string[] }> {\n\t\ttry {\n\t\t\tconst tokenToValidate = token || (await this.getStoredGitHubToken());\n\t\t\tif (!tokenToValidate) {\n\t\t\t\treturn { valid: false };\n\t\t\t}\n\n\t\t\tconst response = await axios.get('https://api.github.com/user', {\n\t\t\t\theaders: {\n\t\t\t\t\tAccept: 'application/vnd.github+json',\n\t\t\t\t\tAuthorization: `Bearer ${tokenToValidate}`,\n\t\t\t\t\t'X-GitHub-Api-Version': '2022-11-28',\n\t\t\t\t\t'User-Agent': 'Braingrid-CLI',\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (response.status >= 400) {\n\t\t\t\treturn { valid: false };\n\t\t\t}\n\n\t\t\tconst user = response.data;\n\t\t\tconst scopes = response.headers['x-oauth-scopes']?.split(', ') || [];\n\n\t\t\treturn {\n\t\t\t\tvalid: true,\n\t\t\t\tuser,\n\t\t\t\tscopes,\n\t\t\t};\n\t\t} catch {\n\t\t\treturn { valid: false };\n\t\t}\n\t}\n}\n","import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';\n\nexport interface RetryOptions {\n\tmaxRetries?: number;\n\tinitialDelay?: number;\n\tmaxDelay?: number;\n\tbackoffMultiplier?: number;\n\tretryableStatuses?: number[];\n\tonRetry?: (attempt: number, delay: number, error: unknown) => void;\n}\n\nconst DEFAULT_OPTIONS: Required<RetryOptions> = {\n\tmaxRetries: 3,\n\tinitialDelay: 1000, // 1 second\n\tmaxDelay: 30000, // 30 seconds\n\tbackoffMultiplier: 2,\n\tretryableStatuses: [408, 429, 500, 502, 503, 504], // Timeout, Too Many Requests, Server Errors\n\tonRetry: () => {}, // No-op by default\n};\n\nexport async function sleep(ms: number): Promise<void> {\n\treturn new Promise(resolve => setTimeout(resolve, ms));\n}\n\nexport function calculateDelay(\n\tattempt: number,\n\tinitialDelay: number,\n\tmaxDelay: number,\n\tbackoffMultiplier: number\n): number {\n\tconst exponentialDelay = initialDelay * Math.pow(backoffMultiplier, attempt - 1);\n\tconst jitteredDelay = exponentialDelay * (0.5 + Math.random() * 0.5); // Add jitter\n\treturn Math.min(jitteredDelay, maxDelay);\n}\n\nexport function isRetryableError(error: unknown, retryableStatuses: number[]): boolean {\n\t// Type guard to check if error has expected properties\n\tconst hasErrorCode = (err: unknown): err is { code: string } =>\n\t\ttypeof err === 'object' && err !== null && 'code' in err;\n\tconst hasErrorMessage = (err: unknown): err is { message?: string } =>\n\t\ttypeof err === 'object' && err !== null;\n\tconst hasResponseStatus = (err: unknown): err is { response?: { status: number } } =>\n\t\ttypeof err === 'object' && err !== null && 'response' in err;\n\t// Network errors are always retryable\n\tif (hasErrorCode(error)) {\n\t\tif (\n\t\t\terror.code === 'ECONNRESET' ||\n\t\t\terror.code === 'ETIMEDOUT' ||\n\t\t\terror.code === 'ENOTFOUND' ||\n\t\t\terror.code === 'ECONNREFUSED' ||\n\t\t\terror.code === 'ECONNABORTED'\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tif (hasErrorMessage(error) && error.message) {\n\t\tif (error.message.includes('network') || error.message.includes('Network')) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// Check if it's an HTTP error with a retryable status\n\tif (hasResponseStatus(error) && error.response?.status) {\n\t\tif (retryableStatuses.includes(error.response.status)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n// Create axios instance with default config\nexport const axiosInstance: AxiosInstance = axios.create({\n\ttimeout: 120000, // 2 minutes default timeout\n\theaders: {\n\t\t'User-Agent': 'Braingrid-CLI',\n\t},\n\t// Don't throw on any status to handle errors ourselves\n\tvalidateStatus: () => true,\n});\n\nexport async function axiosWithRetry<T = unknown>(\n\tconfig: AxiosRequestConfig,\n\toptions?: RetryOptions\n): Promise<AxiosResponse<T>> {\n\tconst opts = { ...DEFAULT_OPTIONS, ...options };\n\tlet lastError: unknown;\n\n\tfor (let attempt = 1; attempt <= opts.maxRetries + 1; attempt++) {\n\t\ttry {\n\t\t\tconst response = await axiosInstance.request<T>(config);\n\n\t\t\t// Check if the response status is retryable\n\t\t\tif (\n\t\t\t\tresponse.status >= 400 &&\n\t\t\t\topts.retryableStatuses.includes(response.status) &&\n\t\t\t\tattempt <= opts.maxRetries\n\t\t\t) {\n\t\t\t\tconst error: Error & { response?: AxiosResponse<T>; status?: number } = new Error(\n\t\t\t\t\t`HTTP ${response.status}: ${response.statusText}`\n\t\t\t\t);\n\t\t\t\terror.response = response;\n\t\t\t\terror.status = response.status;\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\treturn response;\n\t\t} catch (error: unknown) {\n\t\t\tlastError = error;\n\n\t\t\t// Check if we should retry\n\t\t\tif (attempt <= opts.maxRetries && isRetryableError(error, opts.retryableStatuses)) {\n\t\t\t\tconst delay = calculateDelay(\n\t\t\t\t\tattempt,\n\t\t\t\t\topts.initialDelay,\n\t\t\t\t\topts.maxDelay,\n\t\t\t\t\topts.backoffMultiplier\n\t\t\t\t);\n\t\t\t\topts.onRetry(attempt, delay, error);\n\t\t\t\tawait sleep(delay);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If not retryable or max retries exceeded, throw the error\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// This should never be reached, but just in case\n\tthrow lastError || new Error('Unexpected error in axiosWithRetry');\n}\n\n// Enhanced wrapper for common use cases\nexport class RetryableHttpClient {\n\tprivate defaultOptions: RetryOptions;\n\n\tconstructor(defaultOptions?: RetryOptions) {\n\t\tthis.defaultOptions = defaultOptions || {};\n\t}\n\n\tasync get<T = unknown>(\n\t\turl: string,\n\t\tconfig?: AxiosRequestConfig,\n\t\toptions?: RetryOptions\n\t): Promise<AxiosResponse<T>> {\n\t\treturn axiosWithRetry<T>(\n\t\t\t{ ...config, method: 'GET', url },\n\t\t\t{ ...this.defaultOptions, ...options }\n\t\t);\n\t}\n\n\tasync post<T = unknown>(\n\t\turl: string,\n\t\tdata?: unknown,\n\t\tconfig?: AxiosRequestConfig,\n\t\toptions?: RetryOptions\n\t): Promise<AxiosResponse<T>> {\n\t\treturn axiosWithRetry<T>(\n\t\t\t{\n\t\t\t\t...config,\n\t\t\t\tmethod: 'POST',\n\t\t\t\turl,\n\t\t\t\tdata,\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t...config?.headers,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ ...this.defaultOptions, ...options }\n\t\t);\n\t}\n\n\tasync patch<T = unknown>(\n\t\turl: string,\n\t\tdata?: unknown,\n\t\tconfig?: AxiosRequestConfig,\n\t\toptions?: RetryOptions\n\t): Promise<AxiosResponse<T>> {\n\t\treturn axiosWithRetry<T>(\n\t\t\t{\n\t\t\t\t...config,\n\t\t\t\tmethod: 'PATCH',\n\t\t\t\turl,\n\t\t\t\tdata,\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t...config?.headers,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ ...this.defaultOptions, ...options }\n\t\t);\n\t}\n\n\tasync delete<T = unknown>(\n\t\turl: string,\n\t\tconfig?: AxiosRequestConfig,\n\t\toptions?: RetryOptions\n\t): Promise<AxiosResponse<T>> {\n\t\treturn axiosWithRetry<T>(\n\t\t\t{ ...config, method: 'DELETE', url },\n\t\t\t{ ...this.defaultOptions, ...options }\n\t\t);\n\t}\n}\n","import { createHash, randomBytes } from 'crypto';\nimport { createServer, IncomingMessage, ServerResponse } from 'http';\nimport open from 'open';\nimport axios, { AxiosError } from 'axios';\nimport { getConfig } from '../utils/config.js';\nimport { getLogger } from '../utils/logger.js';\nimport type { OAuth2TokenResponse, OAuth2ErrorResponse } from '../types/auth.js';\n\nconst logger = getLogger();\n\nexport interface OAuth2AuthResult {\n\taccessToken: string;\n\trefreshToken?: string;\n\tidToken?: string;\n\texpiresIn?: number;\n\ttokenType?: string;\n}\n\nexport interface OAuth2AuthUrlResult {\n\tauthUrl: string;\n\tredirectUri: string;\n\tstate: string;\n}\n\ninterface PKCEChallenge {\n\tverifier: string;\n\tchallenge: string;\n\tmethod: 'S256';\n}\n\nexport class OAuth2Handler {\n\tprivate abortController?: AbortController;\n\tprivate onAuthCodeReceived?: (authUrl: string) => void;\n\tprivate server?: ReturnType<typeof createServer>;\n\tprivate authorizationCode?: string;\n\tprivate authError?: string;\n\tprivate state?: string;\n\tprivate pkceVerifier?: string;\n\n\t/**\n\t * Set callback for when auth URL is ready\n\t */\n\tsetAuthUrlCallback(callback: (authUrl: string) => void): void {\n\t\tthis.onAuthCodeReceived = callback;\n\t}\n\n\t/**\n\t * Generate PKCE challenge for OAuth2 flow\n\t */\n\tprivate generatePKCEChallenge(): PKCEChallenge {\n\t\t// Generate a cryptographically secure random verifier (43-128 chars)\n\t\tconst verifier = randomBytes(32).toString('base64url');\n\n\t\t// Create challenge from verifier using SHA256\n\t\tconst challenge = createHash('sha256').update(verifier).digest('base64url');\n\n\t\treturn {\n\t\t\tverifier,\n\t\t\tchallenge,\n\t\t\tmethod: 'S256',\n\t\t};\n\t}\n\n\t/**\n\t * Generate a cryptographically secure state parameter\n\t */\n\tprivate generateState(): string {\n\t\treturn randomBytes(32).toString('base64url');\n\t}\n\n\t/**\n\t * Get the fixed port for the callback server\n\t */\n\tprivate getCallbackPort(): number {\n\t\t// Use fixed port 34536 for OAuth callback\n\t\treturn 34536;\n\t}\n\n\t/**\n\t * Start local HTTP server to handle OAuth callback\n\t */\n\tprivate async startCallbackServer(port: number): Promise<void> {\n\t\treturn new Promise(resolve => {\n\t\t\tthis.server = createServer((req: IncomingMessage, res: ServerResponse) => {\n\t\t\t\tconst url = new URL(req.url || '', `http://127.0.0.1:${port}`);\n\n\t\t\t\t// Handle OAuth callback\n\t\t\t\tif (url.pathname === '/callback') {\n\t\t\t\t\tconst code = url.searchParams.get('code');\n\t\t\t\t\tconst error = url.searchParams.get('error');\n\t\t\t\t\tconst state = url.searchParams.get('state');\n\n\t\t\t\t\t// Validate state parameter\n\t\t\t\t\tif (state !== this.state) {\n\t\t\t\t\t\tres.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });\n\t\t\t\t\t\tres.end(`\n\t\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t\t<h1>Authentication Failed</h1>\n\t\t\t\t\t\t\t\t\t<p>Invalid state parameter. Please try again.</p>\n\t\t\t\t\t\t\t\t\t<script>window.setTimeout(() => window.close(), 3000);</script>\n\t\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t\t</html>\n\t\t\t\t\t\t`);\n\t\t\t\t\t\tthis.authError = 'Invalid state parameter';\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\t// Handle error response\n\t\t\t\t\t\tconst errorDescription = url.searchParams.get('error_description') || 'Unknown error';\n\t\t\t\t\t\tres.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });\n\t\t\t\t\t\tres.end(`\n\t\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t\t<h1>Authentication Failed</h1>\n\t\t\t\t\t\t\t\t\t<p>${errorDescription}</p>\n\t\t\t\t\t\t\t\t\t<script>window.setTimeout(() => window.close(), 3000);</script>\n\t\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t\t</html>\n\t\t\t\t\t\t`);\n\t\t\t\t\t\tthis.authError = errorDescription;\n\t\t\t\t\t} else if (code) {\n\t\t\t\t\t\t// Success! Store the code\n\t\t\t\t\t\tthis.authorizationCode = code;\n\t\t\t\t\t\tres.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\n\t\t\t\t\t\tres.end(`\n\t\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t\t<head>\n\t\t\t\t\t\t\t\t\t<style>\n\t\t\t\t\t\t\t\t\t\tbody { font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }\n\t\t\t\t\t\t\t\t\t\t.container { background: white; padding: 2rem; border-radius: 10px; box-shadow: 0 10px 40px rgba(0,0,0,0.1); text-align: center; }\n\t\t\t\t\t\t\t\t\t\th1 { color: #2d3748; margin-bottom: 1rem; }\n\t\t\t\t\t\t\t\t\t\tp { color: #718096; }\n\t\t\t\t\t\t\t\t\t\t.success-icon { font-size: 3rem; margin-bottom: 1rem; }\n\t\t\t\t\t\t\t\t\t</style>\n\t\t\t\t\t\t\t\t</head>\n\t\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t\t<div class=\"container\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"success-icon\">✅</div>\n\t\t\t\t\t\t\t\t\t\t<h1>Authentication Successful!</h1>\n\t\t\t\t\t\t\t\t\t\t<p>You can now close this window and return to the CLI.</p>\n\t\t\t\t\t\t\t\t\t\t<script>window.setTimeout(() => window.close(), 2000);</script>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t\t</html>\n\t\t\t\t\t\t`);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// No code or error\n\t\t\t\t\t\tres.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });\n\t\t\t\t\t\tres.end(`\n\t\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t\t<h1>Authentication Failed</h1>\n\t\t\t\t\t\t\t\t\t<p>No authorization code received.</p>\n\t\t\t\t\t\t\t\t\t<script>window.setTimeout(() => window.close(), 3000);</script>\n\t\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t\t</html>\n\t\t\t\t\t\t`);\n\t\t\t\t\t\tthis.authError = 'No authorization code received';\n\t\t\t\t\t}\n\n\t\t\t\t\t// Close the server after handling the callback\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tif (this.server) {\n\t\t\t\t\t\t\tthis.server.close();\n\t\t\t\t\t\t\tthis.server = undefined;\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 500);\n\t\t\t\t} else {\n\t\t\t\t\t// Handle other routes (redirect to /callback or show waiting page)\n\t\t\t\t\tres.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\n\t\t\t\t\tres.end(`\n\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t<head>\n\t\t\t\t\t\t\t\t<style>\n\t\t\t\t\t\t\t\t\tbody { font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }\n\t\t\t\t\t\t\t\t\t.container { background: white; padding: 2rem; border-radius: 10px; box-shadow: 0 10px 40px rgba(0,0,0,0.1); text-align: center; }\n\t\t\t\t\t\t\t\t\th1 { color: #2d3748; }\n\t\t\t\t\t\t\t\t\t.spinner { border: 3px solid #f3f4f6; border-top: 3px solid #667eea; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 1rem auto; }\n\t\t\t\t\t\t\t\t\t@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\n\t\t\t\t\t\t\t\t</style>\n\t\t\t\t\t\t\t</head>\n\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t<div class=\"container\">\n\t\t\t\t\t\t\t\t\t<h1>Waiting for authentication...</h1>\n\t\t\t\t\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t\t\t\t\t\t<p>Please complete the authentication in your browser.</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t</html>\n\t\t\t\t\t`);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.server.listen(port, '127.0.0.1', () => {\n\t\t\t\tlogger.debug(`Callback server listening on http://127.0.0.1:${port}`);\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Build the authorization URL with PKCE parameters\n\t */\n\tprivate buildAuthorizationUrl(pkce: PKCEChallenge, redirectUri: string): string {\n\t\tconst config = getConfig();\n\n\t\t// Use WorkOS AuthKit directly like the MCP server does\n\t\tconst authUrl = config.getWorkOSAuthUrl();\n\n\t\t// Generate state for CSRF protection\n\t\tthis.state = this.generateState();\n\n\t\tconst params = new URLSearchParams({\n\t\t\tclient_id: config.oauthClientId || 'braingrid-cli',\n\t\t\tredirect_uri: redirectUri,\n\t\t\tresponse_type: 'code',\n\t\t\tscope: 'openid email profile offline_access',\n\t\t\tstate: this.state,\n\t\t\tcode_challenge: pkce.challenge,\n\t\t\tcode_challenge_method: pkce.method,\n\t\t});\n\n\t\treturn `${authUrl}/oauth2/authorize?${params.toString()}`;\n\t}\n\n\t/**\n\t * Exchange authorization code for tokens\n\t */\n\tprivate async exchangeCodeForTokens(\n\t\tcode: string,\n\t\tverifier: string,\n\t\tredirectUri: string\n\t): Promise<OAuth2TokenResponse> {\n\t\tconst config = getConfig();\n\t\t// Use WorkOS AuthKit token endpoint\n\t\tconst tokenUrl = `${config.getWorkOSAuthUrl()}/oauth2/token`;\n\n\t\tconst params = new URLSearchParams({\n\t\t\tgrant_type: 'authorization_code',\n\t\t\tclient_id: config.oauthClientId || 'braingrid-cli',\n\t\t\tcode: code,\n\t\t\tredirect_uri: redirectUri,\n\t\t\tcode_verifier: verifier,\n\t\t});\n\n\t\tlogger.debug('Exchanging authorization code for tokens', { tokenUrl });\n\n\t\ttry {\n\t\t\tconst response = await axios.post<OAuth2TokenResponse>(tokenUrl, params.toString(), {\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/x-www-form-urlencoded',\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tlogger.debug('Token exchange successful', {\n\t\t\t\thasAccessToken: !!response.data.access_token,\n\t\t\t\thasRefreshToken: !!response.data.refresh_token,\n\t\t\t});\n\n\t\t\treturn response.data;\n\t\t} catch (error) {\n\t\t\tif (error instanceof AxiosError && error.response) {\n\t\t\t\tconst errorData = error.response.data as OAuth2ErrorResponse;\n\t\t\t\tlogger.error('Token exchange failed', {\n\t\t\t\t\tstatus: error.response.status,\n\t\t\t\t\terror: errorData,\n\t\t\t\t});\n\t\t\t\tthrow new Error(`Token exchange failed: ${errorData.error_description || errorData.error}`);\n\t\t\t}\n\t\t\tthrow new Error(\n\t\t\t\t`Token exchange failed: ${error instanceof Error ? error.message : String(error)}`\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Wait for the authorization code from the callback\n\t */\n\tprivate async waitForAuthorizationCode(timeoutMs: number = 300000): Promise<string> {\n\t\t// 5 minutes timeout\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst startTime = Date.now();\n\n\t\t\tconst checkInterval = setInterval(() => {\n\t\t\t\t// Check if we should abort\n\t\t\t\tif (this.abortController?.signal.aborted) {\n\t\t\t\t\tclearInterval(checkInterval);\n\t\t\t\t\treject(new Error('Authentication cancelled'));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Check for error\n\t\t\t\tif (this.authError) {\n\t\t\t\t\tclearInterval(checkInterval);\n\t\t\t\t\treject(new Error(this.authError));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Check for success\n\t\t\t\tif (this.authorizationCode) {\n\t\t\t\t\tclearInterval(checkInterval);\n\t\t\t\t\tresolve(this.authorizationCode);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Check for timeout\n\t\t\t\tif (Date.now() - startTime > timeoutMs) {\n\t\t\t\t\tclearInterval(checkInterval);\n\t\t\t\t\treject(new Error('Authentication timeout - no response received'));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}, 500); // Check every 500ms\n\t\t});\n\t}\n\n\t/**\n\t * Prepare OAuth2 flow and return auth URL (for RPC mode)\n\t * Starts the callback server but doesn't open the browser\n\t */\n\tasync prepareAuthUrl(): Promise<OAuth2AuthUrlResult> {\n\t\tlogger.info('Preparing OAuth2 authentication URL for RPC mode');\n\n\t\t// Create new AbortController for this authentication session\n\t\tthis.abortController = new AbortController();\n\n\t\t// Reset state\n\t\tthis.authorizationCode = undefined;\n\t\tthis.authError = undefined;\n\t\tthis.state = undefined;\n\t\tthis.pkceVerifier = undefined;\n\n\t\t// Step 1: Generate PKCE challenge\n\t\tconst pkce = this.generatePKCEChallenge();\n\t\tthis.pkceVerifier = pkce.verifier; // Store for later use\n\t\tlogger.debug('PKCE challenge generated');\n\n\t\t// Step 2: Use fixed port and start callback server\n\t\tconst port = this.getCallbackPort();\n\t\tconst redirectUri = `http://127.0.0.1:${port}/callback`;\n\t\tlogger.info('Starting callback server', { port, redirectUri });\n\n\t\tawait this.startCallbackServer(port);\n\n\t\t// Step 3: Build authorization URL\n\t\tconst authUrl = this.buildAuthorizationUrl(pkce, redirectUri);\n\t\tlogger.info('Authorization URL ready for RPC client', { authUrl });\n\n\t\tif (!this.state) {\n\t\t\tthrow new Error('State not initialized');\n\t\t}\n\n\t\treturn {\n\t\t\tauthUrl,\n\t\t\tredirectUri,\n\t\t\tstate: this.state,\n\t\t};\n\t}\n\n\t/**\n\t * Complete the OAuth2 flow after browser authentication (for RPC mode)\n\t * Call this after prepareAuthUrl() and the user has authenticated\n\t */\n\tasync completeAuth(timeoutMs: number = 300000): Promise<OAuth2AuthResult> {\n\t\tif (!this.pkceVerifier) {\n\t\t\tthrow new Error('Must call prepareAuthUrl() before completeAuth()');\n\t\t}\n\n\t\ttry {\n\t\t\t// Wait for authorization code from callback\n\t\t\tlogger.info('Waiting for user to complete authentication in browser...');\n\t\t\tconst code = await this.waitForAuthorizationCode(timeoutMs);\n\t\t\tlogger.info('Authorization code received');\n\n\t\t\t// Get redirect URI from server (it's always the same port)\n\t\t\tconst port = this.getCallbackPort();\n\t\t\tconst redirectUri = `http://127.0.0.1:${port}/callback`;\n\n\t\t\t// Exchange code for tokens\n\t\t\tconst tokens = await this.exchangeCodeForTokens(code, this.pkceVerifier, redirectUri);\n\t\t\tlogger.info('Authentication successful');\n\n\t\t\t// Return token info\n\t\t\treturn {\n\t\t\t\taccessToken: tokens.access_token,\n\t\t\t\trefreshToken: tokens.refresh_token,\n\t\t\t\tidToken: tokens.id_token,\n\t\t\t\texpiresIn: tokens.expires_in,\n\t\t\t\ttokenType: tokens.token_type,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthis.abort();\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\t// Clean up server if still running\n\t\t\tif (this.server) {\n\t\t\t\tthis.server.close();\n\t\t\t\tthis.server = undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Initiates the OAuth2 authorization code flow with PKCE\n\t */\n\tasync authenticate(): Promise<OAuth2AuthResult> {\n\t\tlogger.info('Starting OAuth2 authentication flow with PKCE');\n\n\t\t// Create new AbortController for this authentication session\n\t\tthis.abortController = new AbortController();\n\n\t\t// Reset state\n\t\tthis.authorizationCode = undefined;\n\t\tthis.authError = undefined;\n\t\tthis.state = undefined;\n\n\t\ttry {\n\t\t\t// Step 1: Generate PKCE challenge\n\t\t\tconst pkce = this.generatePKCEChallenge();\n\t\t\tlogger.debug('PKCE challenge generated');\n\n\t\t\t// Step 2: Use fixed port and start callback server\n\t\t\tconst port = this.getCallbackPort();\n\t\t\tconst redirectUri = `http://127.0.0.1:${port}/callback`;\n\t\t\tlogger.info('Starting callback server', { port, redirectUri });\n\n\t\t\tawait this.startCallbackServer(port);\n\n\t\t\t// Step 3: Build authorization URL\n\t\t\tconst authUrl = this.buildAuthorizationUrl(pkce, redirectUri);\n\t\t\tlogger.info('Authorization URL ready', { authUrl });\n\n\t\t\t// Notify callback if set\n\t\t\tif (this.onAuthCodeReceived) {\n\t\t\t\tthis.onAuthCodeReceived(authUrl);\n\t\t\t}\n\n\t\t\t// Step 4: Open browser\n\t\t\ttry {\n\t\t\t\tlogger.debug('Opening browser for authentication');\n\t\t\t\tawait open(authUrl);\n\t\t\t\tlogger.info('Browser opened automatically');\n\t\t\t} catch (error) {\n\t\t\t\tlogger.warn('Failed to open browser automatically', { error });\n\t\t\t\tlogger.info(`Please open the following URL manually:\\n${authUrl}`);\n\t\t\t}\n\n\t\t\t// Step 5: Wait for authorization code\n\t\t\tlogger.info('Waiting for user to complete authentication...');\n\t\t\tconst code = await this.waitForAuthorizationCode();\n\t\t\tlogger.info('Authorization code received');\n\n\t\t\t// Step 6: Exchange code for tokens\n\t\t\tconst tokens = await this.exchangeCodeForTokens(code, pkce.verifier, redirectUri);\n\t\t\tlogger.info('Authentication successful');\n\n\t\t\t// Step 7: Return token info\n\t\t\treturn {\n\t\t\t\taccessToken: tokens.access_token,\n\t\t\t\trefreshToken: tokens.refresh_token,\n\t\t\t\tidToken: tokens.id_token,\n\t\t\t\texpiresIn: tokens.expires_in,\n\t\t\t\ttokenType: tokens.token_type,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\t// Abort any ongoing operations\n\t\t\tthis.abort();\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\t// Clean up server if still running\n\t\t\tif (this.server) {\n\t\t\t\tthis.server.close();\n\t\t\t\tthis.server = undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Refresh an access token using a refresh token\n\t */\n\tasync refreshToken(refreshToken: string): Promise<OAuth2AuthResult> {\n\t\tconst config = getConfig();\n\t\t// Use WorkOS AuthKit token endpoint for refresh\n\t\tconst tokenUrl = `${config.getWorkOSAuthUrl()}/oauth2/token`;\n\n\t\tconst params = new URLSearchParams({\n\t\t\tgrant_type: 'refresh_token',\n\t\t\tclient_id: config.oauthClientId || 'braingrid-cli',\n\t\t\trefresh_token: refreshToken,\n\t\t});\n\n\t\tlogger.debug('Refreshing access token');\n\n\t\ttry {\n\t\t\tconst response = await axios.post<OAuth2TokenResponse>(tokenUrl, params.toString(), {\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/x-www-form-urlencoded',\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tlogger.debug('Token refresh successful');\n\n\t\t\treturn {\n\t\t\t\taccessToken: response.data.access_token,\n\t\t\t\trefreshToken: response.data.refresh_token,\n\t\t\t\tidToken: response.data.id_token,\n\t\t\t\texpiresIn: response.data.expires_in,\n\t\t\t\ttokenType: response.data.token_type,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tif (error instanceof AxiosError && error.response) {\n\t\t\t\tconst errorData = error.response.data as OAuth2ErrorResponse;\n\t\t\t\tlogger.error('Token refresh failed', {\n\t\t\t\t\tstatus: error.response.status,\n\t\t\t\t\terror: errorData,\n\t\t\t\t});\n\t\t\t\tthrow new Error(`Token refresh failed: ${errorData.error_description || errorData.error}`);\n\t\t\t}\n\t\t\tthrow new Error(\n\t\t\t\t`Token refresh failed: ${error instanceof Error ? error.message : String(error)}`\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Abort any ongoing authentication\n\t */\n\tabort(): void {\n\t\tif (this.abortController) {\n\t\t\tthis.abortController.abort();\n\t\t\tthis.abortController = undefined;\n\t\t}\n\n\t\tif (this.server) {\n\t\t\tthis.server.close();\n\t\t\tthis.server = undefined;\n\t\t}\n\t}\n}\n","/**\n * Build-time constants injected by tsup during compilation.\n * These values are determined when the package is built, not at runtime.\n */\n\n/**\n * BUILD_ENV determines which configuration to use.\n * - 'production': Uses production URLs (set via BUILD_ENV=production during build)\n * - 'development': Uses development/local URLs (set via BUILD_ENV=development during build)\n *\n * This value is injected at build time by tsup and cannot be changed at runtime.\n */\ndeclare const __BUILD_ENV__: string | undefined;\nexport const BUILD_ENV = (\n\ttypeof __BUILD_ENV__ !== 'undefined'\n\t\t? __BUILD_ENV__\n\t\t: process.env.NODE_ENV === 'test'\n\t\t\t? 'development'\n\t\t\t: 'production'\n) as 'production' | 'development';\n\n/**\n * CLI_VERSION is read from package.json during build and baked into the bundle.\n * Used for update checks and version display.\n *\n * This value is injected at build time by tsup and cannot be changed at runtime.\n */\ndeclare const __CLI_VERSION__: string | undefined;\nexport const CLI_VERSION = typeof __CLI_VERSION__ !== 'undefined' ? __CLI_VERSION__ : '0.0.0-test';\n\n/**\n * Production configuration\n * Used when BUILD_ENV === 'production' (npm published package)\n */\nexport const PRODUCTION_CONFIG = {\n\tapiUrl: 'https://app.braingrid.ai',\n\tworkosAuthUrl: 'https://sensitive-harvest-60.authkit.app',\n\tworkosClientId: 'client_01K6H010C9K69HSDPM9CQM85S7',\n} as const;\n\n/**\n * Development configuration\n * Used when BUILD_ENV === 'development' (local development)\n */\nexport const DEVELOPMENT_CONFIG = {\n\tapiUrl: 'https://app.dev.braingrid.ai',\n\tworkosAuthUrl: 'https://balanced-celebration-78-staging.authkit.app',\n\tworkosClientId: 'client_01K6H04GF21T4JXNS3JDQM3YNE',\n} as const;\n","import { BUILD_ENV, PRODUCTION_CONFIG, DEVELOPMENT_CONFIG } from '../build-config.js';\n\nexport interface BrainGridConfig {\n\tapiUrl: string;\n\torganizationId?: string;\n\tclientId?: string;\n\toauthClientId?: string;\n\tgetWorkOSAuthUrl(): string;\n\tgetWebAppUrl(): string;\n}\n\nexport function getConfig(): BrainGridConfig {\n\t// Determine base config based on BUILD_ENV\n\tconst baseConfig = BUILD_ENV === 'production' ? PRODUCTION_CONFIG : DEVELOPMENT_CONFIG;\n\n\t// In development builds, allow NODE_ENV to override\n\tlet apiUrl: string = baseConfig.apiUrl;\n\tif (BUILD_ENV === 'development') {\n\t\tif (process.env.NODE_ENV === 'local' || process.env.NODE_ENV === 'test') {\n\t\t\t// In local/test environment, use localhost\n\t\t\tapiUrl = 'http://localhost:3377';\n\t\t} else if (process.env.NODE_ENV === 'development') {\n\t\t\t// In development, use dev server\n\t\t\tapiUrl = DEVELOPMENT_CONFIG.apiUrl;\n\t\t}\n\t}\n\n\t// Determine WorkOS AuthKit URL based on environment\n\tconst getWorkOSAuthUrl = (): string => {\n\t\t// Allow override via environment variable\n\t\tif (process.env.WORKOS_AUTH_URL) {\n\t\t\treturn process.env.WORKOS_AUTH_URL;\n\t\t}\n\n\t\t// In production builds, always use production URL\n\t\tif (BUILD_ENV === 'production') {\n\t\t\treturn PRODUCTION_CONFIG.workosAuthUrl;\n\t\t}\n\n\t\t// In development builds, respect NODE_ENV\n\t\tconst env = process.env.NODE_ENV || 'development';\n\t\tif (env === 'local' || env === 'test' || env === 'development' || env === 'staging') {\n\t\t\treturn DEVELOPMENT_CONFIG.workosAuthUrl;\n\t\t}\n\t\treturn PRODUCTION_CONFIG.workosAuthUrl;\n\t};\n\n\t// Determine WorkOS OAuth client ID based on environment\n\tconst getOAuthClientId = (): string => {\n\t\t// Allow override via environment variable\n\t\tif (process.env.WORKOS_CLIENT_ID) {\n\t\t\treturn process.env.WORKOS_CLIENT_ID;\n\t\t}\n\n\t\t// In production builds, always use production client ID\n\t\tif (BUILD_ENV === 'production') {\n\t\t\treturn PRODUCTION_CONFIG.workosClientId;\n\t\t}\n\n\t\t// In development builds, respect NODE_ENV\n\t\tconst env = process.env.NODE_ENV || 'development';\n\t\tif (env === 'local' || env === 'test' || env === 'development' || env === 'staging') {\n\t\t\treturn DEVELOPMENT_CONFIG.workosClientId;\n\t\t}\n\t\treturn PRODUCTION_CONFIG.workosClientId;\n\t};\n\n\t// Determine web app URL based on environment\n\tconst getWebAppUrl = (): string => {\n\t\t// Allow override via environment variable\n\t\tif (process.env.BRAINGRID_WEB_URL) {\n\t\t\treturn process.env.BRAINGRID_WEB_URL;\n\t\t}\n\n\t\t// In production builds, always use production URL\n\t\tif (BUILD_ENV === 'production') {\n\t\t\treturn PRODUCTION_CONFIG.apiUrl;\n\t\t}\n\n\t\t// In development builds, respect NODE_ENV\n\t\tconst env = process.env.NODE_ENV || 'development';\n\t\tif (env === 'local' || env === 'test') {\n\t\t\treturn 'http://localhost:3377';\n\t\t}\n\t\treturn DEVELOPMENT_CONFIG.apiUrl;\n\t};\n\n\treturn {\n\t\tapiUrl: process.env.BRAINGRID_API_URL || apiUrl,\n\t\torganizationId: process.env.BRAINGRID_ORG_ID,\n\t\tclientId: process.env.BRAINGRID_CLIENT_ID || 'braingrid-cli',\n\t\toauthClientId: getOAuthClientId(),\n\t\tgetWorkOSAuthUrl,\n\t\tgetWebAppUrl,\n\t};\n}\n","/**\n * JWT utility functions\n * Note: This is basic JWT decoding without signature verification\n * The server validates the token signature when we make API calls\n */\n\nexport interface JWTPayload {\n\t// Standard JWT claims\n\tsub?: string; // Subject (user ID)\n\texp?: number; // Expiration time\n\tiat?: number; // Issued at\n\tnbf?: number; // Not before\n\tiss?: string; // Issuer\n\taud?: string | string[]; // Audience\n\n\t// Custom claims that might be in the token\n\temail?: string;\n\tfirstName?: string;\n\tfirst_name?: string;\n\tlastName?: string;\n\tlast_name?: string;\n\tname?: string;\n\tgiven_name?: string;\n\tfamily_name?: string;\n\torganizationId?: string;\n\torganization_id?: string;\n\torg?: string;\n\tmetadata?: Record<string, unknown>;\n}\n\n/**\n * Decode a JWT token to extract the payload\n * Note: This does NOT verify the signature - that's the server's job\n */\nexport function decodeJWT(token: string): JWTPayload | null {\n\ttry {\n\t\t// JWT format: header.payload.signature\n\t\tconst parts = token.split('.');\n\t\tif (parts.length !== 3) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Decode the payload (base64url)\n\t\tconst payload = parts[1];\n\t\t// Replace URL-safe characters with standard base64 characters\n\t\tconst base64 = payload.replace(/-/g, '+').replace(/_/g, '/');\n\t\t// Add padding if necessary\n\t\tconst padded = base64 + '=='.substring(0, (4 - (base64.length % 4)) % 4);\n\n\t\tconst decoded = Buffer.from(padded, 'base64').toString('utf-8');\n\t\treturn JSON.parse(decoded);\n\t} catch {\n\t\t// Invalid token format or JSON\n\t\treturn null;\n\t}\n}\n\n/**\n * Check if a JWT token is expired\n */\nexport function isJWTExpired(token: string): boolean {\n\tconst payload = decodeJWT(token);\n\tif (!payload || !payload.exp) {\n\t\t// If we can't decode or no expiry, assume it's invalid\n\t\treturn true;\n\t}\n\n\t// exp is in seconds, Date.now() is in milliseconds\n\treturn Date.now() >= payload.exp * 1000;\n}\n\n/**\n * Extract user information from JWT payload\n */\nexport function extractUserFromJWT(payload: JWTPayload): {\n\tid: string;\n\temail: string;\n\tfirstName: string;\n\tlastName: string;\n\torganizationId: string;\n} {\n\treturn {\n\t\tid: payload.sub || '',\n\t\temail: payload.email || '',\n\t\t// Try different naming conventions for first name\n\t\tfirstName:\n\t\t\tpayload.firstName ||\n\t\t\tpayload.first_name ||\n\t\t\tpayload.given_name ||\n\t\t\t(payload.name ? payload.name.split(' ')[0] : ''),\n\t\t// Try different naming conventions for last name\n\t\tlastName:\n\t\t\tpayload.lastName ||\n\t\t\tpayload.last_name ||\n\t\t\tpayload.family_name ||\n\t\t\t(payload.name ? payload.name.split(' ').slice(1).join(' ') : ''),\n\t\t// Try different naming conventions for organization\n\t\torganizationId: payload.organizationId || payload.organization_id || payload.org || 'default',\n\t};\n}\n","/**\n * Credential Store - Encrypted credential storage using conf\n *\n * Provides a keytar-compatible API for storing credentials securely\n * using file-based encrypted storage.\n *\n * Storage locations:\n * - macOS: ~/Library/Preferences/BrainGrid/config.json\n * - Linux: ~/.config/BrainGrid/config.json\n * - Windows: %APPDATA%\\BrainGrid\\config.json\n *\n * Security:\n * - Encrypted using AES-256-CBC\n * - Encryption key derived from machine ID + app salt\n * - File permissions automatically set to 0600 on Unix systems\n */\n\nimport Conf from 'conf';\nimport machineId from 'node-machine-id';\nimport crypto from 'crypto';\n\n// App-specific salt for key derivation\nconst APP_SALT = 'braingrid-cli-v1-credentials';\n\n// Derive encryption key from machine ID + salt\n// This makes the encryption key machine-specific\nfunction deriveEncryptionKey(): string {\n\ttry {\n\t\tconst id = machineId.machineIdSync();\n\t\treturn crypto\n\t\t\t.createHash('sha256')\n\t\t\t.update(id + APP_SALT)\n\t\t\t.digest('hex')\n\t\t\t.substring(0, 32); // 32 bytes for AES-256\n\t} catch {\n\t\t// Fallback if machine ID fails (unlikely)\n\t\t// This is still better than plain text\n\t\tconsole.warn('⚠️ Could not derive machine-specific encryption key, using fallback');\n\t\treturn crypto.createHash('sha256').update(APP_SALT).digest('hex').substring(0, 32);\n\t}\n}\n\n// Initialize encrypted configuration store\nconst store = new Conf({\n\tprojectName: 'BrainGrid',\n\tprojectSuffix: '', // Override default 'nodejs' suffix for cleaner directory name\n\tencryptionKey: deriveEncryptionKey(),\n\tclearInvalidConfig: true, // Clear config if decryption fails\n});\n\n/**\n * Credential store with keytar-compatible API\n */\nexport const credentialStore = {\n\t/**\n\t * Get a stored password/credential\n\t * @param service Service name (e.g., 'braingrid-cli')\n\t * @param account Account name (e.g., 'session', 'refresh-token')\n\t * @returns The stored credential or null if not found\n\t */\n\tasync getPassword(service: string, account: string): Promise<string | null> {\n\t\tconst key = `${service}.${account}`;\n\t\tconst value = store.get(key);\n\t\treturn value !== undefined ? String(value) : null;\n\t},\n\n\t/**\n\t * Store a password/credential\n\t * @param service Service name\n\t * @param account Account name\n\t * @param password The credential to store\n\t */\n\tasync setPassword(service: string, account: string, password: string): Promise<void> {\n\t\tconst key = `${service}.${account}`;\n\t\tstore.set(key, password);\n\t},\n\n\t/**\n\t * Delete a stored password/credential\n\t * @param service Service name\n\t * @param account Account name\n\t */\n\tasync deletePassword(service: string, account: string): Promise<void> {\n\t\tconst key = `${service}.${account}`;\n\t\tstore.delete(key);\n\t},\n\n\t/**\n\t * Get the path to the encrypted config file\n\t * Useful for informing users where credentials are stored\n\t */\n\tgetStoragePath(): string {\n\t\treturn store.path;\n\t},\n};\n","/**\n * Error Formatter Utility\n *\n * Extracts user-friendly error messages from API errors (AxiosError)\n * and provides context-aware error messages for common scenarios.\n */\n\nimport { AxiosError } from 'axios';\nimport chalk from 'chalk';\nimport type { ErrorResponse } from '../types/api.js';\nimport { handleError } from './error-handler.js';\n\n/**\n * Format an error for display to the user\n * Extracts API error details from AxiosError responses\n */\nexport function formatError(error: unknown, context?: string): string {\n\t// Handle AxiosError specifically\n\tif (isAxiosError(error)) {\n\t\treturn formatAxiosError(error, context);\n\t}\n\n\t// Handle objects with response property (mock AxiosError in tests)\n\tif (error && typeof error === 'object' && 'response' in error) {\n\t\treturn formatAxiosError(error as AxiosError, context);\n\t}\n\n\t// Handle regular Error objects\n\tif (error instanceof Error) {\n\t\treturn chalk.red(`❌ ${error.message}`);\n\t}\n\n\t// Fallback for unknown error types\n\treturn chalk.red(`❌ ${String(error)}`);\n}\n\n/**\n * Type guard to check if error is an AxiosError\n */\nfunction isAxiosError(error: unknown): error is AxiosError {\n\treturn (\n\t\ttypeof error === 'object' &&\n\t\terror !== null &&\n\t\t'isAxiosError' in error &&\n\t\terror.isAxiosError === true\n\t);\n}\n\n/**\n * Format AxiosError with API response details\n */\nfunction formatAxiosError(error: AxiosError, context?: string): string {\n\tconst status = error.response?.status;\n\tconst data = error.response?.data;\n\n\t// Try to extract structured error from API response\n\tif (data && typeof data === 'object' && 'error' in data) {\n\t\tconst errorResponse = data as ErrorResponse;\n\t\tif (errorResponse.error?.message) {\n\t\t\t// Use API error message if available\n\t\t\treturn chalk.red(`❌ ${errorResponse.error.message}`);\n\t\t}\n\t}\n\n\t// Use new enhanced error handler for common status codes (404, 401, 402, 403, 422)\n\tif (status && [404, 401, 402, 403, 422].includes(status)) {\n\t\treturn handleError(error, context);\n\t}\n\n\t// Handle other HTTP status codes with basic messages\n\tif (status) {\n\t\treturn chalk.red(`❌ ${getStatusMessage(status, context, error)}`);\n\t}\n\n\t// Handle network errors (no response)\n\tif (error.code === 'ECONNREFUSED') {\n\t\treturn chalk.red(\n\t\t\t'❌ Could not connect to BrainGrid API. Please check your network connection.'\n\t\t);\n\t}\n\n\tif (error.code === 'ETIMEDOUT') {\n\t\treturn chalk.red('❌ Request timed out. Please try again.');\n\t}\n\n\t// Fallback to error message\n\treturn chalk.red(`❌ ${error.message}`);\n}\n\n/**\n * Get user-friendly message for HTTP status codes\n */\nfunction getStatusMessage(status: number, context?: string, error?: AxiosError): string {\n\tswitch (status) {\n\t\tcase 400: {\n\t\t\t// Bad Request - try to extract details from response\n\t\t\tconst data = error?.response?.data;\n\t\t\tif (data && typeof data === 'object') {\n\t\t\t\t// Check for validation errors or detailed message\n\t\t\t\tif ('message' in data && typeof data.message === 'string') {\n\t\t\t\t\treturn data.message;\n\t\t\t\t}\n\t\t\t\tif ('detail' in data && typeof data.detail === 'string') {\n\t\t\t\t\treturn data.detail;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn context\n\t\t\t\t? `Invalid ${context} - please check your input and try again`\n\t\t\t\t: 'Invalid request - please check your input and try again';\n\t\t}\n\n\t\tcase 401:\n\t\t\treturn 'Authentication required. Please run \"braingrid login\" to authenticate.';\n\n\t\tcase 403:\n\t\t\treturn context\n\t\t\t\t? `You don't have permission to access this ${context}`\n\t\t\t\t: \"You don't have permission to perform this action\";\n\n\t\tcase 404:\n\t\t\treturn context ? `${context} not found` : 'Resource not found';\n\n\t\tcase 409:\n\t\t\treturn context\n\t\t\t\t? `${context} already exists or conflicts with existing data`\n\t\t\t\t: 'Resource already exists or conflicts with existing data';\n\n\t\tcase 422:\n\t\t\treturn 'Validation failed - please check your input';\n\n\t\tcase 429:\n\t\t\treturn 'Too many requests. Please wait a moment and try again.';\n\n\t\tcase 500:\n\t\t\treturn 'Server error. Please try again later.';\n\n\t\tcase 502:\n\t\tcase 503:\n\t\tcase 504:\n\t\t\treturn 'BrainGrid service is temporarily unavailable. Please try again later.';\n\n\t\tdefault:\n\t\t\treturn `Request failed with status ${status}`;\n\t}\n}\n\n/**\n * Format context string for error messages\n * Converts resource names to user-friendly format\n */\nexport function getResourceContext(resourceType: string, id?: string): string {\n\tconst formatted = resourceType.charAt(0).toUpperCase() + resourceType.slice(1);\n\treturn id ? `${formatted} '${id}'` : formatted;\n}\n","/**\n * Error Handler - Centralized error handling with context-aware messages\n *\n * Provides specialized error handling for common API errors:\n * - 404: Resource not found (project/requirement/task)\n * - 401: Authentication required\n * - 403: Permission denied\n * - 422: Validation errors\n */\n\nimport chalk from 'chalk';\nimport type { AxiosError } from 'axios';\n\n/**\n * Extract project ID from API URL\n * Matches patterns like: /api/v1/projects/PROJ-123/...\n */\nfunction extractProjectIdFromUrl(url?: string): string | null {\n\tif (!url) return null;\n\tconst match = url.match(/\\/projects\\/([A-Z]+-\\d+)/);\n\treturn match ? match[1] : null;\n}\n\n/**\n * Extract requirement ID from API URL\n * Matches patterns like: /api/v1/projects/{projectId}/requirements/REQ-456/...\n */\nfunction extractRequirementIdFromUrl(url?: string): string | null {\n\tif (!url) return null;\n\tconst match = url.match(/\\/requirements\\/([A-Z]+-\\d+)/);\n\treturn match ? match[1] : null;\n}\n\n/**\n * Extract task ID from API URL\n * Matches patterns like: /api/v1/projects/{projectId}/requirements/{reqId}/tasks/TASK-789\n */\nfunction extractTaskIdFromUrl(url?: string): string | null {\n\tif (!url) return null;\n\tconst match = url.match(/\\/tasks\\/([A-Z]+-\\d+)/);\n\treturn match ? match[1] : null;\n}\n\n/**\n * Detect resource type from URL\n */\nfunction detectResourceType(url?: string): 'project' | 'requirement' | 'task' | 'unknown' {\n\tif (!url) return 'unknown';\n\n\t// Check for task first (most specific)\n\tif (url.includes('/tasks/') || url.endsWith('/tasks')) return 'task';\n\t// Then requirement\n\tif (url.includes('/requirements/') || url.endsWith('/requirements')) return 'requirement';\n\t// Then project (matches both /projects/PROJ-123 and /projects)\n\tif (url.includes('/projects')) return 'project';\n\n\treturn 'unknown';\n}\n\n/**\n * Handle 404 Resource Not Found errors\n * Provides context-aware messages based on the resource type\n */\nexport function handleResourceNotFound(error: AxiosError, context?: string): string {\n\tconst url = error.config?.url;\n\tconst resourceType = detectResourceType(url);\n\n\t// Extract resource IDs\n\tconst projectId = extractProjectIdFromUrl(url);\n\tconst requirementId = extractRequirementIdFromUrl(url);\n\tconst taskId = extractTaskIdFromUrl(url);\n\n\t// Build error message based on resource type\n\tlet message = chalk.red('❌ ');\n\n\tswitch (resourceType) {\n\t\tcase 'task': {\n\t\t\tif (taskId) {\n\t\t\t\tmessage += `Task '${taskId}' not found`;\n\t\t\t} else {\n\t\t\t\tmessage += 'Task not found';\n\t\t\t}\n\t\t\tmessage += '\\n\\n' + chalk.dim('The task may have been deleted or the ID is incorrect.');\n\t\t\tif (projectId && requirementId) {\n\t\t\t\tmessage +=\n\t\t\t\t\t'\\n' +\n\t\t\t\t\tchalk.dim('List tasks with:\\n') +\n\t\t\t\t\tchalk.cyan(` braingrid task list ${requirementId}`);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 'requirement': {\n\t\t\tif (requirementId) {\n\t\t\t\tmessage += `Requirement '${requirementId}' not found`;\n\t\t\t} else {\n\t\t\t\tmessage += 'Requirement not found';\n\t\t\t}\n\t\t\tmessage +=\n\t\t\t\t'\\n\\n' + chalk.dim('The requirement may have been deleted or the ID is incorrect.');\n\t\t\tif (projectId) {\n\t\t\t\tmessage +=\n\t\t\t\t\t'\\n' +\n\t\t\t\t\tchalk.dim('List requirements with:\\n') +\n\t\t\t\t\tchalk.cyan(` braingrid requirement list -p ${projectId}`);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 'project': {\n\t\t\tif (projectId) {\n\t\t\t\tmessage += `Project '${projectId}' not found`;\n\t\t\t} else {\n\t\t\t\tmessage += 'Project not found';\n\t\t\t}\n\t\t\tmessage +=\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('The project may not exist or you may not have access to it.') +\n\t\t\t\t'\\n' +\n\t\t\t\tchalk.dim('List your projects with:\\n') +\n\t\t\t\tchalk.cyan(' braingrid project list');\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\t// Unknown resource type, fall back to generic message\n\t\t\tif (context) {\n\t\t\t\tmessage += `Error ${context}: not found`;\n\t\t\t} else {\n\t\t\t\tmessage += 'Resource not found';\n\t\t\t}\n\t\t\tmessage +=\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('The requested resource does not exist or you may not have access to it.');\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn message;\n}\n\n/**\n * Handle 401 Authentication errors\n */\nexport function handleAuthError(_error: AxiosError, _context?: string): string {\n\treturn (\n\t\tchalk.red('❌ Authentication required') +\n\t\t'\\n\\n' +\n\t\tchalk.dim('Your session may have expired or you are not logged in.') +\n\t\t'\\n' +\n\t\tchalk.dim('Please authenticate with:\\n') +\n\t\tchalk.cyan(' braingrid login')\n\t);\n}\n\n/**\n * Handle 403 Permission errors\n */\nexport function handlePermissionError(error: AxiosError, context?: string): string {\n\tconst url = error.config?.url;\n\tconst resourceType = detectResourceType(url);\n\tconst projectId = extractProjectIdFromUrl(url);\n\n\tlet message = chalk.red('❌ Permission denied');\n\n\tif (context) {\n\t\tmessage = chalk.red(`❌ Permission denied: ${context}`);\n\t}\n\n\tmessage += '\\n\\n' + chalk.dim('You do not have permission to perform this action.');\n\n\tif (resourceType === 'project' && projectId) {\n\t\tmessage +=\n\t\t\t'\\n' +\n\t\t\tchalk.dim('Check if you have access to this project:\\n') +\n\t\t\tchalk.cyan(` braingrid project show -p ${projectId}`);\n\t} else {\n\t\tmessage += '\\n' + chalk.dim('Contact your project administrator for access.');\n\t}\n\n\treturn message;\n}\n\n/**\n * Handle 402 Payment Required errors\n * Handles billing and quota limit errors\n */\nexport function handlePaymentRequiredError(error: AxiosError, context?: string): string {\n\t// Try to extract error details from response\n\tconst responseData = error.response?.data as\n\t\t| { error?: string; code?: string; errorCode?: string; quotaKey?: string }\n\t\t| undefined;\n\n\tconst errorCode = responseData?.errorCode || responseData?.code;\n\tconst quotaKey = responseData?.quotaKey;\n\n\tlet message = chalk.red('❌ Usage limit reached');\n\n\t// Handle organization unfunded error\n\tif (errorCode === 'ORG_UNFUNDED') {\n\t\tmessage = chalk.red('❌ Organization subscription required');\n\t\tmessage +=\n\t\t\t'\\n\\n' +\n\t\t\tchalk.dim('Your organization needs an active subscription to use this feature.') +\n\t\t\t'\\n\\n' +\n\t\t\tchalk.dim('Please contact your organization administrator or visit:\\n') +\n\t\t\tchalk.cyan(' https://braingrid.ai/pricing');\n\t\treturn message;\n\t}\n\n\t// Handle quota exceeded error with specific quota key\n\tif (errorCode === 'QUOTA_EXCEEDED' && quotaKey) {\n\t\tmessage = chalk.red(`❌ Quota exceeded: ${quotaKey}`);\n\t\tmessage +=\n\t\t\t'\\n\\n' +\n\t\t\tchalk.dim(`Your organization has reached its usage limit for ${quotaKey}.`) +\n\t\t\t'\\n\\n' +\n\t\t\tchalk.dim('To continue using this feature:\\n') +\n\t\t\tchalk.dim(' • Upgrade your plan at ') +\n\t\t\tchalk.cyan('https://braingrid.ai/pricing') +\n\t\t\t'\\n' +\n\t\t\tchalk.dim(' • Contact your administrator to increase quota');\n\t\treturn message;\n\t}\n\n\t// Handle quota exceeded without specific key\n\tif (errorCode === 'QUOTA_EXCEEDED') {\n\t\tmessage +=\n\t\t\t'\\n\\n' +\n\t\t\tchalk.dim('Your organization has reached its usage limit.') +\n\t\t\t'\\n\\n' +\n\t\t\tchalk.dim('To continue:\\n') +\n\t\t\tchalk.dim(' • Upgrade your plan at ') +\n\t\t\tchalk.cyan('https://braingrid.ai/pricing') +\n\t\t\t'\\n' +\n\t\t\tchalk.dim(' • Contact your administrator');\n\t\treturn message;\n\t}\n\n\t// Generic 402 error (no specific error code)\n\tif (context) {\n\t\tmessage = chalk.red(`❌ Usage limit reached: ${context}`);\n\t}\n\n\tmessage +=\n\t\t'\\n\\n' +\n\t\tchalk.dim('Your organization has reached its usage limit.') +\n\t\t'\\n\\n' +\n\t\tchalk.dim('To continue:\\n') +\n\t\tchalk.dim(' • Upgrade your plan at ') +\n\t\tchalk.cyan('https://braingrid.ai/pricing') +\n\t\t'\\n' +\n\t\tchalk.dim(' • Contact support at ') +\n\t\tchalk.cyan('support@braingrid.ai');\n\n\treturn message;\n}\n\n/**\n * Handle 422 Validation errors\n * Extracts validation error details from response\n */\nexport function handleValidationError(error: AxiosError, context?: string): string {\n\tlet message = chalk.red('❌ Validation error');\n\n\tif (context) {\n\t\tmessage = chalk.red(`❌ Validation error: ${context}`);\n\t}\n\n\t// Try to extract validation details from response\n\tconst responseData = error.response?.data as\n\t\t| { message?: string; errors?: Record<string, string[]> }\n\t\t| undefined;\n\n\tif (responseData?.message) {\n\t\tmessage += '\\n\\n' + chalk.yellow(responseData.message);\n\t}\n\n\tif (responseData?.errors) {\n\t\tmessage += '\\n\\n' + chalk.dim('Validation errors:');\n\t\tfor (const [field, errors] of Object.entries(responseData.errors)) {\n\t\t\tmessage += '\\n' + chalk.dim(` ${field}:`);\n\t\t\tfor (const error of errors) {\n\t\t\t\tmessage += '\\n' + chalk.dim(` - ${error}`);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tmessage += '\\n\\n' + chalk.dim('Please check your input and try again.');\n\t}\n\n\treturn message;\n}\n\n/**\n * Main error handler - routes to appropriate specialized handler\n */\nexport function handleError(error: AxiosError, context?: string): string {\n\tconst status = error.response?.status;\n\n\tswitch (status) {\n\t\tcase 404: {\n\t\t\treturn handleResourceNotFound(error, context);\n\t\t}\n\t\tcase 401: {\n\t\t\treturn handleAuthError(error, context);\n\t\t}\n\t\tcase 402: {\n\t\t\treturn handlePaymentRequiredError(error, context);\n\t\t}\n\t\tcase 403: {\n\t\t\treturn handlePermissionError(error, context);\n\t\t}\n\t\tcase 422: {\n\t\t\treturn handleValidationError(error, context);\n\t\t}\n\t\tdefault: {\n\t\t\t// Fallback for other errors\n\t\t\tconst responseData = error.response?.data as { message?: string } | undefined;\n\t\t\tconst apiMessage = responseData?.message;\n\n\t\t\tif (apiMessage) {\n\t\t\t\treturn context ? `Error ${context}: ${apiMessage}` : apiMessage;\n\t\t\t}\n\n\t\t\tif (error.message) {\n\t\t\t\treturn context ? `Error ${context}: ${error.message}` : error.message;\n\t\t\t}\n\n\t\t\treturn context ? `Error ${context}` : 'An unexpected error occurred';\n\t\t}\n\t}\n}\n","/**\n * Generic ID normalization utility for resource identifiers\n *\n * This module provides a unified approach to normalizing resource IDs\n * (Projects, Requirements, Tasks) from various user input formats.\n */\n\n/**\n * Normalize a resource ID from various formats to API-compatible format:\n * - \"PREFIX-123\" -> \"PREFIX-123\" (already normalized)\n * - \"prefix-123\" -> \"PREFIX-123\" (uppercase prefix)\n * - \"PREFIX 123\" -> \"PREFIX-123\" (replace space with dash, uppercase)\n * - \"prefix 123\" -> \"PREFIX-123\" (replace space with dash, uppercase)\n * - \"123\" -> \"PREFIX-123\" (add prefix)\n * - \"uuid-string\" -> \"uuid-string\" (UUID, return as-is)\n *\n * @param prefix The resource prefix (e.g., 'PROJ', 'REQ', 'TASK')\n * @param input The user-provided ID string\n * @returns The normalized ID suitable for API calls\n *\n * @example\n * normalizeId('PROJ', 'proj-123') // Returns 'PROJ-123'\n * normalizeId('REQ', 'REQ 456') // Returns 'REQ-456'\n * normalizeId('TASK', '789') // Returns 'TASK-789'\n */\nexport function normalizeId(prefix: string, input: string): string {\n\tconst trimmed = input.trim();\n\tconst upperPrefix = prefix.toUpperCase();\n\n\t// Handle \"PREFIX-123\" or \"prefix-123\" format (already has dash)\n\tconst dashMatch = trimmed.match(new RegExp(`^${prefix}-(\\\\d+)$`, 'i'));\n\tif (dashMatch) {\n\t\t// Strip leading zeros by parsing as integer\n\t\tconst num = parseInt(dashMatch[1], 10);\n\t\treturn `${upperPrefix}-${num}`;\n\t}\n\n\t// Handle \"PREFIX 123\" or \"prefix 123\" format (space instead of dash)\n\tconst spaceMatch = trimmed.match(new RegExp(`^${prefix}\\\\s+(\\\\d+)$`, 'i'));\n\tif (spaceMatch) {\n\t\t// Strip leading zeros by parsing as integer\n\t\tconst num = parseInt(spaceMatch[1], 10);\n\t\treturn `${upperPrefix}-${num}`;\n\t}\n\n\t// Handle plain number format \"123\"\n\tif (/^\\d+$/.test(trimmed)) {\n\t\t// Strip leading zeros by parsing as integer\n\t\tconst num = parseInt(trimmed, 10);\n\t\treturn `${upperPrefix}-${num}`;\n\t}\n\n\t// Assume it's a UUID - return as-is\n\treturn trimmed;\n}\n","import { Project } from '../types/project.js';\nimport { normalizeId } from './id-normalization.js';\n\n/**\n * Format a project with friendly PROJ-<number> format\n * Note: short_id already contains \"PROJ-123\" format\n */\nexport function formatProjectId(project: Project): string {\n\treturn project.short_id;\n}\n\n/**\n * Normalize project ID from various formats to API-compatible format:\n * - \"PROJ-123\" -> \"PROJ-123\" (already normalized)\n * - \"proj-123\" -> \"PROJ-123\" (uppercase)\n * - \"PROJ 123\" -> \"PROJ-123\" (add dash, uppercase)\n * - \"proj 123\" -> \"PROJ-123\" (add dash, uppercase)\n * - \"123\" -> \"PROJ-123\" (add prefix)\n * - \"uuid-string\" -> \"uuid-string\" (UUID, return as-is)\n *\n * This function takes user input and returns the ID that should be used in API calls\n */\nexport function parseProjectId(input: string): string {\n\treturn normalizeId('PROJ', input);\n}\n\n/**\n * Find a project by either short_id or UUID\n */\nexport function findProjectById(projects: Project[], identifier: string): Project | undefined {\n\tconst normalized = parseProjectId(identifier);\n\n\t// Try to find by short_id first (handles PROJ-X format)\n\tconst byShortId = projects.find(proj => proj.short_id === normalized);\n\tif (byShortId) {\n\t\treturn byShortId;\n\t}\n\n\t// Try to find by UUID\n\treturn projects.find(proj => proj.id === normalized);\n}\n","/**\n * Workspace Manager\n *\n * Manages workspace-level state including:\n * - Current project resolution (from .braingrid/project.json)\n * - Active requirement context (session-scoped)\n *\n * This provides a centralized way to access workspace context across handlers.\n */\n\nimport chalk from 'chalk';\nimport { getLocalProjectId } from './local-store.js';\nimport { parseProjectId } from './projects.js';\nimport { getCurrentBranch, parseRequirementFromBranch } from './git.js';\nimport { normalizeRequirementId } from './requirements.js';\n\n/**\n * Result type for project resolution\n */\nexport type WorkspaceProjectResult =\n\t| {\n\t\t\tsuccess: true;\n\t\t\tprojectId: string; // normalized (e.g., \"PROJ-123\")\n\t }\n\t| {\n\t\t\tsuccess: false;\n\t\t\terror: string; // formatted error message with chalk\n\t };\n\n/**\n * Result type for requirement resolution\n */\nexport type WorkspaceRequirementResult =\n\t| {\n\t\t\tsuccess: true;\n\t\t\trequirementId: string; // normalized (e.g., \"REQ-123\")\n\t }\n\t| {\n\t\t\tsuccess: false;\n\t\t\terror: string; // formatted error message with chalk\n\t };\n\n/**\n * Manages workspace-level state\n *\n * Singleton pattern - one instance per CLI session\n */\nexport class WorkspaceManager {\n\tprivate activeRequirementId: string | null = null;\n\n\t/**\n\t * Get the project ID for the current workspace\n\t *\n\t * Resolution order:\n\t * 1. If explicitProjectId provided → normalize and return it\n\t * 2. Check .braingrid/project.json for configured project (at git root)\n\t * 3. If not initialized → return error with initialization instructions\n\t *\n\t * @param explicitProjectId - Optional project ID from -p or --project flag\n\t * @returns Result with either projectId (normalized) or error message\n\t */\n\tasync getProject(explicitProjectId?: string): Promise<WorkspaceProjectResult> {\n\t\t// If explicit project provided via flag\n\t\tif (explicitProjectId) {\n\t\t\tconst normalized = parseProjectId(explicitProjectId);\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tprojectId: normalized,\n\t\t\t};\n\t\t}\n\n\t\t// Try to get from .braingrid/project.json (searches git root first)\n\t\tconst localProjectId = await getLocalProjectId();\n\t\tif (localProjectId) {\n\t\t\tconst normalized = parseProjectId(localProjectId);\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tprojectId: normalized,\n\t\t\t};\n\t\t}\n\n\t\t// Not initialized\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror:\n\t\t\t\tchalk.red('❌ No project specified and no local project found.') +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('To initialize this workspace, run:\\n') +\n\t\t\t\tchalk.cyan(' braingrid init') +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('Or specify a project explicitly:\\n') +\n\t\t\t\tchalk.cyan(' braingrid <command> -p PROJ-123'),\n\t\t};\n\t}\n\n\t/**\n\t * Get the requirement ID for the current workspace\n\t *\n\t * Resolution order:\n\t * 1. If explicitRequirementId provided → normalize and return it\n\t * 2. Try to parse from current git branch name (e.g., \"feature/REQ-123-description\")\n\t * 3. If not found → return error with usage instructions\n\t *\n\t * @param explicitRequirementId - Optional requirement ID from -r or --requirement flag or [id] argument\n\t * @returns Result with either requirementId (normalized) or error message\n\t */\n\tasync getRequirement(explicitRequirementId?: string): Promise<WorkspaceRequirementResult> {\n\t\t// If explicit requirement provided via flag or argument\n\t\tif (explicitRequirementId) {\n\t\t\tconst normalized = normalizeRequirementId(explicitRequirementId);\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\trequirementId: normalized,\n\t\t\t};\n\t\t}\n\n\t\t// Try to parse from git branch name\n\t\tconst branchName = await getCurrentBranch();\n\t\tif (branchName) {\n\t\t\tconst requirementId = parseRequirementFromBranch(branchName);\n\t\t\tif (requirementId) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\trequirementId,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Not found\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror:\n\t\t\t\tchalk.red('❌ No requirement specified.') +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('Unable to auto-detect requirement from branch name.\\n') +\n\t\t\t\tchalk.dim('Please provide a requirement ID explicitly:\\n') +\n\t\t\t\tchalk.cyan(' braingrid requirement show REQ-123') +\n\t\t\t\t'\\n' +\n\t\t\t\tchalk.dim(' or\\n') +\n\t\t\t\tchalk.cyan(' braingrid task list -r REQ-123') +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim(\n\t\t\t\t\t'Tip: Name your branch with a requirement ID (e.g., feature/REQ-123-description)\\n'\n\t\t\t\t) +\n\t\t\t\tchalk.dim('to enable auto-detection.'),\n\t\t};\n\t}\n\n\t/**\n\t * Set the active requirement for this workspace session\n\t *\n\t * This is used to automatically include requirement context in agent conversations\n\t *\n\t * @param requirementId - The requirement ID to set as active\n\t */\n\tsetActiveRequirement(requirementId: string): void {\n\t\tthis.activeRequirementId = requirementId;\n\t}\n\n\t/**\n\t * Get the currently active requirement ID\n\t *\n\t * @returns The active requirement ID or null if none set\n\t */\n\tgetActiveRequirement(): string | null {\n\t\treturn this.activeRequirementId;\n\t}\n\n\t/**\n\t * Clear the active requirement\n\t */\n\tclearActiveRequirement(): void {\n\t\tthis.activeRequirementId = null;\n\t}\n\n\t/**\n\t * Check if there is an active requirement set\n\t *\n\t * @returns true if a requirement is active, false otherwise\n\t */\n\thasActiveRequirement(): boolean {\n\t\treturn this.activeRequirementId !== null;\n\t}\n}\n\n// Export singleton instance\nexport const workspaceManager = new WorkspaceManager();\n","/**\n * Local Project Store\n * Handles reading/writing .braingrid/project.json\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { LocalProjectConfig, LocalProjectConfigSchema } from '../types/local-project.js';\nimport { getGitRoot } from './git.js';\n\nconst BRAINGRID_DIR = '.braingrid';\nconst PROJECT_CONFIG_FILE = 'project.json';\n\n/**\n * Get the default directory for .braingrid folder\n * Prefers git repository root, falls back to current working directory\n */\nasync function getDefaultCwd(): Promise<string> {\n\tconst gitRoot = await getGitRoot();\n\treturn gitRoot || process.cwd();\n}\n\n/**\n * Get the path to the .braingrid directory\n */\nexport async function getBraingridDir(cwd?: string): Promise<string> {\n\tconst dir = cwd ?? (await getDefaultCwd());\n\treturn path.join(dir, BRAINGRID_DIR);\n}\n\n/**\n * Get the path to the project.json file\n */\nexport async function getProjectConfigPath(cwd?: string): Promise<string> {\n\tconst braingridDir = await getBraingridDir(cwd);\n\treturn path.join(braingridDir, PROJECT_CONFIG_FILE);\n}\n\n/**\n * Check if .braingrid/project.json exists\n */\nexport async function projectConfigExists(cwd?: string): Promise<boolean> {\n\tconst configPath = await getProjectConfigPath(cwd);\n\treturn fs.existsSync(configPath);\n}\n\n/**\n * Ensure .braingrid directory exists\n */\nasync function ensureBraingridDir(cwd?: string): Promise<void> {\n\tconst dir = await getBraingridDir(cwd);\n\tif (!fs.existsSync(dir)) {\n\t\tfs.mkdirSync(dir, { recursive: true });\n\t}\n}\n\n/**\n * Load project configuration from .braingrid/project.json\n * @throws Error if file doesn't exist or is invalid\n */\nexport async function loadProjectConfig(cwd?: string): Promise<LocalProjectConfig> {\n\tconst configPath = await getProjectConfigPath(cwd);\n\n\tif (!fs.existsSync(configPath)) {\n\t\tthrow new Error(`Project not initialized. Run 'braingrid init' to initialize this repository.`);\n\t}\n\n\tconst content = fs.readFileSync(configPath, 'utf8');\n\tconst data = JSON.parse(content);\n\n\t// Validate with Zod schema\n\treturn LocalProjectConfigSchema.parse(data);\n}\n\n/**\n * Save project configuration to .braingrid/project.json\n */\nexport async function saveProjectConfig(config: LocalProjectConfig, cwd?: string): Promise<void> {\n\tawait ensureBraingridDir(cwd);\n\n\tconst configPath = await getProjectConfigPath(cwd);\n\tconst content = JSON.stringify(config, null, 2);\n\n\tfs.writeFileSync(configPath, content, 'utf8');\n}\n\n/**\n * Delete .braingrid/project.json\n */\nexport async function deleteProjectConfig(cwd?: string): Promise<void> {\n\tconst configPath = await getProjectConfigPath(cwd);\n\tif (fs.existsSync(configPath)) {\n\t\tfs.unlinkSync(configPath);\n\t}\n}\n\n/**\n * Get the local project ID from .braingrid/project.json\n * Returns the short_id (e.g., PROJ-123) if project.json exists, null otherwise\n */\nexport async function getLocalProjectId(cwd?: string): Promise<string | null> {\n\ttry {\n\t\tconst config = await loadProjectConfig(cwd);\n\t\treturn config.project_short_id;\n\t} catch {\n\t\treturn null;\n\t}\n}\n","/**\n * Local Project Configuration Types\n * Stores project information in .braingrid/project.json\n */\n\nimport { z } from 'zod';\n\n// Repository schema (internal use only)\nconst LocalRepositorySchema = z.object({\n\tid: z.string().uuid(),\n\towner: z.string(),\n\tname: z.string(),\n\tfull_name: z.string(),\n\turl: z.string().url().optional(),\n});\n\nexport type LocalRepository = z.infer<typeof LocalRepositorySchema>;\n\n// Local project configuration schema\nexport const LocalProjectConfigSchema = z.object({\n\torganization_id: z.string(),\n\tproject_id: z.string().uuid(),\n\tproject_short_id: z.string(),\n\tproject_name: z.string(),\n\tproject_description: z.string().nullable(),\n\trepository: LocalRepositorySchema.nullable(),\n\tcreated_at: z.string(),\n});\n\nexport type LocalProjectConfig = z.infer<typeof LocalProjectConfigSchema>;\n","/**\n * Git Utilities\n *\n * Provides functions to interact with git repositories:\n * - Detect if current directory is a git repository\n * - Get remote repository information (owner/name)\n * - Get current branch\n * - Get git user configuration\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\n\nconst execAsync = promisify(exec);\n\nexport interface GitRepoInfo {\n\tisRepo: boolean;\n\towner: string | null;\n\tname: string | null;\n\tbranch: string | null;\n\tuserName: string | null;\n\tuserEmail: string | null;\n\tremoteUrl: string | null;\n}\n\nexport interface GitUser {\n\tname: string | null;\n\temail: string | null;\n}\n\nexport interface GitHubRepo {\n\towner: string;\n\tname: string;\n}\n\n/**\n * Check if current directory is inside a git repository\n */\nexport async function isGitRepository(): Promise<boolean> {\n\ttry {\n\t\tconst { stdout } = await execAsync('git rev-parse --is-inside-work-tree');\n\t\treturn stdout.trim() === 'true';\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Get the URL of the 'origin' remote\n */\nexport async function getRemoteUrl(): Promise<string | null> {\n\ttry {\n\t\tconst { stdout } = await execAsync('git config --get remote.origin.url');\n\t\treturn stdout.trim() || null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Parse GitHub repository owner and name from a git remote URL\n * Supports both HTTPS and SSH formats:\n * - https://github.com/owner/repo.git\n * - git@github.com:owner/repo.git\n */\nexport function parseGitHubRepo(url: string): GitHubRepo | null {\n\tif (!url) return null;\n\n\t// Match HTTPS format: https://github.com/owner/repo.git\n\tconst httpsMatch = url.match(/https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+?)(\\.git)?$/);\n\tif (httpsMatch) {\n\t\treturn {\n\t\t\towner: httpsMatch[1],\n\t\t\tname: httpsMatch[2],\n\t\t};\n\t}\n\n\t// Match SSH format: git@github.com:owner/repo.git\n\tconst sshMatch = url.match(/git@github\\.com:([^/]+)\\/([^/]+?)(\\.git)?$/);\n\tif (sshMatch) {\n\t\treturn {\n\t\t\towner: sshMatch[1],\n\t\t\tname: sshMatch[2],\n\t\t};\n\t}\n\n\treturn null;\n}\n\n/**\n * Get the current branch name\n */\nexport async function getCurrentBranch(): Promise<string | null> {\n\ttry {\n\t\tconst { stdout } = await execAsync('git rev-parse --abbrev-ref HEAD');\n\t\treturn stdout.trim() || null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Parse requirement ID from a git branch name\n * Supports patterns like: REQ-123, feature/REQ-123, feature/REQ-123-description, req-456-feature\n * Returns the requirement ID in uppercase format (e.g., \"REQ-123\") or null if not found\n */\nexport function parseRequirementFromBranch(branchName: string): string | null {\n\tif (!branchName) return null;\n\n\t// Match REQ-digits pattern (case-insensitive)\n\tconst match = branchName.match(/REQ-(\\d+)/i);\n\tif (match) {\n\t\t// Return in uppercase format: REQ-123\n\t\treturn `REQ-${match[1]}`;\n\t}\n\n\treturn null;\n}\n\n/**\n * Get the git repository root directory\n * Returns the absolute path to the repository root, or null if not in a git repository\n */\nexport async function getGitRoot(): Promise<string | null> {\n\ttry {\n\t\tconst { stdout } = await execAsync('git rev-parse --show-toplevel');\n\t\treturn stdout.trim() || null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Get git user configuration (name and email)\n */\nexport async function getGitUser(): Promise<GitUser> {\n\tlet name: string | null = null;\n\tlet email: string | null = null;\n\n\ttry {\n\t\tconst { stdout: nameStdout } = await execAsync('git config --get user.name');\n\t\tname = nameStdout.trim() || null;\n\t} catch {\n\t\t// user.name not configured\n\t}\n\n\ttry {\n\t\tconst { stdout: emailStdout } = await execAsync('git config --get user.email');\n\t\temail = emailStdout.trim() || null;\n\t} catch {\n\t\t// user.email not configured\n\t}\n\n\treturn { name, email };\n}\n\n/**\n * Get comprehensive git repository information\n * Returns null if not in a git repository\n */\nexport async function getGitRepositoryInfo(): Promise<GitRepoInfo | null> {\n\tconst isRepo = await isGitRepository();\n\n\tif (!isRepo) {\n\t\treturn {\n\t\t\tisRepo: false,\n\t\t\towner: null,\n\t\t\tname: null,\n\t\t\tbranch: null,\n\t\t\tuserName: null,\n\t\t\tuserEmail: null,\n\t\t\tremoteUrl: null,\n\t\t};\n\t}\n\n\tconst [remoteUrl, branch, gitUser] = await Promise.all([\n\t\tgetRemoteUrl(),\n\t\tgetCurrentBranch(),\n\t\tgetGitUser(),\n\t]);\n\n\tconst repo = remoteUrl ? parseGitHubRepo(remoteUrl) : null;\n\n\treturn {\n\t\tisRepo: true,\n\t\towner: repo?.owner || null,\n\t\tname: repo?.name || null,\n\t\tbranch,\n\t\tuserName: gitUser.name,\n\t\tuserEmail: gitUser.email,\n\t\tremoteUrl,\n\t};\n}\n","import { Requirement } from '../types/requirement.js';\nimport { normalizeId } from './id-normalization.js';\n\n/**\n * Format a requirement with friendly REQ-<number> format\n * Note: short_id already contains \"REQ-123\" format\n */\nexport function formatRequirementId(requirement: Requirement): string {\n\treturn requirement.short_id || `REQ-${requirement.req_id || 0}`;\n}\n\n/**\n * Normalize requirement ID from various formats to API-compatible format:\n * - \"REQ-123\" -> \"REQ-123\" (already normalized)\n * - \"req-123\" -> \"REQ-123\" (uppercase)\n * - \"REQ 123\" -> \"REQ-123\" (add dash, uppercase)\n * - \"req 123\" -> \"REQ-123\" (add dash, uppercase)\n * - \"123\" -> \"REQ-123\" (add prefix)\n * - \"uuid-string\" -> \"uuid-string\" (UUID, return as-is)\n *\n * This function takes user input and returns the ID that should be used in API calls\n */\nexport function normalizeRequirementId(input: string): string {\n\treturn normalizeId('REQ', input);\n}\n\n/**\n * Parse a requirement ID from various formats:\n * - \"REQ-123\" -> { type: 'req_id', value: 123 }\n * - \"req-123\" -> { type: 'req_id', value: 123 }\n * - \"REQ 123\" -> { type: 'req_id', value: 123 }\n * - \"req 123\" -> { type: 'req_id', value: 123 }\n * - \"123\" -> { type: 'req_id', value: 123 }\n * - \"uuid-string\" -> { type: 'uuid', value: 'uuid-string' }\n */\nexport function parseRequirementId(input: string): {\n\ttype: 'req_id' | 'uuid';\n\tvalue: string | number;\n} {\n\t// Trim whitespace\n\tconst trimmed = input.trim();\n\n\t// Handle \"REQ-123\" or \"req-123\" format (with dash)\n\tconst reqDashMatch = trimmed.match(/^REQ-(\\d+)$/i);\n\tif (reqDashMatch) {\n\t\treturn { type: 'req_id', value: parseInt(reqDashMatch[1], 10) };\n\t}\n\n\t// Handle \"REQ 123\" or \"req 123\" format (with space)\n\tconst reqSpaceMatch = trimmed.match(/^REQ\\s+(\\d+)$/i);\n\tif (reqSpaceMatch) {\n\t\treturn { type: 'req_id', value: parseInt(reqSpaceMatch[1], 10) };\n\t}\n\n\t// Handle plain number format\n\tconst numberMatch = trimmed.match(/^\\d+$/);\n\tif (numberMatch) {\n\t\treturn { type: 'req_id', value: parseInt(trimmed, 10) };\n\t}\n\n\t// Assume it's a UUID\n\treturn { type: 'uuid', value: trimmed };\n}\n\n/**\n * Find a requirement by either req_id or UUID\n */\nexport function findRequirementById(\n\trequirements: Requirement[],\n\tidentifier: string\n): Requirement | undefined {\n\tconst parsed = parseRequirementId(identifier);\n\n\tif (parsed.type === 'req_id') {\n\t\treturn requirements.find(req => req.short_id === `REQ-${parsed.value}`);\n\t} else {\n\t\treturn requirements.find(req => req.id === parsed.value);\n\t}\n}\n\n/**\n * Get query parameters for API calls based on identifier type\n * Note: API doesn't support req_id parameter, so we only return id for UUIDs\n */\nexport function getRequirementQueryParams(identifier: string): { id?: string } {\n\tconst parsed = parseRequirementId(identifier);\n\n\tif (parsed.type === 'uuid') {\n\t\treturn { id: parsed.value as string };\n\t} else {\n\t\t// For req_id, we'll need to search differently\n\t\treturn {};\n\t}\n}\n","/**\n * Spinner Utility\n *\n * Provides a simple polling spinner for async operations with user feedback.\n * Shows an animated spinner while waiting for a condition to become true.\n */\n\nimport chalk from 'chalk';\n\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\n/**\n * Wait for a condition with animated spinner\n *\n * Polls an async check function and displays a spinner while waiting.\n * Clears the spinner on completion or timeout.\n *\n * @param message - Message to display next to spinner\n * @param checkFn - Async function that returns true when condition is met\n * @param intervalMs - Polling interval in milliseconds (default: 3000)\n * @param maxAttempts - Maximum number of attempts (default: 60 = 3 minutes at 3s interval)\n * @returns Promise that resolves to true if condition met, false if timeout\n *\n * @example\n * ```typescript\n * const success = await waitWithSpinner(\n * 'Waiting for repository access',\n * async () => await checkAccess(),\n * 3000,\n * 60\n * );\n * ```\n */\nexport async function waitWithSpinner(\n\tmessage: string,\n\tcheckFn: () => Promise<boolean>,\n\tintervalMs: number = 3000,\n\tmaxAttempts: number = 60\n): Promise<boolean> {\n\tlet frameIndex = 0;\n\tlet spinnerInterval: NodeJS.Timeout | null = null;\n\n\t// Function to update spinner\n\tconst updateSpinner = (): void => {\n\t\tconst frame = SPINNER_FRAMES[frameIndex];\n\t\tframeIndex = (frameIndex + 1) % SPINNER_FRAMES.length;\n\n\t\t// Clear current line and write new spinner\n\t\tprocess.stdout.write(`\\r${chalk.cyan(frame)} ${message}...`);\n\t};\n\n\t// Start spinner animation (update every 100ms for smooth animation)\n\tspinnerInterval = setInterval(updateSpinner, 100);\n\n\ttry {\n\t\t// Poll with the specified interval\n\t\tfor (let attempt = 0; attempt < maxAttempts; attempt++) {\n\t\t\tconst result = await checkFn();\n\n\t\t\tif (result) {\n\t\t\t\t// Success! Clear spinner and return\n\t\t\t\tif (spinnerInterval) clearInterval(spinnerInterval);\n\t\t\t\tprocess.stdout.write('\\r' + ' '.repeat(message.length + 10) + '\\r'); // Clear line\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// Wait before next attempt (unless this was the last attempt)\n\t\t\tif (attempt < maxAttempts - 1) {\n\t\t\t\tawait new Promise(resolve => setTimeout(resolve, intervalMs));\n\t\t\t}\n\t\t}\n\n\t\t// Timeout - clear spinner and return false\n\t\tif (spinnerInterval) clearInterval(spinnerInterval);\n\t\tprocess.stdout.write('\\r' + ' '.repeat(message.length + 10) + '\\r'); // Clear line\n\t\treturn false;\n\t} catch (error) {\n\t\t// Error during polling - clean up and rethrow\n\t\tif (spinnerInterval) clearInterval(spinnerInterval);\n\t\tprocess.stdout.write('\\r' + ' '.repeat(message.length + 10) + '\\r'); // Clear line\n\t\tthrow error;\n\t}\n}\n\n/**\n * Simple one-time spinner display\n *\n * Shows a spinner without polling. Useful for operations that manage their own timing.\n * Returns a cleanup function to clear the spinner.\n *\n * @param message - Message to display\n * @param color - Chalk color function (default: cyan for AI operations, use gray for CRUD)\n * @returns Cleanup function to stop and clear the spinner\n *\n * @example\n * ```typescript\n * const stop = showSpinner('Loading');\n * await doWork();\n * stop();\n * ```\n */\nexport function showSpinner(message: string, color: typeof chalk.cyan = chalk.cyan): () => void {\n\tlet frameIndex = 0;\n\tconst interval = setInterval(() => {\n\t\tconst frame = SPINNER_FRAMES[frameIndex];\n\t\tframeIndex = (frameIndex + 1) % SPINNER_FRAMES.length;\n\t\tprocess.stdout.write(`\\r${color(frame)} ${message}...`);\n\t}, 100);\n\n\treturn (): void => {\n\t\tclearInterval(interval);\n\t\tprocess.stdout.write('\\r' + ' '.repeat(message.length + 10) + '\\r');\n\t};\n}\n","/**\n * Internal Repository Service\n *\n * For internal use only - not exposed as CLI commands.\n * Handles API interactions with BrainGrid v1 Repository endpoints.\n *\n * This service provides methods to:\n * - List repositories with filtering and pagination\n * - Get detailed information about specific repositories\n *\n * @internal\n */\n\nimport { AxiosInstance } from 'axios';\nimport { BraingridAuth } from '../auth.js';\nimport { createAuthenticatedAxios } from '../../utils/axios-with-auth.js';\nimport { Repository, ListRepositoriesResponse } from '../../types/github.js';\n\n/**\n * Internal service for Repository API operations\n */\nexport class RepositoryService {\n\tprivate baseUrl: string;\n\tprivate auth: BraingridAuth;\n\tprivate axios: AxiosInstance;\n\n\tconstructor(baseUrl: string, auth: BraingridAuth) {\n\t\tthis.baseUrl = baseUrl;\n\t\tthis.auth = auth;\n\t\tthis.axios = createAuthenticatedAxios(auth);\n\t}\n\n\tprivate getHeaders(): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t};\n\t}\n\n\t/**\n\t * List repositories for the authenticated organization\n\t *\n\t * @param params - Optional filtering and pagination parameters\n\t * @param params.page - Page number (default: 1, min: 1)\n\t * @param params.limit - Number of repositories per page (default: 10, min: 1, max: 100)\n\t * @param params.owner - Filter repositories by owner name\n\t * @param params.name - Filter repositories by name (requires owner parameter)\n\t * @returns List of repositories with pagination\n\t * @throws {Error} On API errors (401, 404, 422, 500)\n\t *\n\t * @example\n\t * ```typescript\n\t * // List all repositories with pagination\n\t * const result = await repositoryService.listRepositories({ page: 1, limit: 10 });\n\t * console.log(result.repositories);\n\t * console.log(result.pagination);\n\t *\n\t * // Filter by owner\n\t * const microsoftRepos = await repositoryService.listRepositories({ owner: 'microsoft' });\n\t *\n\t * // Filter by owner and name\n\t * const tsRepo = await repositoryService.listRepositories({ owner: 'microsoft', name: 'typescript' });\n\t * ```\n\t */\n\tasync listRepositories(params?: {\n\t\tpage?: number;\n\t\tlimit?: number;\n\t\towner?: string;\n\t\tname?: string;\n\t}): Promise<ListRepositoriesResponse> {\n\t\tconst url = `${this.baseUrl}/api/v1/repositories`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<ListRepositoriesResponse>(url, { headers, params });\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Get detailed information about a specific repository\n\t *\n\t * Supports both UUID and short ID formats (e.g., \"REPO-1\").\n\t * Returns repository details including metadata and sync status.\n\t *\n\t * @param repositoryId - Repository UUID or short ID (e.g., \"REPO-1\")\n\t * @returns Detailed repository information\n\t * @throws {Error} On API errors (401, 404, 422, 500)\n\t *\n\t * @example\n\t * ```typescript\n\t * // Using short ID\n\t * const repo = await repositoryService.getRepository('REPO-1');\n\t *\n\t * // Using UUID\n\t * const repo = await repositoryService.getRepository('550e8400-e29b-41d4-a716-446655440000');\n\t *\n\t * console.log(repo.full_name);\n\t * console.log(repo.last_synced_at);\n\t * ```\n\t */\n\tasync getRepository(repositoryId: string): Promise<Repository> {\n\t\tconst url = `${this.baseUrl}/api/v1/repositories/${repositoryId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<Repository>(url, { headers });\n\t\treturn response.data;\n\t}\n}\n","/**\n * Repository Access Utility\n *\n * Helpers for checking GitHub installation and repository access during project initialization.\n * Handles detection of owner-specific installations and repository visibility in BrainGrid.\n */\n\nimport { GitHubInstallation } from '../types/github.js';\nimport { RepositoryService } from '../services/internal/repository-service.js';\n\n/**\n * Find a GitHub installation for a specific repository owner\n *\n * @param owner - The GitHub repository owner (org or user)\n * @param installations - List of GitHub installations to search\n * @returns The matching installation or null if not found\n *\n * @example\n * ```typescript\n * const installation = findInstallationForOwner('myorg', installations);\n * if (installation) {\n * console.log(`Found installation for ${installation.account_name}`);\n * }\n * ```\n */\nexport function findInstallationForOwner(\n\towner: string,\n\tinstallations: GitHubInstallation[]\n): GitHubInstallation | null {\n\t// Case-insensitive match on account_name\n\tconst normalizedOwner = owner.toLowerCase();\n\n\treturn installations.find(inst => inst.account_name.toLowerCase() === normalizedOwner) || null;\n}\n\n/**\n * Check if a repository is accessible in BrainGrid\n *\n * Queries the repository API to see if the specific owner/name combination\n * is visible to the authenticated user's organization.\n *\n * @param repositoryService - Repository service instance\n * @param owner - GitHub repository owner\n * @param name - GitHub repository name\n * @returns True if repository is accessible, false otherwise\n *\n * @example\n * ```typescript\n * const hasAccess = await checkRepositoryAccess(repoService, 'myorg', 'myrepo');\n * if (hasAccess) {\n * console.log('Repository is accessible in BrainGrid');\n * }\n * ```\n */\nexport async function checkRepositoryAccess(\n\trepositoryService: RepositoryService,\n\towner: string,\n\tname: string\n): Promise<boolean> {\n\ttry {\n\t\tconst response = await repositoryService.listRepositories({\n\t\t\towner,\n\t\t\tname,\n\t\t\tlimit: 1,\n\t\t});\n\n\t\t// If we get results, the repository is accessible\n\t\treturn response.repositories.length > 0;\n\t} catch {\n\t\t// If the API call fails, assume no access\n\t\treturn false;\n\t}\n}\n\n/**\n * Poll for repository access with timeout\n *\n * Continuously checks if a repository becomes accessible in BrainGrid.\n * Useful when waiting for a user to grant access through the web UI.\n *\n * @param repositoryService - Repository service instance\n * @param owner - GitHub repository owner\n * @param name - GitHub repository name\n * @param intervalMs - Polling interval in milliseconds (default: 3000)\n * @param maxAttempts - Maximum number of polling attempts (default: 60 = 3 minutes at 3s interval)\n * @returns Promise that resolves to true if access is granted, false if timeout\n *\n * @example\n * ```typescript\n * const granted = await pollForRepositoryAccess(repoService, 'myorg', 'myrepo');\n * if (granted) {\n * console.log('Access granted!');\n * } else {\n * console.log('Timeout - access not granted within 3 minutes');\n * }\n * ```\n */\nexport async function pollForRepositoryAccess(\n\trepositoryService: RepositoryService,\n\towner: string,\n\tname: string,\n\tintervalMs: number = 3000,\n\tmaxAttempts: number = 60\n): Promise<boolean> {\n\tfor (let attempt = 0; attempt < maxAttempts; attempt++) {\n\t\tconst hasAccess = await checkRepositoryAccess(repositoryService, owner, name);\n\n\t\tif (hasAccess) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Wait before next attempt (unless this was the last attempt)\n\t\tif (attempt < maxAttempts - 1) {\n\t\t\tawait new Promise(resolve => setTimeout(resolve, intervalMs));\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Get repository ID from BrainGrid API\n *\n * Fetches the repository details to get its BrainGrid UUID, which is needed\n * for linking repositories to projects.\n *\n * @param repositoryService - Repository service instance\n * @param owner - GitHub repository owner\n * @param name - GitHub repository name\n * @returns Repository UUID or null if not found\n *\n * @example\n * ```typescript\n * const repoId = await getRepositoryId(repoService, 'myorg', 'myrepo');\n * if (repoId) {\n * await projectService.createProject({ name: 'My Project', repository_ids: [repoId] });\n * }\n * ```\n */\nexport async function getRepositoryId(\n\trepositoryService: RepositoryService,\n\towner: string,\n\tname: string\n): Promise<string | null> {\n\ttry {\n\t\tconst response = await repositoryService.listRepositories({\n\t\t\towner,\n\t\t\tname,\n\t\t\tlimit: 1,\n\t\t});\n\n\t\tif (response.repositories.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn response.repositories[0].id;\n\t} catch {\n\t\treturn null;\n\t}\n}\n","import chalk from 'chalk';\nimport {\n\tRequirement,\n\tRequirementDetail,\n\tRequirementTask as Task,\n\tRequirementStatus,\n} from '../types/requirement.js';\nimport { Task as TaskType } from '../types/task.js';\nimport { Project } from '../types/project.js';\nimport { formatRequirementId } from './requirements.js';\nimport { formatTaskId, getTaskStatusIcon } from './tasks.js';\n\n/**\n * Convert API URL to web UI URL\n * @param apiUrl - The API base URL (e.g., \"https://app.braingrid.ai\" or \"https://app.dev.braingrid.ai\")\n * @returns Web UI base URL\n */\nfunction getWebUiUrl(apiUrl: string): string {\n\t// If API URL contains dev.braingrid.ai, use dev web UI\n\tif (apiUrl.includes('dev.braingrid.ai')) {\n\t\treturn 'https://app.dev.braingrid.ai';\n\t}\n\t// Default to production\n\treturn 'https://app.braingrid.ai';\n}\n\nexport function formatRequirementsList(requirements: Requirement[], total: number): string {\n\tif (requirements.length === 0) {\n\t\treturn chalk.yellow('No requirements found.\\n');\n\t}\n\n\tlet output = chalk.bold.cyan(`📋 Requirements (${requirements.length} of ${total})\\n\\n`);\n\n\trequirements.forEach((req, index) => {\n\t\tconst statusColor = getStatusColor(req.status);\n\t\tconst statusIcon = getStatusIcon(req.status);\n\n\t\toutput += chalk.bold(`${index + 1}. ${req.name}\\n`);\n\t\toutput += ` ${statusIcon} Status: ${statusColor(req.status)}\\n`;\n\t\toutput += ` 📝 ${req.description}\\n`;\n\t\toutput += ` 🆔 ID: ${chalk.gray(formatRequirementId(req))}\\n`;\n\t\toutput += ` 📎 UUID: ${chalk.gray(req.id)}\\n`;\n\n\t\tif (req.assigned_to) {\n\t\t\toutput += ` 👤 Assigned: ${chalk.blue(req.assigned_to)}\\n`;\n\t\t}\n\n\t\toutput += ` 📅 Updated: ${chalk.gray(new Date(req.updated_at).toLocaleDateString())}\\n\\n`;\n\t});\n\n\treturn output;\n}\n\nexport function formatRequirementDetail(requirement: Requirement): string {\n\tconst statusColor = getStatusColor(requirement.status);\n\tconst statusIcon = getStatusIcon(requirement.status);\n\n\tlet output = chalk.bold.cyan(`📋 Requirement Details\\n`);\n\toutput += chalk.gray('━'.repeat(50)) + '\\n\\n';\n\n\toutput += chalk.bold(`Name: ${requirement.name}\\n`);\n\toutput += `${statusIcon} Status: ${statusColor(requirement.status)}\\n`;\n\toutput += `🆔 ID: ${chalk.gray(formatRequirementId(requirement))}\\n`;\n\toutput += `📎 UUID: ${chalk.gray(requirement.id)}\\n`;\n\n\tif (requirement.assigned_to) {\n\t\toutput += `👤 Assigned: ${chalk.blue(requirement.assigned_to)}\\n`;\n\t}\n\n\toutput += `📅 Created: ${chalk.gray(new Date(requirement.created_at).toLocaleDateString())}\\n`;\n\toutput += `📅 Updated: ${chalk.gray(new Date(requirement.updated_at).toLocaleDateString())}\\n\\n`;\n\n\toutput += chalk.bold('Description:\\n');\n\toutput += `${requirement.description}\\n\\n`;\n\n\treturn output;\n}\n\nexport function formatTasksList(tasks: Task[], total?: number): string {\n\tif (tasks.length === 0) {\n\t\treturn chalk.yellow('No tasks found.\\n');\n\t}\n\n\tconst displayTotal = total !== undefined ? ` of ${total}` : '';\n\tlet output = chalk.bold.cyan(`📝 Tasks (${tasks.length}${displayTotal})\\n\\n`);\n\n\ttasks.forEach((task, index) => {\n\t\tconst statusColor = getStatusColor(task.status);\n\t\tconst statusIcon = getTaskStatusIcon(task.status);\n\n\t\toutput += chalk.bold(`${index + 1}. ${task.title}\\n`);\n\t\toutput += ` ${statusIcon} Status: ${statusColor(task.status)}\\n`;\n\t\toutput += ` 📄 ${task.content}\\n`;\n\t\toutput += ` 🆔 ID: ${chalk.gray(formatTaskId(task))}\\n`;\n\t\toutput += ` 📎 UUID: ${chalk.gray(task.id)}\\n`;\n\n\t\tif (task.assigned_to) {\n\t\t\toutput += ` 👤 Assigned: ${chalk.blue(task.assigned_to)}\\n`;\n\t\t}\n\n\t\toutput += ` 📅 Updated: ${chalk.gray(new Date(task.updated_at).toLocaleDateString())}\\n\\n`;\n\t});\n\n\treturn output;\n}\n\n/**\n * Format task list with support for multiple output formats\n */\nexport function formatTasksListOutput(\n\ttasks: TaskType[],\n\tformat: 'table' | 'json' | 'xml' | 'markdown',\n\tverbose: boolean,\n\toptions?: {\n\t\trequirementId?: string;\n\t\tprojectShortId?: string;\n\t\trequirementShortId?: string;\n\t\tapiUrl?: string;\n\t}\n): string {\n\tif (tasks.length === 0) {\n\t\treturn chalk.yellow('No tasks found.');\n\t}\n\n\t// Handle format + verbose combinations\n\tswitch (format) {\n\t\tcase 'json':\n\t\t\tif (verbose) {\n\t\t\t\t// Full task objects with content\n\t\t\t\treturn JSON.stringify(tasks, null, 2);\n\t\t\t} else {\n\t\t\t\t// Subset of fields (table columns only)\n\t\t\t\treturn formatTasksListJsonSubset(tasks);\n\t\t\t}\n\n\t\tcase 'xml':\n\t\t\tif (verbose) {\n\t\t\t\t// Full tasks with content\n\t\t\t\treturn formatTasksListXml(tasks);\n\t\t\t} else {\n\t\t\t\t// Subset of fields (table columns only)\n\t\t\t\treturn formatTasksListXmlSubset(tasks);\n\t\t\t}\n\n\t\tcase 'markdown':\n\t\t\tif (verbose) {\n\t\t\t\t// Detailed markdown with content per task\n\t\t\t\treturn formatTasksListMarkdownVerbose(tasks, options);\n\t\t\t} else {\n\t\t\t\t// Markdown table\n\t\t\t\treturn formatTasksListMarkdown(tasks);\n\t\t\t}\n\n\t\tcase 'table':\n\t\tdefault:\n\t\t\tif (verbose) {\n\t\t\t\t// Multi-line detailed view with content\n\t\t\t\treturn formatTasksListVerbose(tasks, options);\n\t\t\t} else {\n\t\t\t\t// Compact table\n\t\t\t\treturn formatTasksListTable(tasks);\n\t\t\t}\n\t}\n}\n\n/**\n * Table format (default) - compact table view\n */\nfunction formatTasksListTable(tasks: TaskType[]): string {\n\tlet output = chalk.bold(`📋 Tasks (${tasks.length})\\n\\n`);\n\toutput +=\n\t\t'ID Short ID Status Title Assigned To Blocked\\n';\n\toutput += '─'.repeat(120) + '\\n';\n\n\tfor (const task of tasks) {\n\t\tconst id = task.id.substring(0, 36).padEnd(36);\n\t\tconst shortId = `TASK-${task.number}`.padEnd(8);\n\t\tconst statusEmoji = getTaskStatusEmoji(task.status);\n\t\tconst statusText = task.status.padEnd(12);\n\t\tconst title = task.title.substring(0, 28).padEnd(28);\n\t\tconst assignedTo = (task.assigned_to || 'Unassigned').substring(0, 13).padEnd(13);\n\t\tconst blocked = task.blocked_by.length > 0 ? task.blocked_by.join(', ') : 'None';\n\t\toutput += `${id} ${shortId} ${statusEmoji} ${statusText} ${title} ${assignedTo} ${blocked}\\n`;\n\t}\n\n\treturn output;\n}\n\n/**\n * Verbose format - detailed multi-line format per task\n */\nfunction formatTasksListVerbose(\n\ttasks: TaskType[],\n\toptions?: {\n\t\trequirementId?: string;\n\t\tprojectShortId?: string;\n\t\trequirementShortId?: string;\n\t\tapiUrl?: string;\n\t}\n): string {\n\tlet output = chalk.bold(`📋 Tasks (${tasks.length})\\n\\n`);\n\tconst divider = chalk.gray('─'.repeat(50));\n\n\tfor (let i = 0; i < tasks.length; i++) {\n\t\tconst task = tasks[i];\n\t\tconst statusEmoji = getTaskStatusEmoji(task.status);\n\n\t\t// Task header\n\t\toutput += `${statusEmoji} ${chalk.bold(task.title)}\\n`;\n\n\t\t// Short ID\n\t\toutput += `${chalk.bold('Short ID:')} TASK-${task.number}\\n`;\n\n\t\t// ID (UUID)\n\t\toutput += `${chalk.bold('ID:')} ${task.id}\\n`;\n\n\t\t// URL (if options provided)\n\t\tif (options?.apiUrl && options?.requirementId) {\n\t\t\tconst webUiUrl = getWebUiUrl(options.apiUrl);\n\t\t\toutput += `${chalk.bold('URL:')} ${webUiUrl}/requirements/overview?id=${options.requirementId}&tab=tasks\\n`;\n\t\t}\n\n\t\t// Project\n\t\toutput += `${chalk.bold('Project:')} ${options?.projectShortId || 'N/A'}\\n`;\n\n\t\t// Requirement\n\t\toutput += `${chalk.bold('Requirement:')} ${options?.requirementShortId || 'N/A'}\\n`;\n\n\t\t// Status\n\t\toutput += `${chalk.bold('Status:')} ${task.status}\\n`;\n\n\t\t// Assigned to\n\t\tif (task.assigned_to) {\n\t\t\toutput += `${chalk.bold('Assigned to:')} ${task.assigned_to}\\n`;\n\t\t} else {\n\t\t\toutput += `${chalk.bold('Assigned to:')} Unassigned\\n`;\n\t\t}\n\n\t\t// Timestamps\n\t\tif (task.created_at) {\n\t\t\toutput += `${chalk.bold('Created:')} ${new Date(task.created_at).toLocaleString()}\\n`;\n\t\t}\n\t\tif (task.updated_at) {\n\t\t\toutput += `${chalk.bold('Updated:')} ${new Date(task.updated_at).toLocaleString()}\\n`;\n\t\t}\n\t\tif (task.started_at) {\n\t\t\toutput += `${chalk.bold('Started:')} ${new Date(task.started_at).toLocaleString()}\\n`;\n\t\t}\n\t\tif (task.finished_at) {\n\t\t\toutput += `${chalk.bold('Finished:')} ${new Date(task.finished_at).toLocaleString()}\\n`;\n\t\t}\n\n\t\t// Content (with dividers)\n\t\tif (task.content) {\n\t\t\toutput += `\\n${divider}\\n`;\n\t\t\toutput += `${chalk.bold('Content:')}\\n${task.content}\\n`;\n\t\t\toutput += `${divider}\\n`;\n\t\t}\n\n\t\t// Blocked by\n\t\tif (task.blocked_by && task.blocked_by.length > 0) {\n\t\t\toutput += `\\n${chalk.bold('Blocked by:')} ${task.blocked_by.join(', ')}\\n`;\n\t\t}\n\n\t\t// Separator between tasks (except last)\n\t\tif (i < tasks.length - 1) {\n\t\t\toutput += '\\n' + chalk.gray('═'.repeat(50)) + '\\n\\n';\n\t\t}\n\t}\n\n\treturn output;\n}\n\n/**\n * JSON subset format - returns only table columns in JSON\n */\nfunction formatTasksListJsonSubset(tasks: TaskType[]): string {\n\tconst subset = tasks.map(task => ({\n\t\tid: task.id,\n\t\tnumber: task.number,\n\t\ttitle: task.title,\n\t\tstatus: task.status,\n\t\tassigned_to: task.assigned_to,\n\t\tblocked_by: task.blocked_by,\n\t}));\n\treturn JSON.stringify(subset, null, 2);\n}\n\n/**\n * XML format - structured XML output\n */\nfunction formatTasksListXml(tasks: TaskType[]): string {\n\tlet xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n\txml += '<tasks>\\n';\n\n\tfor (const task of tasks) {\n\t\txml += ' <task>\\n';\n\t\txml += ` <id>${escapeXml(task.id)}</id>\\n`;\n\t\txml += ` <number>${escapeXml(task.number)}</number>\\n`;\n\t\txml += ` <title>${escapeXml(task.title)}</title>\\n`;\n\t\tif (task.content) {\n\t\t\txml += ` <content>${escapeXml(task.content)}</content>\\n`;\n\t\t}\n\t\txml += ` <status>${escapeXml(task.status)}</status>\\n`;\n\t\tif (task.assigned_to) {\n\t\t\txml += ` <assigned_to>${escapeXml(task.assigned_to)}</assigned_to>\\n`;\n\t\t}\n\t\tif (task.created_at) {\n\t\t\txml += ` <created_at>${escapeXml(task.created_at)}</created_at>\\n`;\n\t\t}\n\t\tif (task.updated_at) {\n\t\t\txml += ` <updated_at>${escapeXml(task.updated_at)}</updated_at>\\n`;\n\t\t}\n\t\tif (task.started_at) {\n\t\t\txml += ` <started_at>${escapeXml(task.started_at)}</started_at>\\n`;\n\t\t}\n\t\tif (task.finished_at) {\n\t\t\txml += ` <finished_at>${escapeXml(task.finished_at)}</finished_at>\\n`;\n\t\t}\n\t\tif (task.blocked_by && task.blocked_by.length > 0) {\n\t\t\txml += ' <blocked_by>\\n';\n\t\t\tfor (const blocker of task.blocked_by) {\n\t\t\t\txml += ` <task>${escapeXml(blocker)}</task>\\n`;\n\t\t\t}\n\t\t\txml += ' </blocked_by>\\n';\n\t\t}\n\t\txml += ' </task>\\n';\n\t}\n\n\txml += '</tasks>';\n\treturn xml;\n}\n\n/**\n * XML subset format - returns only table columns in XML\n */\nfunction formatTasksListXmlSubset(tasks: TaskType[]): string {\n\tlet xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n\txml += '<tasks>\\n';\n\n\tfor (const task of tasks) {\n\t\txml += ' <task>\\n';\n\t\txml += ` <id>${escapeXml(task.id)}</id>\\n`;\n\t\txml += ` <number>${escapeXml(task.number)}</number>\\n`;\n\t\txml += ` <title>${escapeXml(task.title)}</title>\\n`;\n\t\txml += ` <status>${escapeXml(task.status)}</status>\\n`;\n\t\tif (task.assigned_to) {\n\t\t\txml += ` <assigned_to>${escapeXml(task.assigned_to)}</assigned_to>\\n`;\n\t\t}\n\t\tif (task.blocked_by && task.blocked_by.length > 0) {\n\t\t\txml += ' <blocked_by>\\n';\n\t\t\tfor (const blocker of task.blocked_by) {\n\t\t\t\txml += ` <task>${escapeXml(blocker)}</task>\\n`;\n\t\t\t}\n\t\t\txml += ' </blocked_by>\\n';\n\t\t}\n\t\txml += ' </task>\\n';\n\t}\n\n\txml += '</tasks>';\n\treturn xml;\n}\n\n/**\n * Markdown format - Markdown table\n */\nfunction formatTasksListMarkdown(tasks: TaskType[]): string {\n\tlet md = `# Tasks (${tasks.length})\\n\\n`;\n\tmd += '| ID | Short ID | Status | Title | Assigned To | Blocked | Updated |\\n';\n\tmd += '|----|----------|--------|-------|-------------|---------|----------|\\n';\n\n\tfor (const task of tasks) {\n\t\tconst id = task.id;\n\t\tconst shortId = `TASK-${task.number}`;\n\t\tconst status = task.status;\n\t\tconst title = task.title;\n\t\tconst assignedTo = task.assigned_to || 'Unassigned';\n\t\tconst blocked = task.blocked_by.length > 0 ? task.blocked_by.join(', ') : 'None';\n\t\tconst updated = task.updated_at ? new Date(task.updated_at).toLocaleDateString() : 'N/A';\n\n\t\tmd += `| ${id} | ${shortId} | ${status} | ${title} | ${assignedTo} | ${blocked} | ${updated} |\\n`;\n\t}\n\n\treturn md;\n}\n\n/**\n * Markdown verbose format - detailed markdown with content per task\n */\nfunction formatTasksListMarkdownVerbose(\n\ttasks: TaskType[],\n\toptions?: {\n\t\trequirementId?: string;\n\t\tprojectShortId?: string;\n\t\trequirementShortId?: string;\n\t\tapiUrl?: string;\n\t}\n): string {\n\tlet md = `# Tasks (${tasks.length})\\n\\n`;\n\n\tfor (let i = 0; i < tasks.length; i++) {\n\t\tconst task = tasks[i];\n\t\tconst statusEmoji = getTaskStatusEmoji(task.status);\n\n\t\tmd += `## ${statusEmoji} ${task.title}\\n\\n`;\n\t\tmd += `**Short ID:** TASK-${task.number}\\n\\n`;\n\t\tmd += `**ID:** ${task.id}\\n\\n`;\n\n\t\tif (options?.apiUrl && options?.requirementId) {\n\t\t\tconst webUiUrl = getWebUiUrl(options.apiUrl);\n\t\t\tmd += `**URL:** ${webUiUrl}/requirements/overview?id=${options.requirementId}&tab=tasks\\n\\n`;\n\t\t}\n\n\t\tmd += `**Project:** ${options?.projectShortId || 'N/A'}\\n\\n`;\n\t\tmd += `**Requirement:** ${options?.requirementShortId || 'N/A'}\\n\\n`;\n\t\tmd += `**Status:** ${task.status}\\n\\n`;\n\t\tmd += `**Assigned to:** ${task.assigned_to || 'Unassigned'}\\n\\n`;\n\n\t\t// Timestamps\n\t\tif (task.created_at) {\n\t\t\tmd += `**Created:** ${new Date(task.created_at).toLocaleString()}\\n\\n`;\n\t\t}\n\t\tif (task.updated_at) {\n\t\t\tmd += `**Updated:** ${new Date(task.updated_at).toLocaleString()}\\n\\n`;\n\t\t}\n\t\tif (task.started_at) {\n\t\t\tmd += `**Started:** ${new Date(task.started_at).toLocaleString()}\\n\\n`;\n\t\t}\n\t\tif (task.finished_at) {\n\t\t\tmd += `**Finished:** ${new Date(task.finished_at).toLocaleString()}\\n\\n`;\n\t\t}\n\n\t\t// Content\n\t\tif (task.content) {\n\t\t\tmd += `### Content\\n\\n${task.content}\\n\\n`;\n\t\t}\n\n\t\t// Blocked by\n\t\tif (task.blocked_by && task.blocked_by.length > 0) {\n\t\t\tmd += `**Blocked by:** ${task.blocked_by.join(', ')}\\n\\n`;\n\t\t}\n\n\t\t// Separator between tasks (except last)\n\t\tif (i < tasks.length - 1) {\n\t\t\tmd += '---\\n\\n';\n\t\t}\n\t}\n\n\treturn md;\n}\n\n/**\n * Escape XML special characters\n */\nfunction escapeXml(str: string | null | undefined): string {\n\t// Convert null/undefined to empty string to prevent crashes\n\tconst safeStr = str ?? '';\n\treturn safeStr\n\t\t.replace(/&/g, '&')\n\t\t.replace(/</g, '<')\n\t\t.replace(/>/g, '>')\n\t\t.replace(/\"/g, '"')\n\t\t.replace(/'/g, ''');\n}\n\nexport function formatTaskDetail(task: Task): string {\n\tconst statusColor = getStatusColor(task.status);\n\tconst statusIcon = getTaskStatusIcon(task.status);\n\n\tlet output = chalk.bold.cyan(`📝 Task Details\\n`);\n\toutput += chalk.gray('━'.repeat(50)) + '\\n\\n';\n\n\toutput += chalk.bold(`Title: ${task.title}\\n`);\n\toutput += `${statusIcon} Status: ${statusColor(task.status)}\\n`;\n\toutput += `🆔 ID: ${chalk.gray(formatTaskId(task))}\\n`;\n\toutput += `📎 UUID: ${chalk.gray(task.id)}\\n`;\n\toutput += `🔗 Requirement: ${chalk.gray(task.requirement_id)}\\n`;\n\n\tif (task.assigned_to) {\n\t\toutput += `👤 Assigned: ${chalk.blue(task.assigned_to)}\\n`;\n\t}\n\n\toutput += `📅 Created: ${chalk.gray(new Date(task.created_at).toLocaleDateString())}\\n`;\n\toutput += `📅 Updated: ${chalk.gray(new Date(task.updated_at).toLocaleDateString())}\\n\\n`;\n\n\toutput += chalk.bold('Content:\\n');\n\toutput += `${task.content}\\n\\n`;\n\n\treturn output;\n}\n\n/**\n * Get emoji for requirement status\n */\nexport function getRequirementStatusEmoji(status: RequirementStatus): string {\n\tswitch (status) {\n\t\tcase 'IDEA':\n\t\t\treturn '💡';\n\t\tcase 'PLANNED':\n\t\t\treturn '📝';\n\t\tcase 'IN_PROGRESS':\n\t\t\treturn '🚧';\n\t\tcase 'REVIEW':\n\t\t\treturn '👀';\n\t\tcase 'COMPLETED':\n\t\t\treturn '✅';\n\t\tcase 'CANCELLED':\n\t\t\treturn '❌';\n\t\tdefault:\n\t\t\treturn '❓';\n\t}\n}\n\n/**\n * Format requirement output with consistent field order and dividers\n * Field order: Short ID, ID (UUID), URL, Project, Branch, Status, Assigned to, Created at, Updated at, Description, Content, Tasks\n * Includes dividers before/after content and after tasks count\n */\nexport function formatRequirementOutput(\n\trequirement: RequirementDetail,\n\toptions?: {\n\t\tshowContent?: boolean;\n\t\tshowTasks?: boolean;\n\t\tshowTaskList?: boolean;\n\t\tshowDescription?: boolean;\n\t\tshowUpdated?: boolean;\n\t\tsuccessMessage?: string;\n\t\tapiUrl?: string;\n\t\tprojectShortId?: string;\n\t}\n): string {\n\tconst statusEmoji = getRequirementStatusEmoji(requirement.status);\n\tconst divider = chalk.gray('─'.repeat(50));\n\n\tlet message = '';\n\n\t// Success message header (if provided)\n\tif (options?.successMessage) {\n\t\tmessage += chalk.green(`✅ ${options.successMessage}\\n\\n`);\n\t}\n\n\t// Requirement name with status emoji\n\tmessage += `${statusEmoji} ${chalk.bold(requirement.name)}\\n\\n`;\n\n\t// Short ID\n\tmessage += `${chalk.bold('Short ID:')} ${requirement.short_id || 'N/A'}\\n`;\n\n\t// ID (UUID)\n\tmessage += `${chalk.bold('ID:')} ${requirement.id}\\n`;\n\n\t// URL\n\tif (options?.apiUrl) {\n\t\tconst webUiUrl = getWebUiUrl(options.apiUrl);\n\t\tmessage += `${chalk.bold('URL:')} ${webUiUrl}/requirements/overview?id=${requirement.id}\\n`;\n\t}\n\n\t// Project\n\tmessage += `${chalk.bold('Project:')} ${options?.projectShortId || 'N/A'}\\n`;\n\n\t// Branch\n\tif (requirement.branch) {\n\t\tmessage += `${chalk.bold('Branch:')} ${requirement.branch}\\n`;\n\t}\n\n\t// Status\n\tmessage += `${chalk.bold('Status:')} ${requirement.status}\\n`;\n\n\t// Assigned to (always show)\n\tif (requirement.assignee) {\n\t\tconst assigneeName =\n\t\t\trequirement.assignee.first_name || requirement.assignee.last_name\n\t\t\t\t? `${requirement.assignee.first_name || ''} ${requirement.assignee.last_name || ''}`.trim()\n\t\t\t\t: requirement.assignee.email;\n\t\tmessage += `${chalk.bold('Assigned to:')} ${assigneeName} (${requirement.assignee.email})\\n`;\n\t} else {\n\t\tmessage += `${chalk.bold('Assigned to:')} Unassigned\\n`;\n\t}\n\n\t// Created timestamp\n\tmessage += `${chalk.bold('Created:')} ${new Date(requirement.created_at).toLocaleString()}\\n`;\n\n\t// Updated timestamp (optional)\n\tif (options?.showUpdated) {\n\t\tmessage += `${chalk.bold('Updated:')} ${new Date(requirement.updated_at).toLocaleString()}\\n`;\n\t}\n\n\t// Description section (with dividers)\n\tif (options?.showDescription && requirement.description) {\n\t\tmessage += `\\n${divider}\\n`;\n\t\tmessage += `${chalk.bold('Description:')}\\n${requirement.description}\\n`;\n\t\tmessage += `${divider}\\n`;\n\t}\n\n\t// Content section (with dividers)\n\tif (options?.showContent && requirement.content) {\n\t\tmessage += `\\n${divider}\\n`;\n\t\tmessage += `${chalk.bold('Content:')}\\n${requirement.content}\\n`;\n\t\tmessage += `${divider}\\n`;\n\t}\n\n\t// Tasks section (with divider after count or list)\n\tif (options?.showTaskList) {\n\t\t// Show detailed task list\n\t\tmessage += `\\n${chalk.bold('Tasks:')}\\n`;\n\t\tif (requirement.tasks && requirement.tasks.length > 0) {\n\t\t\tfor (const task of requirement.tasks) {\n\t\t\t\tconst taskEmoji = getRequirementStatusEmoji(task.status);\n\t\t\t\tmessage += ` ${taskEmoji} ${task.number}. ${task.title} (${task.status})\\n`;\n\t\t\t}\n\t\t}\n\t\tmessage += `${divider}\\n`;\n\t} else if (options?.showTasks) {\n\t\t// Show task count only (always show, even if 0/0)\n\t\tconst tasks = requirement.tasks || [];\n\t\tconst completedTasks = tasks.filter(task => task.status === 'COMPLETED').length;\n\t\tconst totalTasks = tasks.length;\n\t\tmessage += `\\n${chalk.bold('Tasks:')} ${completedTasks}/${totalTasks} completed\\n`;\n\t\tmessage += `${divider}\\n`;\n\t}\n\n\treturn message;\n}\n\n/**\n * Get emoji for task status (internal use only)\n */\nfunction getTaskStatusEmoji(status: string): string {\n\tswitch (status) {\n\t\tcase 'PLANNED':\n\t\t\treturn '📝';\n\t\tcase 'IN_PROGRESS':\n\t\t\treturn '🚧';\n\t\tcase 'COMPLETED':\n\t\t\treturn '✅';\n\t\tcase 'CANCELLED':\n\t\t\treturn '❌';\n\t\tdefault:\n\t\t\treturn '❓';\n\t}\n}\n\n/**\n * Format task output with consistent field order and dividers\n * Field order: Short ID, ID (UUID), URL, Project, Requirement, Status, Assigned to, Created, Updated, Started, Finished, Content, Blocked by\n * Includes dividers before/after content\n */\nexport function formatTaskOutput(\n\ttask: TaskType,\n\toptions?: {\n\t\tshowContent?: boolean;\n\t\tsuccessMessage?: string;\n\t\tapiUrl?: string;\n\t\tprojectShortId?: string;\n\t\trequirementShortId?: string;\n\t\trequirementId?: string;\n\t}\n): string {\n\tconst statusEmoji = getTaskStatusEmoji(task.status);\n\tconst divider = chalk.gray('─'.repeat(50));\n\n\tlet message = '';\n\n\t// Success message header (if provided)\n\tif (options?.successMessage) {\n\t\tmessage += chalk.green(`✅ ${options.successMessage}\\n\\n`);\n\t}\n\n\t// Task title with status emoji\n\tmessage += `${statusEmoji} ${chalk.bold(task.title)}\\n\\n`;\n\n\t// Short ID (TASK-{number})\n\tmessage += `${chalk.bold('Short ID:')} TASK-${task.number}\\n`;\n\n\t// ID (UUID)\n\tmessage += `${chalk.bold('ID:')} ${task.id}\\n`;\n\n\t// URL - use requirement UUID with tab=tasks\n\tif (options?.apiUrl && options?.requirementId) {\n\t\tconst webUiUrl = getWebUiUrl(options.apiUrl);\n\t\tmessage += `${chalk.bold('URL:')} ${webUiUrl}/requirements/overview?id=${options.requirementId}&tab=tasks\\n`;\n\t}\n\n\t// Project\n\tmessage += `${chalk.bold('Project:')} ${options?.projectShortId || 'N/A'}\\n`;\n\n\t// Requirement\n\tmessage += `${chalk.bold('Requirement:')} ${options?.requirementShortId || 'N/A'}\\n`;\n\n\t// Status\n\tmessage += `${chalk.bold('Status:')} ${task.status}\\n`;\n\n\t// Assigned to (always show)\n\tif (task.assigned_to) {\n\t\t// TODO: Fetch assignee details from API when available\n\t\tmessage += `${chalk.bold('Assigned to:')} ${task.assigned_to}\\n`;\n\t} else {\n\t\tmessage += `${chalk.bold('Assigned to:')} Unassigned\\n`;\n\t}\n\n\t// Created timestamp (if available)\n\tif (task.created_at) {\n\t\tmessage += `${chalk.bold('Created:')} ${new Date(task.created_at).toLocaleString()}\\n`;\n\t}\n\n\t// Updated timestamp (if available)\n\tif (task.updated_at) {\n\t\tmessage += `${chalk.bold('Updated:')} ${new Date(task.updated_at).toLocaleString()}\\n`;\n\t}\n\n\t// Started timestamp (if available)\n\tif (task.started_at) {\n\t\tmessage += `${chalk.bold('Started:')} ${new Date(task.started_at).toLocaleString()}\\n`;\n\t}\n\n\t// Finished timestamp (if available)\n\tif (task.finished_at) {\n\t\tmessage += `${chalk.bold('Finished:')} ${new Date(task.finished_at).toLocaleString()}\\n`;\n\t}\n\n\t// Content section (with dividers)\n\tif (options?.showContent && task.content) {\n\t\tmessage += `\\n${divider}\\n`;\n\t\tmessage += `${chalk.bold('Content:')}\\n${task.content}\\n`;\n\t\tmessage += `${divider}\\n`;\n\t}\n\n\t// Blocked by section\n\tif (task.blocked_by && task.blocked_by.length > 0) {\n\t\tmessage += `\\n${chalk.bold('Blocked by:')} ${task.blocked_by.join(', ')}\\n`;\n\t}\n\n\treturn message;\n}\n\nexport function formatErrorMessage(message: string): string {\n\treturn chalk.red(`❌ ${message}`);\n}\n\nexport function formatSuccessMessage(message: string): string {\n\treturn chalk.green(`✅ ${message}`);\n}\n\nexport function formatInfoMessage(message: string): string {\n\treturn chalk.blue(`ℹ️ ${message}`);\n}\n\nexport function formatWarningMessage(message: string): string {\n\treturn chalk.yellow(`⚠️ ${message}`);\n}\n\nfunction getStatusColor(status: string) {\n\tswitch (status) {\n\t\tcase 'PLANNED':\n\t\t\treturn chalk.blue;\n\t\tcase 'IN_PROGRESS':\n\t\t\treturn chalk.yellow;\n\t\tcase 'COMPLETED':\n\t\t\treturn chalk.green;\n\t\tcase 'CANCELLED':\n\t\t\treturn chalk.red;\n\t\tdefault:\n\t\t\treturn chalk.gray;\n\t}\n}\n\nfunction getStatusIcon(status: string): string {\n\tswitch (status) {\n\t\tcase 'PLANNED':\n\t\t\treturn '📋';\n\t\tcase 'IN_PROGRESS':\n\t\t\treturn '🔄';\n\t\tcase 'COMPLETED':\n\t\t\treturn '✅';\n\t\tcase 'CANCELLED':\n\t\t\treturn '❌';\n\t\tdefault:\n\t\t\treturn '❓';\n\t}\n}\n\n/**\n * Format requirement list output in Markdown format\n */\nexport function formatRequirementListMarkdown(\n\trequirements: Requirement[],\n\tpagination?: { page: number; limit: number; total: number }\n): string {\n\tlet md = '# Requirements\\n\\n';\n\n\tif (requirements.length === 0) {\n\t\tmd += '_No requirements found._\\n';\n\t\treturn md;\n\t}\n\n\tmd += '| Short ID | Status | Name | Branch | Progress |\\n';\n\tmd += '|----------|--------|------|--------|----------|\\n';\n\n\tfor (const req of requirements) {\n\t\tconst shortId = req.short_id || req.id.slice(0, 11);\n\t\tconst status = req.status;\n\t\tconst name = req.name;\n\t\tconst branch = req.branch || 'N/A';\n\t\tconst progress = req.task_progress ? `${req.task_progress.progress_percentage}%` : 'N/A';\n\n\t\tmd += `| ${shortId} | ${status} | ${name} | ${branch} | ${progress} |\\n`;\n\t}\n\n\tif (pagination) {\n\t\tmd += '\\n';\n\t\tconst totalPages = Math.ceil(pagination.total / pagination.limit);\n\t\tmd += `_Page ${pagination.page} of ${totalPages} (${pagination.total} total)_\\n`;\n\t}\n\n\treturn md;\n}\n\n/**\n * Format requirement list output in XML format\n */\nexport function formatRequirementListXml(\n\trequirements: Requirement[],\n\tpagination?: { page: number; limit: number; total: number }\n): string {\n\tlet xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n\txml += '<requirements>\\n';\n\n\tif (pagination) {\n\t\txml += ' <pagination>\\n';\n\t\txml += ` <page>${pagination.page}</page>\\n`;\n\t\txml += ` <limit>${pagination.limit}</limit>\\n`;\n\t\txml += ` <total>${pagination.total}</total>\\n`;\n\t\txml += ` <total_pages>${Math.ceil(pagination.total / pagination.limit)}</total_pages>\\n`;\n\t\txml += ' </pagination>\\n';\n\t}\n\n\txml += ' <items>\\n';\n\tfor (const req of requirements) {\n\t\txml += ' <requirement>\\n';\n\t\txml += ` <id>${escapeXml(req.id)}</id>\\n`;\n\t\tif (req.short_id) {\n\t\t\txml += ` <short_id>${escapeXml(req.short_id)}</short_id>\\n`;\n\t\t}\n\t\txml += ` <name>${escapeXml(req.name)}</name>\\n`;\n\t\tif (req.description) {\n\t\t\txml += ` <description>${escapeXml(req.description)}</description>\\n`;\n\t\t}\n\t\txml += ` <status>${escapeXml(req.status)}</status>\\n`;\n\t\tif (req.branch) {\n\t\t\txml += ` <branch>${escapeXml(req.branch)}</branch>\\n`;\n\t\t}\n\t\tif (req.task_progress) {\n\t\t\txml += ' <task_progress>\\n';\n\t\t\txml += ` <total>${req.task_progress.total}</total>\\n`;\n\t\t\txml += ` <completed>${req.task_progress.completed}</completed>\\n`;\n\t\t\txml += ` <progress_percentage>${req.task_progress.progress_percentage}</progress_percentage>\\n`;\n\t\t\txml += ' </task_progress>\\n';\n\t\t}\n\t\tif (req.assigned_to) {\n\t\t\txml += ` <assigned_to>${escapeXml(req.assigned_to)}</assigned_to>\\n`;\n\t\t}\n\t\tif (req.assignee) {\n\t\t\txml += ' <assignee>\\n';\n\t\t\txml += ` <id>${escapeXml(req.assignee.id)}</id>\\n`;\n\t\t\txml += ` <first_name>${escapeXml(req.assignee.first_name)}</first_name>\\n`;\n\t\t\txml += ` <last_name>${escapeXml(req.assignee.last_name)}</last_name>\\n`;\n\t\t\txml += ` <email>${escapeXml(req.assignee.email)}</email>\\n`;\n\t\t\txml += ' </assignee>\\n';\n\t\t}\n\t\txml += ` <created_at>${escapeXml(req.created_at)}</created_at>\\n`;\n\t\txml += ` <updated_at>${escapeXml(req.updated_at)}</updated_at>\\n`;\n\t\txml += ' </requirement>\\n';\n\t}\n\txml += ' </items>\\n';\n\txml += '</requirements>\\n';\n\n\treturn xml;\n}\n\n/**\n * Format requirement breakdown output in Markdown format\n */\nexport function formatRequirementBreakdownMarkdown(\n\trequirementShortId: string,\n\ttasks: Array<{\n\t\tnumber: string;\n\t\ttitle: string;\n\t\tstatus: string;\n\t\tcontent?: string;\n\t\tblocked_by: string[];\n\t\tid: string;\n\t}>\n): string {\n\tlet md = `# Breakdown: ${requirementShortId}\\n\\n`;\n\tmd += `Generated ${tasks.length} task${tasks.length !== 1 ? 's' : ''}\\n\\n`;\n\n\tif (tasks.length === 0) {\n\t\tmd += '_No tasks generated._\\n';\n\t\treturn md;\n\t}\n\n\tfor (const task of tasks) {\n\t\tmd += `## Task ${task.number}: ${task.title}\\n\\n`;\n\t\tmd += `- **Status:** ${task.status}\\n`;\n\t\tmd += `- **ID:** ${task.id}\\n`;\n\t\tif (task.blocked_by.length > 0) {\n\t\t\tmd += `- **Blocked by:** ${task.blocked_by.join(', ')}\\n`;\n\t\t}\n\t\tif (task.content) {\n\t\t\tmd += `\\n### Content\\n\\n${task.content}\\n`;\n\t\t}\n\t\tmd += '\\n';\n\t}\n\n\treturn md;\n}\n\n/**\n * Format requirement breakdown output in XML format\n */\nexport function formatRequirementBreakdownXml(\n\trequirementShortId: string,\n\ttasks: Array<{\n\t\tnumber: string;\n\t\ttitle: string;\n\t\tstatus: string;\n\t\tcontent?: string;\n\t\tblocked_by: string[];\n\t\tid: string;\n\t\tcreated_at: string;\n\t\tupdated_at: string;\n\t\tassigned_to: string | null;\n\t}>\n): string {\n\tlet xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n\txml += '<breakdown>\\n';\n\txml += ` <requirement_short_id>${escapeXml(requirementShortId)}</requirement_short_id>\\n`;\n\txml += ` <task_count>${tasks.length}</task_count>\\n`;\n\txml += ' <tasks>\\n';\n\n\tfor (const task of tasks) {\n\t\txml += ' <task>\\n';\n\t\txml += ` <number>${escapeXml(task.number)}</number>\\n`;\n\t\txml += ` <title>${escapeXml(task.title)}</title>\\n`;\n\t\txml += ` <status>${escapeXml(task.status)}</status>\\n`;\n\t\txml += ` <id>${escapeXml(task.id)}</id>\\n`;\n\t\tif (task.content) {\n\t\t\txml += ` <content>${escapeXml(task.content)}</content>\\n`;\n\t\t}\n\t\tif (task.blocked_by.length > 0) {\n\t\t\txml += ' <blocked_by>\\n';\n\t\t\tfor (const blocker of task.blocked_by) {\n\t\t\t\txml += ` <task>${escapeXml(blocker)}</task>\\n`;\n\t\t\t}\n\t\t\txml += ' </blocked_by>\\n';\n\t\t}\n\t\tif (task.assigned_to) {\n\t\t\txml += ` <assigned_to>${escapeXml(task.assigned_to)}</assigned_to>\\n`;\n\t\t}\n\t\txml += ` <created_at>${escapeXml(task.created_at)}</created_at>\\n`;\n\t\txml += ` <updated_at>${escapeXml(task.updated_at)}</updated_at>\\n`;\n\t\txml += ' </task>\\n';\n\t}\n\n\txml += ' </tasks>\\n';\n\txml += '</breakdown>\\n';\n\n\treturn xml;\n}\n\n/**\n * Format requirement build output in Markdown format\n * Includes full requirement details and all tasks with content\n */\nexport function formatRequirementBuildMarkdown(\n\trequirement: RequirementDetail,\n\toptions?: {\n\t\tapiUrl?: string;\n\t\tprojectShortId?: string;\n\t}\n): string {\n\tconst statusEmoji = getRequirementStatusEmoji(requirement.status);\n\n\tlet md = `# ${statusEmoji} ${requirement.name}\\n\\n`;\n\n\t// Requirement metadata\n\tmd += `**Short ID:** ${requirement.short_id || 'N/A'}\\n\\n`;\n\tmd += `**ID:** ${requirement.id}\\n\\n`;\n\n\tif (options?.apiUrl) {\n\t\tconst webUiUrl = getWebUiUrl(options.apiUrl);\n\t\tmd += `**URL:** ${webUiUrl}/requirements/overview?id=${requirement.id}\\n\\n`;\n\t}\n\n\tmd += `**Project:** ${options?.projectShortId || 'N/A'}\\n\\n`;\n\tif (requirement.branch) {\n\t\tmd += `**Branch:** ${requirement.branch}\\n\\n`;\n\t}\n\tmd += `**Status:** ${requirement.status}\\n\\n`;\n\n\t// Assigned to\n\tif (requirement.assignee) {\n\t\tconst assigneeName =\n\t\t\trequirement.assignee.first_name || requirement.assignee.last_name\n\t\t\t\t? `${requirement.assignee.first_name || ''} ${requirement.assignee.last_name || ''}`.trim()\n\t\t\t\t: requirement.assignee.email;\n\t\tmd += `**Assigned to:** ${assigneeName} (${requirement.assignee.email})\\n\\n`;\n\t} else {\n\t\tmd += `**Assigned to:** Unassigned\\n\\n`;\n\t}\n\n\tmd += `**Created:** ${new Date(requirement.created_at).toLocaleString()}\\n\\n`;\n\tmd += `**Updated:** ${new Date(requirement.updated_at).toLocaleString()}\\n\\n`;\n\n\t// Description\n\tif (requirement.description) {\n\t\tmd += `## Description\\n\\n${requirement.description}\\n\\n`;\n\t}\n\n\t// Content\n\tif (requirement.content) {\n\t\tmd += `## Content\\n\\n${requirement.content}\\n\\n`;\n\t}\n\n\t// Tasks\n\tconst tasks = requirement.tasks || [];\n\tmd += `## Tasks (${tasks.length})\\n\\n`;\n\n\tif (tasks.length === 0) {\n\t\tmd += '_No tasks available_\\n\\n';\n\t\tmd += '💡 _Run `braingrid requirement breakdown [id]` to generate tasks using AI_\\n';\n\t} else {\n\t\tfor (let i = 0; i < tasks.length; i++) {\n\t\t\tconst task = tasks[i];\n\t\t\tconst taskEmoji = getRequirementStatusEmoji(task.status);\n\n\t\t\tmd += `### ${taskEmoji} Task ${task.number}: ${task.title}\\n\\n`;\n\t\t\tmd += `**Short ID:** TASK-${task.number}\\n\\n`;\n\t\t\tmd += `**ID:** ${task.id}\\n\\n`;\n\n\t\t\tif (options?.apiUrl) {\n\t\t\t\tconst webUiUrl = getWebUiUrl(options.apiUrl);\n\t\t\t\tmd += `**URL:** ${webUiUrl}/requirements/overview?id=${requirement.id}&tab=tasks\\n\\n`;\n\t\t\t}\n\n\t\t\tmd += `**Status:** ${task.status}\\n\\n`;\n\n\t\t\tif (task.assigned_to) {\n\t\t\t\tmd += `**Assigned to:** ${task.assigned_to}\\n\\n`;\n\t\t\t} else {\n\t\t\t\tmd += `**Assigned to:** Unassigned\\n\\n`;\n\t\t\t}\n\n\t\t\tif (task.created_at) {\n\t\t\t\tmd += `**Created:** ${new Date(task.created_at).toLocaleString()}\\n\\n`;\n\t\t\t}\n\t\t\tif (task.updated_at) {\n\t\t\t\tmd += `**Updated:** ${new Date(task.updated_at).toLocaleString()}\\n\\n`;\n\t\t\t}\n\t\t\tif (task.started_at) {\n\t\t\t\tmd += `**Started:** ${new Date(task.started_at).toLocaleString()}\\n\\n`;\n\t\t\t}\n\t\t\tif (task.finished_at) {\n\t\t\t\tmd += `**Finished:** ${new Date(task.finished_at).toLocaleString()}\\n\\n`;\n\t\t\t}\n\n\t\t\t// Task content\n\t\t\tif (task.content) {\n\t\t\t\tmd += `#### Content\\n\\n${task.content}\\n\\n`;\n\t\t\t}\n\n\t\t\t// Blocked by\n\t\t\tif (task.blocked_by && task.blocked_by.length > 0) {\n\t\t\t\tmd += `**Blocked by:** ${task.blocked_by.join(', ')}\\n\\n`;\n\t\t\t}\n\n\t\t\t// Separator between tasks (except last)\n\t\t\tif (i < tasks.length - 1) {\n\t\t\t\tmd += '---\\n\\n';\n\t\t\t}\n\t\t}\n\t}\n\n\treturn md;\n}\n\n/**\n * Format requirement build output in JSON format\n * Includes full requirement details and all tasks with content\n */\nexport function formatRequirementBuildJson(requirement: RequirementDetail): string {\n\t// Add hint if no tasks are available\n\tconst tasks = requirement.tasks || [];\n\tif (tasks.length === 0) {\n\t\treturn JSON.stringify(\n\t\t\t{\n\t\t\t\t...requirement,\n\t\t\t\t_hint: \"Run 'braingrid requirement breakdown [id]' to generate tasks using AI\",\n\t\t\t},\n\t\t\tnull,\n\t\t\t2\n\t\t);\n\t}\n\treturn JSON.stringify(requirement, null, 2);\n}\n\n/**\n * Format requirement build output in XML format\n * Includes full requirement details and all tasks with content\n */\nexport function formatRequirementBuildXml(requirement: RequirementDetail): string {\n\tlet xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n\txml += '<requirement>\\n';\n\n\t// Requirement metadata\n\txml += ` <id>${escapeXml(requirement.id)}</id>\\n`;\n\txml += ` <short_id>${escapeXml(requirement.short_id || '')}</short_id>\\n`;\n\txml += ` <name>${escapeXml(requirement.name)}</name>\\n`;\n\txml += ` <status>${escapeXml(requirement.status)}</status>\\n`;\n\tif (requirement.branch) {\n\t\txml += ` <branch>${escapeXml(requirement.branch)}</branch>\\n`;\n\t}\n\n\t// Assigned to\n\tif (requirement.assignee) {\n\t\txml += ' <assignee>\\n';\n\t\txml += ` <email>${escapeXml(requirement.assignee.email)}</email>\\n`;\n\t\tif (requirement.assignee.first_name) {\n\t\t\txml += ` <first_name>${escapeXml(requirement.assignee.first_name)}</first_name>\\n`;\n\t\t}\n\t\tif (requirement.assignee.last_name) {\n\t\t\txml += ` <last_name>${escapeXml(requirement.assignee.last_name)}</last_name>\\n`;\n\t\t}\n\t\txml += ' </assignee>\\n';\n\t}\n\n\t// Timestamps\n\txml += ` <created_at>${escapeXml(requirement.created_at)}</created_at>\\n`;\n\txml += ` <updated_at>${escapeXml(requirement.updated_at)}</updated_at>\\n`;\n\n\t// Description\n\tif (requirement.description) {\n\t\txml += ` <description>${escapeXml(requirement.description)}</description>\\n`;\n\t}\n\n\t// Content\n\tif (requirement.content) {\n\t\txml += ` <content>${escapeXml(requirement.content)}</content>\\n`;\n\t}\n\n\t// Tasks\n\tconst tasks = requirement.tasks || [];\n\txml += ` <tasks count=\"${tasks.length}\">\\n`;\n\n\tif (tasks.length === 0) {\n\t\txml += ` <hint>Run 'braingrid requirement breakdown [id]' to generate tasks using AI</hint>\\n`;\n\t} else {\n\t\tfor (const task of tasks) {\n\t\t\txml += ' <task>\\n';\n\t\t\txml += ` <id>${escapeXml(task.id)}</id>\\n`;\n\t\t\txml += ` <number>${escapeXml(String(task.number))}</number>\\n`;\n\t\t\txml += ` <title>${escapeXml(task.title)}</title>\\n`;\n\t\t\txml += ` <status>${escapeXml(task.status)}</status>\\n`;\n\n\t\t\tif (task.content) {\n\t\t\t\txml += ` <content>${escapeXml(task.content)}</content>\\n`;\n\t\t\t}\n\n\t\t\tif (task.assigned_to) {\n\t\t\t\txml += ` <assigned_to>${escapeXml(task.assigned_to)}</assigned_to>\\n`;\n\t\t\t}\n\n\t\t\tif (task.created_at) {\n\t\t\t\txml += ` <created_at>${escapeXml(task.created_at)}</created_at>\\n`;\n\t\t\t}\n\t\t\tif (task.updated_at) {\n\t\t\t\txml += ` <updated_at>${escapeXml(task.updated_at)}</updated_at>\\n`;\n\t\t\t}\n\t\t\tif (task.started_at) {\n\t\t\t\txml += ` <started_at>${escapeXml(task.started_at)}</started_at>\\n`;\n\t\t\t}\n\t\t\tif (task.finished_at) {\n\t\t\t\txml += ` <finished_at>${escapeXml(task.finished_at)}</finished_at>\\n`;\n\t\t\t}\n\n\t\t\tif (task.blocked_by && task.blocked_by.length > 0) {\n\t\t\t\txml += ' <blocked_by>\\n';\n\t\t\t\tfor (const blocker of task.blocked_by) {\n\t\t\t\t\txml += ` <task>${escapeXml(blocker)}</task>\\n`;\n\t\t\t\t}\n\t\t\t\txml += ' </blocked_by>\\n';\n\t\t\t}\n\n\t\t\txml += ' </task>\\n';\n\t\t}\n\t}\n\n\txml += ' </tasks>\\n';\n\txml += '</requirement>';\n\n\treturn xml;\n}\n\n/**\n * Format project list output in Markdown format\n * Includes table with pagination metadata\n */\nexport function formatProjectListMarkdown(\n\tprojects: Project[],\n\tpagination?: { page: number; limit: number; total: number; has_more?: boolean }\n): string {\n\tif (projects.length === 0) {\n\t\treturn '# Projects\\n\\n_No projects found._\\n';\n\t}\n\n\tlet md = pagination\n\t\t? `# Projects (${projects.length} of ${pagination.total})\\n\\n`\n\t\t: `# Projects (${projects.length})\\n\\n`;\n\tmd += '| Short ID | Name | Repository | Created | Updated |\\n';\n\tmd += '|----------|------|------------|---------|----------|\\n';\n\n\tfor (const project of projects) {\n\t\tconst shortId = project.short_id || 'N/A';\n\t\tconst name = project.name;\n\t\tconst repo = project.repository?.full_name || 'N/A';\n\t\tconst created = new Date(project.created_at).toLocaleDateString();\n\t\tconst updated = new Date(project.updated_at).toLocaleDateString();\n\n\t\tmd += `| ${shortId} | ${name} | ${repo} | ${created} | ${updated} |\\n`;\n\t}\n\n\tif (pagination) {\n\t\tmd += `\\n**Page ${pagination.page} of ${Math.ceil(pagination.total / pagination.limit)}** (${pagination.total} total)\\n`;\n\t}\n\n\treturn md;\n}\n\n/**\n * Format project list output in XML format\n * Includes pagination metadata\n */\nexport function formatProjectListXml(\n\tprojects: Project[],\n\tpagination?: { page: number; limit: number; total: number; has_more?: boolean }\n): string {\n\tlet xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n\txml += '<projects>\\n';\n\tif (pagination) {\n\t\txml += ' <pagination>\\n';\n\t\txml += ` <page>${pagination.page}</page>\\n`;\n\t\txml += ` <limit>${pagination.limit}</limit>\\n`;\n\t\txml += ` <total>${pagination.total}</total>\\n`;\n\t\txml += ' </pagination>\\n';\n\t}\n\txml += ' <items>\\n';\n\n\tfor (const project of projects) {\n\t\txml += ' <project>\\n';\n\t\txml += ` <id>${escapeXml(project.id)}</id>\\n`;\n\t\txml += ` <short_id>${escapeXml(project.short_id || '')}</short_id>\\n`;\n\t\txml += ` <name>${escapeXml(project.name)}</name>\\n`;\n\n\t\tif (project.description) {\n\t\t\txml += ` <description>${escapeXml(project.description)}</description>\\n`;\n\t\t}\n\n\t\tif (project.repository) {\n\t\t\txml += ' <repository>\\n';\n\t\t\txml += ` <id>${escapeXml(project.repository.id)}</id>\\n`;\n\t\t\txml += ` <full_name>${escapeXml(project.repository.full_name)}</full_name>\\n`;\n\t\t\txml += ` <name>${escapeXml(project.repository.name)}</name>\\n`;\n\t\t\txml += ' </repository>\\n';\n\t\t}\n\n\t\txml += ` <created_at>${escapeXml(project.created_at)}</created_at>\\n`;\n\t\txml += ` <updated_at>${escapeXml(project.updated_at)}</updated_at>\\n`;\n\t\txml += ' </project>\\n';\n\t}\n\n\txml += ' </items>\\n';\n\txml += '</projects>';\n\n\treturn xml;\n}\n\n/**\n * Format single project output in Markdown format\n */\nexport function formatProjectShowMarkdown(project: Project): string {\n\tlet md = `# ${project.name}\\n\\n`;\n\n\tmd += `**Short ID:** ${project.short_id || 'N/A'}\\n\\n`;\n\tmd += `**ID:** ${project.id}\\n\\n`;\n\n\tif (project.description) {\n\t\tmd += `**Description:** ${project.description}\\n\\n`;\n\t}\n\n\tif (project.repository) {\n\t\tmd += `**Repository:** ${project.repository.full_name}\\n\\n`;\n\t}\n\n\tmd += `**Created:** ${new Date(project.created_at).toLocaleString()}\\n\\n`;\n\tmd += `**Updated:** ${new Date(project.updated_at).toLocaleString()}\\n`;\n\n\treturn md;\n}\n\n/**\n * Format single project output in XML format\n */\nexport function formatProjectShowXml(project: Project): string {\n\tlet xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n\txml += '<project>\\n';\n\txml += ` <id>${escapeXml(project.id)}</id>\\n`;\n\txml += ` <short_id>${escapeXml(project.short_id || '')}</short_id>\\n`;\n\txml += ` <name>${escapeXml(project.name)}</name>\\n`;\n\n\tif (project.description) {\n\t\txml += ` <description>${escapeXml(project.description)}</description>\\n`;\n\t}\n\n\tif (project.repository) {\n\t\txml += ' <repository>\\n';\n\t\txml += ` <id>${escapeXml(project.repository.id)}</id>\\n`;\n\t\txml += ` <full_name>${escapeXml(project.repository.full_name)}</full_name>\\n`;\n\t\txml += ` <name>${escapeXml(project.repository.name)}</name>\\n`;\n\t\txml += ' </repository>\\n';\n\t}\n\n\txml += ` <created_at>${escapeXml(project.created_at)}</created_at>\\n`;\n\txml += ` <updated_at>${escapeXml(project.updated_at)}</updated_at>\\n`;\n\txml += '</project>';\n\n\treturn xml;\n}\n","import { RequirementTask as Task } from '../types/requirement.js';\nimport { normalizeId } from './id-normalization.js';\n\nexport function formatTaskId(task: Task): string {\n\treturn `TASK-${task.number}`;\n}\n\n/**\n * Normalize task ID from various formats to API-compatible format:\n * - \"TASK-123\" -> \"TASK-123\" (already normalized)\n * - \"task-123\" -> \"TASK-123\" (uppercase)\n * - \"TASK 123\" -> \"TASK-123\" (add dash, uppercase)\n * - \"task 123\" -> \"TASK-123\" (add dash, uppercase)\n * - \"123\" -> \"TASK-123\" (add prefix)\n * - \"uuid-string\" -> \"uuid-string\" (UUID, return as-is)\n *\n * This function takes user input and returns the ID that should be used in API calls\n */\nexport function normalizeTaskId(input: string): string {\n\treturn normalizeId('TASK', input);\n}\n\nexport function parseTaskId(input: string): { type: 'number' | 'uuid'; value: string | number } {\n\t// Trim whitespace\n\tconst trimmed = input.trim();\n\n\t// Handle \"TASK-123\" or \"task-123\" format (with dash)\n\tconst taskDashMatch = trimmed.match(/^TASK-(\\d+)$/i);\n\tif (taskDashMatch) {\n\t\treturn { type: 'number', value: parseInt(taskDashMatch[1], 10) };\n\t}\n\n\t// Handle \"TASK 123\" or \"task 123\" format (with space)\n\tconst taskSpaceMatch = trimmed.match(/^TASK\\s+(\\d+)$/i);\n\tif (taskSpaceMatch) {\n\t\treturn { type: 'number', value: parseInt(taskSpaceMatch[1], 10) };\n\t}\n\n\t// Handle plain number format\n\tconst numberMatch = trimmed.match(/^\\d+$/);\n\tif (numberMatch) {\n\t\treturn { type: 'number', value: parseInt(trimmed, 10) };\n\t}\n\n\t// Assume it's a UUID\n\treturn { type: 'uuid', value: trimmed };\n}\n\nexport function findTaskById(tasks: Task[], identifier: string): Task | null {\n\tconst parsed = parseTaskId(identifier);\n\n\tif (parsed.type === 'number') {\n\t\treturn tasks.find(task => task.number === parsed.value) || null;\n\t} else {\n\t\treturn tasks.find(task => task.id === parsed.value) || null;\n\t}\n}\n\nexport function getTaskStatusIcon(status: string): string {\n\tswitch (status) {\n\t\tcase 'PLANNED':\n\t\t\treturn '📋';\n\t\tcase 'IN_PROGRESS':\n\t\t\treturn '🔄';\n\t\tcase 'COMPLETED':\n\t\t\treturn '✅';\n\t\tcase 'CANCELLED':\n\t\t\treturn '❌';\n\t\tdefault:\n\t\t\treturn '📋';\n\t}\n}\n","/**\n * Requirement Resource Handlers\n *\n * Handles all requirement-related commands:\n * - list: List all requirements\n * - show: Show requirement details\n * - create: Create a new requirement\n * - update: Update requirement information\n * - delete: Delete a requirement\n */\n\nimport chalk from 'chalk';\nimport { RequirementService } from '../services/requirement-service.js';\nimport { BraingridAuth } from '../services/auth.js';\nimport { getConfig } from '../utils/config.js';\nimport { formatError, getResourceContext } from '../utils/error-formatter.js';\nimport { handleError } from '../utils/error-handler.js';\nimport { workspaceManager } from '../utils/workspace-manager.js';\nimport { normalizeRequirementId } from '../utils/requirements.js';\nimport { showSpinner } from '../utils/spinner.js';\nimport {\n\tformatRequirementOutput,\n\tgetRequirementStatusEmoji,\n\tformatRequirementBuildMarkdown,\n\tformatRequirementBuildJson,\n\tformatRequirementBuildXml,\n\tformatRequirementListMarkdown,\n\tformatRequirementListXml,\n\tformatRequirementBreakdownMarkdown,\n\tformatRequirementBreakdownXml,\n} from '../utils/formatting.js';\nimport type { HandlerResult } from './types.js';\nimport type { RequirementStatus } from '../types/requirement.js';\nimport type { AxiosError } from 'axios';\n\nfunction getServices(): {\n\trequirementService: RequirementService;\n\tauth: BraingridAuth;\n\tconfig: ReturnType<typeof getConfig>;\n} {\n\tconst config = getConfig();\n\tconst auth = new BraingridAuth(config.apiUrl);\n\tconst requirementService = new RequirementService(config.apiUrl, auth);\n\treturn { requirementService, auth, config };\n}\n\nexport async function handleRequirementList(opts: {\n\tproject?: string;\n\tstatus?: string;\n\tformat?: string;\n\tpage?: string;\n\tlimit?: string;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { requirementService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Validate format option\n\t\tconst format = opts.format || 'table';\n\t\tif (!['table', 'json', 'xml', 'markdown'].includes(format)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t`❌ Invalid format: ${format}. Supported formats: table, json, xml, markdown`\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\tstopSpinner = showSpinner('Loading requirements', chalk.gray);\n\t\tconst response = await requirementService.listProjectRequirements(projectId, {\n\t\t\tstatus: opts.status as RequirementStatus | undefined,\n\t\t\tpage: opts.page ? parseInt(opts.page, 10) : 1,\n\t\t\tlimit: opts.limit ? parseInt(opts.limit, 10) : 20,\n\t\t});\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\t// Format output based on requested format\n\t\tlet output: string;\n\t\tswitch (format) {\n\t\t\tcase 'json': {\n\t\t\t\toutput = JSON.stringify(response, null, 2);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'xml': {\n\t\t\t\toutput = formatRequirementListXml(response.requirements, response.pagination);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'markdown': {\n\t\t\t\toutput = formatRequirementListMarkdown(response.requirements, response.pagination);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'table':\n\t\t\tdefault: {\n\t\t\t\t// Table format\n\t\t\t\tif (response.requirements.length === 0) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tmessage: chalk.yellow('No requirements found.'),\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\toutput = chalk.bold('📋 Requirements\\n\\n');\n\t\t\t\toutput +=\n\t\t\t\t\t'Short ID Status Name Branch Progress\\n';\n\t\t\t\toutput += '─'.repeat(90) + '\\n';\n\n\t\t\t\tfor (const req of response.requirements) {\n\t\t\t\t\tconst shortId = (req.short_id || req.id.slice(0, 11)).padEnd(11);\n\t\t\t\t\tconst statusEmoji = getRequirementStatusEmoji(req.status);\n\t\t\t\t\tconst statusText = req.status.padEnd(12);\n\t\t\t\t\tconst name = req.name.substring(0, 23).padEnd(23);\n\t\t\t\t\tconst branch = (req.branch || 'N/A').substring(0, 18).padEnd(18);\n\t\t\t\t\tconst progress = req.task_progress ? `${req.task_progress.progress_percentage}%` : 'N/A';\n\t\t\t\t\toutput += `${shortId} ${statusEmoji} ${statusText} ${name} ${branch} ${progress}\\n`;\n\t\t\t\t}\n\n\t\t\t\toutput += '\\n';\n\t\t\t\toutput += `Page ${response.pagination.page} of ${Math.ceil(response.pagination.total / response.pagination.limit)}`;\n\t\t\t\toutput += ` (${response.pagination.total} total)`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: response,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'listing requirements'),\n\t\t};\n\t}\n}\n\nexport async function handleRequirementShow(opts?: {\n\tid?: string;\n\tproject?: string;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { requirementService, auth, config } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Get requirement ID (explicit or auto-detected from git branch)\n\t\tconst requirementResult = await workspaceManager.getRequirement(opts?.id);\n\t\tif (!requirementResult.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: requirementResult.error,\n\t\t\t};\n\t\t}\n\t\tconst requirementId = requirementResult.requirementId;\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts?.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement ID\n\t\tconst normalizedId = normalizeRequirementId(requirementId);\n\t\tstopSpinner = showSpinner('Loading requirement', chalk.gray);\n\t\tconst requirement = await requirementService.getProjectRequirement(projectId, normalizedId);\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\t// Use centralized formatting function\n\t\tconst output = formatRequirementOutput(requirement, {\n\t\t\tshowDescription: true,\n\t\t\tshowContent: true,\n\t\t\tshowTasks: true,\n\t\t\tshowUpdated: true,\n\t\t\tapiUrl: config.apiUrl,\n\t\t\tprojectShortId: projectId,\n\t\t});\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: '\\n' + output,\n\t\t\tdata: requirement,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('requirement', opts?.id || 'unknown')),\n\t\t};\n\t}\n}\n\nexport async function handleRequirementCreate(opts: {\n\tproject?: string;\n\tname: string;\n\tcontent?: string;\n\tassignedTo?: string;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { requirementService, auth, config } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Validate assigned_to is a UUID if provided\n\t\tif (opts.assignedTo) {\n\t\t\tconst uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\t\t\tconst emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\n\t\t\tif (emailRegex.test(opts.assignedTo)) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t\t'❌ Email addresses are not supported for --assigned-to yet.\\n' +\n\t\t\t\t\t\t\t'Please use the user UUID instead.\\n' +\n\t\t\t\t\t\t\t'Email lookup will be supported when the API provides a user lookup endpoint.'\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (!uuidRegex.test(opts.assignedTo)) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t\t'❌ Invalid UUID format for --assigned-to.\\n' +\n\t\t\t\t\t\t\t'Please provide a valid user UUID (e.g., \"550e8400-e29b-41d4-a716-446655440000\")'\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tstopSpinner = showSpinner('Creating requirement', chalk.gray);\n\t\tconst requirement = await requirementService.createProjectRequirement(projectId, {\n\t\t\tname: opts.name,\n\t\t\tcontent: opts.content || null,\n\t\t\tassigned_to: opts.assignedTo || null,\n\t\t});\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\t// Use centralized formatting function\n\t\tconst message = formatRequirementOutput(requirement, {\n\t\t\tshowContent: !!opts.content,\n\t\t\tshowTasks: true,\n\t\t\tsuccessMessage: `Created requirement ${requirement.short_id}`,\n\t\t\tapiUrl: config.apiUrl,\n\t\t\tprojectShortId: projectId,\n\t\t});\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage,\n\t\t\tdata: requirement,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\t// Use new centralized error handler\n\t\tif (error && typeof error === 'object' && 'response' in error) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: handleError(error as AxiosError, 'creating requirement'),\n\t\t\t};\n\t\t}\n\n\t\t// Fallback for non-Axios errors\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: chalk.red(`❌ Error creating requirement: ${errorMessage}`),\n\t\t};\n\t}\n}\n\nexport async function handleRequirementSpecify(opts: {\n\tproject?: string;\n\tprompt: string;\n\tformat?: string;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { requirementService, auth, config } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Validate format option\n\t\tconst format = opts.format || 'table';\n\t\tif (!['table', 'json', 'xml', 'markdown'].includes(format)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t`❌ Invalid format: ${format}. Supported formats: table, json, xml, markdown`\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Validate prompt length (API requires 10-5000 chars)\n\t\tif (opts.prompt.length < 10) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Prompt must be at least 10 characters long'),\n\t\t\t};\n\t\t}\n\t\tif (opts.prompt.length > 5000) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Prompt must be no more than 5000 characters long'),\n\t\t\t};\n\t\t}\n\n\t\t// Show spinner while processing\n\t\tstopSpinner = showSpinner('Specifying requirement...');\n\n\t\tconst requirement = await requirementService.specifyRequirement(projectId, {\n\t\t\tprompt: opts.prompt,\n\t\t});\n\n\t\t// Stop spinner and format the requirement\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\t// Format output based on requested format\n\t\tlet output: string;\n\t\tswitch (format) {\n\t\t\tcase 'json': {\n\t\t\t\toutput = JSON.stringify(requirement, null, 2);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'xml': {\n\t\t\t\toutput = formatRequirementBuildXml(requirement);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'markdown': {\n\t\t\t\toutput = formatRequirementBuildMarkdown(requirement, {\n\t\t\t\t\tapiUrl: config.apiUrl,\n\t\t\t\t\tprojectShortId: projectId,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'table':\n\t\t\tdefault: {\n\t\t\t\t// Use centralized formatting function\n\t\t\t\toutput = formatRequirementOutput(requirement, {\n\t\t\t\t\tshowContent: true,\n\t\t\t\t\tshowTasks: true,\n\t\t\t\t\tsuccessMessage: `Created and refined requirement ${requirement.short_id}`,\n\t\t\t\t\tapiUrl: config.apiUrl,\n\t\t\t\t\tprojectShortId: projectId,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: requirement,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'specifying requirement'),\n\t\t};\n\t}\n}\n\nexport async function handleRequirementUpdate(opts: {\n\tid?: string;\n\tproject?: string;\n\tstatus?: string;\n\tname?: string;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { requirementService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.status && !opts.name) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Please provide at least one field to update (--status or --name)'),\n\t\t\t};\n\t\t}\n\n\t\t// Get requirement ID (explicit or auto-detected from git branch)\n\t\tconst requirementResult = await workspaceManager.getRequirement(opts.id);\n\t\tif (!requirementResult.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: requirementResult.error,\n\t\t\t};\n\t\t}\n\t\tconst requirementId = requirementResult.requirementId;\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement ID\n\t\tconst normalizedId = normalizeRequirementId(requirementId);\n\t\tstopSpinner = showSpinner('Updating requirement', chalk.gray);\n\t\tconst requirement = await requirementService.updateProjectRequirement(projectId, normalizedId, {\n\t\t\tstatus: opts.status as RequirementStatus | undefined,\n\t\t\tname: opts.name,\n\t\t});\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green(`✅ Updated requirement ${requirement.short_id}: ${requirement.name}`),\n\t\t\tdata: requirement,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('requirement', opts.id || 'unknown')),\n\t\t};\n\t}\n}\n\nexport async function handleRequirementDelete(opts: {\n\tid?: string;\n\tproject?: string;\n\tforce?: boolean;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { requirementService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.force) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.yellow(\n\t\t\t\t\t'⚠️ Deleting a requirement is permanent. Use --force to confirm deletion.'\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Get requirement ID (explicit or auto-detected from git branch)\n\t\tconst requirementResult = await workspaceManager.getRequirement(opts.id);\n\t\tif (!requirementResult.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: requirementResult.error,\n\t\t\t};\n\t\t}\n\t\tconst requirementId = requirementResult.requirementId;\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement ID\n\t\tconst normalizedId = normalizeRequirementId(requirementId);\n\t\tstopSpinner = showSpinner('Deleting requirement', chalk.gray);\n\t\tawait requirementService.deleteProjectRequirement(projectId, normalizedId);\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green(`✅ Deleted requirement ${requirementId}`),\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('requirement', opts.id || 'unknown')),\n\t\t};\n\t}\n}\n\nexport async function handleRequirementBreakdown(opts: {\n\tid?: string;\n\tproject?: string;\n\tformat?: string;\n}): Promise<HandlerResult> {\n\tlet stop: (() => void) | undefined;\n\ttry {\n\t\tconst { requirementService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Validate format option\n\t\tconst format = opts.format || 'table';\n\t\tif (!['table', 'json', 'xml', 'markdown'].includes(format)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red(\n\t\t\t\t\t`❌ Invalid format: ${format}. Supported formats: table, json, xml, markdown`\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Get requirement ID (explicit or auto-detected from git branch)\n\t\tconst requirementResult = await workspaceManager.getRequirement(opts.id);\n\t\tif (!requirementResult.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: requirementResult.error,\n\t\t\t};\n\t\t}\n\t\tconst requirementId = requirementResult.requirementId;\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement ID\n\t\tconst normalizedId = normalizeRequirementId(requirementId);\n\n\t\t// Show spinner while processing\n\t\tstop = showSpinner('Breaking down requirement into tasks...');\n\n\t\tconst response = await requirementService.breakdownRequirement(projectId, normalizedId, {});\n\n\t\t// Stop spinner and format the tasks\n\t\tstop();\n\n\t\t// Format output based on requested format\n\t\tlet output: string;\n\t\tswitch (format) {\n\t\t\tcase 'json': {\n\t\t\t\toutput = JSON.stringify(response, null, 2);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'xml': {\n\t\t\t\toutput = formatRequirementBreakdownXml(response.requirement_short_id, response.tasks);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'markdown': {\n\t\t\t\toutput = formatRequirementBreakdownMarkdown(response.requirement_short_id, response.tasks);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'table':\n\t\t\tdefault: {\n\t\t\t\t// Table view - compact display\n\t\t\t\toutput = chalk.green(\n\t\t\t\t\t`✅ Generated ${response.tasks.length} tasks for ${response.requirement_short_id}\\n\\n`\n\t\t\t\t);\n\t\t\t\toutput += 'Number Status Title\\n';\n\t\t\t\toutput += '─'.repeat(80) + '\\n';\n\n\t\t\t\tfor (const task of response.tasks) {\n\t\t\t\t\tconst statusEmoji = getRequirementStatusEmoji(task.status);\n\t\t\t\t\tconst number = task.number.padEnd(6);\n\t\t\t\t\tconst statusText = task.status.padEnd(12);\n\t\t\t\t\tconst title = task.title.substring(0, 55);\n\t\t\t\t\toutput += `${number} ${statusEmoji} ${statusText} ${title}\\n`;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: response,\n\t\t};\n\t} catch (error: unknown) {\n\t\tstop?.(); // Clear spinner on error if it was started\n\t\t// Use centralized error handler\n\t\tif (error && typeof error === 'object' && 'response' in error) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: handleError(\n\t\t\t\t\terror as AxiosError,\n\t\t\t\t\t`breaking down requirement ${opts.id || 'unknown'}`\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Fallback for non-Axios errors\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: chalk.red(`❌ Error breaking down requirement: ${errorMessage}`),\n\t\t};\n\t}\n}\n\nexport async function handleRequirementBuild(opts: {\n\tid?: string;\n\tproject?: string;\n\tformat?: string;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { requirementService, auth, config } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Validate format option\n\t\tconst format = opts.format || 'markdown';\n\t\tif (!['markdown', 'json', 'xml'].includes(format)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Invalid format. Must be one of: markdown, json, xml'),\n\t\t\t};\n\t\t}\n\n\t\t// Get requirement ID (explicit or auto-detected from git branch)\n\t\tconst requirementResult = await workspaceManager.getRequirement(opts.id);\n\t\tif (!requirementResult.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: requirementResult.error,\n\t\t\t};\n\t\t}\n\t\tconst requirementId = requirementResult.requirementId;\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement ID\n\t\tconst normalizedId = normalizeRequirementId(requirementId);\n\t\tstopSpinner = showSpinner('Building requirement with tasks', chalk.gray);\n\t\tconst requirement = await requirementService.getProjectRequirement(projectId, normalizedId);\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\t// Format output based on selected format\n\t\tlet output: string;\n\t\tswitch (format) {\n\t\t\tcase 'json': {\n\t\t\t\toutput = formatRequirementBuildJson(requirement);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'xml': {\n\t\t\t\toutput = formatRequirementBuildXml(requirement);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'markdown':\n\t\t\tdefault: {\n\t\t\t\toutput = formatRequirementBuildMarkdown(requirement, {\n\t\t\t\t\tapiUrl: config.apiUrl,\n\t\t\t\t\tprojectShortId: projectId,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: requirement,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('requirement', opts.id || 'unknown')),\n\t\t};\n\t}\n}\n","/**\n * Requirement Service\n * Handles all API interactions for requirements\n */\n\nimport { AxiosInstance } from 'axios';\nimport { BraingridAuth } from './auth.js';\nimport { createAuthenticatedAxios } from '../utils/axios-with-auth.js';\nimport {\n\tRequirement,\n\tRequirementDetail,\n\tCreateRequirementRequest,\n\tSpecifyRequirementRequest,\n\tUpdateRequirementRequest,\n\tListRequirementsResponse,\n\tRequirementStatus,\n\tBreakdownRequest,\n\tBreakdownResponse,\n} from '../types/requirement.js';\n\nexport class RequirementService {\n\tprivate baseUrl: string;\n\tprivate auth: BraingridAuth;\n\tprivate axios: AxiosInstance;\n\n\tconstructor(baseUrl: string, auth: BraingridAuth) {\n\t\tthis.baseUrl = baseUrl;\n\t\tthis.auth = auth;\n\t\tthis.axios = createAuthenticatedAxios(auth);\n\t}\n\n\tprivate getHeaders(): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t};\n\t}\n\n\t// Project-scoped requirements\n\tasync listProjectRequirements(\n\t\tprojectId: string,\n\t\tparams?: {\n\t\t\tstatus?: RequirementStatus;\n\t\t\tpage?: number;\n\t\t\tlimit?: number;\n\t\t}\n\t): Promise<ListRequirementsResponse> {\n\t\tconst queryParams = new URLSearchParams();\n\t\tif (params?.status) queryParams.append('status', params.status);\n\t\tif (params?.page) queryParams.append('page', params.page.toString());\n\t\tif (params?.limit) queryParams.append('limit', params.limit.toString());\n\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements?${queryParams.toString()}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<ListRequirementsResponse>(url, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync getProjectRequirement(\n\t\tprojectId: string,\n\t\trequirementId: string\n\t): Promise<RequirementDetail> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<RequirementDetail>(url, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync createProjectRequirement(\n\t\tprojectId: string,\n\t\tdata: CreateRequirementRequest\n\t): Promise<Requirement> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.post<Requirement>(url, data, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync specifyRequirement(\n\t\tprojectId: string,\n\t\tdata: SpecifyRequirementRequest\n\t): Promise<RequirementDetail> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/specify`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.post<RequirementDetail>(url, data, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync updateProjectRequirement(\n\t\tprojectId: string,\n\t\trequirementId: string,\n\t\tdata: UpdateRequirementRequest\n\t): Promise<Requirement> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.patch<Requirement>(url, data, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync deleteProjectRequirement(projectId: string, requirementId: string): Promise<void> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tawait this.axios.delete(url, { headers });\n\t}\n\n\tasync breakdownRequirement(\n\t\tprojectId: string,\n\t\trequirementId: string,\n\t\tdata: BreakdownRequest\n\t): Promise<BreakdownResponse> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}/breakdown`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.post<BreakdownResponse>(url, data, { headers });\n\t\treturn response.data;\n\t}\n}\n","/**\n * Task Resource Handlers\n *\n * Handles all task-related commands:\n * - list: List tasks for a requirement\n * - show: Show task details\n * - create: Create a new task\n * - update: Update task information\n * - delete: Delete a task\n */\n\nimport chalk from 'chalk';\nimport { TaskService } from '../services/task-service.js';\nimport { BraingridAuth } from '../services/auth.js';\nimport { getConfig } from '../utils/config.js';\nimport { formatError, getResourceContext } from '../utils/error-formatter.js';\nimport { formatTaskOutput, formatTasksListOutput } from '../utils/formatting.js';\nimport { workspaceManager } from '../utils/workspace-manager.js';\nimport { normalizeRequirementId } from '../utils/requirements.js';\nimport { normalizeTaskId } from '../utils/tasks.js';\nimport { showSpinner } from '../utils/spinner.js';\nimport type { HandlerResult } from './types.js';\nimport type { TaskStatus } from '../types/task.js';\n\nfunction getServices(): { taskService: TaskService; auth: BraingridAuth } {\n\tconst config = getConfig();\n\tconst auth = new BraingridAuth(config.apiUrl);\n\tconst taskService = new TaskService(config.apiUrl, auth);\n\treturn { taskService, auth };\n}\n\nexport async function handleTaskList(opts: {\n\trequirement?: string;\n\tproject?: string;\n\tformat?: 'table' | 'json' | 'xml' | 'markdown';\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { taskService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.requirement) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.red('❌ No requirement specified.\\n\\n') +\n\t\t\t\t\tchalk.dim('Please provide a requirement ID:\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task list -r REQ-456') +\n\t\t\t\t\tchalk.dim(' (if initialized) or\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task list -r REQ-456 -p PROJ-123'),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement ID\n\t\tconst requirementId = normalizeRequirementId(opts.requirement);\n\n\t\tstopSpinner = showSpinner('Loading tasks', chalk.gray);\n\t\tconst response = await taskService.listTasks(projectId, requirementId);\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\t// Handle empty task list\n\t\tif (response.tasks.length === 0) {\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: chalk.yellow('No tasks found.'),\n\t\t\t\tdata: response,\n\t\t\t};\n\t\t}\n\n\t\t// Use project and requirement short IDs for formatting\n\t\tconst projectShortId = projectId;\n\t\tconst requirementShortId = opts.requirement;\n\n\t\t// Determine format (default to markdown for full content)\n\t\tconst format = opts.format || 'markdown';\n\n\t\t// Use formatTasksListOutput - always show full content\n\t\tconst config = getConfig();\n\t\tconst output = formatTasksListOutput(response.tasks, format, true, {\n\t\t\trequirementId,\n\t\t\tprojectShortId,\n\t\t\trequirementShortId,\n\t\t\tapiUrl: config.apiUrl,\n\t\t});\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: response,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'listing tasks'),\n\t\t};\n\t}\n}\n\nexport async function handleTaskSummary(opts: {\n\trequirement?: string;\n\tproject?: string;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { taskService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.requirement) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.red('❌ No requirement specified.\\n\\n') +\n\t\t\t\t\tchalk.dim('Please provide a requirement ID:\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task summary -r REQ-456') +\n\t\t\t\t\tchalk.dim(' (if initialized) or\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task summary -r REQ-456 -p PROJ-123'),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement ID\n\t\tconst requirementId = normalizeRequirementId(opts.requirement);\n\n\t\tstopSpinner = showSpinner('Loading tasks', chalk.gray);\n\t\tconst response = await taskService.listTasks(projectId, requirementId);\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\t// Handle empty task list\n\t\tif (response.tasks.length === 0) {\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: chalk.yellow('No tasks found.'),\n\t\t\t\tdata: response,\n\t\t\t};\n\t\t}\n\n\t\t// Use project and requirement short IDs for formatting\n\t\tconst projectShortId = projectId;\n\t\tconst requirementShortId = opts.requirement;\n\n\t\t// Always use table format without content (verbose=false)\n\t\tconst config = getConfig();\n\t\tconst output = formatTasksListOutput(response.tasks, 'table', false, {\n\t\t\trequirementId,\n\t\t\tprojectShortId,\n\t\t\trequirementShortId,\n\t\t\tapiUrl: config.apiUrl,\n\t\t});\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: response,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'listing tasks'),\n\t\t};\n\t}\n}\n\nexport async function handleTaskShow(\n\tid: string,\n\topts?: { requirement?: string; project?: string }\n): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { taskService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts?.requirement) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.red('❌ No requirement specified.\\n\\n') +\n\t\t\t\t\tchalk.dim('Please provide a requirement ID:\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task show TASK-789 -r REQ-456') +\n\t\t\t\t\tchalk.dim(' (if initialized) or\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task show TASK-789 -r REQ-456 -p PROJ-123'),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement and task IDs\n\t\tconst requirementId = normalizeRequirementId(opts.requirement);\n\t\tconst taskId = normalizeTaskId(id);\n\n\t\tconst config = getConfig();\n\t\tstopSpinner = showSpinner('Loading task', chalk.gray);\n\t\tconst task = await taskService.getTask(projectId, requirementId, taskId);\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\tconst output = formatTaskOutput(task, {\n\t\t\tshowContent: true,\n\t\t\tapiUrl: config.apiUrl,\n\t\t\tprojectShortId: projectId,\n\t\t\trequirementShortId: opts.requirement,\n\t\t\trequirementId,\n\t\t});\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: task,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('task', id)),\n\t\t};\n\t}\n}\n\nexport async function handleTaskCreate(opts: {\n\trequirement?: string;\n\tproject?: string;\n\ttitle: string;\n\tcontent?: string;\n}): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { taskService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.requirement) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.red('❌ No requirement specified.\\n\\n') +\n\t\t\t\t\tchalk.dim('Please provide a requirement ID:\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task create -r REQ-456 --title \"...\"') +\n\t\t\t\t\tchalk.dim(' (if initialized) or\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task create -r REQ-456 -p PROJ-123 --title \"...\"'),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement ID\n\t\tconst requirementId = normalizeRequirementId(opts.requirement);\n\n\t\t// Use short IDs for display\n\t\tconst projectShortId = projectId;\n\t\tconst requirementShortId = opts.requirement;\n\n\t\tconst config = getConfig();\n\t\tstopSpinner = showSpinner('Creating task', chalk.gray);\n\t\tconst task = await taskService.createTask(projectId, requirementId, {\n\t\t\ttitle: opts.title,\n\t\t\tcontent: opts.content,\n\t\t});\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\tconst output = formatTaskOutput(task, {\n\t\t\tshowContent: !!opts.content,\n\t\t\tsuccessMessage: `Created task ${task.number}`,\n\t\t\tapiUrl: config.apiUrl,\n\t\t\tprojectShortId,\n\t\t\trequirementShortId,\n\t\t\trequirementId,\n\t\t});\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: task,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'creating task'),\n\t\t};\n\t}\n}\n\nexport async function handleTaskUpdate(\n\tid: string,\n\topts: {\n\t\trequirement?: string;\n\t\tproject?: string;\n\t\tstatus?: string;\n\t\ttitle?: string;\n\t}\n): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { taskService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.status && !opts.title) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Please provide at least one field to update (--status or --title)'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.requirement) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.red('❌ No requirement specified.\\n\\n') +\n\t\t\t\t\tchalk.dim('Please provide a requirement ID:\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task update TASK-789 -r REQ-456 --status COMPLETED') +\n\t\t\t\t\tchalk.dim(' (if initialized) or\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task update TASK-789 -r REQ-456 -p PROJ-123 --status COMPLETED'),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement and task IDs\n\t\tconst requirementId = normalizeRequirementId(opts.requirement);\n\t\tconst taskId = normalizeTaskId(id);\n\n\t\tconst config = getConfig();\n\t\tstopSpinner = showSpinner('Updating task', chalk.gray);\n\t\tconst task = await taskService.updateTask(projectId, requirementId, taskId, {\n\t\t\tstatus: opts.status as TaskStatus | undefined,\n\t\t\ttitle: opts.title,\n\t\t});\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\tconst output = formatTaskOutput(task, {\n\t\t\tshowContent: true,\n\t\t\tsuccessMessage: `Updated task ${task.number}`,\n\t\t\tapiUrl: config.apiUrl,\n\t\t\tprojectShortId: projectId,\n\t\t\trequirementShortId: opts.requirement,\n\t\t\trequirementId,\n\t\t});\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: task,\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('task', id)),\n\t\t};\n\t}\n}\n\nexport async function handleTaskDelete(\n\tid: string,\n\topts: { requirement?: string; project?: string; force?: boolean }\n): Promise<HandlerResult> {\n\tlet stopSpinner: (() => void) | null = null;\n\n\ttry {\n\t\tconst { taskService, auth } = getServices();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Not authenticated. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.force) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.yellow('⚠️ Deleting a task is permanent. Use --force to confirm deletion.'),\n\t\t\t};\n\t\t}\n\n\t\tif (!opts.requirement) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.red('❌ No requirement specified.\\n\\n') +\n\t\t\t\t\tchalk.dim('Please provide a requirement ID:\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task delete TASK-789 -r REQ-456 --force') +\n\t\t\t\t\tchalk.dim(' (if initialized) or\\n') +\n\t\t\t\t\tchalk.cyan('braingrid task delete TASK-789 -r REQ-456 -p PROJ-123 --force'),\n\t\t\t};\n\t\t}\n\n\t\t// Get project ID from workspace\n\t\tconst workspace = await workspaceManager.getProject(opts.project);\n\t\tif (!workspace.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: workspace.error,\n\t\t\t};\n\t\t}\n\t\tconst projectId = workspace.projectId;\n\n\t\t// Normalize the requirement and task IDs\n\t\tconst requirementId = normalizeRequirementId(opts.requirement);\n\t\tconst taskId = normalizeTaskId(id);\n\n\t\tstopSpinner = showSpinner('Deleting task', chalk.gray);\n\t\tawait taskService.deleteTask(projectId, requirementId, taskId);\n\t\tstopSpinner();\n\t\tstopSpinner = null;\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green(`✅ Deleted task ${id}`),\n\t\t};\n\t} catch (error: unknown) {\n\t\tif (stopSpinner) {\n\t\t\tstopSpinner();\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, getResourceContext('task', id)),\n\t\t};\n\t}\n}\n","/**\n * Task Service\n * Handles all API interactions for tasks\n */\n\nimport { AxiosInstance } from 'axios';\nimport { BraingridAuth } from './auth.js';\nimport { createAuthenticatedAxios } from '../utils/axios-with-auth.js';\nimport { Task, CreateTaskRequest, UpdateTaskRequest, ListTasksResponse } from '../types/task.js';\n\nexport class TaskService {\n\tprivate baseUrl: string;\n\tprivate auth: BraingridAuth;\n\tprivate axios: AxiosInstance;\n\n\tconstructor(baseUrl: string, auth: BraingridAuth) {\n\t\tthis.baseUrl = baseUrl;\n\t\tthis.auth = auth;\n\t\tthis.axios = createAuthenticatedAxios(auth);\n\t}\n\n\tprivate getHeaders(): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t};\n\t}\n\n\tasync listTasks(\n\t\tprojectId: string,\n\t\trequirementId: string,\n\t\tparams?: {\n\t\t\tpage?: number;\n\t\t\tlimit?: number;\n\t\t}\n\t): Promise<ListTasksResponse> {\n\t\tconst queryParams = new URLSearchParams();\n\t\tif (params?.page) queryParams.append('page', params.page.toString());\n\t\tif (params?.limit) queryParams.append('limit', params.limit.toString());\n\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}/tasks?${queryParams.toString()}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<ListTasksResponse>(url, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync getTask(projectId: string, requirementId: string, taskId: string): Promise<Task> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}/tasks/${taskId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<Task>(url, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync createTask(\n\t\tprojectId: string,\n\t\trequirementId: string,\n\t\tdata: CreateTaskRequest\n\t): Promise<Task> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}/tasks`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.post<Task>(url, data, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync updateTask(\n\t\tprojectId: string,\n\t\trequirementId: string,\n\t\ttaskId: string,\n\t\tdata: UpdateTaskRequest\n\t): Promise<Task> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}/tasks/${taskId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.patch<Task>(url, data, { headers });\n\t\treturn response.data;\n\t}\n\n\tasync deleteTask(projectId: string, requirementId: string, taskId: string): Promise<void> {\n\t\tconst url = `${this.baseUrl}/api/v1/projects/${projectId}/requirements/${requirementId}/tasks/${taskId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tawait this.axios.delete(url, { headers });\n\t}\n}\n","/**\n * Auth Handlers\n *\n * Handles authentication-related commands:\n * - login: Authenticate with BrainGrid\n * - logout: Sign out from BrainGrid\n * - whoami: Show current user information\n */\n\nimport chalk from 'chalk';\nimport { BraingridAuth } from '../services/auth.js';\nimport { getConfig } from '../utils/config.js';\nimport { formatError } from '../utils/error-formatter.js';\nimport { getGitUser } from '../utils/git.js';\nimport { getLogger } from '../utils/logger.js';\nimport type { HandlerResult } from './types.js';\n\nconst logger = getLogger();\n\nfunction getAuth(): BraingridAuth {\n\tconst config = getConfig();\n\treturn new BraingridAuth(config.apiUrl);\n}\n\nexport async function handleLogin(): Promise<HandlerResult> {\n\ttry {\n\t\tconst auth = getAuth();\n\n\t\tconsole.log(chalk.blue('🔐 Starting OAuth2 authentication flow...'));\n\t\tconsole.log(chalk.dim('Your browser will open to complete authentication.\\n'));\n\n\t\t// Capture git user info (best effort - won't fail if git not configured)\n\t\tconst gitUser = await getGitUser();\n\n\t\t// Set up callback to display auth URL if browser fails to open\n\t\tconst session = await auth.login((authUrl: string) => {\n\t\t\tconsole.log(chalk.dim(\"If your browser didn't open automatically, visit:\"));\n\t\t\tconsole.log(chalk.bold.cyan(authUrl));\n\t\t\tconsole.log(chalk.dim('\\nWaiting for authentication...\\n'));\n\t\t}, gitUser);\n\n\t\tif (!session) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Login failed. Please try again.'),\n\t\t\t};\n\t\t}\n\n\t\t// Debug: Log JWT token\n\t\tconst storedSession = await auth.getStoredSession();\n\t\tif (storedSession) {\n\t\t\tlogger.debug('[AUTH_HANDLER] Login successful', { jwt: storedSession.sealed_session });\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green('✅ Successfully logged in to BrainGrid!'),\n\t\t\tdata: session,\n\t\t};\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error),\n\t\t};\n\t}\n}\n\nexport async function handleLogout(): Promise<HandlerResult> {\n\ttry {\n\t\tconst auth = getAuth();\n\n\t\tawait auth.clearSession();\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green('✅ Successfully logged out.'),\n\t\t};\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error),\n\t\t};\n\t}\n}\n\nexport async function handleWhoami(): Promise<HandlerResult> {\n\ttry {\n\t\tconst auth = getAuth();\n\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.yellow('⚠️ Not logged in. Run `braingrid login` to authenticate.'),\n\t\t\t};\n\t\t}\n\n\t\tconst session = await auth.getStoredSession();\n\t\tif (!session) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ No session found.'),\n\t\t\t};\n\t\t}\n\n\t\t// Debug: Log JWT token\n\t\tlogger.debug('[AUTH_HANDLER] whoami - Current session', { jwt: session.sealed_session });\n\n\t\tlet output = chalk.bold('\\n👤 Current User\\n\\n');\n\t\toutput += `${chalk.bold('User ID:')} ${session.user.id}\\n`;\n\t\toutput += `${chalk.bold('Email:')} ${session.user.email}\\n`;\n\t\toutput += `${chalk.bold('Name:')} ${session.user.firstName} ${session.user.lastName}\\n`;\n\t\toutput += `${chalk.bold('Org ID:')} ${session.organization_id}\\n`;\n\t\toutput += `${chalk.bold('Session:')} ${new Date(session.created_at).toLocaleString()}\\n`;\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: session,\n\t\t};\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error),\n\t\t};\n\t}\n}\n","/**\n * Status Handler\n *\n * Handles the status command which displays:\n * - Authentication status\n * - Git repository information\n * - Configuration details\n * - Overall CLI status\n */\n\nimport chalk from 'chalk';\nimport { BraingridAuth } from '../services/auth.js';\nimport { credentialStore } from '../services/credential-store.js';\nimport { getConfig } from '../utils/config.js';\nimport { getGitRepositoryInfo } from '../utils/git.js';\nimport { checkInstalledCliTools } from '../utils/cli-tools.js';\nimport { formatError } from '../utils/error-formatter.js';\nimport { showSpinner } from '../utils/spinner.js';\nimport type { HandlerResult } from './types.js';\n\nfunction getAuth(): BraingridAuth {\n\tconst config = getConfig();\n\treturn new BraingridAuth(config.apiUrl);\n}\n\nexport async function handleStatus(): Promise<HandlerResult> {\n\ttry {\n\t\tconst config = getConfig();\n\t\tconst auth = getAuth();\n\n\t\tconst stop = showSpinner('Checking status', chalk.gray);\n\n\t\t// Check authentication (force server validation to detect expired tokens)\n\t\tconst isAuthenticated = await auth.isAuthenticated(true);\n\n\t\tstop();\n\n\t\t// Build status output\n\t\tlet output = chalk.bold.cyan('\\n🧠 BrainGrid CLI Status\\n\\n');\n\n\t\t// Authentication Section\n\t\toutput += chalk.bold('Authentication\\n');\n\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\n\t\tif (!isAuthenticated) {\n\t\t\toutput += chalk.red('❌ Not authenticated\\n');\n\t\t\toutput += chalk.dim(' Run ') + chalk.cyan('braingrid login') + chalk.dim(' to sign in\\n\\n');\n\n\t\t\t// Git Repository Section\n\t\t\toutput += chalk.bold('Git Repository\\n');\n\t\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\n\t\t\tconst gitInfo = await getGitRepositoryInfo();\n\n\t\t\tif (!gitInfo || !gitInfo.isRepo) {\n\t\t\t\toutput += chalk.yellow('⚠️ Not in a git repository\\n\\n');\n\t\t\t} else {\n\t\t\t\toutput += chalk.green('✅ Repository detected!\\n');\n\n\t\t\t\t// Show repository owner/name\n\t\t\t\tif (gitInfo.owner && gitInfo.name) {\n\t\t\t\t\toutput += `${chalk.bold('Owner:')} ${gitInfo.owner}\\n`;\n\t\t\t\t\toutput += `${chalk.bold('Name:')} ${gitInfo.name}\\n`;\n\t\t\t\t} else if (gitInfo.remoteUrl) {\n\t\t\t\t\toutput += `${chalk.bold('Remote:')} ${gitInfo.remoteUrl}\\n`;\n\t\t\t\t} else {\n\t\t\t\t\toutput += chalk.yellow('⚠️ Local repository (no remote)\\n');\n\t\t\t\t}\n\n\t\t\t\t// Show branch\n\t\t\t\tif (gitInfo.branch) {\n\t\t\t\t\toutput += `${chalk.bold('Branch:')} ${gitInfo.branch}\\n`;\n\t\t\t\t}\n\n\t\t\t\t// Show git user\n\t\t\t\tif (gitInfo.userName || gitInfo.userEmail) {\n\t\t\t\t\tconst userDisplay =\n\t\t\t\t\t\tgitInfo.userName && gitInfo.userEmail\n\t\t\t\t\t\t\t? `${gitInfo.userName} <${gitInfo.userEmail}>`\n\t\t\t\t\t\t\t: gitInfo.userName || gitInfo.userEmail;\n\t\t\t\t\toutput += `${chalk.bold('Git User:')} ${userDisplay}\\n`;\n\t\t\t\t} else {\n\t\t\t\t\toutput +=\n\t\t\t\t\t\t`${chalk.bold('Git User:')} ` +\n\t\t\t\t\t\tchalk.yellow('⚠️ Not configured (run git config --global user.name/email)\\n');\n\t\t\t\t}\n\n\t\t\t\toutput += '\\n';\n\t\t\t}\n\n\t\t\t// Installed Coding Tools Section\n\t\t\toutput += chalk.bold('Installed Coding Tools\\n');\n\t\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\n\t\t\tconst cliToolsUnauthenticated = await checkInstalledCliTools();\n\n\t\t\tconst installedTools = cliToolsUnauthenticated.filter(tool => tool.installed);\n\n\t\t\tif (installedTools.length === 0) {\n\t\t\t\toutput += chalk.yellow('⚠️ No coding tools detected\\n\\n');\n\t\t\t} else {\n\t\t\t\tinstalledTools.forEach(tool => {\n\t\t\t\t\tconst versionInfo = tool.version ? chalk.dim(` (${tool.version})`) : '';\n\t\t\t\t\toutput += `${chalk.green('✅')} ${tool.name}${versionInfo}\\n`;\n\t\t\t\t});\n\t\t\t\toutput += '\\n';\n\t\t\t}\n\n\t\t\t// Configuration Section\n\t\t\toutput += chalk.bold('Configuration\\n');\n\t\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\t\t\toutput += `${chalk.bold('API URL:')} ${config.apiUrl}\\n`;\n\t\t\toutput += `${chalk.bold('OAuth Client:')} ${config.oauthClientId}\\n`;\n\t\t\toutput += `${chalk.bold('Redirect URI:')} http://127.0.0.1:34536/callback\\n`;\n\t\t\toutput += `${chalk.bold('Config Path:')} ${credentialStore.getStoragePath()}\\n\\n`;\n\n\t\t\t// Overall Status\n\t\t\toutput += chalk.bold('Overall Status\\n');\n\t\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\t\t\toutput += chalk.yellow('⚠️ Setup required - please authenticate\\n');\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: output,\n\t\t\t\tdata: { authenticated: false },\n\t\t\t};\n\t\t}\n\n\t\tconst session = await auth.getStoredSession();\n\t\tif (!session) {\n\t\t\toutput += chalk.red('❌ Session not found\\n\\n');\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: output,\n\t\t\t\tdata: { authenticated: false },\n\t\t\t};\n\t\t}\n\n\t\t// Show authentication details\n\t\toutput += chalk.green('✅ Authenticated\\n');\n\t\tconst userName = `${session.user.firstName || ''} ${session.user.lastName || ''}`.trim();\n\t\tif (userName) {\n\t\t\toutput += `${chalk.bold('Name:')} ${userName}\\n`;\n\t\t}\n\t\toutput += `${chalk.bold('Email:')} ${session.user.email}\\n`;\n\t\toutput += `${chalk.bold('User ID:')} ${session.user.id}\\n`;\n\t\toutput += `${chalk.bold('Organization:')} ${session.organization_id}\\n`;\n\n\t\t// Session info\n\t\tconst sessionAge = Math.floor((Date.now() - session.created_at.getTime()) / 1000 / 60);\n\t\toutput += `${chalk.bold('Session Age:')} ${sessionAge} minutes\\n`;\n\t\toutput += `${chalk.bold('API URL:')} ${config.apiUrl}\\n`;\n\t\toutput += `${chalk.bold('Config Path:')} ${credentialStore.getStoragePath()}\\n\\n`;\n\n\t\t// Git Repository Section\n\t\toutput += chalk.bold('Git Repository\\n');\n\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\n\t\tconst gitInfo = await getGitRepositoryInfo();\n\n\t\tif (!gitInfo || !gitInfo.isRepo) {\n\t\t\toutput += chalk.yellow('⚠️ Not in a git repository\\n\\n');\n\t\t} else {\n\t\t\toutput += chalk.green('✅ Repository detected!\\n');\n\n\t\t\t// Show repository owner/name\n\t\t\tif (gitInfo.owner && gitInfo.name) {\n\t\t\t\toutput += `${chalk.bold('Owner:')} ${gitInfo.owner}\\n`;\n\t\t\t\toutput += `${chalk.bold('Name:')} ${gitInfo.name}\\n`;\n\t\t\t} else if (gitInfo.remoteUrl) {\n\t\t\t\toutput += `${chalk.bold('Remote:')} ${gitInfo.remoteUrl}\\n`;\n\t\t\t} else {\n\t\t\t\toutput += chalk.yellow('⚠️ Local repository (no remote)\\n');\n\t\t\t}\n\n\t\t\t// Show branch\n\t\t\tif (gitInfo.branch) {\n\t\t\t\toutput += `${chalk.bold('Branch:')} ${gitInfo.branch}\\n`;\n\t\t\t}\n\n\t\t\t// Show git user\n\t\t\tif (gitInfo.userName || gitInfo.userEmail) {\n\t\t\t\tconst userDisplay =\n\t\t\t\t\tgitInfo.userName && gitInfo.userEmail\n\t\t\t\t\t\t? `${gitInfo.userName} <${gitInfo.userEmail}>`\n\t\t\t\t\t\t: gitInfo.userName || gitInfo.userEmail;\n\t\t\t\toutput += `${chalk.bold('Git User:')} ${userDisplay}\\n`;\n\t\t\t} else {\n\t\t\t\toutput +=\n\t\t\t\t\t`${chalk.bold('Git User:')} ` +\n\t\t\t\t\tchalk.yellow('⚠️ Not configured (run git config --global user.name/email)\\n');\n\t\t\t}\n\n\t\t\toutput += '\\n';\n\t\t}\n\n\t\t// Installed Coding Tools Section\n\t\toutput += chalk.bold('Installed Coding Tools\\n');\n\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\n\t\tconst cliTools = await checkInstalledCliTools();\n\t\tconst installedTools = cliTools.filter(tool => tool.installed);\n\n\t\tif (installedTools.length === 0) {\n\t\t\toutput += chalk.yellow('⚠️ No coding tools detected\\n\\n');\n\t\t} else {\n\t\t\tinstalledTools.forEach(tool => {\n\t\t\t\tconst versionInfo = tool.version ? chalk.dim(` (${tool.version})`) : '';\n\t\t\t\toutput += `${chalk.green('✅')} ${tool.name}${versionInfo}\\n`;\n\t\t\t});\n\t\t\toutput += '\\n';\n\t\t}\n\n\t\t// Configuration Section\n\t\toutput += chalk.bold('Configuration\\n');\n\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\t\toutput += `${chalk.bold('OAuth Client:')} ${config.oauthClientId}\\n`;\n\t\toutput += `${chalk.bold('Redirect URI:')} http://127.0.0.1:34536/callback\\n`;\n\t\toutput += `${chalk.bold('Auth Server:')} ${config.getWorkOSAuthUrl()}\\n\\n`;\n\n\t\t// Overall Status\n\t\toutput += chalk.bold('Overall Status\\n');\n\t\toutput += chalk.dim('─'.repeat(50)) + '\\n';\n\t\toutput += chalk.green('✅ Ready to use BrainGrid CLI\\n');\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: output,\n\t\t\tdata: { authenticated: true, session },\n\t\t};\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error),\n\t\t};\n\t}\n}\n","/**\n * Init Handler\n * Handles the `braingrid init` command for initializing a repository with a BrainGrid project\n */\n\nimport chalk from 'chalk';\nimport { confirm, select, input } from '@inquirer/prompts';\nimport { BraingridAuth } from '../services/auth.js';\nimport { ProjectService } from '../services/project-service.js';\nimport { GitHubService } from '../services/internal/github-service.js';\nimport { getConfig } from '../utils/config.js';\nimport { getGitRepositoryInfo } from '../utils/git.js';\nimport {\n\tisGitInstalled,\n\tinstallGit,\n\tgetManualInstallInstructions,\n} from '../utils/git-installer.js';\nimport { isGhInstalled, installGh } from '../utils/gh-installer.js';\nimport { formatError } from '../utils/error-formatter.js';\nimport { projectConfigExists, saveProjectConfig, loadProjectConfig } from '../utils/local-store.js';\nimport { handleLogin } from './auth.handlers.js';\nimport { RepositoryService } from '../services/internal/repository-service.js';\nimport { checkInstalledCliTools } from '../utils/cli-tools.js';\nimport { handleSetupClaudeCode, handleSetupCursor } from './setup.handlers.js';\nimport { access } from 'fs/promises';\nimport {\n\tfindInstallationForOwner,\n\tcheckRepositoryAccess,\n\tgetRepositoryId,\n} from '../utils/repository-access.js';\nimport { waitWithSpinner } from '../utils/spinner.js';\nimport {\n\tcanUseGhAutomation,\n\tinitGitRepo,\n\tcreateGitHubRepoWithGh,\n\tgetCurrentDirectoryName,\n} from '../utils/github-repo.js';\nimport type { HandlerResult } from './types.js';\nimport type { LocalProjectConfig } from '../types/local-project.js';\nimport type { ListProjectsWithRepositoryResponse } from '../types/project.js';\nimport type { GitRepoInfo } from '../utils/git.js';\nimport type { GitHubInstallation } from '../types/github.js';\n\n/**\n * Detect installed IDEs (Claude Code and Cursor)\n */\nasync function detectInstalledIDEs(): Promise<{ claudeCode: boolean; cursor: boolean }> {\n\tconst tools = await checkInstalledCliTools();\n\n\treturn {\n\t\tclaudeCode: tools.find(t => t.name === 'Claude Code')?.installed || false,\n\t\tcursor: tools.find(t => t.name === 'Cursor')?.installed || false,\n\t};\n}\n\n/**\n * Check if a file exists\n */\nasync function fileExists(filePath: string): Promise<boolean> {\n\ttry {\n\t\tawait access(filePath);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction getServices(): {\n\tprojectService: ProjectService;\n\tgithubService: GitHubService;\n\trepositoryService: RepositoryService;\n\tauth: BraingridAuth;\n} {\n\tconst config = getConfig();\n\tconst auth = new BraingridAuth(config.apiUrl);\n\tconst projectService = new ProjectService(config.apiUrl, auth);\n\tconst githubService = new GitHubService(config.apiUrl, auth);\n\tconst repositoryService = new RepositoryService(config.apiUrl, auth);\n\treturn { projectService, githubService, repositoryService, auth };\n}\n\n/**\n * Prompt user to add a GitHub organization installation\n */\nfunction promptToAddOrganization(owner: string, webUrl: string): HandlerResult {\n\treturn {\n\t\tsuccess: false,\n\t\tmessage:\n\t\t\tchalk.yellow('⚠️ No projects found for this repository.\\n\\n') +\n\t\t\tchalk.dim(`Repository: ${owner}/*\\n\\n`) +\n\t\t\tchalk.dim(`You have GitHub connected, but not for the \"${owner}\" organization.\\n\\n`) +\n\t\t\tchalk.dim('To connect ') +\n\t\t\tchalk.cyan(owner) +\n\t\t\tchalk.dim(':\\n') +\n\t\t\tchalk.dim(' 1. Visit: ') +\n\t\t\tchalk.cyan(`${webUrl}/integrations`) +\n\t\t\tchalk.dim('\\n') +\n\t\t\tchalk.dim(' 2. Click \"Add GitHub Organization\"\\n') +\n\t\t\tchalk.dim(` 3. Select \"${owner}\"\\n`) +\n\t\t\tchalk.dim(' 4. Run ') +\n\t\t\tchalk.cyan('braingrid init') +\n\t\t\tchalk.dim(' again'),\n\t};\n}\n\n/**\n * Prompt user to create a project with repository linking\n */\nasync function promptToCreateProject(\n\tgitInfo: GitRepoInfo,\n\tprojectService: ProjectService,\n\trepositoryService: RepositoryService\n): Promise<HandlerResult> {\n\tconst webUrl = getConfig().getWebAppUrl();\n\n\tif (!gitInfo.owner || !gitInfo.name) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: chalk.red('❌ Repository information is incomplete'),\n\t\t};\n\t}\n\n\t// Get repository ID for linking\n\tconst repositoryId = await getRepositoryId(repositoryService, gitInfo.owner, gitInfo.name);\n\n\tif (!repositoryId) {\n\t\t// This shouldn't happen since we checked access, but handle gracefully\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.yellow('⚠️ Repository accessible but could not retrieve details.\\n\\n') +\n\t\t\t\tchalk.dim(`Repository: ${gitInfo.owner}/${gitInfo.name}\\n\\n`) +\n\t\t\t\tchalk.dim('Please try again or create a project manually at: ') +\n\t\t\t\tchalk.cyan(webUrl),\n\t\t};\n\t}\n\n\t// Prompt user to create project\n\tconsole.log(\n\t\tchalk.yellow('⚠️ Repository accessible but no project exists.\\n\\n') +\n\t\t\tchalk.dim(`Repository: ${gitInfo.owner}/${gitInfo.name}\\n`)\n\t);\n\n\tconst shouldCreate = await confirm({\n\t\tmessage: `Would you like to create a project for ${gitInfo.name} now?`,\n\t\tdefault: true,\n\t});\n\n\tif (!shouldCreate) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.dim('\\nProject creation cancelled.\\n\\n') +\n\t\t\t\tchalk.dim('Create a project at ') +\n\t\t\t\tchalk.cyan(webUrl) +\n\t\t\t\tchalk.dim(' and link it to this repository, or use:\\n') +\n\t\t\t\tchalk.cyan(\n\t\t\t\t\t`braingrid project create --name \"${gitInfo.name}\" --repositories \"${gitInfo.owner}/${gitInfo.name}\"`\n\t\t\t\t),\n\t\t};\n\t}\n\n\t// Create project with repository linked\n\ttry {\n\t\tconst project = await projectService.createProject({\n\t\t\tname: gitInfo.name,\n\t\t\tdescription: `Project for ${gitInfo.owner}/${gitInfo.name}`,\n\t\t\trepository_id: repositoryId,\n\t\t});\n\n\t\tconsole.log(chalk.green(`\\n✅ Created project ${project.short_id}: ${project.name}`));\n\t\tconsole.log(chalk.green(`✅ Linked repository ${gitInfo.owner}/${gitInfo.name}\\n`));\n\n\t\treturn { success: true, message: '', data: project };\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'creating project'),\n\t\t};\n\t}\n}\n\n/**\n * Prompt user to grant repository access and poll until granted\n */\nasync function promptToGrantRepositoryAccess(\n\tgitInfo: GitRepoInfo,\n\twebUrl: string,\n\trepositoryService: RepositoryService,\n\tprojectService: ProjectService\n): Promise<HandlerResult> {\n\tif (!gitInfo.owner || !gitInfo.name) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: chalk.red('❌ Repository information is incomplete'),\n\t\t};\n\t}\n\n\tconst owner = gitInfo.owner;\n\tconst name = gitInfo.name;\n\n\tconsole.log(\n\t\tchalk.yellow('⚠️ Repository found but BrainGrid needs access.\\n\\n') +\n\t\t\tchalk.dim(`Repository: ${owner}/${name}\\n\\n`) +\n\t\t\tchalk.dim('Please grant BrainGrid access to this repository:\\n') +\n\t\t\tchalk.dim(' 1. Visit: ') +\n\t\t\tchalk.cyan(`${webUrl}/integrations`) +\n\t\t\tchalk.dim('\\n') +\n\t\t\tchalk.dim(\n\t\t\t\t` 2. Click on your \"${owner}\" installation \"Add/Remove\" to grant BrainGrid access to your repository\\n`\n\t\t\t) +\n\t\t\tchalk.dim(` 3. Select \"${name}\" and save\\n\\n`)\n\t);\n\n\t// Poll for repository access (3 minutes max)\n\tconst accessGranted = await waitWithSpinner(\n\t\t'Waiting for repository access (up to 3 minutes)',\n\t\tasync () => await checkRepositoryAccess(repositoryService, owner, name),\n\t\t3000,\n\t\t60\n\t);\n\n\tif (!accessGranted) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.yellow('\\n⚠️ Repository access not detected within 3 minutes.\\n\\n') +\n\t\t\t\tchalk.dim('Please grant access at: ') +\n\t\t\t\tchalk.cyan(`${webUrl}/integrations`) +\n\t\t\t\tchalk.dim(' and run ') +\n\t\t\t\tchalk.cyan('braingrid init') +\n\t\t\t\tchalk.dim(' again.'),\n\t\t};\n\t}\n\n\tconsole.log(chalk.green('✅ Repository access granted!\\n'));\n\n\t// Now create project with the repository\n\treturn promptToCreateProject(gitInfo, projectService, repositoryService);\n}\n\n/**\n * Handle the case when no project is found for a repository\n * Checks GitHub installations, validates owner, checks repository access, and prompts for project creation\n */\nasync function handleNoProjectForRepository(\n\towner: string,\n\tname: string,\n\tgitInfo: GitRepoInfo,\n\tgithubService: GitHubService,\n\trepositoryService: RepositoryService,\n\tprojectService: ProjectService,\n\tconfig: ReturnType<typeof getConfig>\n): Promise<HandlerResult> {\n\t// Check if user has any GitHub installations\n\tlet allInstallations: GitHubInstallation[];\n\ttry {\n\t\tconst installationsResponse = await githubService.listInstallations({ limit: 100 });\n\t\tallInstallations = installationsResponse.installations;\n\t} catch {\n\t\t// If we can't check installations, proceed with default message\n\t\tallInstallations = [];\n\t}\n\n\tconst webUrl = config.getWebAppUrl();\n\n\tif (allInstallations.length === 0) {\n\t\t// No GitHub installations - prompt to connect GitHub\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.yellow('⚠️ No projects found for this repository.\\n\\n') +\n\t\t\t\tchalk.dim(`Repository: ${owner}/${name}\\n\\n`) +\n\t\t\t\tchalk.dim(\"It looks like you haven't connected your GitHub account yet.\\n\") +\n\t\t\t\tchalk.dim('Please connect GitHub at: ') +\n\t\t\t\tchalk.cyan(`${webUrl}/integrations`) +\n\t\t\t\tchalk.dim('\\n\\nOnce connected, create a project and link it to this repository.'),\n\t\t};\n\t}\n\n\t// Has installations - check if we have the right owner\n\tconst ownerInstallation = findInstallationForOwner(owner, allInstallations);\n\n\tif (!ownerInstallation) {\n\t\t// User has GitHub connected but not for this owner\n\t\treturn promptToAddOrganization(owner, webUrl);\n\t}\n\n\t// Check if repository is accessible\n\tconst hasRepoAccess = await checkRepositoryAccess(repositoryService, owner, name);\n\n\tif (!hasRepoAccess) {\n\t\t// Installation exists but repo not accessible - need to grant access\n\t\treturn promptToGrantRepositoryAccess(gitInfo, webUrl, repositoryService, projectService);\n\t}\n\n\t// Repo accessible but no project - create one\n\treturn promptToCreateProject(gitInfo, projectService, repositoryService);\n}\n\n/**\n * Show setup instructions for users without automation\n */\nfunction showSetupInstructions(scenario: 'no-git' | 'no-remote'): string {\n\tlet message = '';\n\n\tif (scenario === 'no-git') {\n\t\tmessage += chalk.dim('To initialize BrainGrid locally:\\n\\n');\n\t\tmessage += chalk.dim(' 1. Initialize git:\\n');\n\t\tmessage += chalk.cyan(' git init\\n\\n');\n\t} else {\n\t\tmessage += chalk.dim('To connect to GitHub:\\n\\n');\n\t}\n\n\tmessage += chalk.dim(' 2. Create GitHub repository:\\n');\n\tmessage += chalk.dim(' • Install GitHub CLI: ') + chalk.cyan('https://cli.github.com\\n');\n\tmessage += chalk.dim(' Then: ') + chalk.cyan('gh repo create --private --source=.\\n');\n\tmessage += chalk.dim(' • Or manually: ') + chalk.cyan('https://github.com/new\\n\\n');\n\n\tif (scenario === 'no-git') {\n\t\tmessage += chalk.dim(' 3. Run: ') + chalk.cyan('braingrid init\\n\\n');\n\t} else {\n\t\tmessage += chalk.dim(' 3. Add remote and run init:\\n');\n\t\tmessage += chalk.cyan(' git remote add origin <url>\\n');\n\t\tmessage += chalk.cyan(' braingrid init\\n\\n');\n\t}\n\n\tmessage += chalk.bold('Or use BrainGrid without local initialization:\\n\\n');\n\tmessage += chalk.dim(' All commands support the --project flag:\\n');\n\tmessage += chalk.cyan(' braingrid requirement list --project PROJ-123\\n');\n\tmessage += chalk.cyan(' braingrid task create --project PROJ-123 --title \"Task\"\\n\\n');\n\tmessage +=\n\t\tchalk.dim(' Note: Without local init, you must specify --project for each command.') + '\\n';\n\n\treturn message;\n}\n\n/**\n * Handle initialization when directory is not a git repository\n */\nasync function handleNoGitRepository(): Promise<HandlerResult> {\n\tconst canAutomate = await canUseGhAutomation();\n\n\tif (canAutomate) {\n\t\t// Offer one-click setup\n\t\tconst shouldSetup = await confirm({\n\t\t\tmessage: 'Would you like to initialize git and create a GitHub repository?',\n\t\t\tdefault: true,\n\t\t});\n\n\t\tif (shouldSetup) {\n\t\t\t// Initialize git\n\t\t\tconsole.log();\n\t\t\tconst gitInitSuccess = await initGitRepo();\n\n\t\t\tif (!gitInitSuccess) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.red('❌ Failed to initialize git repository'),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconsole.log(chalk.green('✅ Initialized git repository'));\n\n\t\t\t// Get repository name suggestion\n\t\t\tconst dirName = getCurrentDirectoryName();\n\n\t\t\t// Prompt for visibility\n\t\t\tconst isPrivate = await select({\n\t\t\t\tmessage: 'Repository visibility:',\n\t\t\t\tchoices: [\n\t\t\t\t\t{ value: true, name: 'Private' },\n\t\t\t\t\t{ value: false, name: 'Public' },\n\t\t\t\t],\n\t\t\t\tdefault: true,\n\t\t\t});\n\n\t\t\t// Prompt for repository name\n\t\t\tconst repoName = await input({\n\t\t\t\tmessage: 'Repository name:',\n\t\t\t\tdefault: dirName,\n\t\t\t});\n\n\t\t\t// Create GitHub repository\n\t\t\tconsole.log(chalk.dim('\\nCreating repository...\\n'));\n\t\t\tconst repo = await createGitHubRepoWithGh(repoName, isPrivate);\n\n\t\t\tif (!repo) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.red('❌ Failed to create GitHub repository\\n\\n') +\n\t\t\t\t\t\tshowSetupInstructions('no-git'),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconsole.log(chalk.green(`✅ Created repository: ${repo.url}`));\n\t\t\tconsole.log(chalk.green('✅ Added remote origin\\n'));\n\n\t\t\t// Return success with a special flag to continue init\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: 'continue-init', // Special marker to retry init\n\t\t\t\tdata: { repo },\n\t\t\t};\n\t\t}\n\t}\n\n\t// Fallback to instructions\n\treturn {\n\t\tsuccess: false,\n\t\tmessage:\n\t\t\tchalk.yellow('⚠️ This directory is not a git repository.\\n\\n') +\n\t\t\tshowSetupInstructions('no-git'),\n\t};\n}\n\n/**\n * Handle initialization when git repository has no remote\n */\nasync function handleNoGitRemote(): Promise<HandlerResult> {\n\tconst canAutomate = await canUseGhAutomation();\n\n\tif (canAutomate) {\n\t\t// Offer to create GitHub repo\n\t\tconst shouldCreate = await confirm({\n\t\t\tmessage: 'Would you like to create a GitHub repository now?',\n\t\t\tdefault: true,\n\t\t});\n\n\t\tif (shouldCreate) {\n\t\t\t// Get repository name suggestion\n\t\t\tconst dirName = getCurrentDirectoryName();\n\n\t\t\t// Prompt for visibility\n\t\t\tconst isPrivate = await select({\n\t\t\t\tmessage: 'Repository visibility:',\n\t\t\t\tchoices: [\n\t\t\t\t\t{ value: true, name: 'Private' },\n\t\t\t\t\t{ value: false, name: 'Public' },\n\t\t\t\t],\n\t\t\t\tdefault: true,\n\t\t\t});\n\n\t\t\t// Prompt for repository name\n\t\t\tconst repoName = await input({\n\t\t\t\tmessage: 'Repository name:',\n\t\t\t\tdefault: dirName,\n\t\t\t});\n\n\t\t\t// Create GitHub repository\n\t\t\tconsole.log(chalk.dim('\\nCreating repository...\\n'));\n\t\t\tconst repo = await createGitHubRepoWithGh(repoName, isPrivate);\n\n\t\t\tif (!repo) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.red('❌ Failed to create GitHub repository\\n\\n') +\n\t\t\t\t\t\tshowSetupInstructions('no-remote'),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconsole.log(chalk.green(`✅ Created repository: ${repo.url}`));\n\t\t\tconsole.log(chalk.green('✅ Added remote origin\\n'));\n\n\t\t\t// Return success with a special flag to continue init\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: 'continue-init', // Special marker to retry init\n\t\t\t\tdata: { repo },\n\t\t\t};\n\t\t}\n\t}\n\n\t// Fallback to instructions\n\treturn {\n\t\tsuccess: false,\n\t\tmessage:\n\t\t\tchalk.yellow('⚠️ Git repository detected but no GitHub remote configured.\\n\\n') +\n\t\t\tshowSetupInstructions('no-remote'),\n\t};\n}\n\nexport async function handleInit(opts: {\n\tproject?: string;\n\tforce?: boolean;\n}): Promise<HandlerResult> {\n\ttry {\n\t\tconst config = getConfig();\n\t\tconst { projectService, githubService, repositoryService, auth } = getServices();\n\n\t\t// Check if Git is installed (required for BrainGrid CLI)\n\t\tif (!(await isGitInstalled())) {\n\t\t\tconst shouldInstall = await confirm({\n\t\t\t\tmessage: 'Git is required but not installed. Would you like to install it now?',\n\t\t\t\tdefault: true,\n\t\t\t});\n\n\t\t\tif (!shouldInstall) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.yellow('⚠️ Git installation cancelled.\\n\\n') + getManualInstallInstructions(),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Install Git\n\t\t\tconsole.log(); // Add spacing\n\t\t\tconst installResult = await installGit();\n\n\t\t\tif (!installResult.success) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: installResult.message,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Display success message\n\t\t\tconsole.log(installResult.message);\n\t\t\tconsole.log(); // Add spacing\n\n\t\t\t// Verify Git is now available\n\t\t\tif (!(await isGitInstalled())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.red('❌ Git installation completed but git command not found\\n\\n') +\n\t\t\t\t\t\tchalk.dim('You may need to restart your terminal or add Git to your PATH.\\n') +\n\t\t\t\t\t\tgetManualInstallInstructions(),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Check if GitHub CLI is installed (recommended but optional)\n\t\tif (!(await isGhInstalled())) {\n\t\t\tconsole.log(chalk.blue('\\n💡 GitHub CLI is highly recommended for working with BrainGrid.'));\n\t\t\tconsole.log(\n\t\t\t\tchalk.dim(' It enables seamless GitHub integration and repository management.\\n')\n\t\t\t);\n\n\t\t\tconst shouldInstallGh = await confirm({\n\t\t\t\tmessage: 'Would you like to install GitHub CLI now?',\n\t\t\t\tdefault: true,\n\t\t\t});\n\n\t\t\tif (shouldInstallGh) {\n\t\t\t\tconsole.log(); // Add spacing\n\t\t\t\tconst ghInstallResult = await installGh();\n\n\t\t\t\tif (ghInstallResult.success) {\n\t\t\t\t\tconsole.log(ghInstallResult.message);\n\t\t\t\t\tconsole.log(); // Add spacing\n\t\t\t\t} else {\n\t\t\t\t\t// Show error but don't fail - it's optional\n\t\t\t\t\tconsole.log(ghInstallResult.message);\n\t\t\t\t\tconsole.log(chalk.dim('You can install it manually later.\\n'));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconsole.log(chalk.dim('Skipping GitHub CLI installation.\\n'));\n\t\t\t}\n\t\t}\n\n\t\t// Check if already initialized (unless --force)\n\t\tif ((await projectConfigExists()) && !opts.force) {\n\t\t\ttry {\n\t\t\t\tconst existing = await loadProjectConfig();\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.yellow('⚠️ Already initialized.\\n\\n') +\n\t\t\t\t\t\tchalk.dim(`Project: ${existing.project_name} (${existing.project_short_id})\\n`) +\n\t\t\t\t\t\tchalk.dim(`Repository: ${existing.repository?.full_name || 'N/A'}\\n\\n`) +\n\t\t\t\t\t\tchalk.dim('Use --force to reinitialize'),\n\t\t\t\t};\n\t\t\t} catch {\n\t\t\t\t// If config exists but is invalid, continue with init\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.yellow('⚠️ Invalid project configuration found.\\n') +\n\t\t\t\t\t\tchalk.dim('Use --force to reinitialize'),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Check authentication\n\t\tconst isAuthenticated = await auth.isAuthenticated();\n\t\tif (!isAuthenticated) {\n\t\t\t// Prompt user to log in / sign up\n\t\t\tconst shouldLogin = await confirm({\n\t\t\t\tmessage: 'You need to be authenticated. Would you like to log in / sign up now?',\n\t\t\t\tdefault: true,\n\t\t\t});\n\n\t\t\tif (!shouldLogin) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.yellow('⚠️ Authentication required.\\n') +\n\t\t\t\t\t\tchalk.dim('Run ') +\n\t\t\t\t\t\tchalk.cyan('braingrid login') +\n\t\t\t\t\t\tchalk.dim(\" when you're ready to authenticate.\"),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Call login handler\n\t\t\tconsole.log(); // Add spacing before login output\n\t\t\tconst loginResult = await handleLogin();\n\n\t\t\tif (!loginResult.success) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.red('❌ Login failed.\\n') +\n\t\t\t\t\t\tchalk.dim('Please try running ') +\n\t\t\t\t\t\tchalk.cyan('braingrid login') +\n\t\t\t\t\t\tchalk.dim(' again.'),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Verify authentication succeeded\n\t\t\tif (!(await auth.isAuthenticated())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.red('❌ Login was not completed.\\n') +\n\t\t\t\t\t\tchalk.dim('Please try running ') +\n\t\t\t\t\t\tchalk.cyan('braingrid login') +\n\t\t\t\t\t\tchalk.dim(' again.'),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Login successful, continue with init\n\t\t\tconsole.log(); // Add spacing before continuing with init\n\t\t}\n\n\t\t// Get session to retrieve organization_id\n\t\tconst session = await auth.getStoredSession();\n\t\tif (!session) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ No session found. Please run `braingrid login` first.'),\n\t\t\t};\n\t\t}\n\n\t\t// Get git repository info (always needed for URL, even when using --project)\n\t\tlet gitInfo = await getGitRepositoryInfo();\n\n\t\t// Fetch project from API\n\t\tlet project;\n\n\t\tif (opts.project) {\n\t\t\t// Manual mode: fetch project by ID\n\t\t\ttry {\n\t\t\t\tproject = await projectService.getProject(opts.project);\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tchalk.red(`❌ Project not found: ${opts.project}\\n\\n`) +\n\t\t\t\t\t\tchalk.dim('Make sure the project ID is correct and you have access to it.'),\n\t\t\t\t};\n\t\t\t}\n\t\t} else {\n\t\t\t// Auto-detect mode: fetch project by git repository\n\t\t\tif (!gitInfo || !gitInfo.isRepo) {\n\t\t\t\t// Not a git repository - offer to initialize\n\t\t\t\tconst result = await handleNoGitRepository();\n\t\t\t\tif (result.success && result.message === 'continue-init') {\n\t\t\t\t\t// Repository was created - re-fetch git info and continue\n\t\t\t\t\tgitInfo = await getGitRepositoryInfo();\n\t\t\t\t\tif (!gitInfo || !gitInfo.owner || !gitInfo.name) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\tmessage: chalk.red('❌ Failed to get repository information after setup'),\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!gitInfo || !gitInfo.owner || !gitInfo.name) {\n\t\t\t\t// Git repo but no remote - offer to create GitHub repo\n\t\t\t\tconst result = await handleNoGitRemote();\n\t\t\t\tif (result.success && result.message === 'continue-init') {\n\t\t\t\t\t// Repository was created - re-fetch git info and continue\n\t\t\t\t\tgitInfo = await getGitRepositoryInfo();\n\t\t\t\t\tif (!gitInfo || !gitInfo.owner || !gitInfo.name) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\tmessage: chalk.red('❌ Failed to get repository information after setup'),\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// At this point, gitInfo, owner and name are guaranteed to exist\n\t\t\tif (!gitInfo) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.red('❌ Repository information is missing'),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst owner = gitInfo.owner;\n\t\t\tconst name = gitInfo.name;\n\n\t\t\tif (!owner || !name) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.red('❌ Repository information is incomplete'),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlet response: ListProjectsWithRepositoryResponse;\n\t\t\ttry {\n\t\t\t\tresponse = (await projectService.listProjects({\n\t\t\t\t\trepository_owner: owner,\n\t\t\t\t\trepository_name: name,\n\t\t\t\t})) as ListProjectsWithRepositoryResponse;\n\t\t\t} catch (error: unknown) {\n\t\t\t\t// Check if it's a 404 error\n\t\t\t\tif (error && typeof error === 'object' && 'response' in error) {\n\t\t\t\t\tconst axiosError = error as { response?: { status: number } };\n\t\t\t\t\tif (axiosError.response?.status === 404) {\n\t\t\t\t\t\t// No project found - handle the scenario\n\t\t\t\t\t\treturn await handleNoProjectForRepository(\n\t\t\t\t\t\t\towner,\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\tgitInfo,\n\t\t\t\t\t\t\tgithubService,\n\t\t\t\t\t\t\trepositoryService,\n\t\t\t\t\t\t\tprojectService,\n\t\t\t\t\t\t\tconfig\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tif (response.projects.length === 0) {\n\t\t\t\t// No project found - handle the scenario\n\t\t\t\treturn await handleNoProjectForRepository(\n\t\t\t\t\towner,\n\t\t\t\t\tname,\n\t\t\t\t\tgitInfo,\n\t\t\t\t\tgithubService,\n\t\t\t\t\trepositoryService,\n\t\t\t\t\tprojectService,\n\t\t\t\t\tconfig\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Use the first project (could add selection logic if multiple projects)\n\t\t\tproject = response.projects[0];\n\t\t}\n\n\t\t// Display project information\n\t\tconst projectInfo =\n\t\t\tchalk.bold('\\n📦 BrainGrid Project Found\\n\\n') +\n\t\t\tchalk.dim('Project: ') +\n\t\t\tchalk.cyan(project.name) +\n\t\t\t'\\n' +\n\t\t\tchalk.dim('ID: ') +\n\t\t\tchalk.gray(project.short_id) +\n\t\t\t'\\n' +\n\t\t\t(project.description\n\t\t\t\t? chalk.dim('Description: ') + chalk.gray(project.description) + '\\n'\n\t\t\t\t: '') +\n\t\t\tchalk.dim('Repository: ') +\n\t\t\tchalk.gray(project.repository?.full_name || 'N/A') +\n\t\t\t'\\n\\n';\n\n\t\tconsole.log(projectInfo);\n\n\t\t// Always ask for confirmation (unless --force)\n\t\tif (!opts.force) {\n\t\t\tconst shouldInit = await confirm({\n\t\t\t\tmessage: 'Initialize this repository with the above project?',\n\t\t\t\tdefault: true,\n\t\t\t});\n\n\t\t\tif (!shouldInit) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.yellow('Initialization cancelled.'),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Create local project config\n\t\tconst localConfig: LocalProjectConfig = {\n\t\t\torganization_id: session.organization_id,\n\t\t\tproject_id: project.id,\n\t\t\tproject_short_id: project.short_id,\n\t\t\tproject_name: project.name,\n\t\t\tproject_description: project.description || null,\n\t\t\trepository: project.repository\n\t\t\t\t? {\n\t\t\t\t\t\tid: project.repository.id,\n\t\t\t\t\t\towner: project.repository.full_name.split('/')[0], // Parse owner from API full_name\n\t\t\t\t\t\tname: project.repository.name, // Use API name, not git name\n\t\t\t\t\t\tfull_name: project.repository.full_name,\n\t\t\t\t\t\turl: gitInfo?.remoteUrl || undefined,\n\t\t\t\t\t}\n\t\t\t\t: null,\n\t\t\tcreated_at: project.created_at,\n\t\t};\n\n\t\t// Save to .braingrid/project.json (at git repository root)\n\t\tawait saveProjectConfig(localConfig);\n\n\t\tconsole.log(\n\t\t\tchalk.green('✅ Repository initialized successfully!\\n\\n') +\n\t\t\t\tchalk.dim('Project: ') +\n\t\t\t\tchalk.cyan(project.name) +\n\t\t\t\tchalk.dim(` (${project.short_id})`) +\n\t\t\t\t'\\n' +\n\t\t\t\tchalk.dim('Config: ') +\n\t\t\t\tchalk.gray('.braingrid/project.json') +\n\t\t\t\t'\\n'\n\t\t);\n\n\t\t// Detect IDEs and prompt for setup\n\t\tconst installedIDEs = await detectInstalledIDEs();\n\n\t\tif (installedIDEs.claudeCode) {\n\t\t\tconst claudeSetupExists = await fileExists('.claude/commands/specify.md');\n\t\t\tif (!claudeSetupExists) {\n\t\t\t\tconsole.log(''); // Add spacing\n\t\t\t\tconst setupClaude = await confirm({\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t'Claude Code detected. Install BrainGrid integration? (slash commands, skills, status line)',\n\t\t\t\t\tdefault: true,\n\t\t\t\t});\n\n\t\t\t\tif (setupClaude) {\n\t\t\t\t\tconsole.log(''); // Add spacing\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await handleSetupClaudeCode({ force: false });\n\t\t\t\t\t\tif (result.success) {\n\t\t\t\t\t\t\tconsole.log(result.message);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.log(chalk.yellow('⚠️ Claude Code setup was not completed.'));\n\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\tchalk.dim('You can run ') +\n\t\t\t\t\t\t\t\t\tchalk.cyan('braingrid setup claude-code') +\n\t\t\t\t\t\t\t\t\tchalk.dim(' later.')\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tconsole.log(chalk.yellow('⚠️ Claude Code setup encountered an error.'));\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\tchalk.dim('You can run ') +\n\t\t\t\t\t\t\t\tchalk.cyan('braingrid setup claude-code') +\n\t\t\t\t\t\t\t\tchalk.dim(' later.')\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tconsole.log(''); // Add spacing\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (installedIDEs.cursor) {\n\t\t\tconst cursorSetupExists = await fileExists('.cursor/commands/specify.md');\n\t\t\tif (!cursorSetupExists) {\n\t\t\t\tconsole.log(''); // Add spacing\n\t\t\t\tconst setupCursor = await confirm({\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t'Cursor detected. Install BrainGrid integration? (slash commands, rules, context)',\n\t\t\t\t\tdefault: true,\n\t\t\t\t});\n\n\t\t\t\tif (setupCursor) {\n\t\t\t\t\tconsole.log(''); // Add spacing\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await handleSetupCursor({ force: false });\n\t\t\t\t\t\tif (result.success) {\n\t\t\t\t\t\t\tconsole.log(result.message);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.log(chalk.yellow('⚠️ Cursor setup was not completed.'));\n\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\tchalk.dim('You can run ') +\n\t\t\t\t\t\t\t\t\tchalk.cyan('braingrid setup cursor') +\n\t\t\t\t\t\t\t\t\tchalk.dim(' later.')\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tconsole.log(chalk.yellow('⚠️ Cursor setup encountered an error.'));\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\tchalk.dim('You can run ') +\n\t\t\t\t\t\t\t\tchalk.cyan('braingrid setup cursor') +\n\t\t\t\t\t\t\t\tchalk.dim(' later.')\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tconsole.log(''); // Add spacing\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.dim(\n\t\t\t\t'You can now use project-scoped commands without specifying a project ID.'\n\t\t\t),\n\t\t\tdata: localConfig,\n\t\t};\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error, 'initializing repository'),\n\t\t};\n\t}\n}\n","/**\n * Internal GitHub Service\n *\n * For internal use only - not exposed as CLI commands.\n * Handles API interactions with BrainGrid v1 GitHub endpoints.\n *\n * This service provides methods to:\n * - List GitHub installations for the authenticated organization\n * - Get detailed information about specific installations\n *\n * @internal\n */\n\nimport { AxiosInstance } from 'axios';\nimport { BraingridAuth } from '../auth.js';\nimport { createAuthenticatedAxios } from '../../utils/axios-with-auth.js';\nimport { GitHubInstallationDetail, ListGitHubInstallationsResponse } from '../../types/github.js';\n\n/**\n * Internal service for GitHub API operations\n */\nexport class GitHubService {\n\tprivate baseUrl: string;\n\tprivate auth: BraingridAuth;\n\tprivate axios: AxiosInstance;\n\n\tconstructor(baseUrl: string, auth: BraingridAuth) {\n\t\tthis.baseUrl = baseUrl;\n\t\tthis.auth = auth;\n\t\tthis.axios = createAuthenticatedAxios(auth);\n\t}\n\n\tprivate getHeaders(): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t};\n\t}\n\n\t/**\n\t * List GitHub installations for the authenticated organization\n\t *\n\t * @param params - Optional pagination parameters\n\t * @param params.page - Page number (default: 1, min: 1)\n\t * @param params.limit - Number of installations per page (default: 20, min: 1, max: 100)\n\t * @returns List of GitHub installations with pagination\n\t * @throws {Error} On API errors (401, 404, 422, 500)\n\t *\n\t * @example\n\t * ```typescript\n\t * const result = await githubService.listInstallations({ page: 1, limit: 20 });\n\t * console.log(result.installations);\n\t * console.log(result.pagination);\n\t * ```\n\t */\n\tasync listInstallations(params?: {\n\t\tpage?: number;\n\t\tlimit?: number;\n\t}): Promise<ListGitHubInstallationsResponse> {\n\t\tconst url = `${this.baseUrl}/api/v1/github/installations`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<ListGitHubInstallationsResponse>(url, {\n\t\t\theaders,\n\t\t\tparams,\n\t\t});\n\t\treturn response.data;\n\t}\n\n\t/**\n\t * Get detailed information about a specific GitHub installation\n\t *\n\t * Supports both UUID and short ID formats (e.g., \"GITHUB-1\").\n\t * Returns installation details including all associated repositories.\n\t *\n\t * @param installationId - Installation UUID or short ID (e.g., \"GITHUB-1\")\n\t * @returns Detailed installation information with repositories\n\t * @throws {Error} On API errors (401, 404, 422, 500)\n\t *\n\t * @example\n\t * ```typescript\n\t * // Using short ID\n\t * const installation = await githubService.getInstallation('GITHUB-1');\n\t *\n\t * // Using UUID\n\t * const installation = await githubService.getInstallation('550e8400-e29b-41d4-a716-446655440000');\n\t *\n\t * console.log(installation.repositories);\n\t * ```\n\t */\n\tasync getInstallation(installationId: string): Promise<GitHubInstallationDetail> {\n\t\tconst url = `${this.baseUrl}/api/v1/github/installations/${installationId}`;\n\t\tconst headers = this.getHeaders();\n\n\t\tconst response = await this.axios.get<GitHubInstallationDetail>(url, { headers });\n\t\treturn response.data;\n\t}\n}\n","/**\n * Git Installer Utility\n *\n * Automatically installs Git on the user's system using platform-specific package managers:\n * - macOS: Homebrew (if installed) or Xcode Command Line Tools\n * - Windows: winget\n * - Linux: apt/dnf/pacman (auto-detected)\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport chalk from 'chalk';\nimport { isCliInstalled, getCliVersion } from './cli-tools.js';\nimport {\n\tisHomebrewInstalled,\n\tisWingetAvailable,\n\tdetectLinuxPackageManager,\n} from './package-manager-installer.js';\n\nconst execAsync = promisify(exec);\n\nexport interface GitInstallResult {\n\tsuccess: boolean;\n\tmessage: string;\n\tversion?: string;\n}\n\n/**\n * Check if Git is installed\n */\nexport async function isGitInstalled(): Promise<boolean> {\n\treturn isCliInstalled('git');\n}\n\n/**\n * Get Git version if installed\n */\nexport async function getGitVersion(): Promise<string | null> {\n\treturn getCliVersion('git', '--version', output => {\n\t\tconst match = output.match(/git version ([\\d.]+)/);\n\t\treturn match ? match[1] : null;\n\t});\n}\n\n/**\n * Install Git on macOS via Homebrew (when Homebrew is already installed)\n */\nasync function installViaHomebrew(): Promise<GitInstallResult> {\n\tconsole.log(chalk.blue('📦 Installing Git via Homebrew...'));\n\n\ttry {\n\t\tawait execAsync('brew install git', {\n\t\t\ttimeout: 300000, // 5 minutes\n\t\t});\n\n\t\t// Verify installation\n\t\tconst version = await getGitVersion();\n\t\tif (!version) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Git installation completed but git command not found'),\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green(`✅ Git installed successfully (version ${version})!`),\n\t\t\tversion,\n\t\t};\n\t} catch (error: unknown) {\n\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.red('❌ Failed to install Git via Homebrew\\n\\n') +\n\t\t\t\tchalk.dim('Error: ') +\n\t\t\t\terrorMsg +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('Please install Git manually from: ') +\n\t\t\t\tchalk.cyan('https://git-scm.com/download/mac'),\n\t\t};\n\t}\n}\n\n/**\n * Install Git on macOS via Xcode Command Line Tools\n */\nasync function installViaXcodeSelect(): Promise<GitInstallResult> {\n\tconsole.log(chalk.blue('📦 Installing Git via Xcode Command Line Tools...'));\n\tconsole.log(chalk.dim('A system dialog will appear - click \"Install\" to continue.\\n'));\n\n\ttry {\n\t\tawait execAsync('xcode-select --install', {\n\t\t\ttimeout: 600000, // 10 minutes (user interaction required)\n\t\t});\n\n\t\t// Verify installation\n\t\tconst version = await getGitVersion();\n\t\tif (!version) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Git installation completed but git command not found'),\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green(`✅ Git installed successfully (version ${version})!`),\n\t\t\tversion,\n\t\t};\n\t} catch (error: unknown) {\n\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.red('❌ Failed to install Git via Xcode Command Line Tools\\n\\n') +\n\t\t\t\tchalk.dim('Error: ') +\n\t\t\t\terrorMsg +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('Please install Git manually from: ') +\n\t\t\t\tchalk.cyan('https://git-scm.com/download/mac'),\n\t\t};\n\t}\n}\n\n/**\n * Install Git on macOS using best available method\n * Strategy: Use Homebrew if installed, otherwise use xcode-select\n */\nasync function installGitMacOS(): Promise<GitInstallResult> {\n\t// Check if Homebrew is already installed\n\tconst hasHomebrew = await isHomebrewInstalled();\n\n\tif (hasHomebrew) {\n\t\t// User already has Homebrew - use it (fast and familiar)\n\t\treturn installViaHomebrew();\n\t}\n\n\t// No Homebrew - use Xcode Command Line Tools (no need to install Homebrew)\n\treturn installViaXcodeSelect();\n}\n\n/**\n * Install Git on Windows using winget\n */\nasync function installGitWindows(): Promise<GitInstallResult> {\n\t// Check if winget is available\n\tconst hasWinget = await isWingetAvailable();\n\n\tif (!hasWinget) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.red('❌ winget is not available on this system\\n\\n') +\n\t\t\t\tchalk.dim('winget is included in Windows 10 (version 1809+) and Windows 11.\\n') +\n\t\t\t\tchalk.dim('Please install Git manually from: ') +\n\t\t\t\tchalk.cyan('https://git-scm.com/download/win'),\n\t\t};\n\t}\n\n\tconsole.log(chalk.blue('📦 Installing Git via winget...'));\n\n\ttry {\n\t\tawait execAsync('winget install --id Git.Git -e --source winget --silent', {\n\t\t\ttimeout: 300000, // 5 minutes\n\t\t});\n\n\t\t// Verify installation\n\t\tconst version = await getGitVersion();\n\t\tif (!version) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Git installation completed but git command not found'),\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green(`✅ Git installed successfully (version ${version})!`),\n\t\t\tversion,\n\t\t};\n\t} catch (error: unknown) {\n\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.red('❌ Failed to install Git via winget\\n\\n') +\n\t\t\t\tchalk.dim('Error: ') +\n\t\t\t\terrorMsg +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('Please install Git manually from: ') +\n\t\t\t\tchalk.cyan('https://git-scm.com/download/win'),\n\t\t};\n\t}\n}\n\n/**\n * Install Git on Linux using detected package manager\n */\nasync function installGitLinux(): Promise<GitInstallResult> {\n\tconst packageManager = await detectLinuxPackageManager();\n\n\tif (!packageManager) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.red('❌ Could not detect a supported package manager\\n\\n') +\n\t\t\t\tchalk.dim('Supported package managers: apt, dnf, yum, pacman\\n') +\n\t\t\t\tchalk.dim('Please install Git manually from: ') +\n\t\t\t\tchalk.cyan('https://git-scm.com/download/linux'),\n\t\t};\n\t}\n\n\tconsole.log(chalk.blue(`📦 Installing Git via ${packageManager.name}...`));\n\tconsole.log(chalk.dim('This may prompt for your sudo password.\\n'));\n\n\ttry {\n\t\tlet installCommand: string;\n\n\t\tswitch (packageManager.name) {\n\t\t\tcase 'apt':\n\t\t\t\tinstallCommand = 'sudo apt-get update && sudo apt-get install -y git';\n\t\t\t\tbreak;\n\t\t\tcase 'dnf':\n\t\t\t\tinstallCommand = 'sudo dnf install -y git';\n\t\t\t\tbreak;\n\t\t\tcase 'yum':\n\t\t\t\tinstallCommand = 'sudo yum install -y git';\n\t\t\t\tbreak;\n\t\t\tcase 'pacman':\n\t\t\t\tinstallCommand = 'sudo pacman -S --noconfirm git';\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: chalk.red(`❌ Unsupported package manager: ${packageManager.name}`),\n\t\t\t\t};\n\t\t}\n\n\t\tawait execAsync(installCommand, {\n\t\t\ttimeout: 300000, // 5 minutes\n\t\t});\n\n\t\t// Verify installation\n\t\tconst version = await getGitVersion();\n\t\tif (!version) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage: chalk.red('❌ Git installation completed but git command not found'),\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green(`✅ Git installed successfully (version ${version})!`),\n\t\t\tversion,\n\t\t};\n\t} catch (error: unknown) {\n\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.red('❌ Failed to install Git\\n\\n') +\n\t\t\t\tchalk.dim('Error: ') +\n\t\t\t\terrorMsg +\n\t\t\t\t'\\n\\n' +\n\t\t\t\tchalk.dim('Please install Git manually from: ') +\n\t\t\t\tchalk.cyan('https://git-scm.com/download/linux'),\n\t\t};\n\t}\n}\n\n/**\n * Install Git on the current platform\n * Auto-detects platform and uses appropriate package manager\n */\nexport async function installGit(): Promise<GitInstallResult> {\n\tconst platform = process.platform;\n\n\tswitch (platform) {\n\t\tcase 'darwin':\n\t\t\treturn installGitMacOS();\n\n\t\tcase 'win32':\n\t\t\treturn installGitWindows();\n\n\t\tcase 'linux':\n\t\t\treturn installGitLinux();\n\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.red(`❌ Unsupported platform: ${platform}\\n\\n`) +\n\t\t\t\t\tchalk.dim('Please install Git manually from: ') +\n\t\t\t\t\tchalk.cyan('https://git-scm.com/downloads'),\n\t\t\t};\n\t}\n}\n\n/**\n * Get manual installation instructions for the current platform\n */\nexport function getManualInstallInstructions(): string {\n\tconst platform = process.platform;\n\n\tswitch (platform) {\n\t\tcase 'darwin':\n\t\t\treturn (\n\t\t\t\tchalk.yellow('📖 Manual Git Installation (macOS)\\n\\n') +\n\t\t\t\tchalk.dim('Option 1 - Xcode Command Line Tools (recommended):\\n') +\n\t\t\t\tchalk.cyan(' xcode-select --install\\n\\n') +\n\t\t\t\tchalk.dim('Option 2 - Homebrew (if you use package managers):\\n') +\n\t\t\t\tchalk.cyan(\n\t\t\t\t\t' /bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\\n'\n\t\t\t\t) +\n\t\t\t\tchalk.cyan(' brew install git\\n\\n') +\n\t\t\t\tchalk.dim('Option 3 - Official installer:\\n') +\n\t\t\t\tchalk.cyan(' Download from: https://git-scm.com/download/mac')\n\t\t\t);\n\n\t\tcase 'win32':\n\t\t\treturn (\n\t\t\t\tchalk.yellow('📖 Manual Git Installation (Windows)\\n\\n') +\n\t\t\t\tchalk.dim('Option 1 - winget (Windows 10+):\\n') +\n\t\t\t\tchalk.cyan(' winget install --id Git.Git -e --source winget\\n\\n') +\n\t\t\t\tchalk.dim('Option 2 - Official installer:\\n') +\n\t\t\t\tchalk.cyan(' Download from: https://git-scm.com/download/win')\n\t\t\t);\n\n\t\tcase 'linux':\n\t\t\treturn (\n\t\t\t\tchalk.yellow('📖 Manual Git Installation (Linux)\\n\\n') +\n\t\t\t\tchalk.dim('Debian/Ubuntu:\\n') +\n\t\t\t\tchalk.cyan(' sudo apt-get update && sudo apt-get install -y git\\n\\n') +\n\t\t\t\tchalk.dim('Fedora/RHEL:\\n') +\n\t\t\t\tchalk.cyan(' sudo dnf install -y git\\n\\n') +\n\t\t\t\tchalk.dim('Arch Linux:\\n') +\n\t\t\t\tchalk.cyan(' sudo pacman -S git\\n\\n') +\n\t\t\t\tchalk.dim('Or download from: ') +\n\t\t\t\tchalk.cyan('https://git-scm.com/download/linux')\n\t\t\t);\n\n\t\tdefault:\n\t\t\treturn (\n\t\t\t\tchalk.yellow('📖 Manual Git Installation\\n\\n') +\n\t\t\t\tchalk.dim('Download from: ') +\n\t\t\t\tchalk.cyan('https://git-scm.com/downloads')\n\t\t\t);\n\t}\n}\n","/**\n * Setup Resource Handlers\n *\n * Handles setup commands for IDE integrations:\n * - setup claude-code: Install Claude Code integration files\n * - setup cursor: Install Cursor integration files\n */\n\nimport chalk from 'chalk';\nimport { select } from '@inquirer/prompts';\nimport * as path from 'path';\nimport * as fs from 'fs/promises';\nimport { execAsync } from '../utils/command-execution.js';\nimport {\n\tfetchFileFromGitHub,\n\tlistGitHubDirectory,\n\tcopyFileFromGitHub,\n\tinjectContentIntoFile,\n\tinstallStatusLineScript,\n\tupdateClaudeSettings,\n} from '../services/setup-service.js';\nimport type { HandlerResult } from './types.js';\n\nexport interface SetupOptions {\n\tforce?: boolean;\n\tdryRun?: boolean;\n}\n\ninterface FileOperation {\n\ttype: 'copy' | 'inject';\n\tsourcePath: string;\n\ttargetPath: string;\n\texists: boolean;\n}\n\ninterface SetupIntegrationConfig {\n\tname: string;\n\tsourceDirs: string[];\n\ttargetDirs: string[];\n\tinjection: {\n\t\tsourceFile: string;\n\t\ttargetFile: string;\n\t};\n\tdocsUrl: string;\n}\n\n/**\n * Check if a file exists at the given path\n */\nasync function fileExists(filePath: string): Promise<boolean> {\n\ttry {\n\t\tawait fs.access(filePath);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Check if GitHub CLI is installed and user is authenticated\n */\nasync function checkPrerequisites(): Promise<HandlerResult | null> {\n\t// Check if GitHub CLI is installed\n\ttry {\n\t\tawait execAsync('gh --version');\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.red('❌ GitHub CLI is not installed.\\n\\n') +\n\t\t\t\tchalk.dim('Install instructions:\\n') +\n\t\t\t\tchalk.dim(' macOS: ') +\n\t\t\t\tchalk.cyan('brew install gh') +\n\t\t\t\tchalk.dim('\\n') +\n\t\t\t\tchalk.dim(' Windows: ') +\n\t\t\t\tchalk.cyan('winget install GitHub.CLI') +\n\t\t\t\tchalk.dim('\\n') +\n\t\t\t\tchalk.dim(' Linux: See ') +\n\t\t\t\tchalk.cyan('https://cli.github.com/manual/installation') +\n\t\t\t\tchalk.dim('\\n\\n') +\n\t\t\t\tchalk.dim('After installing, run: ') +\n\t\t\t\tchalk.cyan('gh auth login'),\n\t\t};\n\t}\n\n\t// Check if user is authenticated\n\ttry {\n\t\tawait execAsync('gh auth status');\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage:\n\t\t\t\tchalk.red('❌ Not authenticated with GitHub CLI.\\n\\n') +\n\t\t\t\tchalk.dim('Please run: ') +\n\t\t\t\tchalk.cyan('gh auth login'),\n\t\t};\n\t}\n\n\treturn null;\n}\n\n/**\n * Get list of files to be installed\n */\nasync function getFileList(sourcePaths: string[], targetPaths: string[]): Promise<FileOperation[]> {\n\tconst operations: FileOperation[] = [];\n\n\tfor (let i = 0; i < sourcePaths.length; i++) {\n\t\tconst sourcePath = sourcePaths[i];\n\t\tconst targetPath = targetPaths[i];\n\n\t\ttry {\n\t\t\tconst items = await listGitHubDirectory(sourcePath);\n\n\t\t\t// Add file operations for each item\n\t\t\tfor (const item of items) {\n\t\t\t\tif (item.type === 'file') {\n\t\t\t\t\tconst itemTargetPath = path.join(targetPath, item.name);\n\t\t\t\t\tconst exists = await fileExists(itemTargetPath);\n\n\t\t\t\t\toperations.push({\n\t\t\t\t\t\ttype: 'copy',\n\t\t\t\t\t\tsourcePath: item.path,\n\t\t\t\t\t\ttargetPath: itemTargetPath,\n\t\t\t\t\t\texists,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// If directory doesn't exist in repo, skip it\n\t\t\tconsole.warn(\n\t\t\t\tchalk.yellow(`⚠️ Could not list directory: ${sourcePath}`),\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t);\n\t\t}\n\t}\n\n\treturn operations;\n}\n\n/**\n * Display installation plan\n */\nfunction displayInstallationPlan(operations: FileOperation[], injectionFile: string): void {\n\tconsole.log(chalk.bold('\\n📋 Installation Plan:\\n'));\n\n\t// Show injection\n\tconsole.log(chalk.cyan(' Content Injection:'));\n\tconsole.log(chalk.dim(` ${injectionFile}`));\n\n\t// Show file copies\n\tconst newFiles = operations.filter(op => !op.exists);\n\tconst existingFiles = operations.filter(op => op.exists);\n\n\tif (newFiles.length > 0) {\n\t\tconsole.log(chalk.cyan('\\n New Files:'));\n\t\tfor (const op of newFiles) {\n\t\t\tconsole.log(chalk.dim(` ${op.targetPath}`));\n\t\t}\n\t}\n\n\tif (existingFiles.length > 0) {\n\t\tconsole.log(chalk.yellow('\\n Existing Files (will prompt):'));\n\t\tfor (const op of existingFiles) {\n\t\t\tconsole.log(chalk.dim(` ${op.targetPath}`));\n\t\t}\n\t}\n\n\tconsole.log('');\n}\n\n/**\n * Prompt user for file conflict resolution\n */\nasync function promptForConflict(filePath: string): Promise<'overwrite' | 'skip' | 'all' | 'quit'> {\n\tconst answer = await select({\n\t\tmessage: chalk.yellow(`File exists: ${filePath}`),\n\t\tchoices: [\n\t\t\t{ name: '[O]verwrite - Replace this file', value: 'overwrite' },\n\t\t\t{ name: '[S]kip - Keep existing file', value: 'skip' },\n\t\t\t{ name: '[A]ll - Overwrite all remaining', value: 'all' },\n\t\t\t{ name: '[Q]uit - Cancel installation', value: 'quit' },\n\t\t],\n\t});\n\n\treturn answer as 'overwrite' | 'skip' | 'all' | 'quit';\n}\n\n/**\n * Execute file installation\n */\nasync function installFiles(\n\toperations: FileOperation[],\n\tforce: boolean\n): Promise<{ installed: number; skipped: number; cancelled: boolean }> {\n\tlet installed = 0;\n\tlet skipped = 0;\n\tlet overwriteAll = force;\n\n\tfor (const operation of operations) {\n\t\t// Handle file conflicts\n\t\tif (operation.exists && !overwriteAll) {\n\t\t\tconst response = await promptForConflict(operation.targetPath);\n\n\t\t\tif (response === 'quit') {\n\t\t\t\treturn { installed, skipped, cancelled: true };\n\t\t\t} else if (response === 'skip') {\n\t\t\t\tskipped++;\n\t\t\t\tcontinue;\n\t\t\t} else if (response === 'all') {\n\t\t\t\toverwriteAll = true;\n\t\t\t}\n\t\t}\n\n\t\t// Copy file\n\t\ttry {\n\t\t\tawait copyFileFromGitHub(operation.sourcePath, operation.targetPath);\n\t\t\tinstalled++;\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\tchalk.red(`Failed to copy ${operation.targetPath}:`),\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t);\n\t\t\tskipped++;\n\t\t}\n\t}\n\n\treturn { installed, skipped, cancelled: false };\n}\n\n/**\n * Generic setup handler for IDE integrations\n * @private\n */\nasync function _handleSetup(\n\tconfig: SetupIntegrationConfig,\n\topts: SetupOptions\n): Promise<HandlerResult> {\n\ttry {\n\t\t// Check prerequisites\n\t\tconst prerequisiteError = await checkPrerequisites();\n\t\tif (prerequisiteError) {\n\t\t\treturn prerequisiteError;\n\t\t}\n\n\t\tconsole.log(chalk.bold(`🚀 Setting up ${config.name} integration...\\n`));\n\n\t\t// Get file list\n\t\tconst operations = await getFileList(config.sourceDirs, config.targetDirs);\n\n\t\t// Add injection operation\n\t\tconst injectionFileExists = await fileExists(config.injection.targetFile);\n\n\t\toperations.push({\n\t\t\ttype: 'inject',\n\t\t\tsourcePath: config.injection.sourceFile,\n\t\t\ttargetPath: config.injection.targetFile,\n\t\t\texists: injectionFileExists,\n\t\t});\n\n\t\t// Display installation plan\n\t\tdisplayInstallationPlan(\n\t\t\toperations.filter(op => op.type === 'copy'),\n\t\t\tconfig.injection.targetFile\n\t\t);\n\n\t\t// Dry-run mode\n\t\tif (opts.dryRun) {\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.green('✅ Dry-run complete. No files were modified.\\n\\n') +\n\t\t\t\t\tchalk.dim(`Would install ${operations.length} files.`),\n\t\t\t};\n\t\t}\n\n\t\t// Install files\n\t\tconst copyOps = operations.filter(op => op.type === 'copy');\n\t\tconst result = await installFiles(copyOps, opts.force || false);\n\n\t\tif (result.cancelled) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tmessage:\n\t\t\t\t\tchalk.yellow('⚠️ Installation cancelled.\\n\\n') +\n\t\t\t\t\tchalk.dim(`Installed: ${result.installed}, Skipped: ${result.skipped}`),\n\t\t\t\tcode: 'CANCELLED',\n\t\t\t};\n\t\t}\n\n\t\t// Inject content into target file\n\t\ttry {\n\t\t\tconst content = await fetchFileFromGitHub(config.injection.sourceFile);\n\t\t\tawait injectContentIntoFile(config.injection.targetFile, content);\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\tchalk.red(`Failed to inject content into ${config.injection.targetFile}:`),\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t);\n\t\t}\n\n\t\t// Install status line script (Claude Code only)\n\t\tlet statusLineInstalled = false;\n\t\tif (config.name === 'Claude Code') {\n\t\t\ttry {\n\t\t\t\t// Fetch status line script from GitHub (like other files)\n\t\t\t\tconst scriptContent = await fetchFileFromGitHub('claude-code/statusline.sh');\n\t\t\t\tawait installStatusLineScript(scriptContent);\n\t\t\t\tawait updateClaudeSettings();\n\t\t\t\tstatusLineInstalled = true;\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\tchalk.yellow('⚠️ Failed to install status line script:'),\n\t\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Success message\n\t\tconst statusLineMessage = statusLineInstalled\n\t\t\t? chalk.dim(' Status line: .claude/statusline.sh\\n')\n\t\t\t: '';\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage:\n\t\t\t\tchalk.green(`✅ ${config.name} integration installed successfully!\\n\\n`) +\n\t\t\t\tchalk.dim('Files installed:\\n') +\n\t\t\t\tchalk.dim(` Commands: ${result.installed} files\\n`) +\n\t\t\t\tstatusLineMessage +\n\t\t\t\tchalk.dim(` Content injected into: ${config.injection.targetFile}\\n\\n`) +\n\t\t\t\tchalk.dim('Next steps:\\n') +\n\t\t\t\tchalk.dim(' 1. Review the integration files\\n') +\n\t\t\t\tchalk.dim(` 2. Open ${config.name}\\n`) +\n\t\t\t\tchalk.dim(' 3. Try the /specify or /breakdown commands\\n') +\n\t\t\t\tchalk.dim(' 4. Learn more: ') +\n\t\t\t\tchalk.cyan(config.docsUrl),\n\t\t};\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: chalk.red(`❌ Setup failed: ${errorMessage}`),\n\t\t};\n\t}\n}\n\n/**\n * Handle Claude Code setup\n */\nexport async function handleSetupClaudeCode(opts: SetupOptions): Promise<HandlerResult> {\n\tconst config: SetupIntegrationConfig = {\n\t\tname: 'Claude Code',\n\t\tsourceDirs: ['claude-code/commands', 'claude-code/skills'],\n\t\ttargetDirs: ['.claude/commands', '.claude/skills/braingrid-cli'],\n\t\tinjection: {\n\t\t\tsourceFile: 'claude-code/CLAUDE.md',\n\t\t\ttargetFile: 'CLAUDE.md',\n\t\t},\n\t\tdocsUrl: 'https://braingrid.ai/docs/claude-code',\n\t};\n\n\treturn _handleSetup(config, opts);\n}\n\n/**\n * Handle Cursor setup\n */\nexport async function handleSetupCursor(opts: SetupOptions): Promise<HandlerResult> {\n\tconst config: SetupIntegrationConfig = {\n\t\tname: 'Cursor',\n\t\tsourceDirs: ['cursor/commands', 'cursor/rules'],\n\t\ttargetDirs: ['.cursor/commands', '.cursor/rules'],\n\t\tinjection: {\n\t\t\tsourceFile: 'cursor/AGENTS.md',\n\t\t\ttargetFile: 'AGENTS.md',\n\t\t},\n\t\tdocsUrl: 'https://braingrid.ai/docs/cursor',\n\t};\n\n\treturn _handleSetup(config, opts);\n}\n","import { exec, spawn } from 'child_process';\nimport { promisify } from 'util';\n\nexport interface ExecResult {\n\tstdout: string;\n\tstderr: string;\n}\n\nexport interface ExecOptions {\n\tmaxBuffer?: number;\n\ttimeout?: number;\n\tcwd?: string;\n\tenv?: NodeJS.ProcessEnv;\n}\n\nconst execAsyncReal = promisify(exec);\n\n/**\n * Execute a command asynchronously with proper buffer limits and timeout handling\n */\nexport async function execAsync(\n\tcommand: string,\n\toptions?: ExecOptions,\n\tisTestMode: boolean = false,\n\tmockExecHandler?: (command: string) => Promise<ExecResult>\n): Promise<ExecResult> {\n\tif (isTestMode && mockExecHandler) {\n\t\treturn mockExecHandler(command);\n\t}\n\n\t// Set appropriate buffer limits based on command type\n\tconst defaultOptions: ExecOptions = {\n\t\tmaxBuffer: 1024 * 1024 * 10, // 10MB default\n\t\ttimeout: 300000, // 5 minutes\n\t\t...options,\n\t};\n\n\t// Increase buffer for Claude commands that may produce large outputs\n\tif (command.includes('claude')) {\n\t\tdefaultOptions.maxBuffer = 1024 * 1024 * 50; // 50MB for Claude commands\n\t\tdefaultOptions.timeout = 600000; // 10 minutes for Claude\n\t}\n\n\treturn execAsyncReal(command, defaultOptions);\n}\n\n/**\n * Execute a command with streaming output support\n */\nexport async function execStreamAsync(\n\tcommand: string,\n\tonOutput?: (chunk: string) => void,\n\tisTestMode: boolean = false,\n\tmockExecHandler?: (command: string) => Promise<ExecResult>,\n\toptions?: {\n\t\ttimeout?: number;\n\t\tinactivityTimeout?: number;\n\t}\n): Promise<ExecResult> {\n\tif (isTestMode && mockExecHandler) {\n\t\t// For test mode, simulate streaming\n\t\tconst result = await mockExecHandler(command);\n\t\tif (onOutput) {\n\t\t\t// Simulate streaming by sending output in chunks\n\t\t\tconst lines = result.stdout.split('\\n');\n\t\t\tfor (const line of lines) {\n\t\t\t\tif (line.trim()) {\n\t\t\t\t\tonOutput(line + '\\n');\n\t\t\t\t\tawait new Promise(resolve => setTimeout(resolve, 200));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\treturn new Promise((resolve, reject) => {\n\t\t// Parse command to handle quotes properly\n\t\tlet cmd: string;\n\t\tlet args: string[];\n\n\t\tif (command.startsWith('claude -p --dangerously-skip-permissions \"')) {\n\t\t\tcmd = 'claude';\n\t\t\t// Extract the quoted content for non-interactive mode with skip permissions\n\t\t\tconst promptMatch = command.match(/^claude -p --dangerously-skip-permissions \"(.*)\"/s);\n\t\t\targs = promptMatch ? ['-p', '--dangerously-skip-permissions', promptMatch[1]] : [];\n\t\t} else if (command.startsWith('claude -p \"')) {\n\t\t\tcmd = 'claude';\n\t\t\t// Extract the quoted content for non-interactive mode\n\t\t\tconst promptMatch = command.match(/^claude -p \"(.*)\"/s);\n\t\t\targs = promptMatch ? ['-p', promptMatch[1]] : [];\n\t\t} else if (command.startsWith('claude \"')) {\n\t\t\tcmd = 'claude';\n\t\t\t// Extract the quoted content for interactive mode\n\t\t\tconst promptMatch = command.match(/^claude \"(.*)\"/s);\n\t\t\targs = promptMatch ? [promptMatch[1]] : [];\n\t\t} else if (command.startsWith('git commit')) {\n\t\t\t// Special handling for git commit to properly parse the message\n\t\t\tconst parts = command.match(/^git\\s+commit\\s+(.*)$/);\n\t\t\tif (parts && parts[1]) {\n\t\t\t\tcmd = 'git';\n\t\t\t\targs = ['commit'];\n\t\t\t\t// Parse the rest of the arguments, handling -m \"message\" properly\n\t\t\t\tconst argString = parts[1];\n\t\t\t\tconst messageMatch = argString.match(/-m\\s+\"([^\"]+)\"/);\n\t\t\t\tif (messageMatch) {\n\t\t\t\t\targs.push('-m', messageMatch[1]);\n\t\t\t\t\t// Add any other arguments that might be before or after -m\n\t\t\t\t\tconst beforeMessage = argString.substring(0, argString.indexOf('-m')).trim();\n\t\t\t\t\tconst afterMessage = argString\n\t\t\t\t\t\t.substring(argString.indexOf(messageMatch[0]) + messageMatch[0].length)\n\t\t\t\t\t\t.trim();\n\t\t\t\t\tif (beforeMessage) args.unshift(...beforeMessage.split(' '));\n\t\t\t\t\tif (afterMessage) args.push(...afterMessage.split(' '));\n\t\t\t\t} else {\n\t\t\t\t\targs.push(...argString.split(' '));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t[cmd, ...args] = command.split(' ');\n\t\t\t}\n\t\t} else {\n\t\t\t// Simple command splitting for other commands\n\t\t\t[cmd, ...args] = command.split(' ');\n\t\t}\n\n\t\tconst child = spawn(cmd, args, {\n\t\t\tshell: false,\n\t\t\tstdio: ['inherit', 'pipe', 'pipe'],\n\t\t});\n\n\t\tlet stdout = '';\n\t\tlet stderr = '';\n\n\t\t// Smart timeout handling\n\t\tconst isGitCommit = cmd === 'git' && args[0] === 'commit';\n\t\tconst maxTimeout = options?.timeout || (isGitCommit ? 900000 : 300000); // 15 min for git commit, 5 min default\n\t\tconst inactivityTimeout = options?.inactivityTimeout || (isGitCommit ? 60000 : 30000); // 60s for git commit, 30s default\n\n\t\tlet globalTimeoutId: NodeJS.Timeout | null = null;\n\t\tlet inactivityTimeoutId: NodeJS.Timeout | null = null;\n\n\t\tconst clearTimeouts = () => {\n\t\t\tif (globalTimeoutId) clearTimeout(globalTimeoutId);\n\t\t\tif (inactivityTimeoutId) clearTimeout(inactivityTimeoutId);\n\t\t};\n\n\t\tconst resetInactivityTimeout = () => {\n\t\t\tif (inactivityTimeoutId) clearTimeout(inactivityTimeoutId);\n\n\t\t\tinactivityTimeoutId = setTimeout(() => {\n\t\t\t\tclearTimeouts();\n\t\t\t\tchild.kill('SIGTERM');\n\t\t\t\treject(new Error(`Command timed out due to ${inactivityTimeout / 1000}s of inactivity`));\n\t\t\t}, inactivityTimeout);\n\t\t};\n\n\t\t// Set global timeout\n\t\tglobalTimeoutId = setTimeout(() => {\n\t\t\tclearTimeouts();\n\t\t\tchild.kill('SIGTERM');\n\t\t\treject(new Error(`Command exceeded maximum timeout of ${maxTimeout / 1000}s`));\n\t\t}, maxTimeout);\n\n\t\t// Start inactivity timeout\n\t\tresetInactivityTimeout();\n\n\t\tchild.stdout?.on('data', data => {\n\t\t\tconst chunk = data.toString();\n\t\t\tstdout += chunk;\n\t\t\tif (onOutput) {\n\t\t\t\tonOutput(chunk);\n\t\t\t}\n\t\t\t// Reset inactivity timeout on any output\n\t\t\tresetInactivityTimeout();\n\t\t});\n\n\t\tchild.stderr?.on('data', data => {\n\t\t\tconst chunk = data.toString();\n\t\t\tstderr += chunk;\n\t\t\tif (onOutput) {\n\t\t\t\tonOutput(chunk);\n\t\t\t}\n\t\t\t// Reset inactivity timeout on any output (pre-commit hooks often write to stderr)\n\t\t\tresetInactivityTimeout();\n\t\t});\n\n\t\tchild.on('close', code => {\n\t\t\tclearTimeouts();\n\t\t\tif (code === 0) {\n\t\t\t\tresolve({ stdout, stderr });\n\t\t\t} else {\n\t\t\t\treject(new Error(`Command failed with exit code ${code}: ${stderr}`));\n\t\t\t}\n\t\t});\n\n\t\tchild.on('error', error => {\n\t\t\tclearTimeouts();\n\t\t\treject(error);\n\t\t});\n\t});\n}\n\n/**\n * Mock execution handler for testing\n */\nexport async function createMockExecHandler(\n\taddMessage?: (type: 'info' | 'error' | 'system', content: string) => void\n): Promise<(command: string) => Promise<ExecResult>> {\n\treturn async (command: string): Promise<ExecResult> => {\n\t\tif (addMessage) {\n\t\t\taddMessage('info', `🧪 TEST MODE: Simulating command: ${command}`);\n\t\t}\n\n\t\t// Simulate delays\n\t\tawait new Promise(resolve => setTimeout(resolve, 500));\n\n\t\t// Git commands\n\t\tif (command.includes('git branch --show-current')) {\n\t\t\treturn { stdout: 'feature/test-branch', stderr: '' };\n\t\t}\n\t\tif (command.includes('gh repo view')) {\n\t\t\treturn { stdout: 'main', stderr: '' };\n\t\t}\n\t\tif (command.includes('git checkout -b')) {\n\t\t\tconst branchName = command.split(' ').pop();\n\t\t\treturn { stdout: `Switched to a new branch '${branchName}'`, stderr: '' };\n\t\t}\n\t\tif (command.includes('git checkout main')) {\n\t\t\treturn { stdout: 'Switched to branch main', stderr: '' };\n\t\t}\n\t\tif (command.includes('git pull')) {\n\t\t\treturn { stdout: 'Already up to date.', stderr: '' };\n\t\t}\n\t\tif (command.includes('git add .')) {\n\t\t\treturn { stdout: '', stderr: '' };\n\t\t}\n\t\tif (command.includes('git diff --cached --quiet')) {\n\t\t\tthrow new Error('Changes to commit'); // Simulate changes exist\n\t\t}\n\t\tif (command.includes('git commit')) {\n\t\t\treturn { stdout: '[feature/test abc123] feat: mock commit', stderr: '' };\n\t\t}\n\t\tif (command.includes('git push')) {\n\t\t\tconst branchName = command.includes('feature/') ? 'feature/test-branch' : 'current-branch';\n\t\t\treturn {\n\t\t\t\tstdout: `To github.com:test/repo.git\\n * [new branch] ${branchName} -> ${branchName}\\nBranch '${branchName}' set up to track remote branch '${branchName}' from 'origin'.`,\n\t\t\t\tstderr: '',\n\t\t\t};\n\t\t}\n\n\t\t// CLI version checks\n\t\tif (command.includes('claude --version')) {\n\t\t\treturn { stdout: 'claude version 2.1.3', stderr: '' };\n\t\t}\n\t\tif (command.includes('gh --version')) {\n\t\t\treturn { stdout: 'gh version 2.40.1', stderr: '' };\n\t\t}\n\n\t\t// GitHub commands\n\t\tif (command.includes('gh pr create')) {\n\t\t\treturn { stdout: 'https://github.com/test/repo/pull/123', stderr: '' };\n\t\t}\n\n\t\t// Claude commands\n\t\tif (command.includes('Generate a conventional commit')) {\n\t\t\tconst taskTitle = command.includes('login')\n\t\t\t\t? 'login component'\n\t\t\t\t: command.includes('JWT')\n\t\t\t\t\t? 'JWT authentication'\n\t\t\t\t\t: command.includes('logout')\n\t\t\t\t\t\t? 'logout functionality'\n\t\t\t\t\t\t: 'test feature';\n\t\t\treturn { stdout: `feat(auth): add ${taskTitle}`, stderr: '' };\n\t\t}\n\t\tif (command.includes('Generate a comprehensive GitHub Pull Request')) {\n\t\t\treturn {\n\t\t\t\tstdout: `## Summary\\nImplemented mock authentication system with all required functionality.\\n\\n## Tasks Completed\\n- [x] Mock login component\\n- [x] Mock JWT authentication\\n- [x] Mock logout functionality\\n\\n## Testing\\nTest the mock implementation thoroughly.\\n\\n## Notes\\nThis is a test implementation.`,\n\t\t\t\tstderr: '',\n\t\t\t};\n\t\t}\n\t\tif (\n\t\t\tcommand.startsWith('claude -p --dangerously-skip-permissions \"') ||\n\t\t\tcommand.startsWith('claude -p \"') ||\n\t\t\tcommand.startsWith('claude \"')\n\t\t) {\n\t\t\t// Handle task content and other prompts\n\t\t\tconst taskTitle = command.includes('login')\n\t\t\t\t? 'Login Component'\n\t\t\t\t: command.includes('JWT')\n\t\t\t\t\t? 'JWT Authentication'\n\t\t\t\t\t: command.includes('logout')\n\t\t\t\t\t\t? 'Logout Functionality'\n\t\t\t\t\t\t: 'Test Feature';\n\t\t\treturn {\n\t\t\t\tstdout: `# ${taskTitle} Implementation\\n\\n## Files Created/Modified\\n- src/components/auth/${taskTitle.replace(' ', '')}.tsx\\n- src/hooks/useAuth.ts\\n- src/utils/auth.ts\\n\\n## Implementation Details\\nCreated comprehensive ${taskTitle.toLowerCase()} with modern React patterns, TypeScript support, and proper error handling.\\n\\n## Testing\\nAdded unit tests and integration tests for the ${taskTitle.toLowerCase()}.`,\n\t\t\t\tstderr: '',\n\t\t\t};\n\t\t}\n\n\t\t// Default response\n\t\treturn { stdout: 'Mock command executed successfully', stderr: '' };\n\t};\n}\n","import { execAsync } from '../utils/command-execution.js';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\n\nconst GITHUB_OWNER = 'BrainGridAI';\nconst GITHUB_REPO = 'braingrid';\nconst MAX_RETRIES = 3;\nconst INITIAL_RETRY_DELAY = 100;\n\n// Content injection markers\nconst BEGIN_MARKER = '<!-- BEGIN BRAINGRID INTEGRATION -->';\nconst END_MARKER = '<!-- END BRAINGRID INTEGRATION -->';\n\nexport interface GitHubFile {\n\tname: string;\n\ttype: 'file' | 'dir';\n\tpath: string;\n}\n\ninterface GitHubApiFileResponse {\n\tname: string;\n\tpath: string;\n\ttype: 'file' | 'dir';\n\tcontent?: string;\n\tencoding?: string;\n}\n\ninterface GitHubApiError {\n\tmessage: string;\n\tdocumentation_url?: string;\n}\n\n/**\n * Retry a function with exponential backoff\n */\nasync function withRetry<T>(\n\tfn: () => Promise<T>,\n\tretries: number = MAX_RETRIES,\n\tdelay: number = INITIAL_RETRY_DELAY\n): Promise<T> {\n\ttry {\n\t\treturn await fn();\n\t} catch (error) {\n\t\tif (retries === 0) {\n\t\t\tthrow error;\n\t\t}\n\n\t\t// Only retry on network errors, not on 404, 401, etc.\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tconst isNetworkError =\n\t\t\terrorMessage.includes('ECONNRESET') ||\n\t\t\terrorMessage.includes('ETIMEDOUT') ||\n\t\t\terrorMessage.includes('ENOTFOUND') ||\n\t\t\terrorMessage.includes('network');\n\n\t\tif (!isNetworkError) {\n\t\t\tthrow error;\n\t\t}\n\n\t\t// Wait before retrying\n\t\tawait new Promise(resolve => setTimeout(resolve, delay));\n\n\t\t// Retry with exponential backoff\n\t\treturn withRetry(fn, retries - 1, delay * 2);\n\t}\n}\n\n/**\n * Parse GitHub API error response\n */\nfunction parseGitHubError(error: unknown): string {\n\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\n\t// Check for specific GitHub API errors\n\tif (errorMessage.includes('404') || errorMessage.includes('Not Found')) {\n\t\treturn 'File or directory not found in BrainGrid repository';\n\t}\n\n\tif (errorMessage.includes('403') || errorMessage.includes('rate limit')) {\n\t\treturn 'GitHub API rate limit exceeded. Please wait a few minutes and try again.\\nCheck rate limit status: gh api rate_limit';\n\t}\n\n\tif (errorMessage.includes('401') || errorMessage.includes('Unauthorized')) {\n\t\treturn 'GitHub CLI is not authenticated. Run: gh auth login';\n\t}\n\n\t// Try to parse JSON error response\n\ttry {\n\t\tconst match = errorMessage.match(/\\{.*\\}/s);\n\t\tif (match) {\n\t\t\tconst errorData = JSON.parse(match[0]) as GitHubApiError;\n\t\t\treturn errorData.message || errorMessage;\n\t\t}\n\t} catch {\n\t\t// Not JSON, return original message\n\t}\n\n\treturn errorMessage;\n}\n\n/**\n * Fetch a single file from GitHub repository\n * @param path Path to file in repository (e.g., 'claude-code/README.md')\n * @returns File content as string\n */\nexport async function fetchFileFromGitHub(path: string): Promise<string> {\n\treturn withRetry(async () => {\n\t\ttry {\n\t\t\tconst command = `gh api repos/${GITHUB_OWNER}/${GITHUB_REPO}/contents/${path}`;\n\t\t\tconst { stdout } = await execAsync(command);\n\n\t\t\tconst response = JSON.parse(stdout) as GitHubApiFileResponse;\n\n\t\t\t// Verify it's a file\n\t\t\tif (response.type !== 'file') {\n\t\t\t\tthrow new Error(`Path ${path} is not a file`);\n\t\t\t}\n\n\t\t\t// Decode base64 content\n\t\t\tif (!response.content || !response.encoding) {\n\t\t\t\tthrow new Error(`No content found for file ${path}`);\n\t\t\t}\n\n\t\t\tif (response.encoding !== 'base64') {\n\t\t\t\tthrow new Error(`Unexpected encoding: ${response.encoding}`);\n\t\t\t}\n\n\t\t\t// Decode base64 content\n\t\t\tconst content = Buffer.from(response.content, 'base64').toString('utf8');\n\t\t\treturn content;\n\t\t} catch (error) {\n\t\t\tconst parsedError = parseGitHubError(error);\n\t\t\tthrow new Error(`Failed to fetch file ${path}: ${parsedError}`);\n\t\t}\n\t});\n}\n\n/**\n * List files and directories in a GitHub repository directory\n * @param path Path to directory in repository (e.g., 'claude-code/commands')\n * @returns Array of files and directories\n */\nexport async function listGitHubDirectory(path: string): Promise<GitHubFile[]> {\n\treturn withRetry(async () => {\n\t\ttry {\n\t\t\tconst command = `gh api repos/${GITHUB_OWNER}/${GITHUB_REPO}/contents/${path}`;\n\t\t\tconst { stdout } = await execAsync(command);\n\n\t\t\tconst response = JSON.parse(stdout) as GitHubApiFileResponse | GitHubApiFileResponse[];\n\n\t\t\t// Handle single file response (shouldn't happen but be safe)\n\t\t\tif (!Array.isArray(response)) {\n\t\t\t\tthrow new Error(`Path ${path} is not a directory`);\n\t\t\t}\n\n\t\t\t// Map to GitHubFile interface\n\t\t\treturn response.map(item => ({\n\t\t\t\tname: item.name,\n\t\t\t\ttype: item.type,\n\t\t\t\tpath: item.path,\n\t\t\t}));\n\t\t} catch (error) {\n\t\t\tconst parsedError = parseGitHubError(error);\n\t\t\tthrow new Error(`Failed to list directory ${path}: ${parsedError}`);\n\t\t}\n\t});\n}\n\n/**\n * Copy a single file from GitHub to local filesystem\n * @param sourcePath Path to file in GitHub repository\n * @param targetPath Local file path to write to\n */\nexport async function copyFileFromGitHub(sourcePath: string, targetPath: string): Promise<void> {\n\ttry {\n\t\t// Fetch file content from GitHub\n\t\tconst content = await fetchFileFromGitHub(sourcePath);\n\n\t\t// Create parent directories if they don't exist\n\t\tconst parentDir = path.dirname(targetPath);\n\t\tawait fs.mkdir(parentDir, { recursive: true });\n\n\t\t// Write file to local filesystem\n\t\tawait fs.writeFile(targetPath, content, { encoding: 'utf8', mode: 0o644 });\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to copy file ${sourcePath} to ${targetPath}: ${errorMessage}`);\n\t}\n}\n\n/**\n * Copy a directory recursively from GitHub to local filesystem\n *\n * This is a utility function for bulk directory copying with conflict detection.\n * Note: Not currently used by setup command handlers, which use a file-by-file approach\n * for better user experience (progress tracking and interactive conflict resolution).\n * Kept as a utility for future integrations, advanced use cases, or manual scripts.\n *\n * @param sourcePath Path to directory in GitHub repository\n * @param targetPath Local directory path to write to\n * @param existingFiles Set of files that already exist (for conflict tracking)\n * @returns Array of file paths that already exist locally (conflicts)\n */\nexport async function copyDirectoryFromGitHub(\n\tsourcePath: string,\n\ttargetPath: string,\n\texistingFiles: Set<string> = new Set()\n): Promise<string[]> {\n\tconst conflicts: string[] = [];\n\n\ttry {\n\t\t// List directory contents from GitHub\n\t\tconst items = await listGitHubDirectory(sourcePath);\n\n\t\t// Create target directory\n\t\tawait fs.mkdir(targetPath, { recursive: true });\n\n\t\t// Process each item\n\t\tfor (const item of items) {\n\t\t\tconst itemTargetPath = path.join(targetPath, item.name);\n\n\t\t\tif (item.type === 'file') {\n\t\t\t\t// Check if file already exists\n\t\t\t\ttry {\n\t\t\t\t\tawait fs.access(itemTargetPath);\n\t\t\t\t\t// File exists, add to conflicts\n\t\t\t\t\tconflicts.push(itemTargetPath);\n\t\t\t\t\texistingFiles.add(itemTargetPath);\n\t\t\t\t} catch {\n\t\t\t\t\t// File doesn't exist, will be created\n\t\t\t\t}\n\t\t\t} else if (item.type === 'dir') {\n\t\t\t\t// Recursively copy subdirectory\n\t\t\t\tconst subConflicts = await copyDirectoryFromGitHub(\n\t\t\t\t\titem.path,\n\t\t\t\t\titemTargetPath,\n\t\t\t\t\texistingFiles\n\t\t\t\t);\n\t\t\t\tconflicts.push(...subConflicts);\n\t\t\t}\n\t\t}\n\n\t\treturn conflicts;\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to copy directory ${sourcePath} to ${targetPath}: ${errorMessage}`);\n\t}\n}\n\n/**\n * Inject content into a file using markers\n * If file exists with markers, replace content between markers\n * If file exists without markers, append new section with markers\n * If file doesn't exist, create with content wrapped in markers\n * @param targetPath Local file path\n * @param content Content to inject\n */\nexport async function injectContentIntoFile(targetPath: string, content: string): Promise<void> {\n\ttry {\n\t\tlet fileContent: string;\n\t\tlet fileExists = false;\n\n\t\t// Check if file exists\n\t\ttry {\n\t\t\tfileContent = await fs.readFile(targetPath, 'utf8');\n\t\t\tfileExists = true;\n\t\t} catch {\n\t\t\tfileContent = '';\n\t\t}\n\n\t\tif (fileExists) {\n\t\t\t// File exists, check for existing markers\n\t\t\tconst beginIndex = fileContent.indexOf(BEGIN_MARKER);\n\t\t\tconst endIndex = fileContent.indexOf(END_MARKER);\n\n\t\t\tif (beginIndex !== -1 && endIndex !== -1 && endIndex > beginIndex) {\n\t\t\t\t// Markers found, replace content between them\n\t\t\t\tconst before = fileContent.substring(0, beginIndex);\n\t\t\t\tconst after = fileContent.substring(endIndex + END_MARKER.length);\n\t\t\t\tconst newContent = `${before}${BEGIN_MARKER}\\n${content}\\n${END_MARKER}${after}`;\n\t\t\t\tawait fs.writeFile(targetPath, newContent, { encoding: 'utf8' });\n\t\t\t} else {\n\t\t\t\t// No markers found, append new section\n\t\t\t\tconst newContent = `${fileContent}\\n\\n${BEGIN_MARKER}\\n${content}\\n${END_MARKER}\\n`;\n\t\t\t\tawait fs.writeFile(targetPath, newContent, { encoding: 'utf8' });\n\t\t\t}\n\t\t} else {\n\t\t\t// File doesn't exist, create with markers\n\t\t\tconst parentDir = path.dirname(targetPath);\n\t\t\tawait fs.mkdir(parentDir, { recursive: true });\n\n\t\t\tconst newContent = `${BEGIN_MARKER}\\n${content}\\n${END_MARKER}\\n`;\n\t\t\tawait fs.writeFile(targetPath, newContent, { encoding: 'utf8', mode: 0o644 });\n\t\t}\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to inject content into ${targetPath}: ${errorMessage}`);\n\t}\n}\n\n/**\n * Install status line script to .claude directory\n * @param scriptContent Content of the status line script\n * @param targetPath Path to install script (default: .claude/statusline.sh)\n */\nexport async function installStatusLineScript(\n\tscriptContent: string,\n\ttargetPath: string = '.claude/statusline.sh'\n): Promise<void> {\n\ttry {\n\t\t// Ensure .claude directory exists\n\t\tconst parentDir = path.dirname(targetPath);\n\t\tawait fs.mkdir(parentDir, { recursive: true });\n\n\t\t// Write script file with executable permissions\n\t\tawait fs.writeFile(targetPath, scriptContent, { encoding: 'utf8', mode: 0o755 });\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to install status line script to ${targetPath}: ${errorMessage}`);\n\t}\n}\n\n/**\n * Update Claude Code settings.json with status line configuration\n * @param settingsPath Path to settings.json (default: .claude/settings.json)\n * @param scriptPath Path to status line script (default: .claude/statusline.sh)\n */\nexport async function updateClaudeSettings(\n\tsettingsPath: string = '.claude/settings.json',\n\tscriptPath: string = '.claude/statusline.sh'\n): Promise<void> {\n\ttry {\n\t\tlet settings: Record<string, unknown> = {};\n\n\t\t// Read existing settings if file exists\n\t\ttry {\n\t\t\tconst content = await fs.readFile(settingsPath, 'utf8');\n\t\t\tsettings = JSON.parse(content) as Record<string, unknown>;\n\t\t} catch {\n\t\t\t// File doesn't exist or is invalid, start with empty settings\n\t\t}\n\n\t\t// Update statusLine configuration with correct format\n\t\tsettings.statusLine = {\n\t\t\ttype: 'command',\n\t\t\tcommand: scriptPath,\n\t\t\tpadding: 0,\n\t\t};\n\n\t\t// Ensure .claude directory exists\n\t\tconst parentDir = path.dirname(settingsPath);\n\t\tawait fs.mkdir(parentDir, { recursive: true });\n\n\t\t// Write updated settings\n\t\tconst content = JSON.stringify(settings, null, 2);\n\t\tawait fs.writeFile(settingsPath, content, { encoding: 'utf8' });\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to update Claude settings at ${settingsPath}: ${errorMessage}`);\n\t}\n}\n","/**\n * GitHub Repository Utilities\n *\n * Provides functions to automate GitHub repository creation and setup using GitHub CLI.\n * Falls back to manual instructions when automation is not available.\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport path from 'path';\n\nconst execAsync = promisify(exec);\n\nexport interface RepoInfo {\n\towner: string;\n\tname: string;\n\turl: string;\n}\n\n/**\n * Initialize a git repository in the current directory\n */\nexport async function initGitRepo(): Promise<boolean> {\n\ttry {\n\t\tawait execAsync('git init');\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Check if GitHub CLI is authenticated (internal use only)\n */\nasync function isGhAuthenticated(): Promise<boolean> {\n\ttry {\n\t\tawait execAsync('gh auth status');\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Get the current directory name (for suggesting repository name)\n */\nexport function getCurrentDirectoryName(): string {\n\treturn path.basename(process.cwd());\n}\n\n/**\n * Create a GitHub repository using GitHub CLI\n *\n * @param name - Repository name\n * @param isPrivate - Whether the repository should be private\n * @returns Repository information or null if failed\n */\nexport async function createGitHubRepoWithGh(\n\tname: string,\n\tisPrivate: boolean\n): Promise<RepoInfo | null> {\n\ttry {\n\t\tconst visibility = isPrivate ? '--private' : '--public';\n\n\t\t// Create repository with gh CLI\n\t\t// --source=. creates repo from current directory and adds remote\n\t\tconst { stdout } = await execAsync(\n\t\t\t`gh repo create ${name} ${visibility} --source=. --remote=origin`,\n\t\t\t{ timeout: 60000 }\n\t\t);\n\n\t\t// Parse the repository URL from output\n\t\tconst urlMatch = stdout.match(/https:\\/\\/github\\.com\\/([^/]+)\\/([^/\\s]+)/);\n\t\tif (!urlMatch) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\towner: urlMatch[1],\n\t\t\tname: urlMatch[2],\n\t\t\turl: urlMatch[0],\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Check if we can use GitHub CLI automation\n * (both GitHub CLI installed and authenticated)\n */\nexport async function canUseGhAutomation(): Promise<boolean> {\n\tconst { isGhInstalled } = await import('./gh-installer.js');\n\tconst ghInstalled = await isGhInstalled();\n\n\tif (!ghInstalled) {\n\t\treturn false;\n\t}\n\n\treturn isGhAuthenticated();\n}\n","/**\n * Update Handler\n *\n * Handles the update command which:\n * - Detects which package manager was used to install the CLI\n * - Checks for available updates\n * - Updates the CLI to the latest version\n */\n\nimport chalk from 'chalk';\nimport axios from 'axios';\nimport { detectPackageManager, executeUpdate, getUpdateCommand } from '../utils/package-manager.js';\nimport { formatError } from '../utils/error-formatter.js';\nimport { CLI_VERSION } from '../build-config.js';\nimport type { HandlerResult } from './types.js';\n\nconst PACKAGE_NAME = '@braingrid/cli';\nconst NPM_REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}`;\n\n/**\n * Get the current version of the CLI from build config\n * Version is injected at build time from package.json\n */\nfunction getCurrentVersion(): string {\n\treturn CLI_VERSION;\n}\n\n/**\n * Get the latest version from npm registry\n */\nasync function getLatestVersion(): Promise<string> {\n\ttry {\n\t\tconst response = await axios.get(NPM_REGISTRY_URL, {\n\t\t\ttimeout: 10000,\n\t\t});\n\n\t\treturn response.data['dist-tags'].latest;\n\t} catch (error) {\n\t\tthrow new Error(`Failed to fetch latest version: ${formatError(error)}`);\n\t}\n}\n\n/**\n * Compare two semver versions\n * Returns: -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2\n */\nfunction compareVersions(v1: string, v2: string): number {\n\tconst v1Parts = v1.split('.').map(Number);\n\tconst v2Parts = v2.split('.').map(Number);\n\n\tfor (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {\n\t\tconst v1Part = v1Parts[i] || 0;\n\t\tconst v2Part = v2Parts[i] || 0;\n\n\t\tif (v1Part < v2Part) return -1;\n\t\tif (v1Part > v2Part) return 1;\n\t}\n\n\treturn 0;\n}\n\n/**\n * Handle the update command\n */\nexport async function handleUpdate(opts: { check?: boolean }): Promise<HandlerResult> {\n\ttry {\n\t\tconst currentVersion = getCurrentVersion();\n\t\tlet output = chalk.bold.cyan('\\n🔄 BrainGrid CLI Update\\n\\n');\n\n\t\toutput += `${chalk.bold('Current version:')} ${currentVersion}\\n`;\n\n\t\t// Check for latest version\n\t\toutput += chalk.dim('Checking for updates...\\n');\n\t\tconst latestVersion = await getLatestVersion();\n\t\toutput += `${chalk.bold('Latest version:')} ${latestVersion}\\n\\n`;\n\n\t\t// Compare versions\n\t\tconst comparison = compareVersions(currentVersion, latestVersion);\n\n\t\tif (comparison === 0) {\n\t\t\toutput += chalk.green('✅ You are already on the latest version!\\n');\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: output,\n\t\t\t\tdata: { currentVersion, latestVersion, upToDate: true },\n\t\t\t};\n\t\t}\n\n\t\tif (comparison > 0) {\n\t\t\toutput += chalk.yellow('⚠️ You are on a newer version than what is published.\\n');\n\t\t\toutput += chalk.dim(' This is expected if you are developing locally.\\n');\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: output,\n\t\t\t\tdata: { currentVersion, latestVersion, upToDate: false },\n\t\t\t};\n\t\t}\n\n\t\t// Update available\n\t\toutput += chalk.yellow(`⬆️ Update available: ${currentVersion} → ${latestVersion}\\n\\n`);\n\n\t\t// If --check flag, just show the info and exit\n\t\tif (opts.check) {\n\t\t\toutput += chalk.dim('Run ') + chalk.cyan('braingrid update') + chalk.dim(' to update\\n');\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: output,\n\t\t\t\tdata: { currentVersion, latestVersion, upToDate: false },\n\t\t\t};\n\t\t}\n\n\t\t// Detect package manager\n\t\toutput += chalk.dim('Detecting package manager...\\n');\n\t\tconst packageManager = await detectPackageManager(PACKAGE_NAME);\n\t\toutput += `${chalk.bold('Package manager:')} ${packageManager}\\n\\n`;\n\n\t\t// Show update command\n\t\tconst updateCommand = getUpdateCommand(packageManager, PACKAGE_NAME);\n\t\toutput += chalk.dim('Running: ') + chalk.cyan(updateCommand) + '\\n\\n';\n\n\t\tconsole.log(output);\n\n\t\t// Execute update\n\t\texecuteUpdate(packageManager, PACKAGE_NAME);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: chalk.green('\\n✅ Successfully updated BrainGrid CLI!\\n'),\n\t\t\tdata: { currentVersion, latestVersion, packageManager },\n\t\t};\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: formatError(error),\n\t\t};\n\t}\n}\n","/**\n * Package Manager Detection Utility\n *\n * Detects which package manager (npm, pnpm, yarn) was used to install the CLI\n * by checking global installation directories.\n */\n\nimport { execSync } from 'child_process';\nimport { select } from '@inquirer/prompts';\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn';\n\ninterface PackageManagerInfo {\n\tname: PackageManager;\n\tinstalled: boolean;\n\thasPackage: boolean;\n}\n\n/**\n * Check if a package manager is installed on the system\n */\nfunction isPackageManagerInstalled(pm: PackageManager): boolean {\n\ttry {\n\t\texecSync(`which ${pm}`, { stdio: 'ignore', timeout: 2000 });\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Check if the CLI package is installed globally with a specific package manager\n */\nfunction checkGlobalInstallation(pm: PackageManager, packageName: string): boolean {\n\ttry {\n\t\tlet command: string;\n\n\t\tswitch (pm) {\n\t\t\tcase 'npm': {\n\t\t\t\tcommand = `npm list -g ${packageName} 2>&1`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'pnpm': {\n\t\t\t\tcommand = `pnpm list -g ${packageName} 2>&1`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'yarn': {\n\t\t\t\tcommand = `yarn global list 2>&1`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tconst output = execSync(command, {\n\t\t\tencoding: 'utf-8',\n\t\t\ttimeout: 5000,\n\t\t});\n\n\t\t// For npm and pnpm, check if output contains the package name and not \"(empty)\"\n\t\tif (pm === 'npm' || pm === 'pnpm') {\n\t\t\treturn output.includes(packageName) && !output.includes('(empty)');\n\t\t}\n\n\t\t// For yarn, check if package is in the list\n\t\tif (pm === 'yarn') {\n\t\t\treturn output.includes(packageName);\n\t\t}\n\n\t\treturn false;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Get information about available package managers and whether they have the CLI installed\n */\nexport async function getPackageManagerInfo(packageName: string): Promise<PackageManagerInfo[]> {\n\tconst packageManagers: PackageManager[] = ['npm', 'pnpm', 'yarn'];\n\n\treturn packageManagers.map(pm => {\n\t\tconst installed = isPackageManagerInstalled(pm);\n\t\treturn {\n\t\t\tname: pm,\n\t\t\tinstalled,\n\t\t\thasPackage: installed ? checkGlobalInstallation(pm, packageName) : false,\n\t\t};\n\t});\n}\n\n/**\n * Detect which package manager was used to install the CLI\n * Returns the detected package manager or prompts the user if detection fails\n */\nexport async function detectPackageManager(packageName: string): Promise<PackageManager> {\n\tconst pmInfo = await getPackageManagerInfo(packageName);\n\n\t// First, check if any package manager has the package installed\n\tconst installedWith = pmInfo.find(pm => pm.hasPackage);\n\n\tif (installedWith) {\n\t\treturn installedWith.name;\n\t}\n\n\t// If detection failed, check which package managers are available and prompt\n\tconst availablePMs = pmInfo.filter(pm => pm.installed);\n\n\tif (availablePMs.length === 0) {\n\t\tthrow new Error('No package manager found. Please install npm, pnpm, or yarn.');\n\t}\n\n\tif (availablePMs.length === 1) {\n\t\treturn availablePMs[0].name;\n\t}\n\n\t// Multiple package managers available, prompt user\n\tconst selected = await select({\n\t\tmessage: 'Unable to detect which package manager was used. Please select one:',\n\t\tchoices: availablePMs.map(pm => ({\n\t\t\tname: pm.name,\n\t\t\tvalue: pm.name,\n\t\t})),\n\t});\n\n\treturn selected as PackageManager;\n}\n\n/**\n * Get the update command for a specific package manager\n */\nexport function getUpdateCommand(pm: PackageManager, packageName: string): string {\n\tswitch (pm) {\n\t\tcase 'npm': {\n\t\t\treturn `npm install -g ${packageName}@latest`;\n\t\t}\n\t\tcase 'pnpm': {\n\t\t\treturn `pnpm add -g ${packageName}@latest`;\n\t\t}\n\t\tcase 'yarn': {\n\t\t\treturn `yarn global add ${packageName}@latest`;\n\t\t}\n\t}\n}\n\n/**\n * Execute the update command\n */\nexport function executeUpdate(pm: PackageManager, packageName: string): void {\n\tconst command = getUpdateCommand(pm, packageName);\n\n\ttry {\n\t\texecSync(command, {\n\t\t\tstdio: 'inherit',\n\t\t\ttimeout: 120000, // 2 minutes timeout\n\t\t});\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to update package: ${error instanceof Error ? error.message : String(error)}`\n\t\t);\n\t}\n}\n"],"mappings":"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","names":["chalk","axios","axios","axios","AxiosError","logger","axios","AxiosError","validationResult","axios","chalk","error","chalk","input","input","chalk","fs","path","path","fs","input","chalk","chalk","chalk","input","chalk","task","requirement","chalk","task","task","requirement","project","chalk","project","stop","chalk","getServices","chalk","requirement","task","chalk","getServices","chalk","task","chalk","logger","chalk","chalk","getAuth","chalk","gitInfo","installedTools","chalk","select","exec","promisify","chalk","execAsync","promisify","exec","chalk","chalk","path","fs","exec","promisify","execAsync","fs","path","execAsync","fileExists","content","execAsync","chalk","access","exec","promisify","path","execAsync","isGhInstalled","fileExists","access","getServices","chalk","project","select","chalk","axios","select","axios","chalk","require"]}
|